From 5ac3494b99fa82715364572ff72a6f0245702591 Mon Sep 17 00:00:00 2001 From: Antonio Corrales Date: Fri, 14 Jun 2024 17:18:54 +0200 Subject: [PATCH 01/11] Add BookmarkHtmlDaoTest and TagDaoTest, update CI for instrumented tests - Added tests for BookmarkHtmlDao and TagDao - Updated CI workflow to include instrumented tests --- .github/workflows/ci.yml | 15 ++++ .../data/local/room/BookmarkHtmlDaoTest.kt | 59 +++++++++++++++ .../data/local/room/TagsDaoTest.kt | 71 +++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 data/src/androidTest/java/com/desarrollodroide/data/local/room/BookmarkHtmlDaoTest.kt create mode 100644 data/src/androidTest/java/com/desarrollodroide/data/local/room/TagsDaoTest.kt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3062fba..333102c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,7 @@ on: branches: - master - develop + - testing jobs: build: @@ -29,6 +30,19 @@ jobs: - name: Run Unit Tests run: ./gradlew test + - name: Start emulator + uses: ReactiveCircus/android-emulator-runner@v2.22.1 + with: + api-level: 30 + target: default + arch: x86_64 + profile: Nexus 6 + emulator-options: -no-window + disable-animations: true + + - name: Run Instrumented Tests + run: ./gradlew connectedAndroidTest + - name: Build app run: ./gradlew assembleRelease env: @@ -52,3 +66,4 @@ jobs: prerelease: false files: | presentation/build/outputs/apk/release/*.apk + diff --git a/data/src/androidTest/java/com/desarrollodroide/data/local/room/BookmarkHtmlDaoTest.kt b/data/src/androidTest/java/com/desarrollodroide/data/local/room/BookmarkHtmlDaoTest.kt new file mode 100644 index 0000000..674e51d --- /dev/null +++ b/data/src/androidTest/java/com/desarrollodroide/data/local/room/BookmarkHtmlDaoTest.kt @@ -0,0 +1,59 @@ +package com.desarrollodroide.data.local.room + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import com.desarrollodroide.data.local.room.dao.BookmarkHtmlDao +import com.desarrollodroide.data.local.room.database.BookmarksDatabase +import com.desarrollodroide.data.local.room.entity.BookmarkHtmlEntity +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +class BookmarkHtmlDaoTest { + + private lateinit var database: BookmarksDatabase + private lateinit var bookmarkHtmlDao: BookmarkHtmlDao + + private val bookmarkHtml = BookmarkHtmlEntity( + id = 1, + url = "http://example.com", + readableContentHtml = "Test Content" + ) + + @Before + fun setup() { + database = Room.inMemoryDatabaseBuilder( + ApplicationProvider.getApplicationContext(), + BookmarksDatabase::class.java + ) + .allowMainThreadQueries() + .build() + + bookmarkHtmlDao = database.bookmarkHtmlDao() + } + + @After + fun tearDown() { + database.close() + } + + @Test + fun testInsertAndFetchBookmarkHtml(): Unit = runBlocking { + bookmarkHtmlDao.insertOrUpdate(bookmarkHtml) + val retrievedHtml = bookmarkHtmlDao.getHtmlContent(bookmarkHtml.id) + Assert.assertEquals(bookmarkHtml.readableContentHtml, retrievedHtml) + bookmarkHtmlDao.getBookmarkHtml(bookmarkHtml.id)?.let { + Assert.assertEquals(bookmarkHtml, it) + } + } + + @Test + fun testUpdateBookmarkHtml() = runBlocking { + bookmarkHtmlDao.insertOrUpdate(bookmarkHtml) + val updatedBookmarkHtml = bookmarkHtml.copy(readableContentHtml = "Updated Content") + bookmarkHtmlDao.insertOrUpdate(updatedBookmarkHtml) + val retrievedHtml = bookmarkHtmlDao.getHtmlContent(bookmarkHtml.id) + Assert.assertEquals(updatedBookmarkHtml.readableContentHtml, retrievedHtml) + } +} \ No newline at end of file diff --git a/data/src/androidTest/java/com/desarrollodroide/data/local/room/TagsDaoTest.kt b/data/src/androidTest/java/com/desarrollodroide/data/local/room/TagsDaoTest.kt new file mode 100644 index 0000000..070bae2 --- /dev/null +++ b/data/src/androidTest/java/com/desarrollodroide/data/local/room/TagsDaoTest.kt @@ -0,0 +1,71 @@ +package com.desarrollodroide.data.local.room + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import com.desarrollodroide.data.local.room.dao.TagDao +import com.desarrollodroide.data.local.room.database.BookmarksDatabase +import com.desarrollodroide.data.local.room.entity.TagEntity +import junit.framework.TestCase.assertFalse +import junit.framework.TestCase.assertTrue +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test + +class TagDaoTest { + + private lateinit var database: BookmarksDatabase + private lateinit var tagDao: TagDao + + private val tag = TagEntity( + id = 1, + name = "Test Tag", + nBookmarks = 5 + ) + + @Before + fun setup() { + database = Room.inMemoryDatabaseBuilder( + ApplicationProvider.getApplicationContext(), + BookmarksDatabase::class.java + ) + .allowMainThreadQueries() + .build() + + tagDao = database.tagDao() + } + + @After + fun tearDown() { + database.close() + } + + @Test + fun testInsertAndFetchTags() = runBlocking { + tagDao.insertTag(tag) + val retrievedTags = tagDao.getAllTags().first() + assertTrue(retrievedTags.contains(tag)) + tagDao.deleteAllTags() + assertTrue(tagDao.getAllTags().first().isEmpty()) + } + + @Test + fun testDeleteTag() = runBlocking { + tagDao.insertTag(tag) + tagDao.deleteTag(tag) + val retrievedTags = tagDao.getAllTags().first() + assertFalse(retrievedTags.contains(tag)) + } + + @Test + fun testInsertAndFetchMultipleTags() = runBlocking { + val tags = listOf( + TagEntity(1, "Tag1", 2), + TagEntity(2, "Tag2", 3) + ) + tagDao.insertAllTags(tags) + val retrievedTags = tagDao.getAllTags().first() + assertTrue(retrievedTags.containsAll(tags)) + } +} From 6113799de6c7becc28c9020170f6cc58119d038f Mon Sep 17 00:00:00 2001 From: Antonio Corrales Date: Fri, 14 Jun 2024 17:23:05 +0200 Subject: [PATCH 02/11] - Fix android emulator version --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 333102c..a53f70d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: run: ./gradlew test - name: Start emulator - uses: ReactiveCircus/android-emulator-runner@v2.22.1 + uses: ReactiveCircus/android-emulator-runner@v2.31.0 with: api-level: 30 target: default @@ -56,7 +56,7 @@ jobs: - name: Create Release on GitHub uses: softprops/action-gh-release@v1 - if: github.ref == 'refs/heads/master' # Solo crea releases para commits en master + if: github.ref == 'refs/heads/master' env: GITHUB_TOKEN: ${{ secrets.SHIORI_TOKEN }} with: From 7e8ed9ae799af3d3d8dd842e803c3c10a5d1c760 Mon Sep 17 00:00:00 2001 From: Antonio Corrales Date: Fri, 14 Jun 2024 17:31:09 +0200 Subject: [PATCH 03/11] - Fix android emulator #1 --- .github/workflows/ci.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a53f70d..0f7d507 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,15 +30,25 @@ jobs: - name: Run Unit Tests run: ./gradlew test + - name: Install Android SDK + uses: actions/setup-android-sdk@v2 + with: + api-level: 30 + build-tools: 30.0.3 + - name: Start emulator uses: ReactiveCircus/android-emulator-runner@v2.31.0 with: api-level: 30 - target: default + target: google_apis arch: x86_64 profile: Nexus 6 - emulator-options: -no-window + emulator-options: -no-window -no-snapshot disable-animations: true + working-directory: ./ + + - name: Wait for Emulator + run: adb wait-for-device - name: Run Instrumented Tests run: ./gradlew connectedAndroidTest @@ -66,4 +76,3 @@ jobs: prerelease: false files: | presentation/build/outputs/apk/release/*.apk - From 20f104cb0f5d0551515198f591a60088f838ed47 Mon Sep 17 00:00:00 2001 From: Antonio Corrales Date: Tue, 18 Jun 2024 14:56:38 +0200 Subject: [PATCH 04/11] - Fix android emulator #2 --- .github/workflows/ci.yml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f7d507..a53f70d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,25 +30,15 @@ jobs: - name: Run Unit Tests run: ./gradlew test - - name: Install Android SDK - uses: actions/setup-android-sdk@v2 - with: - api-level: 30 - build-tools: 30.0.3 - - name: Start emulator uses: ReactiveCircus/android-emulator-runner@v2.31.0 with: api-level: 30 - target: google_apis + target: default arch: x86_64 profile: Nexus 6 - emulator-options: -no-window -no-snapshot + emulator-options: -no-window disable-animations: true - working-directory: ./ - - - name: Wait for Emulator - run: adb wait-for-device - name: Run Instrumented Tests run: ./gradlew connectedAndroidTest @@ -76,3 +66,4 @@ jobs: prerelease: false files: | presentation/build/outputs/apk/release/*.apk + From 36a4512b73d7724ef97caaa9c7e1cd762390e148 Mon Sep 17 00:00:00 2001 From: Antonio Corrales Date: Tue, 18 Jun 2024 15:04:14 +0200 Subject: [PATCH 05/11] - Fix android emulator #3 --- .github/workflows/ci.yml | 46 ++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a53f70d..790b524 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,9 +8,36 @@ on: - testing jobs: - build: + unit_tests: runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 11 + - name: Run Unit Tests + run: ./gradlew testDebugUnitTest + + android_tests: + runs-on: macos-12 + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 11 + - name: Start Emulator and Run Instrumented Tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 29 + script: ./gradlew connectedDebugAndroidTest + build_and_release: + runs-on: ubuntu-latest + needs: [unit_tests, android_tests] steps: - uses: actions/checkout@v3 @@ -27,22 +54,6 @@ jobs: - name: Setup Gradle uses: gradle/gradle-build-action@v2 - - name: Run Unit Tests - run: ./gradlew test - - - name: Start emulator - uses: ReactiveCircus/android-emulator-runner@v2.31.0 - with: - api-level: 30 - target: default - arch: x86_64 - profile: Nexus 6 - emulator-options: -no-window - disable-animations: true - - - name: Run Instrumented Tests - run: ./gradlew connectedAndroidTest - - name: Build app run: ./gradlew assembleRelease env: @@ -66,4 +77,3 @@ jobs: prerelease: false files: | presentation/build/outputs/apk/release/*.apk - From a0148be9f3a6e128d6a3bc1020e1a928f11e916b Mon Sep 17 00:00:00 2001 From: Antonio Corrales Date: Tue, 18 Jun 2024 15:09:23 +0200 Subject: [PATCH 06/11] - Fix android emulator #4 --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 790b524..01b1643 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,11 +12,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - distribution: 'zulu' - java-version: 11 + distribution: 'temurin' + java-version: 17 - name: Run Unit Tests run: ./gradlew testDebugUnitTest @@ -24,11 +24,11 @@ jobs: runs-on: macos-12 steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - distribution: 'zulu' - java-version: 11 + distribution: 'temurin' + java-version: 17 - name: Start Emulator and Run Instrumented Tests uses: reactivecircus/android-emulator-runner@v2 with: From 231a0899409c4ccde8eab91d8c61bcfc7a127f0d Mon Sep 17 00:00:00 2001 From: Antonio Corrales Date: Tue, 18 Jun 2024 16:37:57 +0200 Subject: [PATCH 07/11] - Add unit tests for domain model mapping methods --- .../data/mapper/MapperTest.kt | 669 ++++++++++++++++++ 1 file changed, 669 insertions(+) create mode 100644 data/src/test/java/com/desarrollodroide/data/mapper/MapperTest.kt diff --git a/data/src/test/java/com/desarrollodroide/data/mapper/MapperTest.kt b/data/src/test/java/com/desarrollodroide/data/mapper/MapperTest.kt new file mode 100644 index 0000000..3408f46 --- /dev/null +++ b/data/src/test/java/com/desarrollodroide/data/mapper/MapperTest.kt @@ -0,0 +1,669 @@ +package com.desarrollodroide.data.mapper + +import com.desarrollodroide.data.local.room.entity.BookmarkEntity +import com.desarrollodroide.data.local.room.entity.TagEntity +import com.desarrollodroide.model.Account +import com.desarrollodroide.model.Tag +import com.desarrollodroide.model.UpdateCachePayload +import org.junit.jupiter.api.Assertions.* +import com.desarrollodroide.network.model.AccountDTO +import com.desarrollodroide.network.model.BookmarkDTO +import com.desarrollodroide.network.model.BookmarksDTO +import com.desarrollodroide.network.model.LivenessResponseDTO +import com.desarrollodroide.network.model.LoginResponseDTO +import com.desarrollodroide.network.model.LoginResponseMessageDTO +import com.desarrollodroide.network.model.ReadableContentResponseDTO +import com.desarrollodroide.network.model.ReadableMessageDto +import com.desarrollodroide.network.model.ReleaseInfoDTO +import com.desarrollodroide.network.model.SessionDTO +import com.desarrollodroide.network.model.TagDTO +import org.junit.jupiter.api.Test + +class MapperTest { + + @Test + fun `SessionDTO toDomainModel maps correctly`() { + val accountDTO = AccountDTO( + id = 1, + userName = "testUser", + password = "password", + isOwner = true, + oldPassword = "oldPass", + newPassword = "newPass", + isLegacyApi = true + ) + val sessionDTO = SessionDTO( + token = "token123", + session = "session123", + account = accountDTO + ) + + val user = sessionDTO.toDomainModel() + + assertEquals("token123", user.token) + assertEquals("session123", user.session) + assertEquals("testUser", user.account.userName) + assertEquals("password", user.account.password) + assertEquals(true, user.account.owner) + assertEquals(true, user.account.isLegacyApi) // Corrected to match the DTO's isLegacyApi value + } + + @Test + fun `SessionDTO toProtoEntity maps correctly`() { + val accountDTO = AccountDTO( + id = 1, + userName = "testUser", + password = "password", + isOwner = true, + oldPassword = "oldPass", + newPassword = "newPass", + isLegacyApi = true + ) + val sessionDTO = SessionDTO( + token = "token123", + session = "session123", + account = accountDTO + ) + + val userPreferences = sessionDTO.toProtoEntity() + + assertEquals(1, userPreferences.id) + assertEquals("testUser", userPreferences.username) + assertEquals(true, userPreferences.owner) + assertEquals("", userPreferences.password) + assertEquals("session123", userPreferences.session) + assertEquals("", userPreferences.url) // Assuming this is not set from DTO + assertEquals(false, userPreferences.rememberPassword) // Assuming default value + assertEquals(true, userPreferences.isLegacyApi) + assertEquals("", userPreferences.token) + } + + @Test + fun `AccountDTO toDomainModel maps correctly`() { + val accountDTO = AccountDTO( + id = 1, + userName = "testUser", + password = "password", + isOwner = true, + oldPassword = "oldPass", + newPassword = "newPass", + isLegacyApi = true + ) + + val account = accountDTO.toDomainModel() + + assertEquals("testUser", account.userName) + assertEquals("password", account.password) + assertEquals(true, account.owner) + assertEquals(true, account.isLegacyApi) // Corrected to match the DTO's isLegacyApi value + } + + @Test + fun `BookmarkDTO toDomainModel maps correctly`() { + val tagDTO = TagDTO( + id = 1, + name = "tag1", + nBookmarks = 5 + ) + + val bookmarkDTO = BookmarkDTO( + id = 1, + url = "http://example.com", + title = "Example Title", + excerpt = "Example Excerpt", + author = "Author Name", + public = 1, + modified = "2023-06-18", + imageURL = "/image.jpg", + hasContent = true, + hasArchive = true, + hasEbook = true, + tags = listOf(tagDTO), + createArchive = true, + createEbook = true + ) + + val serverUrl = "http://example.com" + val bookmark = bookmarkDTO.toDomainModel(serverUrl) + + assertEquals(1, bookmark.id) + assertEquals("http://example.com", bookmark.url) + assertEquals("Example Title", bookmark.title) + assertEquals("Example Excerpt", bookmark.excerpt) + assertEquals("Author Name", bookmark.author) + assertEquals(1, bookmark.public) + assertEquals("2023-06-18", bookmark.modified) + assertEquals("http://example.com/image.jpg", bookmark.imageURL) + assertEquals(true, bookmark.hasContent) + assertEquals(true, bookmark.hasArchive) + assertEquals(true, bookmark.hasEbook) + assertEquals(1, bookmark.tags.size) + assertEquals(1, bookmark.tags[0].id) + assertEquals("tag1", bookmark.tags[0].name) + assertEquals(5, bookmark.tags[0].nBookmarks) + assertEquals(true, bookmark.createArchive) + assertEquals(true, bookmark.createEbook) + } + + + @Test + fun `BookmarksDTO toDomainModel maps correctly`() { + val tagDTO = TagDTO( + id = 1, + name = "tag1", + nBookmarks = 5 + ) + + val bookmarkDTO = BookmarkDTO( + id = 1, + url = "http://example.com", + title = "Example Title", + excerpt = "Example Excerpt", + author = "Author Name", + public = 1, + modified = "2023-06-18", + imageURL = "/image.jpg", + hasContent = true, + hasArchive = true, + hasEbook = true, + tags = listOf(tagDTO), + createArchive = true, + createEbook = true + ) + + val bookmarksDTO = BookmarksDTO( + page = 1, + maxPage = 10, + bookmarks = listOf(bookmarkDTO) + ) + + val serverUrl = "http://example.com" + val bookmarks = bookmarksDTO.toDomainModel(serverUrl) + + assertEquals(1, bookmarks.page) + assertEquals(10, bookmarks.maxPage) + assertEquals(1, bookmarks.bookmarks.size) + + val bookmark = bookmarks.bookmarks[0] + assertEquals(1, bookmark.id) + assertEquals("http://example.com", bookmark.url) + assertEquals("Example Title", bookmark.title) + assertEquals("Example Excerpt", bookmark.excerpt) + assertEquals("Author Name", bookmark.author) + assertEquals(1, bookmark.public) + assertEquals("2023-06-18", bookmark.modified) + assertEquals("http://example.com/image.jpg", bookmark.imageURL) + assertEquals(true, bookmark.hasContent) + assertEquals(true, bookmark.hasArchive) + assertEquals(true, bookmark.hasEbook) + assertEquals(1, bookmark.tags.size) + assertEquals(1, bookmark.tags[0].id) + assertEquals("tag1", bookmark.tags[0].name) + assertEquals(5, bookmark.tags[0].nBookmarks) + assertEquals(true, bookmark.createArchive) + assertEquals(true, bookmark.createEbook) + } + + @Test + fun `TagDTO toDomainModel maps correctly`() { + val tagDTO = TagDTO( + id = 1, + name = "tag1", + nBookmarks = 5 + ) + + val tag = tagDTO.toDomainModel() + + assertEquals(1, tag.id) + assertEquals("tag1", tag.name) + assertEquals(false, tag.selected) // Assuming selected is always false in the domain model + assertEquals(5, tag.nBookmarks) + } + + @Test + fun `TagDTO toDomainModel with null fields maps correctly`() { + val tagDTO = TagDTO( + id = null, + name = null, + nBookmarks = null + ) + + val tag = tagDTO.toDomainModel() + + assertEquals(0, tag.id) // Default value for id + assertEquals("", tag.name) // Default value for name + assertEquals(false, tag.selected) // Assuming selected is always false in the domain model + assertEquals(0, tag.nBookmarks) // Default value for nBookmarks + } + + @Test + fun `TagDTO toEntityModel maps correctly`() { + val tagDTO = TagDTO( + id = 1, + name = "tag1", + nBookmarks = 5 + ) + + val tagEntity = tagDTO.toEntityModel() + + assertEquals(1, tagEntity.id) + assertEquals("tag1", tagEntity.name) + assertEquals(5, tagEntity.nBookmarks) + } + + @Test + fun `TagDTO toEntityModel with null fields maps correctly`() { + val tagDTO = TagDTO( + id = null, + name = null, + nBookmarks = null + ) + + val tagEntity = tagDTO.toEntityModel() + + assertEquals(0, tagEntity.id) // Default value for id + assertEquals("", tagEntity.name) // Default value for name + assertEquals(0, tagEntity.nBookmarks) // Default value for nBookmarks + } + + @Test + fun `TagEntity toDomainModel maps correctly`() { + val tagEntity = TagEntity( + id = 1, + name = "tag1", + nBookmarks = 5 + ) + + val tag = tagEntity.toDomainModel() + + assertEquals(1, tag.id) + assertEquals("tag1", tag.name) + assertEquals(false, tag.selected) // Assuming selected is always false in the domain model + assertEquals(5, tag.nBookmarks) + } + + @Test + fun `Account toRequestBody maps correctly`() { + val account = Account( + id = 1, + userName = "testUser", + password = "password", + owner = true, + serverUrl = "https://example.com", + isLegacyApi = false + ) + + val loginRequestPayload = account.toRequestBody() + + assertEquals("testUser", loginRequestPayload.username) + assertEquals("password", loginRequestPayload.password) + } + + @Test + fun `BookmarkDTO toEntityModel maps correctly`() { + val tagDTO = TagDTO( + id = 1, + name = "tag1", + nBookmarks = 5 + ) + + val bookmarkDTO = BookmarkDTO( + id = 1, + url = "http://example.com", + title = "Example Title", + excerpt = "Example Excerpt", + author = "Author Name", + public = 1, + modified = "2023-06-18", + imageURL = "/image.jpg", + hasContent = true, + hasArchive = true, + hasEbook = true, + tags = listOf(tagDTO), + createArchive = true, + createEbook = true + ) + + val bookmarkEntity = bookmarkDTO.toEntityModel() + + assertEquals(1, bookmarkEntity.id) + assertEquals("http://example.com", bookmarkEntity.url) + assertEquals("Example Title", bookmarkEntity.title) + assertEquals("Example Excerpt", bookmarkEntity.excerpt) + assertEquals("Author Name", bookmarkEntity.author) + assertEquals(1, bookmarkEntity.isPublic) + assertEquals("2023-06-18", bookmarkEntity.modified) + assertEquals("/image.jpg", bookmarkEntity.imageURL) + assertEquals(true, bookmarkEntity.hasContent) + assertEquals(true, bookmarkEntity.hasArchive) + assertEquals(true, bookmarkEntity.hasEbook) + assertEquals(1, bookmarkEntity.tags.size) + assertEquals(1, bookmarkEntity.tags[0].id) + assertEquals("tag1", bookmarkEntity.tags[0].name) + assertEquals(5, bookmarkEntity.tags[0].nBookmarks) + assertEquals(true, bookmarkEntity.createArchive) + assertEquals(true, bookmarkEntity.createEbook) + } + + @Test + fun `BookmarkDTO toEntityModel with null fields maps correctly`() { + val bookmarkDTO = BookmarkDTO( + id = null, + url = null, + title = null, + excerpt = null, + author = null, + public = null, + modified = null, + imageURL = null, + hasContent = null, + hasArchive = null, + hasEbook = null, + tags = null, + createArchive = null, + createEbook = null + ) + + val bookmarkEntity = bookmarkDTO.toEntityModel() + + assertEquals(0, bookmarkEntity.id) // Default value for id + assertEquals("", bookmarkEntity.url) // Default value for url + assertEquals("", bookmarkEntity.title) // Default value for title + assertEquals("", bookmarkEntity.excerpt) // Default value for excerpt + assertEquals("", bookmarkEntity.author) // Default value for author + assertEquals(0, bookmarkEntity.isPublic) // Default value for isPublic + assertEquals("", bookmarkEntity.modified) // Default value for modified + assertEquals("", bookmarkEntity.imageURL) // Default value for imageURL + assertEquals(false, bookmarkEntity.hasContent) // Default value for hasContent + assertEquals(false, bookmarkEntity.hasArchive) // Default value for hasArchive + assertEquals(false, bookmarkEntity.hasEbook) // Default value for hasEbook + assertEquals(0, bookmarkEntity.tags.size) // Default empty list for tags + assertEquals(false, bookmarkEntity.createArchive) // Default value for createArchive + assertEquals(false, bookmarkEntity.createEbook) // Default value for createEbook + } + + @Test + fun `BookmarkEntity toDomainModel maps correctly`() { + val tag = Tag( + id = 1, + name = "tag1", + selected = false, + nBookmarks = 5 + ) + + val bookmarkEntity = BookmarkEntity( + id = 1, + url = "http://example.com", + title = "Example Title", + excerpt = "Example Excerpt", + author = "Author Name", + isPublic = 1, + modified = "2023-06-18", + imageURL = "/image.jpg", + hasContent = true, + hasArchive = true, + hasEbook = true, + tags = listOf(tag), + createArchive = true, + createEbook = true + ) + + val bookmark = bookmarkEntity.toDomainModel() + + assertEquals(1, bookmark.id) + assertEquals("http://example.com", bookmark.url) + assertEquals("Example Title", bookmark.title) + assertEquals("Example Excerpt", bookmark.excerpt) + assertEquals("Author Name", bookmark.author) + assertEquals(1, bookmark.public) + assertEquals("2023-06-18", bookmark.modified) + assertEquals("/image.jpg", bookmark.imageURL) + assertEquals(true, bookmark.hasContent) + assertEquals(true, bookmark.hasArchive) + assertEquals(true, bookmark.hasEbook) + assertEquals(1, bookmark.tags.size) + assertEquals(1, bookmark.tags[0].id) + assertEquals("tag1", bookmark.tags[0].name) + assertEquals(5, bookmark.tags[0].nBookmarks) + assertEquals(true, bookmark.createArchive) + assertEquals(true, bookmark.createEbook) + } + + @Test + fun `BookmarkEntity toDomainModel with empty tags maps correctly`() { + val bookmarkEntity = BookmarkEntity( + id = 1, + url = "http://example.com", + title = "Example Title", + excerpt = "Example Excerpt", + author = "Author Name", + isPublic = 1, + modified = "2023-06-18", + imageURL = "/image.jpg", + hasContent = true, + hasArchive = true, + hasEbook = true, + tags = emptyList(), + createArchive = true, + createEbook = true + ) + + val bookmark = bookmarkEntity.toDomainModel() + + assertEquals(1, bookmark.id) + assertEquals("http://example.com", bookmark.url) + assertEquals("Example Title", bookmark.title) + assertEquals("Example Excerpt", bookmark.excerpt) + assertEquals("Author Name", bookmark.author) + assertEquals(1, bookmark.public) + assertEquals("2023-06-18", bookmark.modified) + assertEquals("/image.jpg", bookmark.imageURL) + assertEquals(true, bookmark.hasContent) + assertEquals(true, bookmark.hasArchive) + assertEquals(true, bookmark.hasEbook) + assertEquals(0, bookmark.tags.size) // Ensure tags are empty + assertEquals(true, bookmark.createArchive) + assertEquals(true, bookmark.createEbook) + } + + @Test + fun `UpdateCachePayload toDTO maps correctly`() { + val updateCachePayload = UpdateCachePayload( + createArchive = true, + createEbook = false, + ids = listOf(1, 2, 3), + keepMetadata = true, + skipExist = false + ) + + val updateCachePayloadDTO = updateCachePayload.toDTO() + + assertEquals(true, updateCachePayloadDTO.createArchive) + assertEquals(false, updateCachePayloadDTO.createEbook) + assertEquals(listOf(1, 2, 3), updateCachePayloadDTO.ids) + assertEquals(true, updateCachePayloadDTO.keepMetadata) + } + + @Test + fun `LivenessResponseDTO toDomainModel maps correctly`() { + val releaseInfoDTO = ReleaseInfoDTO( + version = "1.0.0", + date = "2023-06-18", + commit = "abc123" + ) + + val livenessResponseDTO = LivenessResponseDTO( + ok = true, + message = releaseInfoDTO + ) + + val livenessResponse = livenessResponseDTO.toDomainModel() + + assertEquals(true, livenessResponse.ok) + assertEquals("1.0.0", livenessResponse.message?.version) + assertEquals("2023-06-18", livenessResponse.message?.date) + assertEquals("abc123", livenessResponse.message?.commit) + } + + @Test + fun `LivenessResponseDTO toDomainModel with null message maps correctly`() { + val livenessResponseDTO = LivenessResponseDTO( + ok = true, + message = null + ) + + val livenessResponse = livenessResponseDTO.toDomainModel() + + assertEquals(true, livenessResponse.ok) + assertEquals(null, livenessResponse.message) + } + + @Test + fun `LivenessResponseDTO toDomainModel with null ok maps correctly`() { + val releaseInfoDTO = ReleaseInfoDTO( + version = "1.0.0", + date = "2023-06-18", + commit = "abc123" + ) + + val livenessResponseDTO = LivenessResponseDTO( + ok = null, + message = releaseInfoDTO + ) + + val livenessResponse = livenessResponseDTO.toDomainModel() + + assertEquals(false, livenessResponse.ok) + assertEquals("1.0.0", livenessResponse.message?.version) + assertEquals("2023-06-18", livenessResponse.message?.date) + assertEquals("abc123", livenessResponse.message?.commit) + } + + @Test + fun `ReleaseInfoDTO toDomainModel maps correctly`() { + val releaseInfoDTO = ReleaseInfoDTO( + version = "1.0.0", + date = "2023-06-18", + commit = "abc123" + ) + + val releaseInfo = releaseInfoDTO.toDomainModel() + + assertEquals("1.0.0", releaseInfo.version) + assertEquals("2023-06-18", releaseInfo.date) + assertEquals("abc123", releaseInfo.commit) + } + + @Test + fun `ReleaseInfoDTO toDomainModel with null fields maps correctly`() { + val releaseInfoDTO = ReleaseInfoDTO( + version = null, + date = null, + commit = null + ) + + val releaseInfo = releaseInfoDTO.toDomainModel() + + assertEquals("", releaseInfo.version) // Default value for version + assertEquals("", releaseInfo.date) // Default value for date + assertEquals("", releaseInfo.commit) // Default value for commit + } + + @Test + fun `LoginResponseDTO toProtoEntity maps correctly`() { + val loginResponseMessageDTO = LoginResponseMessageDTO( + expires = 3600, + session = "session123", + token = "token123" + ) + + val loginResponseDTO = LoginResponseDTO( + ok = true, + message = loginResponseMessageDTO, + error = null + ) + + val userPreferences = loginResponseDTO.toProtoEntity(userName = "testUser") + + assertEquals("session123", userPreferences.session) + assertEquals("testUser", userPreferences.username) + assertEquals("token123", userPreferences.token) + assertEquals(false, userPreferences.isLegacyApi) + } + + @Test + fun `LoginResponseDTO toProtoEntity with null message maps correctly`() { + val loginResponseDTO = LoginResponseDTO( + ok = true, + message = null, + error = null + ) + + val userPreferences = loginResponseDTO.toProtoEntity(userName = "testUser") + + assertEquals("", userPreferences.session) // Default value for session + assertEquals("testUser", userPreferences.username) + assertEquals("", userPreferences.token) // Default value for token + assertEquals(false, userPreferences.isLegacyApi) + } + + @Test + fun `ReadableContentResponseDTO toDomainModel maps correctly`() { + val readableMessageDto = ReadableMessageDto( + content = "Sample Content", + html = "

Sample HTML

" + ) + + val readableContentResponseDTO = ReadableContentResponseDTO( + ok = true, + message = readableMessageDto + ) + + val readableContent = readableContentResponseDTO.toDomainModel() + + assertEquals(true, readableContent.ok) + assertEquals("Sample Content", readableContent.message.content) + assertEquals("

Sample HTML

", readableContent.message.html) + } + + @Test + fun `ReadableContentResponseDTO toDomainModel with null fields maps correctly`() { + val readableContentResponseDTO = ReadableContentResponseDTO( + ok = null, + message = null + ) + + val readableContent = readableContentResponseDTO.toDomainModel() + + assertEquals(false, readableContent.ok) // Default value for ok + assertEquals("", readableContent.message.content) // Default value for content + assertEquals("", readableContent.message.html) // Default value for html + } + + @Test + fun `ReadableMessageDto toDomainModel maps correctly`() { + val readableMessageDto = ReadableMessageDto( + content = "Sample Content", + html = "

Sample HTML

" + ) + + val readableMessage = readableMessageDto.toDomainModel() + + assertEquals("Sample Content", readableMessage.content) + assertEquals("

Sample HTML

", readableMessage.html) + } + + @Test + fun `ReadableMessageDto toDomainModel with null fields maps correctly`() { + val readableMessageDto = ReadableMessageDto( + content = null, + html = null + ) + + val readableMessage = readableMessageDto.toDomainModel() + + assertEquals("", readableMessage.content) // Default value for content + assertEquals("", readableMessage.html) // Default value for html + } + +} \ No newline at end of file From e3059d93d50a5946072d8e2d9bd4ccc18bbdc46e Mon Sep 17 00:00:00 2001 From: Antonio Corrales Date: Fri, 5 Jul 2024 10:14:27 +0200 Subject: [PATCH 08/11] - Add server URL validation and server online check --- .idea/inspectionProfiles/Project_Default.xml | 1 + .../pagekeeper/ui/login/LoginScreen.kt | 71 ++++++++++------ .../pagekeeper/ui/login/LoginViewModel.kt | 36 ++++++++- .../pagekeeper/ui/login/ServerUrlTextField.kt | 80 +++++++++++++++++-- 4 files changed, 156 insertions(+), 32 deletions(-) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 44ca2d9..6c6e34e 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,6 +1,7 @@