From 099cc3aaf3c60b3885831a567e91ce97c0ecd537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Mon, 9 Dec 2024 11:10:57 +0100 Subject: [PATCH 1/8] Add ci workflows --- .github/workflows/android-test.yml | 99 ++++++++++++++++++++++++++++++ .github/workflows/changelog.yml | 3 +- .github/workflows/ci.yml | 67 ++++++++++++++++++++ 3 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/android-test.yml create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/android-test.yml b/.github/workflows/android-test.yml new file mode 100644 index 0000000..e499e2f --- /dev/null +++ b/.github/workflows/android-test.yml @@ -0,0 +1,99 @@ +name: Android Emulator Tests +on: [ push, pull_request ] + +jobs: + check-if-tests-exist: + runs-on: ubuntu-latest + outputs: + status: ${{ steps.check-androidTest.outputs.NOT_EMPTY }} + min-sdk-version: ${{ steps.get-sdk-version.outputs.MIN_SDK_VERSION }} + target-sdk-version: ${{ steps.get-sdk-version.outputs.TARGET_SDK_VERSION }} + app-id: ${{ steps.get-app-id.outputs.APP_ID }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "recursive" + - name: Check if androidTest folder is not empty + run: | + echo "NOT_EMPTY=$([ "$(ls -A app/src/androidTest)" ] && echo 'true' || echo 'false')" + echo "NOT_EMPTY=$([ "$(ls -A app/src/androidTest)" ] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT + id: check-androidTest + - name: Get min and target sdk + if: steps.check-androidTest.outputs.NOT_EMPTY == 'true' + id: get-sdk-version + run: | + echo "MIN_SDK_VERSION=$(cat app/build.gradle | grep minSdkVersion | rev | cut -d' ' -f 1 | rev)" >> $GITHUB_OUTPUT + echo "TARGET_SDK_VERSION=$(cat app/build.gradle | grep targetSdkVersion | rev | cut -d' ' -f 1 | rev)" >> $GITHUB_OUTPUT + - name: Get app ID + id: get-app-id + run: | + echo "APP_ID=$(cat app/build.gradle | grep applicationId | rev | cut -d' ' -f 1 | rev | tr -d '"')" >> $GITHUB_OUTPUT + + test: + needs: check-if-tests-exist + if: needs.check-if-tests-exist.outputs.status == 'true' + runs-on: ubuntu-latest + strategy: + matrix: + api-level: [34, "${{ needs.check-if-tests-exist.outputs.min-sdk-version }}", "${{ needs.check-if-tests-exist.outputs.target-sdk-version }}"] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Gradle cache + uses: gradle/gradle-build-action@v3 + + - name: AVD cache + uses: actions/cache@v4 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-${{ matrix.api-level }} + + - name: Set up JDK environment + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 17 + + - name: create AVD and generate snapshot for caching + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: ${{ matrix.api-level >= 30 && 'google_apis' || 'default' }} + arch: ${{ matrix.api-level < 21 && 'x86' || 'x86_64' }} + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: false + script: echo "Generated AVD snapshot for caching." + + - name: Run connected tests + uses: ReactiveCircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: ${{ matrix.api-level >= 30 && 'google_apis' || 'default' }} + arch: ${{ matrix.api-level < 21 && 'x86' || 'x86_64' }} + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + script: | + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}} || true + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.test || true + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.androidTest || true + chmod +x gradlew + ./gradlew :app:connectedCheck --stacktrace + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}} || true + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.test || true + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.androidTest || true diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index ad4099a..6e50db1 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -2,7 +2,7 @@ name: Changelog Generation on: release: - types: [published, released] + types: [published] workflow_dispatch: jobs: @@ -16,6 +16,7 @@ jobs: - uses: rhysd/changelog-from-release/action@v3 with: file: CHANGELOG.md + pull_request: true github_token: ${{ secrets.GITHUB_TOKEN }} commit_summary_template: 'update changelog for %s changes' args: -l 2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fe5b0a9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +name: Continuous Integration +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "recursive" + + - name: Set up JDK environment + uses: actions/setup-java@v3 + with: + distribution: "zulu" + java-version: 17 + + - name: Make gradlew executable + run: chmod +x ./gradlew + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Run local unit tests + run: bash ./gradlew test --stacktrace + + build: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "recursive" + + - name: Set up JDK environment + uses: actions/setup-java@v3 + with: + distribution: "zulu" + java-version: 17 + + - name: Make gradlew executable + run: chmod +x ./gradlew + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Run lint check + run: bash ./gradlew lint + + - name: Upload lint result + uses: actions/upload-artifact@v4 + with: + name: lint-results-debug + path: app/build/reports/lint-results-debug.html + + - name: Build the app + run: bash ./gradlew build --stacktrace + + - name: Build debug apk + run: bash ./gradlew assembleDebug + + - name: Upload debug apk + uses: actions/upload-artifact@v4 + with: + name: debug-apk + path: app/build/outputs/apk/debug/*.apk \ No newline at end of file From 43a1c8e418c0c59038ac50e884a36d32b649bad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Mon, 9 Dec 2024 11:25:07 +0100 Subject: [PATCH 2/8] Update test dependencies --- app/build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 796d075..d78e476 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,8 +76,9 @@ dependencies { // tests testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:2.7.6' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test:rules:1.1.1' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test:rules:1.5.1' + androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.2' testImplementation 'pl.pragmatists:JUnitParams:0.3.6' // dependency injection implementation 'com.squareup.dagger:dagger:1.2.5' From 2639f1a68a6cd00a3ff763d62c0c8b20d9fff83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Mon, 9 Dec 2024 11:25:36 +0100 Subject: [PATCH 3/8] Fix tests in `DateUtilsTest.java` --- .../framework/utils/DateUtilsTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/test/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/framework/utils/DateUtilsTest.java b/app/src/test/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/framework/utils/DateUtilsTest.java index e0967e9..439f2dc 100644 --- a/app/src/test/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/framework/utils/DateUtilsTest.java +++ b/app/src/test/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/framework/utils/DateUtilsTest.java @@ -34,14 +34,14 @@ private DataAsStringTestCaseBuilder[] parametersForFormattedDateString() .setInputPattern(DateUtils.ISO_PATTERN_MIN) .setOutputPaterrn(DE_PATTERN) .setLanguage(DateUtils.DE) - .setExpectedDate("Mi 29.06.2016 15:37"), + .setExpectedDate("Mi. 29.06.2016 15:37"), new DataAsStringTestCaseBuilder() .setInputDate("2016-06-29 15:37") .setInputPattern(DateUtils.ISO_PATTERN_MIN) .setOutputPaterrn(JA_PATTERN) .setLanguage(DateUtils.JA) - .setExpectedDate("2016/06/29 … 15:37"), + .setExpectedDate("2016/06/29 水 15:37"), new DataAsStringTestCaseBuilder() .setInputDate("Wed 06/29/2016 15:37") @@ -51,14 +51,14 @@ private DataAsStringTestCaseBuilder[] parametersForFormattedDateString() .setExpectedDate("2016-06-29 15:37"), new DataAsStringTestCaseBuilder() - .setInputDate("Mi 29.06.2016 15:37") + .setInputDate("Mi. 29.06.2016 15:37") .setInputPattern(DE_PATTERN) .setOutputPaterrn(DateUtils.ISO_PATTERN_MIN) .setLanguage(DateUtils.DE) .setExpectedDate("2016-06-29 15:37"), new DataAsStringTestCaseBuilder() - .setInputDate("2016/06/29 … 15:37") + .setInputDate("2016/06/29 水 15:37") .setInputPattern(JA_PATTERN) .setOutputPaterrn(DateUtils.ISO_PATTERN_MIN) .setLanguage(DateUtils.JA) From 25232429b3998950e13ed0db9a541c0b56d6dd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Mon, 9 Dec 2024 12:18:08 +0100 Subject: [PATCH 4/8] Attempt to fix androidTests --- app/build.gradle | 7 ++- .../AbstractDatabaseTest.java | 26 +++++----- .../ApplicationTest.java | 25 +++++++--- .../MainActivityBasicTest.kt | 26 ++++++++++ .../product/business/ProductServiceTest.java | 48 +++++++++---------- .../ProductConverterServiceTest.java | 20 ++++---- .../persistence/ProductItemDaoTest.java | 24 +++++----- .../business/ShoppingListServiceTest.java | 5 ++ .../persistence/ShoppingListDaoTest.java | 32 ++++++------- .../persistence/StatisticsDaoTest.java | 7 ++- build.gradle | 2 - 11 files changed, 137 insertions(+), 85 deletions(-) create mode 100644 app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/MainActivityBasicTest.kt diff --git a/app/build.gradle b/app/build.gradle index d78e476..dae964b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,11 +6,13 @@ android { defaultConfig { applicationId "privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist" - minSdkVersion 17 + minSdkVersion 19 targetSdkVersion 33 versionCode 8 versionName "1.1" multiDexEnabled true + + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { @@ -77,7 +79,8 @@ dependencies { testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:2.7.6' androidTestImplementation 'androidx.test.ext:junit:1.2.1' - androidTestImplementation 'androidx.test:rules:1.5.1' + androidTestImplementation 'androidx.test:rules:1.6.1' + androidTestImplementation 'androidx.test:core:1.6.1' androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.2' testImplementation 'pl.pragmatists:JUnitParams:0.3.6' // dependency injection diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/AbstractDatabaseTest.java b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/AbstractDatabaseTest.java index b0b2e6e..468e912 100644 --- a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/AbstractDatabaseTest.java +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/AbstractDatabaseTest.java @@ -1,8 +1,12 @@ package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist; -import android.support.test.runner.AndroidJUnit4; -import android.test.AndroidTestCase; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.After; +import org.junit.Before; import org.junit.runner.RunWith; + import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.framework.persistence.DB; /** @@ -11,24 +15,22 @@ * Created: 31.05.16 creation date */ @RunWith(AndroidJUnit4.class) -abstract public class AbstractDatabaseTest extends AndroidTestCase -{ +abstract public class AbstractDatabaseTest { - protected void setUp() throws Exception - { - super.setUp(); + @Before + public void setUp() throws Exception { // delete database before each test - getContext().deleteDatabase(DB.TEST.getDbName()); + InstrumentationRegistry.getInstrumentation().getContext().deleteDatabase(DB.TEST.getDbName()); setupBeforeEachTest(); } - protected void tearDown() throws Exception - { - super.tearDown(); + @After + public void tearDown() throws Exception { cleanAfterEachTest(); } abstract protected void setupBeforeEachTest(); - protected void cleanAfterEachTest(){} + protected void cleanAfterEachTest() { + } } diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/ApplicationTest.java b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/ApplicationTest.java index 1422994..032a31f 100644 --- a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/ApplicationTest.java +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/ApplicationTest.java @@ -1,15 +1,26 @@ package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist; -import android.app.Application; -import android.test.ApplicationTestCase; +import static org.junit.Assert.assertEquals; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Test; +import org.junit.runner.RunWith; /** * Testing Fundamentals */ -public class ApplicationTest extends ApplicationTestCase -{ - public ApplicationTest() - { - super(Application.class); +@RunWith(AndroidJUnit4.class) +public class ApplicationTest { + @Test + public void useApplicationContext() { + assertEquals("privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist", ApplicationProvider.getApplicationContext().getPackageName()); + } + + @Test + public void useContext() { + assertEquals("privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.test", InstrumentationRegistry.getInstrumentation().getContext().getPackageName()); } } \ No newline at end of file diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/MainActivityBasicTest.kt b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/MainActivityBasicTest.kt new file mode 100644 index 0000000..30f9685 --- /dev/null +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/MainActivityBasicTest.kt @@ -0,0 +1,26 @@ +package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.ext.junit.rules.ActivityScenarioRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.ui.main.MainActivity + +@RunWith(AndroidJUnit4::class) +class MainActivityBasicTest { + @get: Rule + var mActivityRule = ActivityScenarioRule(MainActivity::class.java) + + @Test + fun launchActivity() { + } + + @Test + fun openDrawer() { + onView(withContentDescription(R.string.navigation_drawer_open)).perform(click()) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/business/ProductServiceTest.java b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/business/ProductServiceTest.java index 9658d29..9d748a5 100644 --- a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/business/ProductServiceTest.java +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/business/ProductServiceTest.java @@ -1,8 +1,19 @@ package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.product.business; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + import android.content.res.Resources; + +import androidx.test.platform.app.InstrumentationRegistry; + import org.joda.time.DateTime; import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.AbstractDatabaseTest; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.R; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.framework.context.AbstractInstanceFactory; @@ -13,16 +24,12 @@ import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.shoppingList.business.ShoppingListService; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.shoppingList.business.domain.ListItem; -import java.util.Arrays; -import java.util.List; - /** * Description: * Author: Grebiel Jose Ifill Brito * Created: 17.07.16 creation date */ -public class ProductServiceTest extends AbstractDatabaseTest -{ +public class ProductServiceTest extends AbstractDatabaseTest { private ProductService productService; private ShoppingListService shoppingListService; @@ -33,14 +40,13 @@ public class ProductServiceTest extends AbstractDatabaseTest private String language; @Override - protected void setupBeforeEachTest() - { - AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(getContext()); + protected void setupBeforeEachTest() { + AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(InstrumentationRegistry.getInstrumentation().getContext()); productService = (ProductService) instanceFactory.createInstance(ProductService.class); shoppingListService = (ShoppingListService) instanceFactory.createInstance(ShoppingListService.class); productItemDao = (ProductItemDao) instanceFactory.createInstance(ProductItemDao.class); - Resources resources = getContext().getResources(); + Resources resources = InstrumentationRegistry.getInstrumentation().getContext().getResources(); shortDatePattern = resources.getString(R.string.date_short_pattern); timePattern = resources.getString(R.string.time_pattern); language = resources.getString(R.string.language); @@ -67,8 +73,7 @@ protected void setupBeforeEachTest() } @Test - public void testSaveProductItem() - { + public void testSaveProductItem() { ProductItem item = getDefaultItem(); productService.saveOrUpdate(item, listId).toBlocking().single(); @@ -77,8 +82,7 @@ public void testSaveProductItem() } @Test - public void testGetById() - { + public void testGetById() { ProductItem item = getDefaultItem(); productService.saveOrUpdate(item, listId).toBlocking().single(); @@ -87,8 +91,7 @@ public void testGetById() } @Test - public void testDeleteById() - { + public void testDeleteById() { ProductItem item = getDefaultItem(); productService.saveOrUpdate(item, listId).toBlocking().single(); @@ -99,8 +102,7 @@ public void testDeleteById() } @Test - public void testDeleteSelected() - { + public void testDeleteSelected() { ProductItem item1 = getDefaultItem(); item1.setSelectedForDeletion(false); productService.saveOrUpdate(item1, listId).toBlocking().single(); @@ -121,8 +123,7 @@ public void testDeleteSelected() } @Test - public void testGetAllProducts() - { + public void testGetAllProducts() { ProductItem item1 = getDefaultItem(); productService.saveOrUpdate(item1, listId).toBlocking().single(); @@ -140,8 +141,7 @@ public void testGetAllProducts() } @Test - public void testMoveSelectedToEnd() - { + public void testMoveSelectedToEnd() { ProductItem item1 = getDefaultItem(); item1.setChecked(true); ProductItem item2 = getDefaultItem(); @@ -154,8 +154,7 @@ public void testMoveSelectedToEnd() } @Test - public void testDeleteProductsWhenListIsDeleted() - { + public void testDeleteProductsWhenListIsDeleted() { ProductItem item1 = getDefaultItem(); item1.setId(null); item1.setId(null); @@ -177,8 +176,7 @@ public void testDeleteProductsWhenListIsDeleted() } - private ProductItem getDefaultItem() - { + private ProductItem getDefaultItem() { String expectedProductId = "1"; String expectedQuantity = "5"; String expectedNotes = "Some Notes"; diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/business/impl/converter/ProductConverterServiceTest.java b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/business/impl/converter/ProductConverterServiceTest.java index 513e0d8..bd7f33b 100644 --- a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/business/impl/converter/ProductConverterServiceTest.java +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/business/impl/converter/ProductConverterServiceTest.java @@ -1,6 +1,12 @@ package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.product.business.impl.converter; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import androidx.test.platform.app.InstrumentationRegistry; + import org.junit.Test; + import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.AbstractDatabaseTest; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.framework.context.AbstractInstanceFactory; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.framework.context.InstanceFactoryForTests; @@ -12,20 +18,17 @@ * Author: Grebiel Jose Ifill Brito * Created: 17.07.16 creation date */ -public class ProductConverterServiceTest extends AbstractDatabaseTest -{ +public class ProductConverterServiceTest extends AbstractDatabaseTest { private ProductConverterService converterService; @Override - protected void setupBeforeEachTest() - { - AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(getContext()); + protected void setupBeforeEachTest() { + AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(InstrumentationRegistry.getInstrumentation().getContext()); converterService = (ProductConverterService) instanceFactory.createInstance(ProductConverterService.class); } @Test - public void testConvertItemToEntity() throws Exception - { + public void testConvertItemToEntity() throws Exception { String expectedProductId = "1"; String expectedQuantity = "5"; String expectedNotes = "Some Notes"; @@ -52,8 +55,7 @@ public void testConvertItemToEntity() throws Exception } @Test - public void testConvertEntitiesToItem() throws Exception - { + public void testConvertEntitiesToItem() throws Exception { String expectedProductName = "product"; String expectedCategory = "category"; diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/persistence/ProductItemDaoTest.java b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/persistence/ProductItemDaoTest.java index a8eb9ea..68f963f 100644 --- a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/persistence/ProductItemDaoTest.java +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/product/persistence/ProductItemDaoTest.java @@ -1,7 +1,14 @@ package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.product.persistence; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import androidx.test.platform.app.InstrumentationRegistry; + import com.j256.ormlite.dao.ForeignCollection; + import org.junit.Test; + import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.AbstractDatabaseTest; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.framework.context.AbstractInstanceFactory; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.framework.context.InstanceFactoryForTests; @@ -14,8 +21,7 @@ * Author: Grebiel Jose Ifill Brito * Created: 11.06.16 creation date */ -public class ProductItemDaoTest extends AbstractDatabaseTest -{ +public class ProductItemDaoTest extends AbstractDatabaseTest { private ShoppingListDao shoppingListDao; private ProductItemDao productItemDao; @@ -23,9 +29,8 @@ public class ProductItemDaoTest extends AbstractDatabaseTest @Override - protected void setupBeforeEachTest() - { - AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(getContext()); + protected void setupBeforeEachTest() { + AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(InstrumentationRegistry.getInstrumentation().getContext()); shoppingListDao = (ShoppingListDao) instanceFactory.createInstance(ShoppingListDao.class); productItemDao = (ProductItemDao) instanceFactory.createInstance(ProductItemDao.class); @@ -37,8 +42,7 @@ protected void setupBeforeEachTest() } @Test - public void testSave() - { + public void testSave() { ProductItemEntity entity = new ProductItemEntity(); entity.setShoppingList(shoppingList); @@ -53,8 +57,7 @@ public void testSave() } @Test(expected = Exception.class) - public void testSaveWithoutProductTemplate() - { + public void testSaveWithoutProductTemplate() { ProductItemEntity entity = new ProductItemEntity(); entity.setShoppingList(shoppingList); @@ -62,8 +65,7 @@ public void testSaveWithoutProductTemplate() } @Test(expected = Exception.class) - public void testSaveWithoutShoppingList() - { + public void testSaveWithoutShoppingList() { ProductItemEntity entity = new ProductItemEntity(); productItemDao.save(entity); } diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/shoppingList/business/ShoppingListServiceTest.java b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/shoppingList/business/ShoppingListServiceTest.java index 65f9b79..bd557e6 100644 --- a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/shoppingList/business/ShoppingListServiceTest.java +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/shoppingList/business/ShoppingListServiceTest.java @@ -1,5 +1,10 @@ package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.shoppingList.business; +import static androidx.test.InstrumentationRegistry.getContext; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import android.content.res.Resources; import org.joda.time.DateTime; import org.junit.Test; diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/shoppingList/persistence/ShoppingListDaoTest.java b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/shoppingList/persistence/ShoppingListDaoTest.java index 71fdb22..354c102 100644 --- a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/shoppingList/persistence/ShoppingListDaoTest.java +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/shoppingList/persistence/ShoppingListDaoTest.java @@ -1,34 +1,37 @@ package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.shoppingList.persistence; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import androidx.test.platform.app.InstrumentationRegistry; + import org.joda.time.DateTime; import org.junit.Test; + +import java.util.Date; +import java.util.List; + import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.AbstractDatabaseTest; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.framework.context.AbstractInstanceFactory; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.framework.context.InstanceFactoryForTests; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.shoppingList.persistence.entity.ShoppingListEntity; -import java.util.Date; -import java.util.List; - /** * Description: * Author: Grebiel Jose Ifill Brito * Created: 10.06.16 creation date */ -public class ShoppingListDaoTest extends AbstractDatabaseTest -{ +public class ShoppingListDaoTest extends AbstractDatabaseTest { private ShoppingListDao shoppingListDao; @Override - protected void setupBeforeEachTest() - { - AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(getContext()); + protected void setupBeforeEachTest() { + AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(InstrumentationRegistry.getInstrumentation().getContext()); shoppingListDao = (ShoppingListDao) instanceFactory.createInstance(ShoppingListDao.class); } @Test - public void testSave() - { + public void testSave() { ShoppingListEntity entity = new ShoppingListEntity(); entity.setListName("name"); entity.setPriority("HIGH"); @@ -41,8 +44,7 @@ public void testSave() } @Test - public void testGetById() - { + public void testGetById() { String expectedName = "name"; String expectedPriority = "HIGH"; String expectedNotes = "notes"; @@ -67,8 +69,7 @@ public void testGetById() } @Test - public void testGetAllEntities() - { + public void testGetAllEntities() { ShoppingListEntity entity1 = new ShoppingListEntity(); ShoppingListEntity entity2 = new ShoppingListEntity(); entity1.setListName("entity1"); @@ -83,8 +84,7 @@ public void testGetAllEntities() } @Test - public void testDeleteById() - { + public void testDeleteById() { ShoppingListEntity entity1 = new ShoppingListEntity(); ShoppingListEntity entity2 = new ShoppingListEntity(); entity1.setListName("entity1"); diff --git a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/statistics/persistence/StatisticsDaoTest.java b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/statistics/persistence/StatisticsDaoTest.java index defc897..60d0dbd 100644 --- a/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/statistics/persistence/StatisticsDaoTest.java +++ b/app/src/androidTest/java/privacyfriendlyshoppinglist/secuso/org/privacyfriendlyshoppinglist/logic/statistics/persistence/StatisticsDaoTest.java @@ -1,5 +1,10 @@ package privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.logic.statistics.persistence; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import androidx.test.platform.app.InstrumentationRegistry; + import org.joda.time.DateTime; import org.junit.Test; import privacyfriendlyshoppinglist.secuso.org.privacyfriendlyshoppinglist.AbstractDatabaseTest; @@ -22,7 +27,7 @@ public class StatisticsDaoTest extends AbstractDatabaseTest @Override protected void setupBeforeEachTest() { - AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(getContext()); + AbstractInstanceFactory instanceFactory = new InstanceFactoryForTests(InstrumentationRegistry.getInstrumentation().getContext()); statisticsDao = (StatisticsDao) instanceFactory.createInstance(StatisticsDao.class); } diff --git a/build.gradle b/build.gradle index 46b473a..a13bea7 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,6 @@ buildscript { repositories { - jcenter() mavenCentral() google() } @@ -20,7 +19,6 @@ buildscript { allprojects { repositories { - jcenter() mavenCentral() google() maven { url "https://jitpack.io" } From aa42ddcd0e23f954ffa397b1b3fbf12e10417e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Mon, 9 Dec 2024 12:18:58 +0100 Subject: [PATCH 5/8] Remove `android-test.yml` --- .github/workflows/android-test.yml | 99 ------------------------------ 1 file changed, 99 deletions(-) delete mode 100644 .github/workflows/android-test.yml diff --git a/.github/workflows/android-test.yml b/.github/workflows/android-test.yml deleted file mode 100644 index e499e2f..0000000 --- a/.github/workflows/android-test.yml +++ /dev/null @@ -1,99 +0,0 @@ -name: Android Emulator Tests -on: [ push, pull_request ] - -jobs: - check-if-tests-exist: - runs-on: ubuntu-latest - outputs: - status: ${{ steps.check-androidTest.outputs.NOT_EMPTY }} - min-sdk-version: ${{ steps.get-sdk-version.outputs.MIN_SDK_VERSION }} - target-sdk-version: ${{ steps.get-sdk-version.outputs.TARGET_SDK_VERSION }} - app-id: ${{ steps.get-app-id.outputs.APP_ID }} - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - submodules: "recursive" - - name: Check if androidTest folder is not empty - run: | - echo "NOT_EMPTY=$([ "$(ls -A app/src/androidTest)" ] && echo 'true' || echo 'false')" - echo "NOT_EMPTY=$([ "$(ls -A app/src/androidTest)" ] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT - id: check-androidTest - - name: Get min and target sdk - if: steps.check-androidTest.outputs.NOT_EMPTY == 'true' - id: get-sdk-version - run: | - echo "MIN_SDK_VERSION=$(cat app/build.gradle | grep minSdkVersion | rev | cut -d' ' -f 1 | rev)" >> $GITHUB_OUTPUT - echo "TARGET_SDK_VERSION=$(cat app/build.gradle | grep targetSdkVersion | rev | cut -d' ' -f 1 | rev)" >> $GITHUB_OUTPUT - - name: Get app ID - id: get-app-id - run: | - echo "APP_ID=$(cat app/build.gradle | grep applicationId | rev | cut -d' ' -f 1 | rev | tr -d '"')" >> $GITHUB_OUTPUT - - test: - needs: check-if-tests-exist - if: needs.check-if-tests-exist.outputs.status == 'true' - runs-on: ubuntu-latest - strategy: - matrix: - api-level: [34, "${{ needs.check-if-tests-exist.outputs.min-sdk-version }}", "${{ needs.check-if-tests-exist.outputs.target-sdk-version }}"] - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - submodules: 'recursive' - - - name: Enable KVM group perms - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - - - name: Gradle cache - uses: gradle/gradle-build-action@v3 - - - name: AVD cache - uses: actions/cache@v4 - id: avd-cache - with: - path: | - ~/.android/avd/* - ~/.android/adb* - key: avd-${{ matrix.api-level }} - - - name: Set up JDK environment - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: 17 - - - name: create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - target: ${{ matrix.api-level >= 30 && 'google_apis' || 'default' }} - arch: ${{ matrix.api-level < 21 && 'x86' || 'x86_64' }} - force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: false - script: echo "Generated AVD snapshot for caching." - - - name: Run connected tests - uses: ReactiveCircus/android-emulator-runner@v2 - with: - api-level: ${{ matrix.api-level }} - target: ${{ matrix.api-level >= 30 && 'google_apis' || 'default' }} - arch: ${{ matrix.api-level < 21 && 'x86' || 'x86_64' }} - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: true - script: | - adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}} || true - adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.test || true - adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.androidTest || true - chmod +x gradlew - ./gradlew :app:connectedCheck --stacktrace - adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}} || true - adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.test || true - adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.androidTest || true From 0be22d0887d93af40001349f205c0ea06c39a765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Mon, 9 Dec 2024 15:32:33 +0100 Subject: [PATCH 6/8] Add lint config --- app/build.gradle | 3 +++ app/lint.xml | 11 +++++++++++ 2 files changed, 14 insertions(+) create mode 100644 app/lint.xml diff --git a/app/build.gradle b/app/build.gradle index dae964b..534bedd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,6 +55,9 @@ android { ] } } + lint { + lintConfig = file("lint.xml") + } } android.applicationVariants.all { variant -> diff --git a/app/lint.xml b/app/lint.xml new file mode 100644 index 0000000..e9ad894 --- /dev/null +++ b/app/lint.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + From e6d549b4f343174ed44ee7f9de603bbe2d5d1f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Mon, 9 Dec 2024 15:35:09 +0100 Subject: [PATCH 7/8] Replace `android:tint` with `app:tint` --- .../layouts/camera/layout/camera_preview.xml | 88 ++-- .../layout/delete_lists_activity.xml | 46 +- .../layout/delete_products_activity.xml | 46 +- .../res/layouts/main/layout/app_bar_main.xml | 110 ++--- .../products/layout/product_dialog.xml | 358 +++++++------- .../products/layout/product_list_item.xml | 204 ++++---- .../layout/product_list_item_left_hand.xml | 204 ++++---- .../products/layout/products_activity.xml | 185 ++++---- .../layout/shopping_list_dialog.xml | 349 +++++++------- .../layout/shopping_list_item.xml | 195 ++++---- .../layout/shopping_list_item_left_hand.xml | 192 ++++---- .../tutorials/layout/products_tutorial.xml | 375 ++++++++------- .../layout/shopping_list_tutorial.xml | 437 ++++++++++-------- 13 files changed, 1449 insertions(+), 1340 deletions(-) diff --git a/app/src/main/res/layouts/camera/layout/camera_preview.xml b/app/src/main/res/layouts/camera/layout/camera_preview.xml index af8e990..cf084cc 100644 --- a/app/src/main/res/layouts/camera/layout/camera_preview.xml +++ b/app/src/main/res/layouts/camera/layout/camera_preview.xml @@ -1,53 +1,57 @@ - + - + android:id="@+id/camera_preview" + android:layout_width="match_parent" + android:layout_height="match_parent"> + android:id="@+id/button_capture" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_alignParentBottom="true" + + android:layout_gravity="right|bottom" + android:layout_margin="@dimen/fab_margin" + android:layout_marginLeft="@dimen/fab_margin" + android:src="@drawable/ic_camera_alt_white_48sp" + app:layout_anchorGravity="bottom|right|end" + app:tint="@color/white" /> + android:id="@+id/button_flash" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_alignParentEnd="true" + + android:layout_gravity="right|top" + android:layout_margin="@dimen/fab_margin" + android:layout_marginLeft="@dimen/fab_margin" + android:src="@drawable/ic_flash_auto_white_48sp" + app:tint="@color/white" + app:layout_anchorGravity="bottom|right|end" /> + android:id="@+id/button_retake" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_alignParentBottom="true" + android:layout_gravity="left|bottom" + + android:layout_margin="@dimen/fab_margin" + android:layout_marginLeft="@dimen/fab_margin" + android:src="@drawable/ic_undo_white_48sp" + android:visibility="gone" + app:layout_anchorGravity="bottom|right|end" + app:tint="@color/white" /> \ No newline at end of file diff --git a/app/src/main/res/layouts/deletelists/layout/delete_lists_activity.xml b/app/src/main/res/layouts/deletelists/layout/delete_lists_activity.xml index 206dd45..69cc6b1 100644 --- a/app/src/main/res/layouts/deletelists/layout/delete_lists_activity.xml +++ b/app/src/main/res/layouts/deletelists/layout/delete_lists_activity.xml @@ -1,33 +1,31 @@ - + - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + android:id="@+id/recyclerView" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + android:id="@+id/fab_delete_lists" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:layout_margin="@dimen/fab_margin" + android:src="@drawable/ic_delete_white_24sp" + app:layout_anchor="@id/recyclerView" + app:layout_anchorGravity="bottom|right|end" + app:layout_behavior=".ui.fab.ScrollAwareFabBehaviorForDeleteActivities" + app:tint="@color/white" /> diff --git a/app/src/main/res/layouts/deleteproducts/layout/delete_products_activity.xml b/app/src/main/res/layouts/deleteproducts/layout/delete_products_activity.xml index 6c4ac41..e04cd3d 100644 --- a/app/src/main/res/layouts/deleteproducts/layout/delete_products_activity.xml +++ b/app/src/main/res/layouts/deleteproducts/layout/delete_products_activity.xml @@ -1,33 +1,31 @@ - + - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + android:id="@+id/recyclerView" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + android:id="@+id/fab_delete_products" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:layout_margin="@dimen/fab_margin" + android:src="@drawable/ic_delete_white_24sp" + app:layout_anchor="@id/recyclerView" + app:layout_anchorGravity="bottom|right|end" + app:layout_behavior=".ui.fab.ScrollAwareFabBehaviorForDeleteActivities" + app:tint="@color/white" /> diff --git a/app/src/main/res/layouts/main/layout/app_bar_main.xml b/app/src/main/res/layouts/main/layout/app_bar_main.xml index 0fc170c..1ed61a7 100644 --- a/app/src/main/res/layouts/main/layout/app_bar_main.xml +++ b/app/src/main/res/layouts/main/layout/app_bar_main.xml @@ -1,76 +1,76 @@ - + - + + android:id="@+id/recyclerView" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + android:id="@+id/fab_new_list" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:layout_margin="@dimen/fab_margin" + android:src="@android:drawable/ic_input_add" + android:tint="@color/white" + app:layout_anchor="@id/recyclerView" + app:layout_anchorGravity="bottom|right|end" /> + android:id="@+id/insert_alert" + android:layout_width="wrap_content" + android:layout_height="50sp" + android:layout_margin="@dimen/fab_margin" + android:gravity="center_vertical" + android:orientation="horizontal" + android:paddingRight="70sp" + android:visibility="gone" + app:layout_anchor="@id/fab_new_list" + app:layout_anchorGravity="bottom|left"> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:text="@string/alert_message_list" + android:textColor="@color/colorPrimaryDark" + android:textStyle="bold|italic" /> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_keyboard_arrow_right_black_24sp" + app:tint="@color/colorPrimary" /> + android:id="@+id/no_lists_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:orientation="vertical" + android:visibility="gone"> + + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:src="@drawable/icon_splash" /> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:text="@string/lists_empty" + android:textAlignment="center" /> diff --git a/app/src/main/res/layouts/products/layout/product_dialog.xml b/app/src/main/res/layouts/products/layout/product_dialog.xml index 0592f51..7993abc 100644 --- a/app/src/main/res/layouts/products/layout/product_dialog.xml +++ b/app/src/main/res/layouts/products/layout/product_dialog.xml @@ -1,248 +1,256 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + android:id="@+id/dialog_title" + android:layout_width="match_parent" + android:layout_height="@dimen/dialog_title_height" + android:background="@color/colorPrimaryDark" + android:gravity="center" + android:text="@string/product_dialog_title" + android:textColor="@color/white" + android:textStyle="bold" /> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fadeScrollbars="false"> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + + android:layout_toStartOf="@+id/product_checkbox" + app:counterEnabled="true" + app:counterMaxLength="40" + app:errorEnabled="true" + app:errorTextAppearance="@style/error_appearance"> - - + android:id="@+id/product_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/product_name" + android:imeOptions="actionNext" + android:inputType="text|textCapSentences" + android:maxLength="40" + android:selectAllOnFocus="true"> + android:id="@+id/product_checkbox" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" /> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:paddingLeft="@dimen/dialog_padding_horizontal" + android:paddingRight="@dimen/dialog_padding_horizontal" + android:weightSum="1"> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="0.3" + android:gravity="center_vertical" + android:orientation="horizontal"> +