Add base url setup to sign in test

This commit is contained in:
Kirill Kamakin
2022-12-06 21:33:10 +01:00
parent 8c3ec9a40d
commit 77395a07f4
8 changed files with 120 additions and 4 deletions

View File

@@ -134,6 +134,7 @@ dependencies {
androidTestImplementation(libs.junit) androidTestImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.junit) androidTestImplementation(libs.androidx.test.junit)
androidTestImplementation(libs.kaspersky.kaspresso) androidTestImplementation(libs.kaspersky.kaspresso)
androidTestImplementation(libs.okhttp3.mockwebserver)
androidTestImplementation(libs.androidx.test.core) androidTestImplementation(libs.androidx.test.core)
androidTestImplementation(libs.androidx.test.rules) androidTestImplementation(libs.androidx.test.rules)
androidTestImplementation(libs.androidx.test.runner) androidTestImplementation(libs.androidx.test.runner)

View File

@@ -4,8 +4,11 @@ import androidx.test.ext.junit.rules.activityScenarioRule
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
import gq.kirmanak.mealient.screen.BaseUrlScreen
import gq.kirmanak.mealient.screen.DisclaimerScreen import gq.kirmanak.mealient.screen.DisclaimerScreen
import gq.kirmanak.mealient.screen.RecipesListScreen
import gq.kirmanak.mealient.ui.activity.MainActivity import gq.kirmanak.mealient.ui.activity.MainActivity
import okhttp3.mockwebserver.MockWebServer
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@@ -18,13 +21,68 @@ class FirstSetUpTest : TestCase() {
@get:Rule(order = 1) @get:Rule(order = 1)
val mainActivityRule = activityScenarioRule<MainActivity>() val mainActivityRule = activityScenarioRule<MainActivity>()
private lateinit var mockWebServer: MockWebServer
@Test @Test
fun test() = run { fun test() = before {
mockWebServer = MockWebServer()
mockWebServer.dispatch { url, _ ->
if (url == "/api/app/about") versionV1Response else notFoundResponse
}
mockWebServer.start()
}.after {
mockWebServer.shutdown()
}.run {
step("Ensure button is disabled") { step("Ensure button is disabled") {
DisclaimerScreen { DisclaimerScreen {
okayButton { okayButton {
isVisible() isVisible()
isDisabled() isDisabled()
hasAnyText()
}
disclaimerText {
isVisible()
hasText(R.string.fragment_disclaimer_main_text)
}
}
}
step("Close disclaimer screen") {
DisclaimerScreen {
okayButton {
isVisible()
isEnabled()
hasText(R.string.fragment_disclaimer_button_okay)
click()
}
}
}
step("Enter mock server address and click proceed") {
BaseUrlScreen {
progressBar {
isGone()
}
urlInput {
isVisible()
edit.replaceText(mockWebServer.url("/").toString())
hasHint(R.string.fragment_authentication_input_hint_url)
}
proceedButton {
isVisible()
isEnabled()
hasText(R.string.fragment_base_url_save)
click()
}
}
}
step("Check that empty list of recipes is shown") {
RecipesListScreen {
emptyListText {
isVisible()
hasText(R.string.fragment_recipes_list_no_recipes)
} }
} }
} }

View File

@@ -0,0 +1,20 @@
package gq.kirmanak.mealient
import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
val versionV1Response = MockResponse().setResponseCode(200).setBody(
"""{"production":true,"version":"v1.0.0beta-5","demoStatus":false,"allowSignup":true}"""
)
val notFoundResponse = MockResponse().setResponseCode(404).setBody("""{"detail":"Not found"}"""")
fun MockWebServer.dispatch(block: (String, RecordedRequest) -> MockResponse) {
dispatcher = object : Dispatcher() {
override fun dispatch(request: RecordedRequest): MockResponse {
return block(request.path.orEmpty(), request)
}
}
}

View File

@@ -0,0 +1,19 @@
package gq.kirmanak.mealient.screen
import com.kaspersky.kaspresso.screens.KScreen
import gq.kirmanak.mealient.R
import gq.kirmanak.mealient.ui.baseurl.BaseURLFragment
import io.github.kakaocup.kakao.edit.KTextInputLayout
import io.github.kakaocup.kakao.progress.KProgressBar
import io.github.kakaocup.kakao.text.KButton
object BaseUrlScreen : KScreen<BaseUrlScreen>() {
override val layoutId = R.layout.fragment_base_url
override val viewClass = BaseURLFragment::class.java
val urlInput = KTextInputLayout { withId(R.id.url_input_layout) }
val proceedButton = KButton { withId(R.id.button) }
val progressBar = KProgressBar { withId(R.id.progress)}
}

View File

@@ -2,12 +2,15 @@ package gq.kirmanak.mealient.screen
import com.kaspersky.kaspresso.screens.KScreen import com.kaspersky.kaspresso.screens.KScreen
import gq.kirmanak.mealient.R import gq.kirmanak.mealient.R
import gq.kirmanak.mealient.ui.activity.MainActivity import gq.kirmanak.mealient.ui.disclaimer.DisclaimerFragment
import io.github.kakaocup.kakao.text.KButton import io.github.kakaocup.kakao.text.KButton
import io.github.kakaocup.kakao.text.KTextView
object DisclaimerScreen : KScreen<DisclaimerScreen>() { object DisclaimerScreen : KScreen<DisclaimerScreen>() {
override val layoutId = R.layout.fragment_disclaimer override val layoutId = R.layout.fragment_disclaimer
override val viewClass = MainActivity::class.java override val viewClass = DisclaimerFragment::class.java
val okayButton = KButton { withId(R.id.okay) } val okayButton = KButton { withId(R.id.okay) }
val disclaimerText = KTextView { withId(R.id.main_text) }
} }

View File

@@ -0,0 +1,13 @@
package gq.kirmanak.mealient.screen
import com.kaspersky.kaspresso.screens.KScreen
import gq.kirmanak.mealient.R
import gq.kirmanak.mealient.ui.recipes.RecipesListFragment
import io.github.kakaocup.kakao.text.KTextView
object RecipesListScreen : KScreen<RecipesListScreen>() {
override val layoutId: Int = R.layout.fragment_recipes_list
override val viewClass: Class<*> = RecipesListFragment::class.java
val emptyListText = KTextView { withId(R.id.empty_list_text) }
}

View File

@@ -28,7 +28,8 @@ class BaseURLViewModel @Inject constructor(
logger.v { "saveBaseUrl() called with: baseURL = $baseURL" } logger.v { "saveBaseUrl() called with: baseURL = $baseURL" }
_uiState.value = OperationUiState.Progress() _uiState.value = OperationUiState.Progress()
val hasPrefix = ALLOWED_PREFIXES.any { baseURL.startsWith(it) } val hasPrefix = ALLOWED_PREFIXES.any { baseURL.startsWith(it) }
val url = baseURL.takeIf { hasPrefix } ?: WITH_PREFIX_FORMAT.format(baseURL) var url = baseURL.takeIf { hasPrefix } ?: WITH_PREFIX_FORMAT.format(baseURL)
url = url.trimStart().trimEnd { it == '/' || it.isWhitespace() }
viewModelScope.launch { checkBaseURL(url) } viewModelScope.launch { checkBaseURL(url) }
} }

View File

@@ -153,6 +153,7 @@ squareup-leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-an
okhttp3-bom = { group = "com.squareup.okhttp3", name = "okhttp-bom", version.ref = "okhttp" } okhttp3-bom = { group = "com.squareup.okhttp3", name = "okhttp-bom", version.ref = "okhttp" }
okhttp3-okhttp = { group = "com.squareup.okhttp3", name = "okhttp" } okhttp3-okhttp = { group = "com.squareup.okhttp3", name = "okhttp" }
okhttp3-loggingInterceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor" } okhttp3-loggingInterceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor" }
okhttp3-mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "okhttp" }
bumptech-glide-glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide" } bumptech-glide-glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide" }
bumptech-glide-okhttp3 = { group = "com.github.bumptech.glide", name = "okhttp3-integration", version.ref = "glide" } bumptech-glide-okhttp3 = { group = "com.github.bumptech.glide", name = "okhttp3-integration", version.ref = "glide" }