From 05ab872f77738b4b44c90febf052ffc0c0276cab Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Thu, 5 Mar 2026 23:54:00 +0100 Subject: [PATCH] =?UTF-8?q?Diary:=20erg=C3=A4nze=20Mapper-Tests=20f=C3=BCr?= =?UTF-8?q?=20Assignments=20und=20Predefined=20Activities?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/repository/RepositoryMappersTest.kt | 335 ++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 android-app/app/src/test/java/de/trainingstagebuch/app/repository/RepositoryMappersTest.kt diff --git a/android-app/app/src/test/java/de/trainingstagebuch/app/repository/RepositoryMappersTest.kt b/android-app/app/src/test/java/de/trainingstagebuch/app/repository/RepositoryMappersTest.kt new file mode 100644 index 00000000..02fcd779 --- /dev/null +++ b/android-app/app/src/test/java/de/trainingstagebuch/app/repository/RepositoryMappersTest.kt @@ -0,0 +1,335 @@ +package de.trainingstagebuch.app.repository + +import kotlinx.serialization.json.Json +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Test + +class RepositoryMappersTest { + + @Test + fun `mapClubsToHomeData maps count and names`() { + val clubsJson = Json.parseToJsonElement( + """ + [ + {"id":"1","name":"Club A"}, + {"id":"2","name":"Club B"}, + {"id":"3"} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapClubsToHomeData(clubsJson) + + assertEquals(3, result.clubCount) + assertEquals(listOf("Club A", "Club B"), result.clubNames) + } + + @Test + fun `parseErrorPayload parses backend error format`() { + val error = RepositoryMappers.parseErrorPayload( + """{"success":false,"code":"ERROR_UNAUTHORIZED","error":"Nicht autorisiert"}""" + ) + + assertNotNull(error) + assertEquals("ERROR_UNAUTHORIZED", error?.code) + assertEquals("Nicht autorisiert", error?.message) + } + + @Test + fun `parseErrorPayload returns null for invalid json`() { + val error = RepositoryMappers.parseErrorPayload("not-json") + assertNull(error) + } + + @Test + fun `mapMembersToMemberItems maps display names and flags`() { + val membersJson = Json.parseToJsonElement( + """ + [ + {"id":"1","firstName":"Max","lastName":"Mustermann","active":true,"testMembership":false}, + {"id":"2","firstName":"Eva","lastName":"Muster","active":false,"testMembership":true} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapMembersToMemberItems(membersJson) + + assertEquals(2, result.size) + assertEquals("Max", result[0].firstName) + assertEquals("Mustermann", result[0].lastName) + assertEquals("Max Mustermann", result[0].displayName) + assertEquals(true, result[0].active) + assertEquals(false, result[0].testMembership) + assertEquals("Eva Muster", result[1].displayName) + assertEquals(false, result[1].active) + assertEquals(true, result[1].testMembership) + } + + @Test + fun `mapMemberGalleryImages filters by member and primary first`() { + val galleryJson = Json.parseToJsonElement( + """ + [ + {"imageId":"img-2","memberId":"2","url":"b.jpg","isPrimary":false}, + {"imageId":"img-1","memberId":"2","url":"a.jpg","isPrimary":true}, + {"imageId":"img-x","memberId":"3","url":"x.jpg","isPrimary":true} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapMemberGalleryImages(galleryJson, memberId = "2") + + assertEquals(2, result.size) + assertEquals("img-1", result[0].imageId) + assertEquals(true, result[0].isPrimary) + assertEquals("img-2", result[1].imageId) + } + + @Test + fun `mapMemberNotes maps notes with fallback fields`() { + val notesJson = Json.parseToJsonElement( + """ + [ + {"id":"n1","content":"Erste Notiz","createdAt":"2025-01-01"}, + {"_id":"n2","text":"Zweite Notiz"} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapMemberNotes(notesJson) + + assertEquals(2, result.size) + assertEquals("n1", result[0].id) + assertEquals("Erste Notiz", result[0].content) + assertEquals("n2", result[1].id) + assertEquals("Zweite Notiz", result[1].content) + } + + @Test + fun `mapDiaryDates maps required diary fields`() { + val diaryJson = Json.parseToJsonElement( + """ + [ + {"id":"d1","date":"2026-03-01","trainingStart":"18:00","trainingEnd":"20:00","diaryTags":[{"id":"t1","name":"Kondition"}]}, + {"_id":"d2","date":"2026-03-02"} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapDiaryDates(diaryJson) + + assertEquals(2, result.size) + assertEquals("d1", result[0].id) + assertEquals("2026-03-01", result[0].date) + assertEquals("18:00", result[0].trainingStart) + assertEquals("20:00", result[0].trainingEnd) + assertEquals(1, result[0].tags.size) + assertEquals("t1", result[0].tags[0].id) + assertEquals("d2", result[1].id) + assertEquals("2026-03-02", result[1].date) + } + + @Test + fun `mapDiaryParticipants maps participant and member ids`() { + val participantsJson = Json.parseToJsonElement( + """ + [ + {"id":"p1","memberId":"m1","groupId":"g1"}, + {"_id":"p2","memberId":"m2"} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapDiaryParticipants(participantsJson) + + assertEquals(2, result.size) + assertEquals("p1", result[0].id) + assertEquals("m1", result[0].memberId) + assertEquals("g1", result[0].groupId) + assertEquals("p2", result[1].id) + assertEquals("m2", result[1].memberId) + } + + @Test + fun `mapDiaryActivities maps id and description`() { + val activitiesJson = Json.parseToJsonElement( + """ + [ + {"id":"a1","description":"Aufschlagtraining"}, + {"_id":"a2","activity":"Beinarbeit"} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapDiaryActivities(activitiesJson) + + assertEquals(2, result.size) + assertEquals("a1", result[0].id) + assertEquals("Aufschlagtraining", result[0].description) + assertEquals("a2", result[1].id) + assertEquals("Beinarbeit", result[1].description) + } + + @Test + fun `mapTags supports root and nested tag objects`() { + val tagsJson = Json.parseToJsonElement( + """ + [ + {"id":"t1","name":"Technik"}, + {"tag":{"id":"t2","label":"Ausdauer"}} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapTags(tagsJson) + + assertEquals(2, result.size) + assertEquals("t1", result[0].id) + assertEquals("Technik", result[0].name) + assertEquals("t2", result[1].id) + assertEquals("Ausdauer", result[1].name) + } + + @Test + fun `mapDiaryPlanItems maps activity and timeblock`() { + val planJson = Json.parseToJsonElement( + """ + [ + {"id":"p1","activity":"Einspielen","isTimeblock":false}, + {"_id":"p2","isTimeblock":true} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapDiaryPlanItems(planJson) + + assertEquals(2, result.size) + assertEquals("p1", result[0].id) + assertEquals("Einspielen", result[0].activity) + assertEquals(false, result[0].isTimeblock) + assertEquals("p2", result[1].id) + assertEquals(true, result[1].isTimeblock) + } + + @Test + fun `mapDiaryGroups maps id and name`() { + val groupsJson = Json.parseToJsonElement( + """ + [ + {"id":"g1","name":"Gruppe A"}, + {"_id":"g2"} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapDiaryGroups(groupsJson) + + assertEquals(2, result.size) + assertEquals("g1", result[0].id) + assertEquals("Gruppe A", result[0].name) + assertEquals("g2", result[1].id) + } + + @Test + fun `mapParticipantIds maps assignment ids`() { + val json = Json.parseToJsonElement( + """ + [ + {"participantId":"p1"}, + {"participantId":"p2"}, + {"participantId":"p1"} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapParticipantIds(json) + + assertEquals(setOf("p1", "p2"), result) + } + + @Test + fun `mapPredefinedActivities maps id name and optional fields`() { + val json = Json.parseToJsonElement( + """ + [ + {"id":"a1","name":"Topspin VH","code":"TS-VH","duration":"20","durationText":"4x5"}, + {"_id":"a2","name":"Aufschlag"} + ] + """.trimIndent() + ) + + val result = RepositoryMappers.mapPredefinedActivities(json) + + assertEquals(2, result.size) + assertEquals("a1", result[0].id) + assertEquals("Topspin VH", result[0].name) + assertEquals("TS-VH", result[0].code) + assertEquals("20", result[0].duration) + assertEquals("4x5", result[0].durationText) + assertEquals("a2", result[1].id) + assertEquals("Aufschlag", result[1].name) + } + + @Test + fun `mapMemberTransferConfig maps login credentials and defaults`() { + val configJson = Json.parseToJsonElement( + """ + { + "id":"cfg-1", + "server":"https://example.org", + "loginEndpoint":"/auth/login", + "loginCredentials":{"username":"u1","password":"p1","tenant":"abc"}, + "transferEndpoint":"/transfer", + "transferTemplate":"{\"id\":\"{{id}}\"}", + "useBulkMode":true + } + """.trimIndent() + ).let { it as kotlinx.serialization.json.JsonObject } + + val result = RepositoryMappers.mapMemberTransferConfig(configJson) + + assertEquals("cfg-1", result.id) + assertEquals("https://example.org", result.server) + assertEquals("/auth/login", result.loginEndpoint) + assertEquals("json", result.loginFormat) + assertEquals("u1", result.loginUsername) + assertEquals("tenant:abc", result.loginAdditionalField1) + assertEquals("/transfer", result.transferEndpoint) + assertEquals("POST", result.transferMethod) + assertEquals("json", result.transferFormat) + assertEquals(true, result.useBulkMode) + } + + @Test + fun `mapMemberTransferSummary supports numeric and string counts`() { + val summaryJson = Json.parseToJsonElement( + """ + { + "success": false, + "message": "teilweise fehlgeschlagen", + "transferred": 2, + "total": "4", + "invalidMembers": [ + {"member":{"firstName":"Max","lastName":"Mustermann"}}, + {"member":{"id":"m-2"}} + ], + "errors": [ + {"member":"m-2","error":"timeout"}, + "generic error" + ] + } + """.trimIndent() + ).let { it as kotlinx.serialization.json.JsonObject } + + val result = RepositoryMappers.mapMemberTransferSummary(summaryJson) + + assertEquals(false, result.success) + assertEquals("teilweise fehlgeschlagen", result.message) + assertEquals(2, result.transferred) + assertEquals(4, result.total) + assertEquals(listOf("Max Mustermann", "m-2"), result.invalidMembers) + assertEquals(listOf("m-2: timeout", "generic error"), result.errors) + } +}