Skip to content

Instantly share code, notes, and snippets.

@juliuscanute
Last active April 16, 2020 21:48
Show Gist options
  • Select an option

  • Save juliuscanute/4c2708a2d16b7f6d3d093cb2ce685776 to your computer and use it in GitHub Desktop.

Select an option

Save juliuscanute/4c2708a2d16b7f6d3d093cb2ce685776 to your computer and use it in GitHub Desktop.
[Koin Dependencies] #koin #dependencies #module #interceptor #api #dispatcher #ui #instrumentation #test #espresso
class AuthorizationInterceptor : Interceptor, KoinComponent {
// 2
private val petFinderService: PetFinderService by inject()
private var token = Token()
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
var mainResponse = chain.proceed(chain.request())
val mainRequest = chain.request()
if ((mainResponse.code() == 401 || mainResponse.code() == 403) && !
mainResponse.request().url().url().toString().contains("oauth2/token")) {
// 3
val tokenRequest = petFinderService.getToken(clientId =
MainActivity.API_KEY, clientSecret = MainActivity.API_SECRET)
val tokenResponse = tokenRequest.execute()
if (tokenResponse.isSuccessful()) {
tokenResponse.body()?.let {
token = it
val builder =
mainRequest.newBuilder().header("Authorization", "Bearer " +
it.accessToken)
.method(mainRequest.method(), mainRequest.body())
mainResponse = chain.proceed(builder.build())
} }
}
return mainResponse
}
}
{
//...
//Kotlin Dependency Injection Libraries
implementation 'org.koin:koin-core:2.0.1'
implementation 'org.koin:koin-android-scope:2.0.1'
implementation 'org.koin:koin-android-viewmodel:2.0.1'
//...
}
@RunWith(AndroidJUnit4::class)
class FindCompanionInstrumentedTest: KoinTest {
lateinit var testScenario: ActivityScenario<MainActivity>
private val idlingResource = SimpleIdlingResource()
companion object {
// 1
val server = MockWebServer()
// 2
val dispatcher: Dispatcher = object : Dispatcher() {
@Throws(InterruptedException::class)
override fun dispatch(request: RecordedRequest): MockResponse {
return CommonTestDataUtil.dispatch(request) ?: MockResponse().setResponseCode(
404
)
}
}
lateinit var startIntent: Intent
@BeforeClass
@JvmStatic
fun setup() {
// 3
server.setDispatcher(dispatcher)
server.start()
// 3
startIntent = Intent(ApplicationProvider.getApplicationContext(), MainActivity::class.java)
startIntent.putExtra(MainActivity.PETFINDER_URI,
server.url("").toString())
}
}
private fun loadKoinTestModules() {
loadKoinModules(module(override = true) {
single<String>(name = PETFINDER_URL){server.url("").toString()}
}, appModule)
}
@Subscribe
fun onEvent(idlingEntity: IdlingEntity) {
idlingResource.incrementBy(idlingEntity.incrementValue)
}
@Before
fun beforeTestsRun() {
testScenario = ActivityScenario.launch(startIntent)
stopKoin()
loadKoinTestModules()
EventBus.getDefault().register(this)
IdlingRegistry.getInstance().register(idlingResource)
}
@After
fun afterTestsRun() {
// eventbus and idling resources unregister.
IdlingRegistry.getInstance().unregister(idlingResource)
EventBus.getDefault().unregister(this)
stopKoin()
testScenario.close()
}
@Test
fun pressing_the_find_bottom_menu_item_takes_the_user_to_the_find_page() {
onView(withId(R.id.searchForCompanionFragment)).perform(click())
onView(withId(R.id.searchButton)).check(matches(isDisplayed()))
onView(withId(R.id.searchFieldText)).check(matches(isDisplayed()))
}
@Test
fun searching_for_a_companion_and_tapping_on_it_takes_the_user_to_the_companion_details() {
find_and_select_kevin_in_30318()
onView(withText("Rome, GA")).check(matches(isDisplayed()))
onView(withText("Domestic Short Hair")).check(matches(isDisplayed()))
onView(withText("Young")).check(matches(isDisplayed()))
onView(withText("Female")).check(matches(isDisplayed()))
onView(withText("Medium")).check(matches(isDisplayed()))
onView(withText("Meet KEVIN")).check(matches(isDisplayed()))
}
@Test
fun verify_that_companion_details_shows_a_valid_phone_number_and_email() {
find_and_select_kevin_in_30318()
onView(withText("(706) 236-4537")).check(matches(isDisplayed()))
onView(withText("adoptions@gahomelesspets.com")).check(matches(isDisplayed()))
}
@Test
fun searching_for_a_companion_in_30318_returns_two_results() {
onView(withId(R.id.searchForCompanionFragment)).perform(click())
onView(withId(R.id.searchFieldText)).perform(typeText("30318"))
onView(withId(R.id.searchButton)).perform(click())
onView(withId(R.id.searchButton)).check(matches(isDisplayed()))
onView(withText("Joy")).check(matches(isDisplayed()))
onView(withText("Male")).check(matches(isDisplayed()))
onView(withText("Shih Tzu")).check(matches(isDisplayed()))
onView(withText("KEVIN")).check(matches(isDisplayed()))
onView(withText("Female")).check(matches(isDisplayed()))
onView(withText("Domestic Short Hair")).check(matches(isDisplayed()))
}
@Test
fun searching_for_a_companion_in_90210_returns_no_results() {
onView(withId(R.id.searchForCompanionFragment)).perform(click())
onView(withId(R.id.searchFieldText)).perform(typeText("90210"))
onView(withId(R.id.searchButton)).perform(click())
onView(withId(R.id.searchButton)).check(matches(isDisplayed()))
onView(withId(R.id.noResults)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
@Test
fun searching_for_a_companion_in_a_call_returns_an_error_displays_no_results() {
onView(withId(R.id.searchForCompanionFragment)).perform(click())
onView(withId(R.id.searchFieldText)).perform(typeText("dddd"))
onView(withId(R.id.searchButton)).perform(click())
onView(withId(R.id.searchButton)).check(matches(isDisplayed()))
onView(withId(R.id.noResults)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
private fun find_and_select_kevin_in_30318() {
onView(withId(R.id.searchForCompanionFragment)).perform(click())
onView(withId(R.id.searchFieldText)).perform(typeText("30318"))
onView(withId(R.id.searchButton)).perform(click())
onView(withId(R.id.searchButton)).check(matches(isDisplayed()))
onView(withText("KEVIN")).perform(click())
}
}
const val PETFINDER_URL = "PETFINDER_URL"
val urlsModule = module {
single(name = PETFINDER_URL){MainActivity.DEFAULT_PETFINDER_URL}
}
val appModule = module {
single<PetFinderService> {
val logger = HttpLoggingInterceptor()
val client = OkHttpClient.Builder()
.addInterceptor(logger)
.connectTimeout(60L, TimeUnit.SECONDS)
.readTimeout(60L, TimeUnit.SECONDS)
.addInterceptor(AuthorizationInterceptor())
.build()
Retrofit.Builder()
.baseUrl(get(PETFINDER_URL) as String)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.client(client)
.build().create(PetFinderService::class.java)
}
viewModel { ViewCompanionViewModel() }
viewModel { SearchForCompanionViewModel(get()) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment