Complete migration to Compose (#194)

* Migrate disclaimer screen to Compose

* Migrate base URL screen to Compose

* Migrate base URL screen to Compose

* Migrate authentication screen to Compose

* Initialize add recipe screen

* Remove unused resources

* Display add recipe operation result

* Add delete icon to ingredients and instructions

* Allow navigating between fields on add recipe

* Allow navigating between fields on authentication screen

* Allow to proceed from keyboard on base url screen

* Use material icons for recipe item

* Expose base URL as flow

* Initialize Compose navigation

* Allow sending logs again

* Allow to override navigation and top bar per screen

* Add additional logs

* Migrate share recipe screen to Compose

* Fix unit tests

* Restore recipe list tests

* Ensure authentication is shown after URL input

* Add autofill to authentication

* Complete first set up test

* Use image vector from Icons instead of drawable

* Add transition animations

* Fix logging host in Host header

* Do not fail test if login token is used
This commit is contained in:
Kirill Kamakin
2024-01-13 11:28:10 +01:00
committed by GitHub
parent 94f12820bc
commit de4df95a0e
107 changed files with 3294 additions and 2321 deletions

View File

@@ -1,9 +1,11 @@
package gq.kirmanak.mealient
import dagger.hilt.android.testing.HiltAndroidTest
import gq.kirmanak.mealient.screen.AuthenticationScreen
import gq.kirmanak.mealient.screen.BaseUrlScreen
import gq.kirmanak.mealient.screen.DisclaimerScreen
import gq.kirmanak.mealient.screen.RecipesListScreen
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
import io.github.kakaocup.kakao.common.utilities.getResourceString
import org.junit.Before
import org.junit.Test
@@ -13,63 +15,137 @@ class FirstSetUpTest : BaseTestCase() {
@Before
fun dispatchUrls() {
mockWebServer.dispatch { url, _ ->
if (url == "/api/app/about") versionV1Response else notFoundResponse
mockWebServer.dispatch { request ->
when (request.path) {
"/api/app/about" -> versionV1Response
"/api/auth/token" -> {
if (request.body == expectedLoginRequest) {
loginTokenResponse
} else {
notFoundResponse
}
}
"/api/users/api-tokens" -> {
if (request.authorization == expectedApiTokenAuthorizationHeader) {
apiTokenResponse
} else {
notFoundResponse
}
}
"/api/recipes?page=1&perPage=150" -> {
if (request.authorization == expectedAuthorizationHeader ||
request.authorization == expectedApiTokenAuthorizationHeader
) {
recipeSummariesResponse
} else {
notFoundResponse
}
}
else -> notFoundResponse
}
}
}
@Test
fun test() = run {
step("Ensure button is disabled") {
DisclaimerScreen {
step("Disclaimer screen with disabled button") {
onComposeScreen<DisclaimerScreen>(mainActivityRule) {
okayButton {
isVisible()
isDisabled()
hasAnyText()
assertIsNotEnabled()
}
okayButtonText {
assertTextContains(getResourceString(R.string.fragment_disclaimer_button_okay))
}
disclaimerText {
isVisible()
hasText(R.string.fragment_disclaimer_main_text)
assertTextEquals(getResourceString(R.string.fragment_disclaimer_main_text))
}
}
}
step("Close disclaimer screen") {
DisclaimerScreen {
onComposeScreen<DisclaimerScreen>(mainActivityRule) {
okayButtonText {
assertTextEquals(getResourceString(R.string.fragment_disclaimer_button_okay))
}
okayButton {
isVisible()
isEnabled()
hasText(R.string.fragment_disclaimer_button_okay)
click()
assertIsEnabled()
performClick()
}
}
}
step("Enter mock server address and click proceed") {
BaseUrlScreen {
onComposeScreen<BaseUrlScreen>(mainActivityRule) {
progressBar {
isGone()
assertDoesNotExist()
}
urlInput {
isVisible()
edit.replaceText(mockWebServer.url("/").toString())
hasHint(R.string.fragment_authentication_input_hint_url)
performTextInput(mockWebServer.url("/").toString())
}
urlInputLabel {
assertTextEquals(getResourceString(R.string.fragment_authentication_input_hint_url))
}
proceedButtonText {
assertTextEquals(getResourceString(R.string.fragment_base_url_save))
}
proceedButton {
isVisible()
isEnabled()
hasText(R.string.fragment_base_url_save)
click()
assertIsEnabled()
performClick()
}
}
}
step("Check that empty list of recipes is shown") {
RecipesListScreen(mainActivityRule).apply {
errorText {
step("Check that authentication is shown") {
onComposeScreen<AuthenticationScreen>(mainActivityRule) {
emailInput {
assertIsDisplayed()
}
passwordInput {
assertIsDisplayed()
}
loginButton {
assertIsDisplayed()
}
}
}
step("Enter credentials and click proceed") {
onComposeScreen<AuthenticationScreen>(mainActivityRule) {
emailInput {
performTextInput("test@test.test")
}
passwordInput {
performTextInput("password")
}
loginButton {
performClick()
}
}
}
step("Check that empty recipes list is shown") {
onComposeScreen<RecipesListScreen>(mainActivityRule) {
emptyListErrorText {
assertTextEquals(getResourceString(R.string.fragment_recipes_list_no_recipes))
}
openDrawerButton {
assertIsDisplayed()
}
searchRecipesField {
assertIsDisplayed()
assertTextEquals(getResourceString(R.string.fragment_recipes_load_failure_toast_no_reason))
}
}
}