Fix tests

This commit is contained in:
Aidan Follestad 2019-03-14 15:01:24 -07:00
commit 4da8cb5f11
7 changed files with 82 additions and 15 deletions

View file

@ -15,10 +15,15 @@
*/ */
package com.afollestad.nocknock.ui package com.afollestad.nocknock.ui
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.afollestad.nocknock.R import com.afollestad.nocknock.R
import com.afollestad.nocknock.koin.PREF_DARK_MODE import com.afollestad.nocknock.koin.PREF_DARK_MODE
import com.afollestad.nocknock.ui.NightMode.DISABLED
import com.afollestad.nocknock.ui.NightMode.ENABLED
import com.afollestad.nocknock.ui.NightMode.UNKNOWN
import com.afollestad.nocknock.utilities.rx.attachLifecycle import com.afollestad.nocknock.utilities.rx.attachLifecycle
import com.afollestad.rxkprefs.Pref import com.afollestad.rxkprefs.Pref
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
@ -35,13 +40,27 @@ abstract class DarkModeSwitchActivity : AppCompatActivity() {
setTheme(themeRes()) setTheme(themeRes())
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
darkModePref.observe() if (getCurrentNightMode() == UNKNOWN) {
.filter { it != isDarkModeEnabled } darkModePref.observe()
.subscribe { .filter { it != isDarkModeEnabled }
log("Theme changed, recreating Activity.") .subscribe {
recreate() log("Theme changed, recreating Activity.")
} recreate()
.attachLifecycle(this) }
.attachLifecycle(this)
}
}
protected fun getCurrentNightMode(): NightMode {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
return UNKNOWN
}
val currentNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
return when (currentNightMode) {
Configuration.UI_MODE_NIGHT_YES -> return ENABLED
Configuration.UI_MODE_NIGHT_NO -> return DISABLED
else -> UNKNOWN
}
} }
protected fun isDarkMode() = darkModePref.get() protected fun isDarkMode() = darkModePref.get()

View file

@ -0,0 +1,11 @@
package com.afollestad.nocknock.ui
/** @author Aidan Follestad (@afollestad) */
enum class NightMode {
/** Night mode is on at the system level. */
ENABLED,
/** Night mode is off at the system level. */
DISABLED,
/** We don't know about night mode, fallback to custom impl. */
UNKNOWN
}

View file

@ -33,6 +33,7 @@ import com.afollestad.nocknock.data.model.Site
import com.afollestad.nocknock.dialogs.AboutDialog import com.afollestad.nocknock.dialogs.AboutDialog
import com.afollestad.nocknock.notifications.NockNotificationManager import com.afollestad.nocknock.notifications.NockNotificationManager
import com.afollestad.nocknock.ui.DarkModeSwitchActivity import com.afollestad.nocknock.ui.DarkModeSwitchActivity
import com.afollestad.nocknock.ui.NightMode.UNKNOWN
import com.afollestad.nocknock.utilities.providers.IntentProvider import com.afollestad.nocknock.utilities.providers.IntentProvider
import com.afollestad.nocknock.utilities.ui.toast import com.afollestad.nocknock.utilities.ui.toast
import com.afollestad.nocknock.viewUrl import com.afollestad.nocknock.viewUrl
@ -93,7 +94,13 @@ class MainActivity : DarkModeSwitchActivity() {
toolbar.run { toolbar.run {
inflateMenu(R.menu.menu_main) inflateMenu(R.menu.menu_main)
menu.findItem(R.id.dark_mode) menu.findItem(R.id.dark_mode)
.isChecked = isDarkMode() .apply {
if (getCurrentNightMode() == UNKNOWN) {
isVisible = false
} else {
isChecked = isDarkMode()
}
}
setOnMenuItemClickListener { item -> setOnMenuItemClickListener { item ->
when (item.itemId) { when (item.itemId) {
R.id.about -> AboutDialog.show(this@MainActivity) R.id.about -> AboutDialog.show(this@MainActivity)

View file

@ -223,7 +223,7 @@ class ViewSiteViewModel(
private fun getUpdatedDbModel(): Site? { private fun getUpdatedDbModel(): Site? {
val timeout = timeout.value ?: 10_000 val timeout = timeout.value ?: 10_000
val cleanedTags = tags.value?.split(',')?.joinToString { it.trim() } ?: "" val cleanedTags = tags.value?.split(',')?.joinToString(separator = ",") ?: ""
val newSettings = site.settings!!.copy( val newSettings = site.settings!!.copy(
validationIntervalMs = getCheckIntervalMs(), validationIntervalMs = getCheckIntervalMs(),

View file

@ -17,20 +17,21 @@ package com.afollestad.nocknock.ui.addsite
import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.afollestad.nocknock.R import com.afollestad.nocknock.R
import com.afollestad.nocknock.data.model.Header
import com.afollestad.nocknock.data.model.Site import com.afollestad.nocknock.data.model.Site
import com.afollestad.nocknock.data.model.SiteSettings import com.afollestad.nocknock.data.model.SiteSettings
import com.afollestad.nocknock.data.model.Status.WAITING
import com.afollestad.nocknock.data.model.ValidationMode.JAVASCRIPT import com.afollestad.nocknock.data.model.ValidationMode.JAVASCRIPT
import com.afollestad.nocknock.data.model.ValidationMode.STATUS_CODE import com.afollestad.nocknock.data.model.ValidationMode.STATUS_CODE
import com.afollestad.nocknock.data.model.ValidationMode.TERM_SEARCH import com.afollestad.nocknock.data.model.ValidationMode.TERM_SEARCH
import com.afollestad.nocknock.data.model.ValidationResult
import com.afollestad.nocknock.engine.validation.ValidationExecutor import com.afollestad.nocknock.engine.validation.ValidationExecutor
import com.afollestad.nocknock.mockDatabase import com.afollestad.nocknock.mockDatabase
import com.afollestad.nocknock.utilities.ext.MINUTE import com.afollestad.nocknock.utilities.ext.MINUTE
import com.afollestad.nocknock.utilities.livedata.test import com.afollestad.nocknock.utilities.livedata.test
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.argumentCaptor import com.nhaarman.mockitokotlin2.argumentCaptor
import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.verify import com.nhaarman.mockitokotlin2.verify
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -159,19 +160,24 @@ class AddSiteViewModelTest {
val siteCaptor = argumentCaptor<Site>() val siteCaptor = argumentCaptor<Site>()
val settingsCaptor = argumentCaptor<SiteSettings>() val settingsCaptor = argumentCaptor<SiteSettings>()
val validationResultCaptor = argumentCaptor<ValidationResult>()
isLoading.assertValues(true, false) isLoading.assertValues(true, false)
verify(database.siteDao()).insert(siteCaptor.capture()) verify(database.siteDao()).insert(siteCaptor.capture())
verify(database.siteSettingsDao()).insert(settingsCaptor.capture()) verify(database.siteSettingsDao()).insert(settingsCaptor.capture())
verify(database.validationResultsDao(), never()).insert(any()) verify(database.validationResultsDao()).insert(validationResultCaptor.capture())
val settings = settingsCaptor.firstValue val settings = settingsCaptor.firstValue
val result = validationResultCaptor.firstValue.copy(siteId = 1)
val model = siteCaptor.firstValue.copy( val model = siteCaptor.firstValue.copy(
id = 1, // fill it in because our insert captor doesn't catch this id = 1, // fill it in because our insert captor doesn't catch this
settings = settings, settings = settings,
lastResult = null lastResult = result
) )
assertThat(result.reason).isNull()
assertThat(result.status).isEqualTo(WAITING)
verify(validationManager).scheduleValidation( verify(validationManager).scheduleValidation(
site = model, site = model,
rightNow = true, rightNow = true,
@ -191,5 +197,10 @@ class AddSiteViewModelTest {
validationScript.value = null validationScript.value = null
checkIntervalValue.value = 60 checkIntervalValue.value = 60
checkIntervalUnit.value = 1000 checkIntervalUnit.value = 1000
tags.value = "one,two"
headers.value = listOf(
Header(2L, 1L, key = "Content-Type", value = "text/html"),
Header(3L, 1L, key = "User-Agent", value = "NockNock")
)
} }
} }

View file

@ -18,6 +18,8 @@ package com.afollestad.nocknock.ui.viewsite
import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.afollestad.nocknock.MOCK_MODEL_1 import com.afollestad.nocknock.MOCK_MODEL_1
import com.afollestad.nocknock.R import com.afollestad.nocknock.R
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.Site
import com.afollestad.nocknock.data.model.SiteSettings import com.afollestad.nocknock.data.model.SiteSettings
import com.afollestad.nocknock.data.model.Status.CHECKING import com.afollestad.nocknock.data.model.Status.CHECKING
@ -29,6 +31,7 @@ import com.afollestad.nocknock.data.model.ValidationMode.STATUS_CODE
import com.afollestad.nocknock.data.model.ValidationMode.TERM_SEARCH import com.afollestad.nocknock.data.model.ValidationMode.TERM_SEARCH
import com.afollestad.nocknock.data.model.ValidationResult import com.afollestad.nocknock.data.model.ValidationResult
import com.afollestad.nocknock.engine.validation.ValidationExecutor import com.afollestad.nocknock.engine.validation.ValidationExecutor
import com.afollestad.nocknock.fakeRetryPolicy
import com.afollestad.nocknock.mockDatabase import com.afollestad.nocknock.mockDatabase
import com.afollestad.nocknock.notifications.NockNotificationManager import com.afollestad.nocknock.notifications.NockNotificationManager
import com.afollestad.nocknock.utilities.livedata.test import com.afollestad.nocknock.utilities.livedata.test
@ -38,8 +41,10 @@ import com.google.common.truth.Truth.assertThat
import com.nhaarman.mockitokotlin2.any import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.argumentCaptor import com.nhaarman.mockitokotlin2.argumentCaptor
import com.nhaarman.mockitokotlin2.doAnswer import com.nhaarman.mockitokotlin2.doAnswer
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -255,6 +260,8 @@ class ViewSiteViewModelTest {
} }
@Test fun commit_success() = runBlocking { @Test fun commit_success() = runBlocking {
whenever(database.retryPolicyDao().forSite(any())).doReturn(listOf(fakeRetryPolicy(1)))
val isLoading = viewModel.onIsLoading() val isLoading = viewModel.onIsLoading()
.test() .test()
@ -267,11 +274,13 @@ class ViewSiteViewModelTest {
val siteCaptor = argumentCaptor<Site>() val siteCaptor = argumentCaptor<Site>()
val settingsCaptor = argumentCaptor<SiteSettings>() val settingsCaptor = argumentCaptor<SiteSettings>()
val resultCaptor = argumentCaptor<ValidationResult>() val resultCaptor = argumentCaptor<ValidationResult>()
val retryPolicyCaptor = argumentCaptor<RetryPolicy>()
isLoading.assertValues(true, false) isLoading.assertValues(true, false)
verify(database.siteDao()).update(siteCaptor.capture()) verify(database.siteDao()).update(siteCaptor.capture())
verify(database.siteSettingsDao()).update(settingsCaptor.capture()) verify(database.siteSettingsDao()).update(settingsCaptor.capture())
verify(database.validationResultsDao()).update(resultCaptor.capture()) verify(database.validationResultsDao()).update(resultCaptor.capture())
verify(database.retryPolicyDao()).update(retryPolicyCaptor.capture())
// From fillInModel() below // From fillInModel() below
val updatedSettings = MOCK_MODEL_1.settings!!.copy( val updatedSettings = MOCK_MODEL_1.settings!!.copy(
@ -284,11 +293,13 @@ class ViewSiteViewModelTest {
val updatedResult = MOCK_MODEL_1.lastResult!!.copy( val updatedResult = MOCK_MODEL_1.lastResult!!.copy(
status = WAITING status = WAITING
) )
val retryPolicy = retryPolicyCaptor.firstValue
val updatedModel = MOCK_MODEL_1.copy( val updatedModel = MOCK_MODEL_1.copy(
name = "Hello There", name = "Hello There",
url = "https://www.hellothere.com", url = "https://www.hellothere.com",
settings = updatedSettings, settings = updatedSettings,
lastResult = updatedResult lastResult = updatedResult,
retryPolicy = retryPolicy
) )
assertThat(siteCaptor.firstValue).isEqualTo(updatedModel) assertThat(siteCaptor.firstValue).isEqualTo(updatedModel)
@ -373,5 +384,12 @@ class ViewSiteViewModelTest {
validationScript.value = "throw 'Oh no!'" validationScript.value = "throw 'Oh no!'"
checkIntervalValue.value = 24 checkIntervalValue.value = 24
checkIntervalUnit.value = 60000 checkIntervalUnit.value = 60000
tags.value = "one,two"
retryPolicyTimes.value = 5
retryPolicyMinutes.value = 5
headers.value = listOf(
Header(2L, 1L, key = "Content-Type", value = "text/html"),
Header(3L, 1L, key = "User-Agent", value = "NockNock")
)
} }
} }

View file

@ -35,7 +35,8 @@ fun fakeSettingsModel(
validationMode = validationMode, validationMode = validationMode,
validationArgs = null, validationArgs = null,
disabled = false, disabled = false,
networkTimeout = 10000 networkTimeout = 10000,
certificate = null
) )
fun fakeResultModel( fun fakeResultModel(