Skip to content

Commit

Permalink
Bugfixes (#442)
Browse files Browse the repository at this point in the history
* Bump version to v1.15.1

* Fix popup menu style

* Regression test for crash with empty stock tracking fields

* Regression test for crash when exporting PDF

* Fix crash when leaving stock page without refill size filled

* Fix crash in PDF export

* Fix test

* Remove unused library for preferencesx
Add monkey test to tests job
Fix a potential crash when navigating preferences

* Merge monkey test job
  • Loading branch information
Futsch1 authored Jan 20, 2025
1 parent f674244 commit f0ec735
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 27 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Unit test
name: Test

on:
workflow_dispatch:
Expand All @@ -8,7 +8,7 @@ permissions:
contents: read

jobs:
unitTest:
test:
runs-on: ubuntu-latest
env:
target_api_level: 34
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
disable-animations: true
script: echo "Generated AVD snapshot for caching."

- name: Run Android tests and unit tests
- name: Run Android tests, unit tests and monkey test
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
with:
api-level: ${{ env.target_api_level }}
Expand All @@ -68,6 +68,8 @@ jobs:
adb shell input keyevent 3
adb shell settings put secure long_press_timeout 1500
EXIT_CODE=0 && ./gradlew JacocoDebugCodeCoverage || EXIT_CODE=$? && (adb pull /sdcard/googletest/test_outputfiles app/build/outputs/androidTest-results/ || true) && exit $EXIT_CODE
adb install -g app/build/outputs/apk/debug/MedTimer-debug.apk
adb shell monkey -p com.futsch1.medtimer -v 2000
cores: 4

- name: Run fuzzing tests
Expand Down
6 changes: 2 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ android {
minSdk = 28
multiDexEnabled = true
targetSdk = 35
versionCode = 95
versionName = "1.15.0"
versionCode = 96
versionName = "1.15.1"
base.archivesName = "MedTimer"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down Expand Up @@ -85,7 +85,6 @@ dependencies {
val lifecycleViewmodelKtxVersion = "2.8.7"
val roomVersion = "2.6.1"
val colorPickerViewVersion = "2.3.0"
val preferenceXVersion = "1.1.0"
val simplyPDFVersion = "2.1.1"
val gsonVersion = "2.11.0"
val tableViewVersion = "0.8.9.4"
Expand Down Expand Up @@ -123,7 +122,6 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleViewmodelKtxVersion")
implementation("androidx.room:room-runtime:$roomVersion")
implementation("com.github.skydoves:colorpickerview:$colorPickerViewVersion")
implementation("com.takisoft.preferencex:preferencex:$preferenceXVersion")
implementation("com.github.wwdablu:SimplyPDF:$simplyPDFVersion")
implementation("com.google.code.gson:gson:$gsonVersion")
implementation("com.github.evrencoskun:TableView:v$tableViewVersion")
Expand Down
48 changes: 48 additions & 0 deletions app/src/androidTest/java/com/futsch1/medtimer/ExportBackupTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.futsch1.medtimer

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn
import com.adevinta.android.barista.interaction.BaristaDialogInteractions.clickDialogPositiveButton
import com.adevinta.android.barista.interaction.BaristaListInteractions.clickListItem
import com.adevinta.android.barista.interaction.BaristaMenuClickInteractions.openMenu
import org.junit.Test

class ExportBackupTest : BaseTestHelper() {
@Test
fun testTriggerExport() {
openMenu()
clickOn(R.string.generate_test_data)

openMenu()
clickOn(R.string.event_data)
clickOn(R.string.export_csv)
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.wait(Until.findObject(By.textContains("Sharing")), 5_000)
device.pressBack()

openMenu()
clickOn(R.string.event_data)
clickOn(R.string.export_pdf)
device.wait(Until.findObject(By.textContains("Sharing")), 5_000)
device.pressBack()
}

@Test
fun testTriggerBackup() {
openMenu()
clickOn(R.string.generate_test_data)

openMenu()
clickOn(R.string.backup)

clickListItem(-1, 1)
clickDialogPositiveButton()

val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.wait(Until.findObject(By.textContains("Sharing")), 5_000)
device.pressBack()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,33 @@ import com.adevinta.android.barista.interaction.BaristaDialogInteractions
import com.adevinta.android.barista.interaction.BaristaEditTextInteractions.writeTo
import com.adevinta.android.barista.interaction.BaristaListInteractions.clickListItem
import com.adevinta.android.barista.interaction.BaristaListInteractions.clickListItemChild
import com.adevinta.android.barista.rule.flaky.AllowFlaky
import com.futsch1.medtimer.AndroidTestHelper.navigateTo
import org.hamcrest.CoreMatchers.equalTo
import org.junit.Test

class MedicineStockTest : BaseTestHelper() {

@Test
@AllowFlaky(attempts = 1)
//@AllowFlaky(attempts = 1)
fun medicineStockTest() {
val context = InstrumentationRegistry.getInstrumentation().targetContext

AndroidTestHelper.createMedicine("Test")
// Interval reminder (amount 3.5) 10 minutes from now
AndroidTestHelper.createIntervalReminder("Of the pills 3.5 are to be taken", 10)

clickOn(R.id.openStockTracking)
writeTo(R.id.amountLeft, "")
writeTo(R.id.reminderThreshold, "")
writeTo(R.id.refillSize, "")
pressBack()

clickOn(R.id.openStockTracking)
writeTo(R.id.amountLeft, "10.5")
clickOn(R.id.medicineStockReminder)
onData(equalTo(context.getString(R.string.once_below_threshold))).inRoot(RootMatchers.isPlatformPopup())
.perform(click())
writeTo(R.id.reminderThreshold, "4")
writeTo(R.id.reminderThreshold, "4")
writeTo(R.id.refillSize, "10.5")
pressBack()
pressBack()
Expand Down
12 changes: 9 additions & 3 deletions app/src/main/java/com/futsch1/medtimer/PreferencesFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@

import androidx.annotation.IdRes;
import androidx.annotation.RequiresApi;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.SwitchPreference;
import androidx.preference.SwitchPreferenceCompat;

import com.takisoft.preferencex.PreferenceFragmentCompat;

public class PreferencesFragment extends PreferenceFragmentCompat {

@Override
public void onCreatePreferencesFix(Bundle savedInstanceState, String rootKey) {
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);

setupTheme();
Expand Down Expand Up @@ -77,7 +78,12 @@ private void setupPreferencesLink(String preferenceKey, @IdRes int actionId) {
if (preference != null) {
preference.setOnPreferenceClickListener(preference1 ->
{
Navigation.findNavController(requireView()).navigate(actionId);
NavController navController = Navigation.findNavController(requireView());
try {
navController.navigate(actionId);
} catch (IllegalArgumentException e) {
// Intentionally empty
}
return true;
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import android.os.Bundle;

import com.takisoft.preferencex.PreferenceFragmentCompat;
import androidx.preference.PreferenceFragmentCompat;

public class RepeatRemindersPreferencesFragment extends PreferenceFragmentCompat {

@Override
public void onCreatePreferencesFix(Bundle savedInstanceState, String rootKey) {
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.repeat_reminders_preferences, rootKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@

import androidx.preference.MultiSelectListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;

import com.futsch1.medtimer.helpers.TimeHelper;
import com.futsch1.medtimer.reminders.ReminderProcessor;
import com.takisoft.preferencex.PreferenceFragmentCompat;

import java.util.List;
import java.util.stream.Collectors;

public class WeekendModePreferencesFragment extends PreferenceFragmentCompat {

@Override
public void onCreatePreferencesFix(Bundle savedInstanceState, String rootKey) {
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.weekend_mode_preferences, rootKey);

setupWeekendMode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public CSVExport(List<ReminderEvent> reminderEvents, Context context) {
@SuppressWarnings("java:S6300") // Unencrypted file is intended here and not a mistake
public void export(File file) throws ExporterException {
try (FileWriter csvFile = new FileWriter(file)) {
List<String> headerTexts = TableHelper.getTableHeaders(context);
List<String> headerTexts = TableHelper.getTableHeaders(context, true);
csvFile.write(String.join(";", headerTexts) + "\n");

for (ReminderEvent reminderEvent : reminderEvents) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public PDFExport(List<ReminderEvent> reminderEvents, Context context) {
this.context = context;
}


public void export(File file) {
SimplyPdfDocument simplyPdfDocument = getDocument(file);

Expand Down Expand Up @@ -81,7 +80,7 @@ private LinkedList<Cell> getHeader(int[] columnWidths) {
TextProperties headerProperties = getHeaderProperties();
LinkedList<Cell> header = new LinkedList<>();
int colIndex = 0;
for (String headerText : TableHelper.getTableHeaders(context)) {
for (String headerText : TableHelper.getTableHeaders(context, false)) {
header.add(new TextCell(headerText, headerProperties, columnWidths[colIndex++]));
}
return header;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ private TableHelper() {
// Intended empty
}

public static List<String> getTableHeaders(Context context) {
public static List<String> getTableHeaders(Context context, boolean withIsoTimestamps) {
final String[] headerTexts = {
context.getString(R.string.time),
context.getString(R.string.name),
context.getString(R.string.dosage),
context.getString(R.string.taken),
context.getString(R.string.time) + " (ISO 8601)",
context.getString(R.string.taken) + " (ISO 8601)"};
return Arrays.asList(headerTexts);
List<String> names = Arrays.asList(headerTexts);
if (!withIsoTimestamps) {
return names.subList(0, names.size() - 2);
} else {
return names;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class MedicineStockFragment :
MedicineHelper.parseAmount(fragmentView.findViewById<TextInputEditText>(R.id.reminderThreshold).text.toString())
?: entity.outOfStockReminderThreshold

entity.refillSizes = arrayListOf(
val refillSize =
MedicineHelper.parseAmount(fragmentView.findViewById<TextInputEditText>(R.id.refillSize).text.toString())
)
refillSize?.let { entity.refillSizes = arrayListOf(it) }
}

override fun onEntityLoaded(entity: Medicine, fragmentView: View): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
ReminderTableAdapter adapter = new ReminderTableAdapter(tableView, medicineViewModel, requireActivity());

tableView.setAdapter(adapter);
adapter.setColumnHeaderItems(TableHelper.getTableHeaders(getContext()));
adapter.setColumnHeaderItems(TableHelper.getTableHeaders(requireContext(), false));
medicineViewModel.getLiveReminderEvents(0, 0, false).observe(getViewLifecycleOwner(), adapter::submitList);

// This is a workaround for a recycler view bug that causes random crashes
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
Expand Down

0 comments on commit f0ec735

Please sign in to comment.