Update ValidationExecutorTest

This commit is contained in:
Aidan Follestad 2019-01-11 19:57:29 -08:00
commit 6bb131fb23
6 changed files with 378 additions and 109 deletions

View file

@ -19,12 +19,13 @@ import android.app.PendingIntent
import android.content.Intent
import android.content.IntentFilter
import com.afollestad.nocknock.data.AppDatabase
import com.afollestad.nocknock.data.model.RetryPolicy
import com.afollestad.nocknock.data.HeaderDao
import com.afollestad.nocknock.data.RetryPolicyDao
import com.afollestad.nocknock.data.SiteDao
import com.afollestad.nocknock.data.SiteSettingsDao
import com.afollestad.nocknock.data.ValidationResultsDao
import com.afollestad.nocknock.data.model.Header
import com.afollestad.nocknock.data.model.RetryPolicy
import com.afollestad.nocknock.data.model.Site
import com.afollestad.nocknock.data.model.SiteSettings
import com.afollestad.nocknock.data.model.Status
@ -56,7 +57,8 @@ fun fakeSettingsModel(
validationMode = validationMode,
validationArgs = null,
disabled = false,
networkTimeout = 10000
networkTimeout = 10000,
certificate = null
)
fun fakeResultModel(
@ -165,12 +167,29 @@ fun mockDatabase(): AppDatabase {
on { update(isA()) } doReturn 1
on { delete(isA()) } doReturn 1
}
val headerDao = mock<HeaderDao> {
on { all() } doReturn com.afollestad.nocknock.engine.MOCK_MODEL_1.headers + com.afollestad.nocknock.engine.MOCK_MODEL_2.headers + com.afollestad.nocknock.engine.MOCK_MODEL_3.headers
on { forSite(isA()) } doAnswer { inv ->
val id = inv.getArgument<Long>(0)
return@doAnswer when (id) {
1L -> com.afollestad.nocknock.engine.MOCK_MODEL_1.headers
2L -> com.afollestad.nocknock.engine.MOCK_MODEL_2.headers
3L -> com.afollestad.nocknock.engine.MOCK_MODEL_3.headers
else -> listOf()
}
}
on { insert(isA<Header>()) } doReturn 1L
on { insert(isA<List<Header>>()) } doReturn listOf(1L, 2L)
on { update(isA()) } doReturn 1
on { delete(isA()) } doReturn 1
}
return mock {
on { siteDao() } doReturn siteDao
on { siteSettingsDao() } doReturn settingsDao
on { validationResultsDao() } doReturn resultsDao
on { retryPolicyDao() } doReturn retryDao
on { headerDao() } doReturn headerDao
}
}

View file

@ -19,6 +19,7 @@ import android.app.Application
import android.content.Context
import android.net.Uri
import androidx.annotation.CheckResult
import com.afollestad.nocknock.utilities.ext.toUri
import okhttp3.OkHttpClient
import java.io.BufferedInputStream
import java.io.FileInputStream
@ -33,8 +34,8 @@ import timber.log.Timber.d as log
interface SslManager {
@CheckResult fun clientForCertificate(
certUri: Uri,
host: String,
certUri: String,
siteUri: String,
client: OkHttpClient
): OkHttpClient
}
@ -45,21 +46,25 @@ class RealSslManager(
) : SslManager {
override fun clientForCertificate(
certUri: Uri,
host: String,
certUri: String,
siteUri: String,
client: OkHttpClient
): OkHttpClient {
log("Loading certificate $certUri for host $host")
val parsedCertUri = certUri.toUri()
val parsedSiteUri = siteUri.toUri()
val siteHost = parsedSiteUri.host ?: ""
log("Loading certificate $certUri for host $siteHost")
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
keyStore.load(null, null)
val certInputStream = app.openUri(certUri)
val certInputStream = app.openUri(parsedCertUri)
val bis = BufferedInputStream(certInputStream)
val certificateFactory = CertificateFactory.getInstance("X.509")
while (bis.available() > 0) {
val cert = certificateFactory.generateCertificate(bis)
keyStore.setCertificateEntry(host, cert)
keyStore.setCertificateEntry(siteHost, cert)
}
val trustManagerFactory =
@ -76,7 +81,7 @@ class RealSslManager(
.sslSocketFactory(sslContext.socketFactory, trustManager)
.hostnameVerifier { hostname, _ ->
log("Verifying hostname $hostname")
hostname == host
hostname == siteHost
}
.build()
}

View file

@ -17,6 +17,7 @@ package com.afollestad.nocknock.engine.validation
import android.app.job.JobScheduler
import android.app.job.JobScheduler.RESULT_SUCCESS
import android.net.Uri
import com.afollestad.nocknock.data.AppDatabase
import com.afollestad.nocknock.data.allSites
import com.afollestad.nocknock.data.model.Site
@ -25,7 +26,6 @@ import com.afollestad.nocknock.data.model.Status.OK
import com.afollestad.nocknock.engine.R
import com.afollestad.nocknock.engine.ssl.SslManager
import com.afollestad.nocknock.engine.validation.ValidationJob.Companion.KEY_SITE_ID
import com.afollestad.nocknock.utilities.ext.toUri
import com.afollestad.nocknock.utilities.providers.BundleProvider
import com.afollestad.nocknock.utilities.providers.JobInfoProvider
import com.afollestad.nocknock.utilities.providers.StringProvider
@ -45,6 +45,8 @@ data class CheckResult(
typealias ClientTimeoutChanger = (client: OkHttpClient, timeout: Int) -> OkHttpClient
typealias UriConverter = (String) -> Uri
/** @author Aidan Follestad (@afollestad) */
interface ValidationExecutor {
@ -168,8 +170,8 @@ class RealValidationExecutor(
val clientWithTimeout = clientTimeoutChanger(okHttpClient, siteSettings.networkTimeout)
val client = if (!siteSettings.certificate.isNullOrEmpty()) {
sslManager.clientForCertificate(
certUri = siteSettings.certificate!!.toUri(),
host = site.url.toUri().host ?: "",
certUri = siteSettings.certificate!!,
siteUri = site.url,
client = clientWithTimeout
)
} else {
@ -212,9 +214,7 @@ class RealValidationExecutor(
jobScheduler.allPendingJobs
.firstOrNull { job -> job.id == site.id.toInt() }
@Suppress("unused")
@TestOnly
fun setClientTimeoutChanger(changer: ClientTimeoutChanger) {
@TestOnly fun setClientTimeoutChanger(changer: ClientTimeoutChanger) {
this.clientTimeoutChanger = changer
}
}

View file

@ -0,0 +1,189 @@
/**
* Designed and developed by Aidan Follestad (@afollestad)
*
* 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.
*/
package com.afollestad.nocknock.engine
import android.content.Intent
import com.afollestad.nocknock.data.AppDatabase
import com.afollestad.nocknock.data.HeaderDao
import com.afollestad.nocknock.data.RetryPolicyDao
import com.afollestad.nocknock.data.SiteDao
import com.afollestad.nocknock.data.SiteSettingsDao
import com.afollestad.nocknock.data.ValidationResultsDao
import com.afollestad.nocknock.data.model.Header
import com.afollestad.nocknock.data.model.RetryPolicy
import com.afollestad.nocknock.data.model.Site
import com.afollestad.nocknock.data.model.SiteSettings
import com.afollestad.nocknock.data.model.Status
import com.afollestad.nocknock.data.model.Status.OK
import com.afollestad.nocknock.data.model.ValidationMode
import com.afollestad.nocknock.data.model.ValidationMode.STATUS_CODE
import com.afollestad.nocknock.data.model.ValidationResult
import com.nhaarman.mockitokotlin2.doAnswer
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.isA
import com.nhaarman.mockitokotlin2.mock
import java.lang.System.currentTimeMillis
fun fakeIntent(action: String): Intent {
return mock {
on { getAction() } doReturn action
}
}
fun fakeSettingsModel(
id: Long,
validationMode: ValidationMode = STATUS_CODE
) = SiteSettings(
siteId = id,
validationIntervalMs = 600000,
validationMode = validationMode,
validationArgs = null,
disabled = false,
networkTimeout = 10000,
certificate = null
)
fun fakeResultModel(
id: Long,
status: Status = OK,
reason: String? = null
) = ValidationResult(
siteId = id,
status = status,
reason = reason,
timestampMs = currentTimeMillis()
)
fun fakeRetryPolicy(
id: Long,
count: Int = 3,
minutes: Int = 6
) = RetryPolicy(
siteId = id,
count = count,
minutes = minutes
)
fun fakeHeaders(siteId: Long): List<Header> {
return listOf(
Header(id = siteId + 1, siteId = siteId, key = "Content-Type", value = "text/html"),
Header(id = siteId + 2, siteId = siteId, key = "User-Agent", value = "NockNock")
)
}
fun fakeModel(id: Long) = Site(
id = id,
name = "Test",
url = "https://test.com",
tags = "",
settings = fakeSettingsModel(id),
lastResult = fakeResultModel(id),
retryPolicy = fakeRetryPolicy(id),
headers = fakeHeaders(id)
)
val MOCK_MODEL_1 = fakeModel(1)
val MOCK_MODEL_2 = fakeModel(2)
val MOCK_MODEL_3 = fakeModel(3)
val ALL_MOCK_MODELS = listOf(MOCK_MODEL_1, MOCK_MODEL_2, MOCK_MODEL_3)
fun mockDatabase(): AppDatabase {
val siteDao = mock<SiteDao> {
on { insert(isA()) } doReturn 1
on { one(isA()) } doAnswer { inv ->
val id = inv.getArgument<Long>(0)
return@doAnswer when (id) {
1L -> listOf(MOCK_MODEL_1)
2L -> listOf(MOCK_MODEL_2)
3L -> listOf(MOCK_MODEL_3)
else -> listOf()
}
}
on { all() } doReturn ALL_MOCK_MODELS
on { update(isA()) } doAnswer { inv ->
return@doAnswer inv.arguments.size
}
on { delete(isA()) } doAnswer { inv ->
return@doAnswer inv.arguments.size
}
}
val settingsDao = mock<SiteSettingsDao> {
on { insert(isA()) } doReturn 1L
on { forSite(isA()) } doAnswer { inv ->
val id = inv.getArgument<Long>(0)
return@doAnswer when (id) {
1L -> listOf(MOCK_MODEL_1.settings!!)
2L -> listOf(MOCK_MODEL_2.settings!!)
3L -> listOf(MOCK_MODEL_3.settings!!)
else -> listOf()
}
}
on { update(isA()) } doReturn 1
on { delete(isA()) } doReturn 1
}
val resultsDao = mock<ValidationResultsDao> {
on { insert(isA()) } doReturn 1L
on { forSite(isA()) } doAnswer { inv ->
val id = inv.getArgument<Long>(0)
return@doAnswer when (id) {
1L -> listOf(MOCK_MODEL_1.lastResult!!)
2L -> listOf(MOCK_MODEL_2.lastResult!!)
3L -> listOf(MOCK_MODEL_3.lastResult!!)
else -> listOf()
}
}
on { update(isA()) } doReturn 1
on { delete(isA()) } doReturn 1
}
val retryDao = mock<RetryPolicyDao> {
on { insert(isA()) } doReturn 1L
on { forSite(isA()) } doAnswer { inv ->
val id = inv.getArgument<Long>(0)
return@doAnswer when (id) {
1L -> listOf(MOCK_MODEL_1.retryPolicy!!)
2L -> listOf(MOCK_MODEL_2.retryPolicy!!)
3L -> listOf(MOCK_MODEL_3.retryPolicy!!)
else -> listOf()
}
}
on { update(isA()) } doReturn 1
on { delete(isA()) } doReturn 1
}
val headerDao = mock<HeaderDao> {
on { all() } doReturn MOCK_MODEL_1.headers + MOCK_MODEL_2.headers + MOCK_MODEL_3.headers
on { forSite(isA()) } doAnswer { inv ->
val id = inv.getArgument<Long>(0)
return@doAnswer when (id) {
1L -> MOCK_MODEL_1.headers
2L -> MOCK_MODEL_2.headers
3L -> MOCK_MODEL_3.headers
else -> listOf()
}
}
on { insert(isA<Header>()) } doReturn 1L
on { insert(isA<List<Header>>()) } doReturn listOf(1L, 2L)
on { update(isA()) } doReturn 1
on { delete(isA()) } doReturn 1
}
return mock {
on { siteDao() } doReturn siteDao
on { siteSettingsDao() } doReturn settingsDao
on { validationResultsDao() } doReturn resultsDao
on { retryPolicyDao() } doReturn retryDao
on { headerDao() } doReturn headerDao
}
}

View file

@ -18,6 +18,8 @@ package com.afollestad.nocknock.engine
import android.app.job.JobInfo
import android.content.ComponentName
import android.os.PersistableBundle
import com.afollestad.nocknock.data.AppDatabase
import com.afollestad.nocknock.data.model.Site
import com.afollestad.nocknock.utilities.providers.BundleProvider
import com.afollestad.nocknock.utilities.providers.IBundle
import com.afollestad.nocknock.utilities.providers.IBundler
@ -34,11 +36,11 @@ fun testBundleProvider(): BundleProvider {
val realBundle = mock<PersistableBundle>()
val creator = it.getArgument<IBundler>(0)
creator(object : IBundle {
override fun putInt(
override fun putLong(
key: String,
value: Int
value: Long
) {
whenever(realBundle.getInt(key)).doReturn(value)
whenever(realBundle.getLong(key)).doReturn(value)
}
})
return@doAnswer realBundle
@ -66,3 +68,21 @@ fun testJobInfoProvider(): JobInfoProvider {
}
return provider
}
fun AppDatabase.setAllSites(vararg sites: Site) {
whenever(siteDao().all()).doReturn(listOf(*sites))
for (site in sites) {
whenever(siteSettingsDao().forSite(site.id))
.doReturn(listOf(site.settings!!))
if (site.lastResult != null) {
whenever(validationResultsDao().forSite(site.id))
.doReturn(listOf(site.lastResult!!))
}
if (site.retryPolicy != null) {
whenever(retryPolicyDao().forSite(site.id))
.doReturn(listOf(site.retryPolicy!!))
}
whenever(headerDao().forSite(site.id))
.doReturn(site.headers)
}
}

View file

@ -17,13 +17,12 @@ package com.afollestad.nocknock.engine
import android.app.job.JobInfo
import android.app.job.JobScheduler
import com.afollestad.nocknock.data.legacy.ServerModel
import com.afollestad.nocknock.data.model.Header
import com.afollestad.nocknock.data.model.Status.ERROR
import com.afollestad.nocknock.data.model.Status.OK
import com.afollestad.nocknock.data.model.ValidationMode.STATUS_CODE
import com.afollestad.nocknock.data.legacy.ServerModelStore
import com.afollestad.nocknock.engine.ssl.SslManager
import com.afollestad.nocknock.engine.validation.RealValidationExecutor
import com.afollestad.nocknock.engine.validation.ValidationJob.Companion.KEY_SITE_ID
import com.afollestad.nocknock.engine.validation.RealValidationManager
import com.afollestad.nocknock.utilities.providers.StringProvider
import com.google.common.truth.Truth.assertThat
import com.nhaarman.mockitokotlin2.any
@ -56,15 +55,21 @@ class ValidationExecutorTest {
}
private val bundleProvider = testBundleProvider()
private val jobInfoProvider = testJobInfoProvider()
private val store = mock<ServerModelStore>()
private val database = mockDatabase()
private val sslManager = mock<SslManager> {
on { clientForCertificate(any(), any(), any()) } doAnswer { inv ->
inv.getArgument<OkHttpClient>(2)
}
}
private val manager = RealValidationManager(
private val manager = RealValidationExecutor(
jobScheduler,
okHttpClient,
stringProvider,
bundleProvider,
jobInfoProvider,
store
database,
sslManager
).apply {
setClientTimeoutChanger { _, timeout ->
whenever(okHttpClient.callTimeoutMillis()).doReturn(timeout)
@ -72,202 +77,241 @@ class ValidationExecutorTest {
}
}
@Test fun ensureScheduledChecks_noEnabledSites() = runBlocking {
val model1 = fakeModel().copy(disabled = true)
whenever(store.get()).doReturn(listOf(model1))
@Test fun ensureScheduledValidations_noEnabledSites() = runBlocking {
val model1 = fakeModel(id = 1)
model1.settings = model1.settings!!.copy(disabled = true)
database.setAllSites(model1)
manager.ensureScheduledChecks()
manager.ensureScheduledValidations()
verifyNoMoreInteractions(jobScheduler)
}
@Test fun ensureScheduledChecks_sitesAlreadyHaveJobs() = runBlocking<Unit> {
val model1 = fakeModel()
val job1 = fakeJob(model1.id)
whenever(store.get()).doReturn(listOf(model1))
@Test fun ensureScheduledValidations_sitesAlreadyHaveJobs() = runBlocking<Unit> {
val model1 = fakeModel(id = 1)
val job1 = fakeJob(1)
database.setAllSites(model1)
whenever(jobScheduler.allPendingJobs).doReturn(listOf(job1))
manager.ensureScheduledChecks()
manager.ensureScheduledValidations()
verify(jobScheduler, never()).schedule(any())
}
@Test fun ensureScheduledChecks() = runBlocking {
val model1 = fakeModel()
whenever(store.get()).doReturn(listOf(model1))
@Test fun ensureScheduledValidations() = runBlocking {
val model1 = fakeModel(id = 1)
database.setAllSites(model1)
whenever(jobScheduler.allPendingJobs).doReturn(listOf<JobInfo>())
manager.ensureScheduledChecks()
manager.ensureScheduledValidations()
val jobCaptor = argumentCaptor<JobInfo>()
verify(jobScheduler).schedule(jobCaptor.capture())
val jobInfo = jobCaptor.allValues.single()
assertThat(jobInfo.id).isEqualTo(model1.id)
assertThat(jobInfo.extras.getInt(KEY_SITE_ID)).isEqualTo(model1.id)
assertThat(jobInfo.extras.getLong(KEY_SITE_ID)).isEqualTo(model1.id)
}
@Test fun scheduleCheck_rightNow() {
val model1 = fakeModel()
@Test fun scheduleValidation_rightNow() {
val model1 = fakeModel(id = 1)
whenever(jobScheduler.allPendingJobs).doReturn(listOf<JobInfo>())
manager.scheduleCheck(
manager.scheduleValidation(
site = model1,
rightNow = true
)
val jobCaptor = argumentCaptor<JobInfo>()
verify(jobScheduler).schedule(jobCaptor.capture())
verify(jobScheduler).cancel(model1.id)
verify(jobScheduler).cancel(1)
val jobInfo = jobCaptor.allValues.single()
assertThat(jobInfo.id).isEqualTo(model1.id)
assertThat(jobInfo.extras.getInt(KEY_SITE_ID)).isEqualTo(model1.id)
assertThat(jobInfo.extras.getLong(KEY_SITE_ID)).isEqualTo(model1.id)
}
@Test(expected = IllegalStateException::class)
fun scheduleCheck_notFromFinishingJob_haveExistingJob() {
val model1 = fakeModel()
val job1 = fakeJob(model1.id)
fun scheduleValidation_notFromFinishingJob_haveExistingJob() {
val model1 = fakeModel(id = 1)
val job1 = fakeJob(1)
whenever(jobScheduler.allPendingJobs).doReturn(listOf(job1))
manager.scheduleCheck(
manager.scheduleValidation(
site = model1,
fromFinishingJob = false
)
}
@Test fun scheduleCheck_fromFinishingJob_haveExistingJob() {
val model1 = fakeModel()
val job1 = fakeJob(model1.id)
@Test fun scheduleValidation_fromFinishingJob_haveExistingJob() {
val model1 = fakeModel(id = 1)
val job1 = fakeJob(1)
whenever(jobScheduler.allPendingJobs).doReturn(listOf(job1))
manager.scheduleCheck(
manager.scheduleValidation(
site = model1,
fromFinishingJob = true
)
val jobCaptor = argumentCaptor<JobInfo>()
verify(jobScheduler).schedule(jobCaptor.capture())
verify(jobScheduler, never()).cancel(model1.id)
verify(jobScheduler, never()).cancel(any())
val jobInfo = jobCaptor.allValues.single()
assertThat(jobInfo.id).isEqualTo(model1.id)
assertThat(jobInfo.extras.getInt(KEY_SITE_ID)).isEqualTo(model1.id)
assertThat(jobInfo.extras.getLong(KEY_SITE_ID)).isEqualTo(model1.id)
}
@Test fun scheduleCheck() {
val model1 = fakeModel()
@Test fun scheduleValidation() {
val model1 = fakeModel(id = 1)
whenever(jobScheduler.allPendingJobs).doReturn(listOf<JobInfo>())
manager.scheduleCheck(
manager.scheduleValidation(
site = model1,
fromFinishingJob = true
)
val jobCaptor = argumentCaptor<JobInfo>()
verify(jobScheduler).schedule(jobCaptor.capture())
verify(jobScheduler, never()).cancel(model1.id)
verify(jobScheduler, never()).cancel(any())
val jobInfo = jobCaptor.allValues.single()
assertThat(jobInfo.id).isEqualTo(model1.id)
assertThat(jobInfo.extras.getInt(KEY_SITE_ID)).isEqualTo(model1.id)
assertThat(jobInfo.extras.getLong(KEY_SITE_ID)).isEqualTo(model1.id)
}
@Test fun cancelCheck() {
val model1 = fakeModel()
manager.cancelCheck(model1)
verify(jobScheduler).cancel(model1.id)
@Test fun cancelScheduledValidation() {
val model1 = fakeModel(id = 1)
manager.cancelScheduledValidation(model1)
verify(jobScheduler).cancel(1)
}
@Test fun performCheck_httpNotSuccess() = runBlocking {
@Test fun performValidation_httpNotSuccess() = runBlocking {
val response = fakeResponse(500, "Internal Server Error", "Hello World")
val call = mock<Call> {
on { execute() } doReturn response
}
whenever(okHttpClient.newCall(any())).doReturn(call)
val model1 = fakeModel()
val result = manager.performCheck(model1)
val model1 = fakeModel(id = 1)
val result = manager.performValidation(model1)
assertThat(result.model).isEqualTo(
model1.copy(
status = ERROR,
reason = "Response 500 - Hello World"
lastResult = model1.lastResult?.copy(
status = ERROR,
reason = "Response 500 - Hello World"
)
)
)
}
@Test fun performCheck_socketTimeout() = runBlocking {
@Test fun performValidation_socketTimeout() = runBlocking {
val error = SocketTimeoutException("Oh no!")
val call = mock<Call> {
on { execute() } doAnswer { throw error }
}
whenever(okHttpClient.newCall(any())).doReturn(call)
val model1 = fakeModel()
val result = manager.performCheck(model1)
val model1 = fakeModel(id = 1)
val result = manager.performValidation(model1)
assertThat(result.model).isEqualTo(
model1.copy(
status = ERROR,
reason = timeoutError
lastResult = model1.lastResult?.copy(
status = ERROR,
reason = timeoutError
)
)
)
}
@Test fun performCheck_exception() = runBlocking {
@Test fun performValidation_exception() = runBlocking {
val error = Exception("Oh no!")
val call = mock<Call> {
on { execute() } doAnswer { throw error }
}
whenever(okHttpClient.newCall(any())).doReturn(call)
val model1 = fakeModel()
val result = manager.performCheck(model1)
val model1 = fakeModel(id = 1)
val result = manager.performValidation(model1)
assertThat(result.model).isEqualTo(
model1.copy(
status = ERROR,
reason = "Oh no!"
lastResult = model1.lastResult?.copy(
status = ERROR,
reason = "Oh no!"
)
)
)
}
@Test fun performCheck_success() = runBlocking {
@Test fun performValidation_success_withHeaders() = runBlocking {
val requestCaptor = argumentCaptor<Request>()
val response = fakeResponse(200, "OK", "Hello World")
val call = mock<Call> {
on { execute() } doReturn response
}
whenever(okHttpClient.newCall(requestCaptor.capture()))
.doReturn(call)
val model1 = fakeModel(id = 1).copy(
headers = listOf(
Header(
key = "X-Test-Header",
value = "Hello, World!"
)
)
)
val result = manager.performValidation(model1)
val httpRequest = requestCaptor.firstValue
assertThat(result.model).isEqualTo(
model1.copy(
lastResult = model1.lastResult?.copy(
status = OK,
reason = null
)
)
)
assertThat(okHttpClient.callTimeoutMillis())
.isEqualTo(model1.settings!!.networkTimeout)
assertThat(httpRequest.header("X-Test-Header"))
.isEqualTo("Hello, World!")
}
@Test fun performValidation_success_withCustomSslCert() = runBlocking<Unit> {
val response = fakeResponse(200, "OK", "Hello World")
val call = mock<Call> {
on { execute() } doReturn response
}
whenever(okHttpClient.newCall(any())).doReturn(call)
val model1 = fakeModel()
val result = manager.performCheck(model1)
val model1 = fakeModel(id = 1).copy(
url = "http://wwww.mysite.com/test.html",
headers = emptyList()
)
model1.settings = model1.settings!!.copy(
certificate = "file:///sdcard/cert.pem"
)
val result = manager.performValidation(model1)
assertThat(result.model).isEqualTo(
model1.copy(
status = OK,
reason = null
lastResult = model1.lastResult?.copy(
status = OK,
reason = null
)
)
)
assertThat(okHttpClient.callTimeoutMillis())
.isEqualTo(model1.networkTimeout)
}
.isEqualTo(model1.settings!!.networkTimeout)
@Test fun performCheck_401_butStillSuccess() = runBlocking {
val response = fakeResponse(401, "Unauthorized", "Hello World")
val call = mock<Call> {
on { execute() } doReturn response
}
whenever(okHttpClient.newCall(any())).doReturn(call)
val model1 = fakeModel()
val result = manager.performCheck(model1)
assertThat(result.model).isEqualTo(
model1.copy(
status = OK,
reason = null
)
verify(sslManager).clientForCertificate(
"file:///sdcard/cert.pem",
"http://wwww.mysite.com/test.html",
okHttpClient
)
}
@ -293,14 +337,6 @@ class ValidationExecutorTest {
.build()
}
private fun fakeModel() = ServerModel(
id = 1,
name = "Wakanda Forever",
url = "https://www.wakanda.gov",
validationMode = STATUS_CODE,
networkTimeout = 60000
)
private fun fakeJob(id: Int): JobInfo {
return mock {
on { this.id } doReturn id