Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ui tests and create a primitive backend mock #24

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Expand Up @@ -59,6 +59,8 @@ dependencies {
androidTestImplementation(TestLibraries.testRules)
androidTestImplementation(TestLibraries.mockitoAndroid)
androidTestImplementation(TestLibraries.uiAutomator)
androidTestImplementation(TestLibraries.koinTest)
androidTestImplementation(TestLibraries.mockito)

// Development dependencies
debugImplementation(DevLibraries.fragmentTesting)
Expand Down
9 changes: 7 additions & 2 deletions app/src/androidTest/kotlin/com/wire/android/FunctionalTest.kt
Expand Up @@ -6,18 +6,23 @@ import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.rule.ActivityTestRule
import androidx.test.uiautomator.UiDevice
import com.wire.android.framework.koinMockRule
import org.junit.Rule
import org.junit.runner.RunWith
import org.koin.test.KoinTest

open class FunctionalActivityTest(clazz: Class<out Activity>) : FunctionalTest() {
abstract class FunctionalActivityTest(clazz: Class<out Activity>) : FunctionalTest() {

@get:Rule
val activityRule = ActivityTestRule(clazz)
}

@RunWith(AndroidJUnit4::class)
@LargeTest
open class FunctionalTest {
abstract class FunctionalTest : KoinTest {

@get:Rule
val mockProvider = koinMockRule()

val uiDevice = UiDevice.getInstance(getInstrumentation())

Expand Down
14 changes: 0 additions & 14 deletions app/src/androidTest/kotlin/com/wire/android/WireApplicationTest.kt

This file was deleted.

Expand Up @@ -2,14 +2,34 @@ package com.wire.android.feature.auth.registration

import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import com.wire.android.FunctionalActivityTest
import com.wire.android.R
import com.wire.android.core.exception.Conflict
import com.wire.android.core.exception.Forbidden
import com.wire.android.core.functional.Either
import com.wire.android.feature.auth.activation.ActivationRepository
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Test
import org.koin.test.mock.declareMock
import org.mockito.Mockito.`when`

class CreateAccountActivityUITest : FunctionalActivityTest(CreateAccountActivity::class.java) {

@Before
fun setup() {
declareMock<ActivationRepository>().let {
runBlocking {
`when`(it.sendEmailActivationCode(VALID_EMAIL)).thenReturn(Either.Right(Unit))
`when`(it.sendEmailActivationCode(FORBIDDEN_EMAIL)).thenReturn(Either.Left(Forbidden))
`when`(it.sendEmailActivationCode(CONFLICT_EMAIL)).thenReturn(Either.Left(Conflict))
}
}
}

@Test
fun launch_uiElementsVisible() {
onView(withId(R.id.createAccountBackButton)).check(matches(isDisplayed()))
Expand All @@ -30,17 +50,56 @@ class CreateAccountActivityUITest : FunctionalActivityTest(CreateAccountActivity

@Test
fun personal_uiElementsVisible() {
onView(withId(R.id.createPersonalAccountTitleTextView)).perform(click())
onView(withId(R.id.createPersonalAccountLayoutContainer)).perform(click())

onView(withText(R.string.create_personal_account_title)).check(matches(isDisplayed()))
onView(withText(R.string.authentication_tab_layout_title_email)).check(matches(isDisplayed()))
onView(withText(R.string.authentication_tab_layout_title_phone)).check(matches(isDisplayed()))

//TODO: check whether Email entry area is visible
onView(withId(R.id.createPersonalAccountEmailTextInputLayout)).check(matches(isDisplayed()))
}

@Test
fun personal_uiElementsVisibleInLandscape() = rotateScreen {
personal_uiElementsVisible()
}

@Test
fun personalEmailScreen_validEmailFilled_opensCodeVerificationScreen() {
onView(withId(R.id.createPersonalAccountLayoutContainer)).perform(click())
onView(withId(R.id.createPersonalAccountEmailEditText)).perform(replaceText(VALID_EMAIL))

onView(withId(R.id.createPersonalAccountEmailConfirmationButton)).let {
it.check(matches(isEnabled()))
it.perform(click())
}

onView(withText(R.string.create_personal_account_email_code_title)).check(matches(isDisplayed()))
}

@Test
fun personalEmailScreen_forbiddenEmailFilled_showsError() {
onView(withId(R.id.createPersonalAccountLayoutContainer)).perform(click())
onView(withId(R.id.createPersonalAccountEmailEditText)).perform(replaceText(FORBIDDEN_EMAIL))

onView(withId(R.id.createPersonalAccountEmailConfirmationButton)).perform(click())

//TODO: validate after proper dialog is added
}

@Test
fun personalEmailScreen_conflictEmailFilled_showsError() {
onView(withId(R.id.createPersonalAccountLayoutContainer)).perform(click())
onView(withId(R.id.createPersonalAccountEmailEditText)).perform(replaceText(CONFLICT_EMAIL))

onView(withId(R.id.createPersonalAccountEmailConfirmationButton)).perform(click())

//TODO: validate after proper dialog is added
}

companion object {
private const val VALID_EMAIL = "test@wire.com"
private const val FORBIDDEN_EMAIL = "forbidden@wire.com"
private const val CONFLICT_EMAIL = "conflict@wire.com"
}
}
@@ -0,0 +1,7 @@
package com.wire.android.framework

import org.koin.test.KoinTest
import org.koin.test.mock.MockProviderRule
import org.mockito.Mockito

fun KoinTest.koinMockRule() = MockProviderRule.create { clazz -> Mockito.mock(clazz.java) }
Expand Up @@ -4,7 +4,6 @@ import com.wire.android.core.exception.Failure
import com.wire.android.core.functional.Either
import com.wire.android.feature.auth.activation.ActivationRepository
import com.wire.android.feature.auth.activation.datasource.remote.ActivationRemoteDataSource
import kotlinx.coroutines.delay

class ActivationDataSource(private val activationRemoteDataSource: ActivationRemoteDataSource) : ActivationRepository {

Expand Down
Expand Up @@ -4,6 +4,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.wire.android.feature.auth.registration.personal.email.CreatePersonalAccountEmailFragment
import com.wire.android.feature.auth.registration.personal.phone.CreatePersonalAccountPhoneFragment
import java.util.Locale

class CreatePersonalAccountViewPagerAdapter(
Expand All @@ -14,8 +15,8 @@ class CreatePersonalAccountViewPagerAdapter(
override fun getCount(): Int = titles.size

override fun getItem(position: Int): Fragment =
//TODO add phone fragment
CreatePersonalAccountEmailFragment.newInstance()
if (position == PHONE_TAB_POSITION) CreatePersonalAccountPhoneFragment.newInstance()
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

espresso was complaining about ambiguous resources (since there were 2 instances of the same fragment). so I created this empty fragment, which will be filled soon :)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the TODO() then :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a TODO in xml layout

else CreatePersonalAccountEmailFragment.newInstance()

override fun getPageTitle(position: Int): CharSequence =
titles[position].toUpperCase(Locale.getDefault())
Expand Down
@@ -0,0 +1,10 @@
package com.wire.android.feature.auth.registration.personal.phone

import androidx.fragment.app.Fragment
import com.wire.android.R

class CreatePersonalAccountPhoneFragment : Fragment(R.layout.fragment_create_personal_account_phone) {
companion object {
fun newInstance() = CreatePersonalAccountPhoneFragment()
}
}
4 changes: 2 additions & 2 deletions app/src/main/res/layout/fragment_create_personal_account.xml
Expand Up @@ -14,7 +14,7 @@
app:layout_constraintGuide_percent="0.228" />

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/createPersonalAccountTitleTextView"
android:id="@+id/createPersonalAccountHeaderTextView"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

due to duplicate naming

style="@style/TextView.Authentication.Header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Expand All @@ -31,7 +31,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/createPersonalAccountTitleTextView"
app:layout_constraintTop_toBottomOf="@+id/createPersonalAccountHeaderTextView"
app:layout_constraintWidth_percent="@dimen/authentication_editable_field_width_percent">

<com.google.android.material.tabs.TabLayout
Expand Down
Expand Up @@ -17,6 +17,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/create_personal_account_with_email_edit_text_hint"
android:imeOptions="flagNoExtractUi"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the weird keyboard behaviour in landscape mode.

android:inputType="textEmailAddress"
android:paddingEnd="@dimen/create_personal_account_text_input_layout_padding_end">

Expand Down
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content">

<!-- TODO inflate views -->
</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Expand Up @@ -91,6 +91,8 @@ object TestLibraries {
const val uiAutomator = "androidx.test.uiautomator:uiautomator:${Versions.uiAutomator}"
const val coroutinesTest = "org.jetbrains.kotlinx:kotlinx-coroutines-test:${Libraries.Versions.coroutines}"
const val testCore = "androidx.arch.core:core-testing:${Versions.testCore}"
const val koinTest = "org.koin:koin-test:${Libraries.Versions.koin}"

}


Expand Down