From 73ea170b039adfd789b914ec2435532d2c2f605c Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Wed, 29 Jan 2025 14:42:33 +0530 Subject: [PATCH 1/2] Fixed: When a note is deleted, the corresponding file remained in storage. * The note file is now deleted from storage when the user selects multiple notes and deletes them from the "Notes" screen. * Improved note deletion in the "Note Dialog." Previously, when deleting a note from the `AddNoteDialog` on the Notes screen, the file was removed from storage, but its entry remained in the database, causing the note to still appear on the "Notes" screen after deletion. This issue has now been fixed. --- .../kiwixmobile/core/dao/NotesRoomDao.kt | 22 +++++++++++++++++++ .../kiwixmobile/core/main/AddNoteDialog.kt | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/NotesRoomDao.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/NotesRoomDao.kt index f772d242b..6d4f5c622 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/dao/NotesRoomDao.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/dao/NotesRoomDao.kt @@ -23,10 +23,16 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import io.reactivex.Flowable +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.kiwix.kiwixmobile.core.dao.entities.NotesRoomEntity +import org.kiwix.kiwixmobile.core.extensions.deleteFile +import org.kiwix.kiwixmobile.core.extensions.isFileExist import org.kiwix.kiwixmobile.core.page.adapter.Page import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.Companion.fromDatabaseValue +import java.io.File @Dao abstract class NotesRoomDao : PageDao { @@ -71,6 +77,22 @@ abstract class NotesRoomDao : PageDao { notesList.forEachIndexed { _, note -> val notesRoomEntity = NotesRoomEntity(note) deleteNote(noteTitle = notesRoomEntity.noteTitle) + removeNoteFileFromStorage(notesRoomEntity.noteFilePath) + } + } + + /** + * Deletes the saved file from storage. + * When the user deletes a note from the "Notes" screen, + * the associated file should also be removed from storage, + * as it is no longer needed. + */ + private fun removeNoteFileFromStorage(noteFilePath: String) { + CoroutineScope(Dispatchers.IO).launch { + val noteFile = File(noteFilePath) + if (noteFile.isFileExist()) { + noteFile.deleteFile() + } } } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/AddNoteDialog.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/AddNoteDialog.kt index 2068d4156..97eff86d4 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/AddNoteDialog.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/AddNoteDialog.kt @@ -436,7 +436,7 @@ class AddNoteDialog : DialogFragment() { val noteText = dialogNoteAddNoteBinding?.addNoteEditText?.text.toString() if (noteDeleted) { dialogNoteAddNoteBinding?.addNoteEditText?.text?.clear() - mainRepositoryActions.deleteNote(articleNoteFileName) + mainRepositoryActions.deleteNote(getNoteTitle()) disableMenuItems() view?.snack( stringId = R.string.note_delete_successful, From 561af8f735ba0e6e65ecca9bd32c0f4a77b86ebd Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Wed, 29 Jan 2025 15:49:08 +0530 Subject: [PATCH 2/2] Added UI test cases for testing these both scenarios. --- .../kiwixmobile/note/NoteFragmentTest.kt | 83 ++++++++++++++----- .../org/kiwix/kiwixmobile/note/NoteRobot.kt | 10 +++ 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/note/NoteFragmentTest.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/note/NoteFragmentTest.kt index 4ee3c042a..f7ce9e36b 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/note/NoteFragmentTest.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/note/NoteFragmentTest.kt @@ -129,17 +129,7 @@ class NoteFragmentTest : BaseActivityTest() { @Test fun testUserCanSeeNotesForDeletedFiles() { - // delete the notes if any saved to properly run the test scenario - note { - openNoteFragment() - assertToolbarExist() - assertNoteRecyclerViewExist() - clickOnTrashIcon() - assertDeleteNoteDialogDisplayed() - clickOnDeleteButton() - assertNoNotesTextDisplayed() - pressBack() - } + deletePreviouslySavedNotes() loadZimFileInReader("testzim.zim") StandardActions.closeDrawer() // close the drawer if open before running the test cases. note { @@ -188,17 +178,7 @@ class NoteFragmentTest : BaseActivityTest() { @Test fun testZimFileOpenedAfterOpeningNoteOnNotesScreen() { - // delete the notes if any saved to properly run the test scenario - note { - openNoteFragment() - assertToolbarExist() - assertNoteRecyclerViewExist() - clickOnTrashIcon() - assertDeleteNoteDialogDisplayed() - clickOnDeleteButton() - assertNoNotesTextDisplayed() - pressBack() - } + deletePreviouslySavedNotes() loadZimFileInReader("testzim.zim") note { assertHomePageIsLoadedOfTestZimFile() @@ -220,6 +200,65 @@ class NoteFragmentTest : BaseActivityTest() { } } + @Test + fun testNoteEntryIsRemovedFromDatabaseWhenDeletedInAddNoteDialog() { + deletePreviouslySavedNotes() + loadZimFileInReader("testzim.zim") + note { + clickOnNoteMenuItem(context) + assertNoteDialogDisplayed() + writeDemoNote() + saveNote() + pressBack() + openNoteFragment() + assertToolbarExist() + assertNoteRecyclerViewExist() + clickOnSavedNote() + clickOnOpenNote() + assertNoteSaved() + clickOnDeleteIcon() + pressBack() + assertNoNotesTextDisplayed() + } + } + + @Test + fun testNoteFileIsDeletedWhenNoteIsRemovedFromNotesScreen() { + deletePreviouslySavedNotes() + loadZimFileInReader("testzim.zim") + // Save a note. + note { + clickOnNoteMenuItem(context) + assertNoteDialogDisplayed() + writeDemoNote() + saveNote() + pressBack() + } + // Delete that note from "Note" screen. + deletePreviouslySavedNotes() + // Test the note file is deleted or not. + note { + clickOnNoteMenuItem(context) + assertNoteDialogDisplayed() + assertNotDoesNotExist() + pressBack() + } + } + + private fun deletePreviouslySavedNotes() { + // delete the notes if any saved to properly run the test scenario + note { + openNoteFragment() + assertToolbarExist() + assertNoteRecyclerViewExist() + clickOnTrashIcon() + assertDeleteNoteDialogDisplayed() + clickOnDeleteButton() + assertNoNotesTextDisplayed() + pressBack() + } + } + private fun loadZimFileInReader(zimFileName: String) { activityScenario.onActivity { kiwixMainActivity = it diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/note/NoteRobot.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/note/NoteRobot.kt index 9131edba5..9a5659c5c 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/note/NoteRobot.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/note/NoteRobot.kt @@ -26,6 +26,7 @@ import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu import androidx.test.espresso.action.ViewActions.clearText import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.typeText +import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.withContentDescription @@ -111,6 +112,15 @@ class NoteRobot : BaseRobot() { testFlakyView({ isVisible(Text(noteText)) }) } + fun assertNotDoesNotExist() { + testFlakyView({ onView(withText(noteText)).check(doesNotExist()) }) + } + + fun clickOnDeleteIcon() { + pauseForBetterTestPerformance() + testFlakyView({ clickOn(ViewId(R.id.delete_note)) }) + } + fun clickOnTrashIcon() { testFlakyView({ onView(withContentDescription(R.string.pref_clear_notes)).perform(click()) }) }