From 77395a07f445488be866dc5f20c6517ded653f05 Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Tue, 6 Dec 2022 21:33:10 +0100 Subject: [PATCH] Add base url setup to sign in test --- app/build.gradle.kts | 1 + .../gq/kirmanak/mealient/FirstSetUpTest.kt | 60 ++++++++++++++++++- .../mealient/response.VersionResponses.kt | 20 +++++++ .../kirmanak/mealient/screen/BaseUrlScreen.kt | 19 ++++++ .../mealient/screen/DisclaimerScreen.kt | 7 ++- .../mealient/screen/RecipesListScreen.kt | 13 ++++ .../mealient/ui/baseurl/BaseURLViewModel.kt | 3 +- gradle/libs.versions.toml | 1 + 8 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 app/src/androidTest/kotlin/gq/kirmanak/mealient/response.VersionResponses.kt create mode 100644 app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/BaseUrlScreen.kt create mode 100644 app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/RecipesListScreen.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 602fbc3..2633cea 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -134,6 +134,7 @@ dependencies { androidTestImplementation(libs.junit) androidTestImplementation(libs.androidx.test.junit) androidTestImplementation(libs.kaspersky.kaspresso) + androidTestImplementation(libs.okhttp3.mockwebserver) androidTestImplementation(libs.androidx.test.core) androidTestImplementation(libs.androidx.test.rules) androidTestImplementation(libs.androidx.test.runner) diff --git a/app/src/androidTest/kotlin/gq/kirmanak/mealient/FirstSetUpTest.kt b/app/src/androidTest/kotlin/gq/kirmanak/mealient/FirstSetUpTest.kt index 85581fe..ff3d93e 100644 --- a/app/src/androidTest/kotlin/gq/kirmanak/mealient/FirstSetUpTest.kt +++ b/app/src/androidTest/kotlin/gq/kirmanak/mealient/FirstSetUpTest.kt @@ -4,8 +4,11 @@ import androidx.test.ext.junit.rules.activityScenarioRule import com.kaspersky.kaspresso.testcases.api.testcase.TestCase import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest +import gq.kirmanak.mealient.screen.BaseUrlScreen import gq.kirmanak.mealient.screen.DisclaimerScreen +import gq.kirmanak.mealient.screen.RecipesListScreen import gq.kirmanak.mealient.ui.activity.MainActivity +import okhttp3.mockwebserver.MockWebServer import org.junit.Rule import org.junit.Test @@ -18,13 +21,68 @@ class FirstSetUpTest : TestCase() { @get:Rule(order = 1) val mainActivityRule = activityScenarioRule() + private lateinit var mockWebServer: MockWebServer + @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") { DisclaimerScreen { okayButton { isVisible() 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) } } } diff --git a/app/src/androidTest/kotlin/gq/kirmanak/mealient/response.VersionResponses.kt b/app/src/androidTest/kotlin/gq/kirmanak/mealient/response.VersionResponses.kt new file mode 100644 index 0000000..51f8b14 --- /dev/null +++ b/app/src/androidTest/kotlin/gq/kirmanak/mealient/response.VersionResponses.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/BaseUrlScreen.kt b/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/BaseUrlScreen.kt new file mode 100644 index 0000000..00f549f --- /dev/null +++ b/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/BaseUrlScreen.kt @@ -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() { + 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)} +} \ No newline at end of file diff --git a/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/DisclaimerScreen.kt b/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/DisclaimerScreen.kt index d06ab45..5dafb30 100644 --- a/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/DisclaimerScreen.kt +++ b/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/DisclaimerScreen.kt @@ -2,12 +2,15 @@ package gq.kirmanak.mealient.screen import com.kaspersky.kaspresso.screens.KScreen 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.KTextView object DisclaimerScreen : KScreen() { 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 disclaimerText = KTextView { withId(R.id.main_text) } } \ No newline at end of file diff --git a/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/RecipesListScreen.kt b/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/RecipesListScreen.kt new file mode 100644 index 0000000..6c2b171 --- /dev/null +++ b/app/src/androidTest/kotlin/gq/kirmanak/mealient/screen/RecipesListScreen.kt @@ -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() { + 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) } +} \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/baseurl/BaseURLViewModel.kt b/app/src/main/java/gq/kirmanak/mealient/ui/baseurl/BaseURLViewModel.kt index 6330c7a..42afc2b 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/baseurl/BaseURLViewModel.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/baseurl/BaseURLViewModel.kt @@ -28,7 +28,8 @@ class BaseURLViewModel @Inject constructor( logger.v { "saveBaseUrl() called with: baseURL = $baseURL" } _uiState.value = OperationUiState.Progress() 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) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 61e469e..cacae3b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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-okhttp = { group = "com.squareup.okhttp3", name = "okhttp" } 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-okhttp3 = { group = "com.github.bumptech.glide", name = "okhttp3-integration", version.ref = "glide" }