Skip to content

Commit

Permalink
feat: add unit tests (ministero-salute#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
Light2288 authored Jun 12, 2021
1 parent 694c3f0 commit aceb6f7
Show file tree
Hide file tree
Showing 17 changed files with 877 additions and 2 deletions.
14 changes: 14 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ plugins {
id 'dagger.hilt.android.plugin'
}

tasks.whenTaskAdded { task ->
if (task.name == 'assembleDebug')
task.dependsOn test
}

tasks.whenTaskAdded { task ->
if (task.name == 'assembleRelease')
task.dependsOn test
}


android {
compileSdkVersion Config.compileSdk

Expand Down Expand Up @@ -96,4 +107,7 @@ dependencies {
implementation Deps.gson_converter

testImplementation Deps.test_junit
testImplementation "io.mockk:mockk:1.11.0"
testImplementation 'androidx.arch.core:core-testing:2.1.0'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.0'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-verifier-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by climent on 6/8/21 5:54 PM
*/

package it.ministerodellasalute.verificaC19.di

import kotlinx.coroutines.Dispatchers
import javax.inject.Inject

class DispatcherProvider @Inject constructor() {
fun getIO() = Dispatchers.IO
fun getDefault() = Dispatchers.Default
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import dgca.verifier.app.decoder.schema.SchemaValidator
import dgca.verifier.app.decoder.toBase64
import it.ministerodellasalute.verificaC19.data.local.Preferences
import it.ministerodellasalute.verificaC19.data.remote.model.Rule
import it.ministerodellasalute.verificaC19.di.DispatcherProvider
import it.ministerodellasalute.verificaC19.model.ValidationRulesEnum
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand All @@ -63,7 +64,8 @@ class VerificationViewModel @Inject constructor(
private val schemaValidator: SchemaValidator,
private val cborService: CborService,
private val verifierRepository: VerifierRepository,
private val preferences: Preferences
private val preferences: Preferences,
private val dispatcherProvider: DispatcherProvider
) : ViewModel() {

private val _verificationResult = MutableLiveData<VerificationResult>()
Expand All @@ -86,7 +88,7 @@ class VerificationViewModel @Inject constructor(
var greenCertificate: GreenCertificate? = null
val verificationResult = VerificationResult()

withContext(Dispatchers.IO) {
withContext(dispatcherProvider.getIO()) {
val plainInput = prefixValidationService.decode(code, verificationResult)
val compressedCose = base45Service.decode(plainInput, verificationResult)
val cose = compressorService.decode(compressedCose, verificationResult)
Expand Down
1 change: 1 addition & 0 deletions app/src/test/assets/qr_code.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
HC1:NCFTW2BM75VO433KHHV77NSL- 8+C81/N* 3095M%9V\$6MWD5DDDH79:DC0L2Z9USQQ\$Q442JVKT67*5MKG4EMKF.9R67RBHO\$19VMUUSJITYRGG\$79Y35\$U%99I-MZ.N5\$G\$4MG9QWKL%+JMMH:2NL:50/NW8NL:5K.80954 CWOLH6J2MD6*I8NIX45FQD9J9YDDK41W8HP3KCOPG002DBXR8 U8S.B5MUU\$H0D3/OKKUF\$MQVI74H93%L4/9NTOLPOK 4169RA4IPCDE4.EC886FJI05PGI269Q:-4WBCTVK9\$5NHMTVG6SGIDOEF0HJ5Z1KW:S3Y2DYBMYIZEG5M8QOF%MSEXA2IHOGIF3NGBF:W4:AHB0WJVK5WKIY9 BTU:QUPJ/6C/0LQTTZ J4NTBR77QCO+SFMD55KG0EN0RY M1REXUM/C79PSI4L00T1C5H+OUQ6S2L95JVRS*.8UFQV:GKCO8K64NF3R8554LQOE\$4LF7BC3N/H*-FWQ9GPBC UW2V6N426E\$WD26F4+U:2T1HTB-IJ300:V%WVFSBZ+S4T2A0PAL39ZSGTMXKRP438WDL3RIZMG2A\$GH"
1 change: 1 addition & 0 deletions app/src/test/assets/qr_code_cbor.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pAQaYMDj9gYaYL5A9gFiQVQ5AQOhAaRhdoGqYmRuAWJtYW1PUkctMTAwMDMwMjE1YnZwajExMTkzNDkwMDdiZHRqMjAyMS0wMi0xOGJjb2JBVGJjaXgxVVJOOlVWQ0k6MDE6QVQ6MTA4MDc4NDNGOTRBRUUwRUU1MDkzRkJDMjU0QkQ4MTMjQmJtcGxFVS8xLzIwLzE1MjhiaXN4G01pbmlzdHJ5IG9mIEhlYWx0aCwgQXVzdHJpYWJzZAJidGdpODQwNTM5MDA2Y25hbaRjZm50dU1VU1RFUkZSQVU8R09FU1NJTkdFUmJmbnVNdXN0ZXJmcmF1LUfDtsOfaW5nZXJjZ250aEdBQlJJRUxFYmduaEdhYnJpZWxlY3ZlcmUxLjIuMWNkb2JqMTk5OC0wMi0yNg==
10 changes: 10 additions & 0 deletions app/src/test/assets/qr_code_certificate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
MIIBvTCCAWOgAwIBAgIKAXk8i88OleLsuTAKBggqhkjOPQQDAjA2MRYwFAYDVQQD
DA1BVCBER0MgQ1NDQSAxMQswCQYDVQQGEwJBVDEPMA0GA1UECgwGQk1TR1BLMB4X
DTIxMDUwNTEyNDEwNloXDTIzMDUwNTEyNDEwNlowPTERMA8GA1UEAwwIQVQgRFND
IDExCzAJBgNVBAYTAkFUMQ8wDQYDVQQKDAZCTVNHUEsxCjAIBgNVBAUTATEwWTAT
BgcqhkjOPQIBBggqhkjOPQMBBwNCAASt1Vz1rRuW1HqObUE9MDe7RzIk1gq4XW5G
TyHuHTj5cFEn2Rge37+hINfCZZcozpwQKdyaporPUP1TE7UWl0F3o1IwUDAOBgNV
HQ8BAf8EBAMCB4AwHQYDVR0OBBYEFO49y1ISb6cvXshLcp8UUp9VoGLQMB8GA1Ud
IwQYMBaAFP7JKEOflGEvef2iMdtopsetwGGeMAoGCCqGSM49BAMCA0gAMEUCIQDG
2opotWG8tJXN84ZZqT6wUBz9KF8D+z9NukYvnUEQ3QIgdBLFSTSiDt0UJaDF6St2
bkUQuVHW6fQbONd731/M4nc=
1 change: 1 addition & 0 deletions app/src/test/assets/qr_code_compressed_cose.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
eNoVjztIw1AYRomKOLmrIEXFQYy9fx42KSJN9TYWbItpIzppbpqmKU1a0rTURRCKo7o4iq8OIoiiIE6iOIiIgw6Cs4Li4Oiig3E98B2+89RI7LVNvXSFFq7fz0+pwZ15im22dS9evX63dy9eRr4pImVEqnWXamq1lUOSdShia3ZKkWlACLGIAZ7UygUAEFlORChEsl6B8TGNGBoEopd8AdGtOqhKMqzOTsTDCMJSJgxIQCGBY2MiJ2GMMOaRyMaiEwzPRScFYPujxC4XsRqEIIOCwDMCsSr1noTlWBXPXQqUcoEpQyt6+eGAVPWJpZFKtoV4piVwiGf9K6O6o9lNPed41YSazmAlpkjqmJzC6XQ8KWOF5Jxqwp8abs7VqrR8c36zbTmm4eqm4+VlKarE8TQmppOXNeJaRtHQa4ZrwAgzAnq2RAogisJ/JjM6Fxnijh9+A0vjW3jzrvWxI7Vvzmyad7f0WuXr6GOVogCa/PP6/Vv+5KcU78XLG3bjrLMv2TgYiGx91i+0P0+EiW4=
1 change: 1 addition & 0 deletions app/src/test/assets/qr_code_cose.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0oRNogRI2Rk3X8HntrIBJqBZATOkBBpgwOP2BhpgvkD2AWJBVDkBA6EBpGF2gapiZG4BYm1hbU9SRy0xMDAwMzAyMTVidnBqMTExOTM0OTAwN2JkdGoyMDIxLTAyLTE4YmNvYkFUYmNpeDFVUk46VVZDSTowMTpBVDoxMDgwNzg0M0Y5NEFFRTBFRTUwOTNGQkMyNTRCRDgxMyNCYm1wbEVVLzEvMjAvMTUyOGJpc3gbTWluaXN0cnkgb2YgSGVhbHRoLCBBdXN0cmlhYnNkAmJ0Z2k4NDA1MzkwMDZjbmFtpGNmbnR1TVVTVEVSRlJBVTxHT0VTU0lOR0VSYmZudU11c3RlcmZyYXUtR8O2w59pbmdlcmNnbnRoR0FCUklFTEViZ25oR2FicmllbGVjdmVyZTEuMi4xY2RvYmoxOTk4LTAyLTI2WEAqNK/N/CB5Pp1FlckD0QhPo2dRlWfJxy2Oc+6t6IYBATExpDXWj8vkaLD7b0keRX6QbYSzDiJOhKgkQJ3qeLhh
1 change: 1 addition & 0 deletions app/src/test/assets/qr_code_kid.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2Rk3X8HntrI=
1 change: 1 addition & 0 deletions app/src/test/assets/qr_code_plain_input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NCFTW2BM75VO433KHHV77NSL- 8+C81/N* 3095M%9V\$6MWD5DDDH79:DC0L2Z9USQQ\$Q442JVKT67*5MKG4EMKF.9R67RBHO\$19VMUUSJITYRGG\$79Y35\$U%99I-MZ.N5\$G\$4MG9QWKL%+JMMH:2NL:50/NW8NL:5K.80954 CWOLH6J2MD6*I8NIX45FQD9J9YDDK41W8HP3KCOPG002DBXR8 U8S.B5MUU\$H0D3/OKKUF\$MQVI74H93%L4/9NTOLPOK 4169RA4IPCDE4.EC886FJI05PGI269Q:-4WBCTVK9\$5NHMTVG6SGIDOEF0HJ5Z1KW:S3Y2DYBMYIZEG5M8QOF%MSEXA2IHOGIF3NGBF:W4:AHB0WJVK5WKIY9 BTU:QUPJ/6C/0LQTTZ J4NTBR77QCO+SFMD55KG0EN0RY M1REXUM/C79PSI4L00T1C5H+OUQ6S2L95JVRS*.8UFQV:GKCO8K64NF3R8554LQOE\$4LF7BC3N/H*-FWQ9GPBC UW2V6N426E\$WD26F4+U:2T1HTB-IJ300:V%WVFSBZ+S4T2A0PAL39ZSGTMXKRP438WDL3RIZMG2A\$GH
126 changes: 126 additions & 0 deletions app/src/test/assets/verification_rules_success_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
[
{
"name": "android",
"type": "APP_MIN_VERSION",
"value": "4.1.1"
},
{
"name": "ios",
"type": "APP_MIN_VERSION",
"value": "4.1.1"
},
{
"name": "recovery_cert_end_day",
"type": "GENERIC",
"value": "180"
},
{
"name": "recovery_cert_start_day",
"type": "GENERIC",
"value": "0"
},
{
"name": "molecular_test_end_hours",
"type": "GENERIC",
"value": "48"
},
{
"name": "molecular_test_start_hours",
"type": "GENERIC",
"value": "0"
},
{
"name": "rapid_test_end_hours",
"type": "GENERIC",
"value": "48"
},
{
"name": "rapid_test_start_hours",
"type": "GENERIC",
"value": "0"
},

{
"name": "vaccine_start_day_not_complete",
"type": "EU/1/20/1528",
"value": "15"
},
{
"name": "vaccine_end_day_not_complete",
"type": "EU/1/20/1528",
"value": "42"
},
{
"name": "vaccine_start_day_complete",
"type": "EU/1/20/1528",
"value": "15"
},
{
"name": "vaccine_end_day_complete",
"type": "EU/1/20/1528",
"value": "270"
},

{
"name": "vaccine_start_day_not_complete",
"type": "EU/1/20/1507",
"value": "15"
},
{
"name": "vaccine_end_day_not_complete",
"type": "EU/1/20/1507",
"value": "42"
},
{
"name": "vaccine_start_day_complete",
"type": "EU/1/20/1507",
"value": "15"
},
{
"name": "vaccine_end_day_complete",
"type": "EU/1/20/1507",
"value": "270"
},

{
"name": "vaccine_start_day_not_complete",
"type": "EU/1/21/1529",
"value": "15"
},
{
"name": "vaccine_end_day_not_complete",
"type": "EU/1/21/1529",
"value": "84"
},
{
"name": "vaccine_start_day_complete",
"type": "EU/1/21/1529",
"value": "15"
},
{
"name": "vaccine_end_day_complete",
"type": "EU/1/21/1529",
"value": "270"
},

{
"name": "vaccine_start_day_not_complete",
"type": "EU/1/20/1525",
"value": "15"
},
{
"name": "vaccine_end_day_not_complete",
"type": "EU/1/20/1525",
"value": "270"
},
{
"name": "vaccine_start_day_complete",
"type": "EU/1/20/1525",
"value": "15"
},
{
"name": "vaccine_end_day_complete",
"type": "EU/1/20/1525",
"value": "270"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-verifier-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by climent on 6/7/21 3:04 PM
*/

package it.ministerodellasalute.verificaC19.ui

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.RelaxedMockK
import io.mockk.mockk
import io.mockk.slot
import it.ministerodellasalute.verificaC19.data.VerifierRepository
import it.ministerodellasalute.verificaC19.data.local.Preferences
import it.ministerodellasalute.verificaC19.utils.mock.ServiceMocks
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test

class FirstViewModelTest {

@Rule
@JvmField
val instantExecutorRule = InstantTaskExecutorRule()

@RelaxedMockK
private lateinit var preferences: Preferences

@RelaxedMockK
private lateinit var verifierRepository: VerifierRepository

private lateinit var viewModel: FirstViewModel

@Before
fun setup() {
MockKAnnotations.init(this)
viewModel = FirstViewModel(verifierRepository, preferences)
}

@Test
fun `get AppMinVersion from server`() {
val response = ServiceMocks.getVerificationRulesStringResponse()
every { preferences.validationRulesJson }.returns(response)

assertEquals( viewModel.getAppMinVersion(), "4.1.1")
}

@Test
fun `get Last Fetch Date when data not found`() {
every { preferences.dateLastFetch}.returns(-1L)

assertEquals( viewModel.getDateLastSync(), -1)
}

@Test
fun `get Last Fetch Date when data is present`() {
val currentDate = System.currentTimeMillis()

every { preferences.dateLastFetch}.returns(currentDate)

assertEquals( viewModel.getDateLastSync(), currentDate)
}

@Test
fun `get Certificate Fetch Status when the request is not ready`() {
val response = MutableLiveData(true)

val mockObserver = mockk<Observer<Boolean>>()
val slot = slot<Boolean>()
val listOfResponse = arrayListOf<Boolean>()

every { verifierRepository.getCertificateFetchStatus()}.returns(response)

every { mockObserver.onChanged(capture(slot)) } answers {
listOfResponse.add(slot.captured)
}

viewModel = FirstViewModel(verifierRepository, preferences)

viewModel.fetchStatus.observeForever(mockObserver)

assertEquals(true, listOfResponse[0])
}

@Test
fun `get Certificate Fetch Status when the request is ready`() {
val response = MutableLiveData(false)

val mockObserver = mockk<Observer<Boolean>>()
val slot = slot<Boolean>()
val listOfResponse = arrayListOf<Boolean>()

every { verifierRepository.getCertificateFetchStatus()}.returns(response)

every { mockObserver.onChanged(capture(slot)) } answers {
listOfResponse.add(slot.captured)
}

viewModel = FirstViewModel(verifierRepository, preferences)

viewModel.fetchStatus.observeForever(mockObserver)

assertEquals(false, listOfResponse[0])
}

}
Loading

0 comments on commit aceb6f7

Please sign in to comment.