mirror of
https://github.com/afollestad/nock-nock.git
synced 2025-08-07 00:18:38 +00:00
ViewSiteViewModelTest
This commit is contained in:
parent
b57f645c98
commit
8470b65df1
4 changed files with 618 additions and 15 deletions
|
@ -45,7 +45,7 @@ internal fun ViewSiteActivity.maybeDisableChecks() {
|
||||||
message(
|
message(
|
||||||
text = context.getString(R.string.disable_automatic_checks_prompt, model.name).toHtml()
|
text = context.getString(R.string.disable_automatic_checks_prompt, model.name).toHtml()
|
||||||
)
|
)
|
||||||
positiveButton(R.string.disable) { viewModel.disable() }
|
positiveButton(R.string.disable) { viewModel.disableSite() }
|
||||||
negativeButton(android.R.string.cancel)
|
negativeButton(android.R.string.cancel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
package com.afollestad.nocknock.ui.viewsite
|
package com.afollestad.nocknock.ui.viewsite
|
||||||
|
|
||||||
import androidx.annotation.CheckResult
|
import androidx.annotation.CheckResult
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
|
import androidx.annotation.VisibleForTesting.PRIVATE
|
||||||
import androidx.lifecycle.LifecycleObserver
|
import androidx.lifecycle.LifecycleObserver
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
@ -90,10 +92,7 @@ class ViewSiteViewModel(
|
||||||
@CheckResult fun onUrlWarningVisibility(): LiveData<Boolean> {
|
@CheckResult fun onUrlWarningVisibility(): LiveData<Boolean> {
|
||||||
return url.map {
|
return url.map {
|
||||||
val parsed = HttpUrl.parse(it)
|
val parsed = HttpUrl.parse(it)
|
||||||
return@map it.isNotEmpty() &&
|
return@map it.isNotEmpty() && parsed == null
|
||||||
parsed != null &&
|
|
||||||
parsed.scheme() != "http" &&
|
|
||||||
parsed.scheme() != "https"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,11 +100,10 @@ class ViewSiteViewModel(
|
||||||
|
|
||||||
@CheckResult fun onValidationModeDescription(): LiveData<Int> {
|
@CheckResult fun onValidationModeDescription(): LiveData<Int> {
|
||||||
return validationMode.map {
|
return validationMode.map {
|
||||||
when (it) {
|
when (it!!) {
|
||||||
STATUS_CODE -> R.string.validation_mode_status_desc
|
STATUS_CODE -> R.string.validation_mode_status_desc
|
||||||
TERM_SEARCH -> R.string.validation_mode_term_desc
|
TERM_SEARCH -> R.string.validation_mode_term_desc
|
||||||
JAVASCRIPT -> R.string.validation_mode_javascript_desc
|
JAVASCRIPT -> R.string.validation_mode_javascript_desc
|
||||||
else -> throw IllegalStateException("Unknown validation mode: $it")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +202,7 @@ class ViewSiteViewModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun disable() {
|
fun disableSite() {
|
||||||
validationManager.cancelCheck(site)
|
validationManager.cancelCheck(site)
|
||||||
notificationManager.cancelStatusNotification(site)
|
notificationManager.cancelStatusNotification(site)
|
||||||
|
|
||||||
|
@ -224,13 +222,15 @@ class ViewSiteViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
private fun getCheckIntervalMs(): Long {
|
@VisibleForTesting(otherwise = PRIVATE)
|
||||||
|
fun getCheckIntervalMs(): Long {
|
||||||
val value = checkIntervalValue.value ?: return 0
|
val value = checkIntervalValue.value ?: return 0
|
||||||
val unit = checkIntervalUnit.value ?: return 0
|
val unit = checkIntervalUnit.value ?: return 0
|
||||||
return value * unit
|
return value * unit
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getValidationArgs(): String? {
|
@VisibleForTesting(otherwise = PRIVATE)
|
||||||
|
fun getValidationArgs(): String? {
|
||||||
return when (validationMode.value) {
|
return when (validationMode.value) {
|
||||||
TERM_SEARCH -> validationSearchTerm.value
|
TERM_SEARCH -> validationSearchTerm.value
|
||||||
JAVASCRIPT -> validationScript.value
|
JAVASCRIPT -> validationScript.value
|
||||||
|
@ -281,13 +281,13 @@ class ViewSiteViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (validationMode == TERM_SEARCH &&
|
if (validationMode.value == TERM_SEARCH &&
|
||||||
validationSearchTerm.value.isNullOrEmpty()
|
validationSearchTerm.value.isNullOrEmpty()
|
||||||
) {
|
) {
|
||||||
errorCount++
|
errorCount++
|
||||||
validationSearchTermError.value = R.string.please_enter_search_term
|
validationSearchTermError.value = R.string.please_enter_search_term
|
||||||
validationScriptError.value = null
|
validationScriptError.value = null
|
||||||
} else if (validationMode == JAVASCRIPT &&
|
} else if (validationMode.value == JAVASCRIPT &&
|
||||||
validationScript.value.isNullOrEmpty()
|
validationScript.value.isNullOrEmpty()
|
||||||
) {
|
) {
|
||||||
errorCount++
|
errorCount++
|
||||||
|
|
|
@ -15,6 +15,609 @@
|
||||||
*/
|
*/
|
||||||
package com.afollestad.nocknock.ui.viewsite
|
package com.afollestad.nocknock.ui.viewsite
|
||||||
|
|
||||||
class ViewSiteViewModelTest
|
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||||
|
import com.afollestad.nocknock.MOCK_MODEL_1
|
||||||
|
import com.afollestad.nocknock.R
|
||||||
|
import com.afollestad.nocknock.data.model.Site
|
||||||
|
import com.afollestad.nocknock.data.model.SiteSettings
|
||||||
|
import com.afollestad.nocknock.data.model.Status.CHECKING
|
||||||
|
import com.afollestad.nocknock.data.model.Status.ERROR
|
||||||
|
import com.afollestad.nocknock.data.model.Status.OK
|
||||||
|
import com.afollestad.nocknock.data.model.Status.WAITING
|
||||||
|
import com.afollestad.nocknock.data.model.ValidationMode.JAVASCRIPT
|
||||||
|
import com.afollestad.nocknock.data.model.ValidationMode.STATUS_CODE
|
||||||
|
import com.afollestad.nocknock.data.model.ValidationMode.TERM_SEARCH
|
||||||
|
import com.afollestad.nocknock.data.model.ValidationResult
|
||||||
|
import com.afollestad.nocknock.engine.validation.ValidationManager
|
||||||
|
import com.afollestad.nocknock.mockDatabase
|
||||||
|
import com.afollestad.nocknock.notifications.NockNotificationManager
|
||||||
|
import com.afollestad.nocknock.test
|
||||||
|
import com.afollestad.nocknock.utilities.providers.StringProvider
|
||||||
|
import com.google.common.truth.Truth
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import com.nhaarman.mockitokotlin2.any
|
||||||
|
import com.nhaarman.mockitokotlin2.argumentCaptor
|
||||||
|
import com.nhaarman.mockitokotlin2.doAnswer
|
||||||
|
import com.nhaarman.mockitokotlin2.mock
|
||||||
|
import com.nhaarman.mockitokotlin2.never
|
||||||
|
import com.nhaarman.mockitokotlin2.verify
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import java.util.Calendar
|
||||||
|
|
||||||
// TODO this will be mostly identical to the add site test
|
/** @author Aidan Follestad (@afollestad) */
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
class ViewSiteViewModelTest {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TEXT_NONE = "None"
|
||||||
|
private const val TEXT_EVERYTHING_CHECKS_OUT = "Everything checks out!"
|
||||||
|
private const val TEXT_WAITING = "Waiting..."
|
||||||
|
private const val TEXT_CHECKING = "Checking..."
|
||||||
|
private const val TEXT_CHECKS_DISABLED = "Automatic Checks Disabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val stringProvider = mock<StringProvider> {
|
||||||
|
on { get(any()) } doAnswer { inv ->
|
||||||
|
val id = inv.getArgument<Int>(0)
|
||||||
|
when (id) {
|
||||||
|
R.string.none -> TEXT_NONE
|
||||||
|
R.string.everything_checks_out -> TEXT_EVERYTHING_CHECKS_OUT
|
||||||
|
R.string.waiting -> TEXT_WAITING
|
||||||
|
R.string.checking_status -> TEXT_CHECKING
|
||||||
|
R.string.auto_checks_disabled -> TEXT_CHECKS_DISABLED
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private val database = mockDatabase()
|
||||||
|
private val validationManager = mock<ValidationManager>()
|
||||||
|
private val notificationManager = mock<NockNotificationManager>()
|
||||||
|
|
||||||
|
@Rule @JvmField val rule = InstantTaskExecutorRule()
|
||||||
|
|
||||||
|
private val viewModel = ViewSiteViewModel(
|
||||||
|
stringProvider,
|
||||||
|
database,
|
||||||
|
notificationManager,
|
||||||
|
validationManager,
|
||||||
|
Dispatchers.Unconfined,
|
||||||
|
Dispatchers.Unconfined
|
||||||
|
)
|
||||||
|
|
||||||
|
@After fun tearDown() = viewModel.destroy()
|
||||||
|
|
||||||
|
@Test fun onUrlWarningVisibility() {
|
||||||
|
val urlWarningVisibility = viewModel.onUrlWarningVisibility()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
viewModel.url.value = ""
|
||||||
|
urlWarningVisibility.assertValues(false)
|
||||||
|
|
||||||
|
viewModel.url.value = "helloworld"
|
||||||
|
urlWarningVisibility.assertValues(true)
|
||||||
|
|
||||||
|
viewModel.url.value = "http://helloworld.com"
|
||||||
|
urlWarningVisibility.assertValues(false)
|
||||||
|
|
||||||
|
viewModel.url.value = "ftp://helloworld.com"
|
||||||
|
urlWarningVisibility.assertValues(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun onValidationModeDescription() {
|
||||||
|
val description = viewModel.onValidationModeDescription()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
viewModel.validationMode.value = STATUS_CODE
|
||||||
|
description.assertValues(R.string.validation_mode_status_desc)
|
||||||
|
|
||||||
|
viewModel.validationMode.value = TERM_SEARCH
|
||||||
|
description.assertValues(R.string.validation_mode_term_desc)
|
||||||
|
|
||||||
|
viewModel.validationMode.value = JAVASCRIPT
|
||||||
|
description.assertValues(R.string.validation_mode_javascript_desc)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun onValidationSearchTermVisibility() {
|
||||||
|
val visibility = viewModel.onValidationSearchTermVisibility()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
viewModel.validationMode.value = STATUS_CODE
|
||||||
|
visibility.assertValues(false)
|
||||||
|
|
||||||
|
viewModel.validationMode.value = TERM_SEARCH
|
||||||
|
visibility.assertValues(true)
|
||||||
|
|
||||||
|
viewModel.validationMode.value = JAVASCRIPT
|
||||||
|
visibility.assertValues(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun onValidationScriptVisibility() {
|
||||||
|
val visibility = viewModel.onValidationScriptVisibility()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
viewModel.validationMode.value = STATUS_CODE
|
||||||
|
visibility.assertValues(false)
|
||||||
|
|
||||||
|
viewModel.validationMode.value = TERM_SEARCH
|
||||||
|
visibility.assertValues(false)
|
||||||
|
|
||||||
|
viewModel.validationMode.value = JAVASCRIPT
|
||||||
|
visibility.assertValues(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun onDisableChecksVisibility() {
|
||||||
|
val visibility = viewModel.onDisableChecksVisibility()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
viewModel.disabled.value = false
|
||||||
|
visibility.assertValues(true)
|
||||||
|
|
||||||
|
viewModel.disabled.value = true
|
||||||
|
visibility.assertValues(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun onDoneButtonText() {
|
||||||
|
val text = viewModel.onDoneButtonText()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
viewModel.disabled.value = false
|
||||||
|
text.assertValues(R.string.save_changes)
|
||||||
|
|
||||||
|
viewModel.disabled.value = true
|
||||||
|
text.assertValues(R.string.renable_and_save_changes)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun onLastCheckResultText() {
|
||||||
|
val text = viewModel.onLastCheckResultText()
|
||||||
|
.test()
|
||||||
|
val lastResult = ValidationResult(
|
||||||
|
siteId = 1,
|
||||||
|
timestampMs = 10,
|
||||||
|
status = OK,
|
||||||
|
reason = "Hello, world!"
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModel.lastResult.value = null
|
||||||
|
text.assertValues(TEXT_NONE)
|
||||||
|
|
||||||
|
viewModel.lastResult.value = lastResult
|
||||||
|
text.assertValues(TEXT_EVERYTHING_CHECKS_OUT)
|
||||||
|
|
||||||
|
viewModel.lastResult.value = lastResult.copy(status = WAITING)
|
||||||
|
text.assertValues(TEXT_WAITING)
|
||||||
|
|
||||||
|
viewModel.lastResult.value = lastResult.copy(status = CHECKING)
|
||||||
|
text.assertValues(TEXT_CHECKING)
|
||||||
|
|
||||||
|
viewModel.lastResult.value = lastResult.copy(
|
||||||
|
status = ERROR,
|
||||||
|
reason = "Uh oh!"
|
||||||
|
)
|
||||||
|
text.assertValues("Uh oh!")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun onNextCheckText() {
|
||||||
|
viewModel.checkIntervalValue.value = 60
|
||||||
|
viewModel.checkIntervalUnit.value = 5000
|
||||||
|
|
||||||
|
val text = viewModel.onNextCheckText()
|
||||||
|
.test()
|
||||||
|
val calendar = Calendar.getInstance()
|
||||||
|
.apply {
|
||||||
|
set(Calendar.YEAR, 2018)
|
||||||
|
set(Calendar.MONTH, Calendar.DECEMBER)
|
||||||
|
set(Calendar.DAY_OF_MONTH, 6)
|
||||||
|
set(Calendar.HOUR_OF_DAY, 8)
|
||||||
|
set(Calendar.MINUTE, 30)
|
||||||
|
set(Calendar.SECOND, 0)
|
||||||
|
}
|
||||||
|
val lastResult = ValidationResult(
|
||||||
|
siteId = 1,
|
||||||
|
timestampMs = calendar.timeInMillis,
|
||||||
|
status = OK,
|
||||||
|
reason = null
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModel.disabled.value = true
|
||||||
|
viewModel.lastResult.value = lastResult
|
||||||
|
text.assertValues(TEXT_CHECKS_DISABLED)
|
||||||
|
|
||||||
|
viewModel.disabled.value = false
|
||||||
|
text.assertValues("December 6, 8:35AM")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun getCheckIntervalMs() {
|
||||||
|
viewModel.checkIntervalValue.value = 3
|
||||||
|
viewModel.checkIntervalUnit.value = 200
|
||||||
|
Truth.assertThat(viewModel.getCheckIntervalMs())
|
||||||
|
.isEqualTo(600L)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun getValidationArgs() {
|
||||||
|
viewModel.validationSearchTerm.value = "One"
|
||||||
|
viewModel.validationScript.value = "Two"
|
||||||
|
|
||||||
|
viewModel.validationMode.value = STATUS_CODE
|
||||||
|
Truth.assertThat(viewModel.getValidationArgs())
|
||||||
|
.isNull()
|
||||||
|
|
||||||
|
viewModel.validationMode.value = TERM_SEARCH
|
||||||
|
Truth.assertThat(viewModel.getValidationArgs())
|
||||||
|
.isEqualTo("One")
|
||||||
|
|
||||||
|
viewModel.validationMode.value = JAVASCRIPT
|
||||||
|
Truth.assertThat(viewModel.getValidationArgs())
|
||||||
|
.isEqualTo("Two")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun commit_nameError() {
|
||||||
|
val onNameError = viewModel.onNameError()
|
||||||
|
.test()
|
||||||
|
val onUrlError = viewModel.onUrlError()
|
||||||
|
.test()
|
||||||
|
val onTimeoutError = viewModel.onTimeoutError()
|
||||||
|
.test()
|
||||||
|
val onCheckIntervalError = viewModel.onCheckIntervalError()
|
||||||
|
.test()
|
||||||
|
val onSearchTermError = viewModel.onValidationSearchTermError()
|
||||||
|
.test()
|
||||||
|
val onScriptError = viewModel.onValidationScriptError()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
fillInModel().apply {
|
||||||
|
name.value = ""
|
||||||
|
}
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
viewModel.commit(onDone)
|
||||||
|
|
||||||
|
verify(validationManager, never())
|
||||||
|
.scheduleCheck(any(), any(), any(), any())
|
||||||
|
onNameError.assertValues(R.string.please_enter_name)
|
||||||
|
onUrlError.assertNoValues()
|
||||||
|
onTimeoutError.assertNoValues()
|
||||||
|
onCheckIntervalError.assertNoValues()
|
||||||
|
onSearchTermError.assertNoValues()
|
||||||
|
onScriptError.assertNoValues()
|
||||||
|
|
||||||
|
verify(onDone, never()).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun commit_urlEmptyError() {
|
||||||
|
val onNameError = viewModel.onNameError()
|
||||||
|
.test()
|
||||||
|
val onUrlError = viewModel.onUrlError()
|
||||||
|
.test()
|
||||||
|
val onTimeoutError = viewModel.onTimeoutError()
|
||||||
|
.test()
|
||||||
|
val onCheckIntervalError = viewModel.onCheckIntervalError()
|
||||||
|
.test()
|
||||||
|
val onSearchTermError = viewModel.onValidationSearchTermError()
|
||||||
|
.test()
|
||||||
|
val onScriptError = viewModel.onValidationScriptError()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
fillInModel().apply {
|
||||||
|
url.value = ""
|
||||||
|
}
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
viewModel.commit(onDone)
|
||||||
|
|
||||||
|
verify(validationManager, never())
|
||||||
|
.scheduleCheck(any(), any(), any(), any())
|
||||||
|
onNameError.assertNoValues()
|
||||||
|
onUrlError.assertValues(R.string.please_enter_url)
|
||||||
|
onTimeoutError.assertNoValues()
|
||||||
|
onCheckIntervalError.assertNoValues()
|
||||||
|
onSearchTermError.assertNoValues()
|
||||||
|
onScriptError.assertNoValues()
|
||||||
|
|
||||||
|
verify(onDone, never()).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun commit_urlFormatError() {
|
||||||
|
val onNameError = viewModel.onNameError()
|
||||||
|
.test()
|
||||||
|
val onUrlError = viewModel.onUrlError()
|
||||||
|
.test()
|
||||||
|
val onTimeoutError = viewModel.onTimeoutError()
|
||||||
|
.test()
|
||||||
|
val onCheckIntervalError = viewModel.onCheckIntervalError()
|
||||||
|
.test()
|
||||||
|
val onSearchTermError = viewModel.onValidationSearchTermError()
|
||||||
|
.test()
|
||||||
|
val onScriptError = viewModel.onValidationScriptError()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
fillInModel().apply {
|
||||||
|
url.value = "ftp://www.idk.com"
|
||||||
|
}
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
viewModel.commit(onDone)
|
||||||
|
|
||||||
|
verify(validationManager, never())
|
||||||
|
.scheduleCheck(any(), any(), any(), any())
|
||||||
|
onNameError.assertNoValues()
|
||||||
|
onUrlError.assertValues(R.string.please_enter_valid_url)
|
||||||
|
onTimeoutError.assertNoValues()
|
||||||
|
onCheckIntervalError.assertNoValues()
|
||||||
|
onSearchTermError.assertNoValues()
|
||||||
|
onScriptError.assertNoValues()
|
||||||
|
|
||||||
|
verify(onDone, never()).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun commit_networkTimeout_error() {
|
||||||
|
val onNameError = viewModel.onNameError()
|
||||||
|
.test()
|
||||||
|
val onUrlError = viewModel.onUrlError()
|
||||||
|
.test()
|
||||||
|
val onTimeoutError = viewModel.onTimeoutError()
|
||||||
|
.test()
|
||||||
|
val onCheckIntervalError = viewModel.onCheckIntervalError()
|
||||||
|
.test()
|
||||||
|
val onSearchTermError = viewModel.onValidationSearchTermError()
|
||||||
|
.test()
|
||||||
|
val onScriptError = viewModel.onValidationScriptError()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
fillInModel().apply {
|
||||||
|
timeout.value = 0
|
||||||
|
}
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
viewModel.commit(onDone)
|
||||||
|
|
||||||
|
verify(validationManager, never())
|
||||||
|
.scheduleCheck(any(), any(), any(), any())
|
||||||
|
onNameError.assertNoValues()
|
||||||
|
onUrlError.assertNoValues()
|
||||||
|
onTimeoutError.assertValues(R.string.please_enter_networkTimeout)
|
||||||
|
onCheckIntervalError.assertNoValues()
|
||||||
|
onSearchTermError.assertNoValues()
|
||||||
|
onScriptError.assertNoValues()
|
||||||
|
|
||||||
|
verify(onDone, never()).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun commit_checkIntervalError() {
|
||||||
|
val onNameError = viewModel.onNameError()
|
||||||
|
.test()
|
||||||
|
val onUrlError = viewModel.onUrlError()
|
||||||
|
.test()
|
||||||
|
val onTimeoutError = viewModel.onTimeoutError()
|
||||||
|
.test()
|
||||||
|
val onCheckIntervalError = viewModel.onCheckIntervalError()
|
||||||
|
.test()
|
||||||
|
val onSearchTermError = viewModel.onValidationSearchTermError()
|
||||||
|
.test()
|
||||||
|
val onScriptError = viewModel.onValidationScriptError()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
fillInModel().apply {
|
||||||
|
checkIntervalValue.value = 0
|
||||||
|
}
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
viewModel.commit(onDone)
|
||||||
|
|
||||||
|
verify(validationManager, never())
|
||||||
|
.scheduleCheck(any(), any(), any(), any())
|
||||||
|
onNameError.assertNoValues()
|
||||||
|
onUrlError.assertNoValues()
|
||||||
|
onTimeoutError.assertNoValues()
|
||||||
|
onCheckIntervalError.assertValues(R.string.please_enter_check_interval)
|
||||||
|
onSearchTermError.assertNoValues()
|
||||||
|
onScriptError.assertNoValues()
|
||||||
|
|
||||||
|
verify(onDone, never()).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun commit_termSearchError() {
|
||||||
|
val onNameError = viewModel.onNameError()
|
||||||
|
.test()
|
||||||
|
val onUrlError = viewModel.onUrlError()
|
||||||
|
.test()
|
||||||
|
val onTimeoutError = viewModel.onTimeoutError()
|
||||||
|
.test()
|
||||||
|
val onCheckIntervalError = viewModel.onCheckIntervalError()
|
||||||
|
.test()
|
||||||
|
val onSearchTermError = viewModel.onValidationSearchTermError()
|
||||||
|
.test()
|
||||||
|
val onScriptError = viewModel.onValidationScriptError()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
fillInModel().apply {
|
||||||
|
validationMode.value = TERM_SEARCH
|
||||||
|
validationSearchTerm.value = ""
|
||||||
|
}
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
viewModel.commit(onDone)
|
||||||
|
|
||||||
|
verify(validationManager, never())
|
||||||
|
.scheduleCheck(any(), any(), any(), any())
|
||||||
|
onNameError.assertNoValues()
|
||||||
|
onUrlError.assertNoValues()
|
||||||
|
onTimeoutError.assertNoValues()
|
||||||
|
onCheckIntervalError.assertNoValues()
|
||||||
|
onSearchTermError.assertValues(R.string.please_enter_search_term)
|
||||||
|
onScriptError.assertNoValues()
|
||||||
|
|
||||||
|
verify(onDone, never()).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun commit_javaScript_error() {
|
||||||
|
val onNameError = viewModel.onNameError()
|
||||||
|
.test()
|
||||||
|
val onUrlError = viewModel.onUrlError()
|
||||||
|
.test()
|
||||||
|
val onTimeoutError = viewModel.onTimeoutError()
|
||||||
|
.test()
|
||||||
|
val onCheckIntervalError = viewModel.onCheckIntervalError()
|
||||||
|
.test()
|
||||||
|
val onSearchTermError = viewModel.onValidationSearchTermError()
|
||||||
|
.test()
|
||||||
|
val onScriptError = viewModel.onValidationScriptError()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
fillInModel().apply {
|
||||||
|
validationMode.value = JAVASCRIPT
|
||||||
|
validationScript.value = ""
|
||||||
|
}
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
viewModel.commit(onDone)
|
||||||
|
|
||||||
|
verify(validationManager, never())
|
||||||
|
.scheduleCheck(any(), any(), any(), any())
|
||||||
|
onNameError.assertNoValues()
|
||||||
|
onUrlError.assertNoValues()
|
||||||
|
onTimeoutError.assertNoValues()
|
||||||
|
onCheckIntervalError.assertNoValues()
|
||||||
|
onSearchTermError.assertNoValues()
|
||||||
|
onScriptError.assertValues(R.string.please_enter_javaScript)
|
||||||
|
|
||||||
|
verify(onDone, never()).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun commit_success() = runBlocking {
|
||||||
|
val isLoading = viewModel.onIsLoading()
|
||||||
|
.test()
|
||||||
|
val onNameError = viewModel.onNameError()
|
||||||
|
.test()
|
||||||
|
val onUrlError = viewModel.onUrlError()
|
||||||
|
.test()
|
||||||
|
val onTimeoutError = viewModel.onTimeoutError()
|
||||||
|
.test()
|
||||||
|
val onSearchTermError = viewModel.onValidationSearchTermError()
|
||||||
|
.test()
|
||||||
|
val onScriptError = viewModel.onValidationScriptError()
|
||||||
|
.test()
|
||||||
|
val onCheckIntervalError = viewModel.onCheckIntervalError()
|
||||||
|
.test()
|
||||||
|
|
||||||
|
fillInModel()
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
|
||||||
|
viewModel.site = MOCK_MODEL_1
|
||||||
|
viewModel.commit(onDone)
|
||||||
|
|
||||||
|
val siteCaptor = argumentCaptor<Site>()
|
||||||
|
val settingsCaptor = argumentCaptor<SiteSettings>()
|
||||||
|
val resultCaptor = argumentCaptor<ValidationResult>()
|
||||||
|
|
||||||
|
isLoading.assertValues(true, false)
|
||||||
|
verify(database.siteDao()).update(siteCaptor.capture())
|
||||||
|
verify(database.siteSettingsDao()).update(settingsCaptor.capture())
|
||||||
|
verify(database.validationResultsDao()).update(resultCaptor.capture())
|
||||||
|
|
||||||
|
// From fillInModel() below
|
||||||
|
val updatedSettings = MOCK_MODEL_1.settings!!.copy(
|
||||||
|
networkTimeout = 30000,
|
||||||
|
validationMode = JAVASCRIPT,
|
||||||
|
validationArgs = "throw 'Oh no!'",
|
||||||
|
disabled = false,
|
||||||
|
validationIntervalMs = 24 * 60000
|
||||||
|
)
|
||||||
|
val updatedResult = MOCK_MODEL_1.lastResult!!.copy(
|
||||||
|
status = WAITING
|
||||||
|
)
|
||||||
|
val updatedModel = MOCK_MODEL_1.copy(
|
||||||
|
name = "Hello There",
|
||||||
|
url = "https://www.hellothere.com",
|
||||||
|
settings = updatedSettings,
|
||||||
|
lastResult = updatedResult
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(siteCaptor.firstValue).isEqualTo(updatedModel)
|
||||||
|
assertThat(settingsCaptor.firstValue).isEqualTo(updatedSettings)
|
||||||
|
assertThat(resultCaptor.firstValue).isEqualTo(updatedResult)
|
||||||
|
|
||||||
|
verify(validationManager).scheduleCheck(
|
||||||
|
site = updatedModel,
|
||||||
|
rightNow = true,
|
||||||
|
cancelPrevious = true,
|
||||||
|
fromFinishingJob = false
|
||||||
|
)
|
||||||
|
|
||||||
|
onNameError.assertNoValues()
|
||||||
|
onUrlError.assertNoValues()
|
||||||
|
onTimeoutError.assertNoValues()
|
||||||
|
onCheckIntervalError.assertNoValues()
|
||||||
|
onSearchTermError.assertNoValues()
|
||||||
|
onScriptError.assertNoValues()
|
||||||
|
|
||||||
|
verify(onDone).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun checkNow() {
|
||||||
|
val status = viewModel.status.test()
|
||||||
|
|
||||||
|
viewModel.site = MOCK_MODEL_1
|
||||||
|
val expectedModel = MOCK_MODEL_1.copy(
|
||||||
|
lastResult = MOCK_MODEL_1.lastResult!!.copy(
|
||||||
|
status = WAITING
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModel.checkNow()
|
||||||
|
verify(validationManager).scheduleCheck(
|
||||||
|
site = expectedModel,
|
||||||
|
rightNow = true,
|
||||||
|
cancelPrevious = true
|
||||||
|
)
|
||||||
|
status.assertValues(WAITING)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun removeSite() {
|
||||||
|
val isLoading = viewModel.onIsLoading()
|
||||||
|
.test()
|
||||||
|
val onDone = mock<() -> Unit>()
|
||||||
|
|
||||||
|
viewModel.site = MOCK_MODEL_1
|
||||||
|
viewModel.removeSite(onDone)
|
||||||
|
isLoading.assertValues(true, false)
|
||||||
|
|
||||||
|
verify(validationManager).cancelCheck(MOCK_MODEL_1)
|
||||||
|
verify(notificationManager).cancelStatusNotification(MOCK_MODEL_1)
|
||||||
|
verify(database.siteDao()).delete(MOCK_MODEL_1)
|
||||||
|
verify(database.siteSettingsDao()).delete(MOCK_MODEL_1.settings!!)
|
||||||
|
verify(database.validationResultsDao()).delete(MOCK_MODEL_1.lastResult!!)
|
||||||
|
verify(onDone).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun disableSite() {
|
||||||
|
val isLoading = viewModel.onIsLoading()
|
||||||
|
.test()
|
||||||
|
val disabled = viewModel.disabled.test()
|
||||||
|
|
||||||
|
viewModel.site = MOCK_MODEL_1
|
||||||
|
viewModel.disableSite()
|
||||||
|
isLoading.assertValues(true, false)
|
||||||
|
disabled.assertValues(true)
|
||||||
|
|
||||||
|
val expectedSite = MOCK_MODEL_1.copy(
|
||||||
|
settings = MOCK_MODEL_1.settings!!.copy(
|
||||||
|
disabled = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
verify(validationManager).cancelCheck(MOCK_MODEL_1)
|
||||||
|
verify(notificationManager).cancelStatusNotification(MOCK_MODEL_1)
|
||||||
|
verify(database.siteDao()).update(expectedSite)
|
||||||
|
verify(database.siteSettingsDao()).update(expectedSite.settings!!)
|
||||||
|
verify(database.validationResultsDao()).update(expectedSite.lastResult!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fillInModel() = viewModel.apply {
|
||||||
|
name.value = "Hello There"
|
||||||
|
url.value = "https://www.hellothere.com"
|
||||||
|
timeout.value = 30000
|
||||||
|
validationMode.value = JAVASCRIPT
|
||||||
|
validationSearchTerm.value = null
|
||||||
|
validationScript.value = "throw 'Oh no!'"
|
||||||
|
checkIntervalValue.value = 24
|
||||||
|
checkIntervalUnit.value = 60000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,6 @@ fun Long.formatDate(): String {
|
||||||
if (this <= 0) {
|
if (this <= 0) {
|
||||||
return "(None)"
|
return "(None)"
|
||||||
}
|
}
|
||||||
val df = SimpleDateFormat("MMMM dd, hh:mm:ss a", Locale.getDefault())
|
val df = SimpleDateFormat("MMMM d, h:mma", Locale.getDefault())
|
||||||
return df.format(Date(this))
|
return df.format(Date(this))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue