From 68accb40357821a45220fd78ff760a3b59295877 Mon Sep 17 00:00:00 2001
From: chris-cwa <69595386+chris-cwa@users.noreply.github.com>
Date: Thu, 20 May 2021 15:17:47 +0200
Subject: [PATCH] Vaccination Server Test (EXPOSUREAPP-6890) (#3231)

* unit tests for vaccination server

* renamed resources

Co-authored-by: BMItter <Berndus@gmx.de>
Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>
---
 .../core/server/valueset/VaccinationServer.kt |  10 +-
 .../server/valueset/VaccinationServerTest.kt  | 109 ++++++++++++++++++
 .../vaccination/valueset_default.zip          | Bin 0 -> 259 bytes
 .../vaccination/valueset_invalid.zip          | Bin 0 -> 118 bytes
 4 files changed, 117 insertions(+), 2 deletions(-)
 create mode 100644 Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationServerTest.kt
 create mode 100755 Corona-Warn-App/src/test/resources/vaccination/valueset_default.zip
 create mode 100755 Corona-Warn-App/src/test/resources/vaccination/valueset_invalid.zip

diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationServer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationServer.kt
index 0d108cd2a..5e064692b 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationServer.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationServer.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.vaccination.core.server.valueset
 
+import androidx.annotation.VisibleForTesting
 import dagger.Lazy
 import dagger.Reusable
 import de.rki.coronawarnapp.server.protocols.internal.dgc.ValueSetsOuterClass
@@ -15,6 +16,7 @@ import okhttp3.ResponseBody
 import retrofit2.HttpException
 import retrofit2.Response
 import timber.log.Timber
+import java.io.InputStream
 import java.util.Locale
 import javax.inject.Inject
 
@@ -50,8 +52,12 @@ class VaccinationServer @Inject constructor(
             apiV1.get().getValueSets(languageCode = languageCode)
         }
 
-    private fun ResponseBody.parseBody(): ValueSetsOuterClass.ValueSets {
-        val fileMap = this.byteStream().unzip().readIntoMap()
+    private fun ResponseBody.parseBody(): ValueSetsOuterClass.ValueSets =
+        parseBody(byteStream())
+
+    @VisibleForTesting
+    internal fun parseBody(inputStream: InputStream): ValueSetsOuterClass.ValueSets {
+        val fileMap = inputStream.unzip().readIntoMap()
 
         val exportBinary = fileMap[EXPORT_BINARY_FILE_NAME]
         val exportSignature = fileMap[EXPORT_SIGNATURE_FILE_NAME]
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationServerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationServerTest.kt
new file mode 100644
index 000000000..0c27822e1
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/vaccination/core/server/valueset/VaccinationServerTest.kt
@@ -0,0 +1,109 @@
+package de.rki.coronawarnapp.vaccination.core.server.valueset
+
+import dagger.Lazy
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.security.SignatureValidation
+import de.rki.coronawarnapp.vaccination.core.server.valueset.internal.ValueSetInvalidSignatureException
+import io.kotest.assertions.throwables.shouldThrow
+import io.kotest.matchers.shouldBe
+import io.kotest.matchers.shouldNotBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import io.mockk.just
+import io.mockk.runs
+import io.mockk.verify
+import okhttp3.Cache
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import testhelpers.BaseTest
+import java.io.File
+
+class VaccinationServerTest : BaseTest() {
+
+    /**
+     * contains both binary and signature
+     */
+    private val exportZip = File("src/test/resources/vaccination/valueset_default.zip")
+
+    /**
+     * binary is missing
+     */
+    private val invalidExportZip = File("src/test/resources/vaccination/valueset_invalid.zip")
+
+    @MockK lateinit var cache: Cache
+    @MockK lateinit var apiV1: Lazy<VaccinationValueSetApiV1>
+    @MockK lateinit var dispatcherProvider: DispatcherProvider
+    @MockK lateinit var signatureValidation: SignatureValidation
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+        exportZip.exists() shouldBe true
+        invalidExportZip.exists() shouldBe true
+    }
+
+    private fun createInstance() = VaccinationServer(
+        cache,
+        apiV1,
+        dispatcherProvider,
+        signatureValidation
+    )
+
+    @Test
+    fun `valid export data`() {
+        every { signatureValidation.hasValidSignature(any(), any()) } returns true
+        exportZip.inputStream().use {
+            createInstance().parseBody(it).apply {
+                this shouldNotBe null
+                ma.apply {
+                    itemsCount shouldBe 1
+                    getItems(0).apply {
+                        key shouldBe "maKey"
+                        displayText shouldBe "maDisplayText"
+                    }
+                }
+                mp.apply {
+                    itemsCount shouldBe 1
+                    getItems(0).apply {
+                        key shouldBe "mpKey"
+                        displayText shouldBe "mpDisplayText"
+                    }
+                }
+                vp.apply {
+                    itemsCount shouldBe 1
+                    getItems(0).apply {
+                        key shouldBe "vpKey"
+                        displayText shouldBe "vpDisplayText"
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    fun `invalid signature`() {
+        every { signatureValidation.hasValidSignature(any(), any()) } returns false
+        exportZip.inputStream().use {
+            shouldThrow<ValueSetInvalidSignatureException> {
+                createInstance().parseBody(it)
+            }
+        }
+    }
+
+    @Test
+    fun `a file is missing`() {
+        invalidExportZip.inputStream().use {
+            shouldThrow<ValueSetInvalidSignatureException> {
+                createInstance().parseBody(it)
+            }
+        }
+    }
+
+    @Test
+    fun `call to clear invalidates cache`() {
+        every { cache.evictAll() } just runs
+        createInstance().clear()
+        verify { cache.evictAll() }
+    }
+}
diff --git a/Corona-Warn-App/src/test/resources/vaccination/valueset_default.zip b/Corona-Warn-App/src/test/resources/vaccination/valueset_default.zip
new file mode 100755
index 0000000000000000000000000000000000000000..07bab18cc3ed089272171b18702eda8d62cab2d9
GIT binary patch
literal 259
zcmWIWW@Zs#U|`^2$k?$ts48gb7F{6E4~V&dIJKf6zo<knDKqc!qz6KelXSH|_^lOr
zq^n(UQb+HE=NcZ*wHks<r=K{b6irNBqF~f1Fw;dvk|6+UC<8+?&`_W`aDZfJab|je
wHzSh>18(a<+87xWpt=!`LFmJ714IKzUnmem^?~hUWdq4E0bv1<t_5)z0HOOe&;S4c

literal 0
HcmV?d00001

diff --git a/Corona-Warn-App/src/test/resources/vaccination/valueset_invalid.zip b/Corona-Warn-App/src/test/resources/vaccination/valueset_invalid.zip
new file mode 100755
index 0000000000000000000000000000000000000000..7a574548e639ff20f9d465304ff3c03c3ed8437d
GIT binary patch
literal 118
zcmWIWW@Zs#0D<Nmn}fg%D8U7!Q!5Jci%Rs0Gt&dS8JR>FaI1u9Qh@43*2l^Q5@ZBI
K3m~llRsjI<R1aSO

literal 0
HcmV?d00001

-- 
GitLab