diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/build.gradle b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/build.gradle index 333a309..1f92faf 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/build.gradle +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/build.gradle @@ -9,11 +9,11 @@ apply plugin: 'kotlin-kapt' apply plugin: "androidx.navigation.safeargs.kotlin" android { - compileSdkVersion 28 + compileSdkVersion 30 defaultConfig { applicationId "com.raywenderlich.codingcompanionfinder" minSdkVersion 21 - targetSdkVersion 28 + targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -27,17 +27,34 @@ android { dataBinding { enabled = true } + + sourceSets { + String sharedTestDir = 'src/sharedTest/java' + String sharedResources = 'src/sharedTest/assets' + test { + java.srcDirs += sharedTestDir + resources.srcDirs += sharedResources + } + androidTest { + java.srcDirs += sharedTestDir + resources.srcDirs += sharedResources + } + } + + testOptions { + unitTests.includeAndroidResources = true + unitTests.returnDefaultValues = true + } } dependencies { // android stuff implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.google.android.material:material:1.0.0' - implementation "com.android.support:design:28.0.0" - implementation 'androidx.appcompat:appcompat:1.1.0-rc01' - implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1' + implementation 'com.google.android.material:material:1.3.0' + implementation 'androidx.appcompat:appcompat:1.3.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.legacy:legacy-support-v4:1.0.0' @@ -46,48 +63,69 @@ dependencies { implementation "android.arch.navigation:navigation-fragment-ktx:1.0.0" // use -ktx for // Glide - implementation("com.github.bumptech.glide:glide:4.8.0") { + implementation("com.github.bumptech.glide:glide:4.12.0") { exclude group: "com.android.support" } - kapt 'com.github.bumptech.glide:compiler:4.8.0' + kapt 'com.github.bumptech.glide:compiler:4.12.0' // carouselview library implementation "com.synnapps:carouselview:0.1.5" // retrofit - implementation "com.squareup.okhttp3:logging-interceptor:3.11.0" - implementation 'com.squareup.retrofit2:retrofit:2.5.0' - implementation 'com.squareup.retrofit2:converter-gson:2.5.0' - implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' + implementation "com.squareup.okhttp3:logging-interceptor:3.14.9" + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // eventbus implementation 'org.greenrobot:eventbus:3.1.1' // Architecture components - def lifecycle_version = "2.0.0" + def lifecycle_version = "2.2.0" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // Koin - implementation 'org.koin:koin-android-viewmodel:1.0.1' - androidTestImplementation 'org.koin:koin-test:1.0.1' + implementation 'org.koin:koin-android-viewmodel:2.0.1' + androidTestImplementation 'org.koin:koin-test:2.0.1' // permissions - implementation 'com.karumi:dexter:5.0.0' + implementation 'com.karumi:dexter:6.0.0' + + def coroutinesVersion = "1.5.0" // testing dependencies - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.2.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' - androidTestImplementation "androidx.test:rules:1.2.0" - androidTestImplementation "androidx.test.ext:junit:1.1.1" - androidTestImplementation "android.arch.navigation:navigation-testing:1.0.0-alpha08" + testImplementation 'junit:junit:4.13.2' + testImplementation 'androidx.test:runner:1.3.0' + testImplementation 'androidx.test.espresso:espresso-core:3.3.0' + testImplementation "androidx.test:rules:1.3.0" + testImplementation "androidx.test.ext:junit:1.1.2" + testImplementation "androidx.navigation:navigation-testing:2.3.5" + testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.0' + testImplementation "androidx.test.espresso:espresso-contrib:3.3.0" + testImplementation 'org.robolectric:robolectric:4.5.1' + testImplementation 'org.koin:koin-test:2.0.1' + testImplementation "androidx.arch.core:core-testing:2.1.0" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion" + testImplementation 'com.github.javafaker:javafaker:0.18' + testImplementation 'androidx.test.espresso:espresso-intents:3.3.0' + +// Once https://issuetracker.google.com/127986458 is fixed this can be testImplementation +// fragmentscenario testing + debugImplementation 'androidx.fragment:fragment-testing:1.3.4' + debugImplementation "androidx.test:core:1.3.0" + + androidTestImplementation 'androidx.test.espresso:espresso-intents:3.3.0' + androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" + androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion" + androidTestImplementation "androidx.arch.core:core-testing:2.1.0" + androidTestImplementation "org.robolectric:annotations:4.5.1" + androidTestImplementation 'androidx.test:runner:1.3.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + androidTestImplementation "androidx.test:rules:1.3.0" + androidTestImplementation "androidx.test.ext:junit:1.1.2" + androidTestImplementation "androidx.navigation:navigation-testing:2.3.5" androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.12.0' - androidTestImplementation "androidx.test.espresso:espresso-contrib:3.2.0" - androidTestImplementation 'androidx.test.espresso:espresso-intents:3.2.0' - - // Once https://issuetracker.google.com/127986458 is fixed this can betestImplementation - // fragmentscenario testing - debugImplementation 'androidx.fragment:fragment-testing:1.1.0-rc04' - debugImplementation "androidx.test:core:1.2.0" + androidTestImplementation "androidx.test.espresso:espresso-contrib:3.3.0" + androidTestImplementation 'com.github.javafaker:javafaker:0.18' } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/.gitkeep b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/com/raywenderlich/codingcompanionfinder/.gitkeep b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/com/raywenderlich/codingcompanionfinder/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/com/raywenderlich/codingcompanionfinder/SimpleIdlingResource.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/com/raywenderlich/codingcompanionfinder/SimpleIdlingResource.kt deleted file mode 100644 index 0f8d377..0000000 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/com/raywenderlich/codingcompanionfinder/SimpleIdlingResource.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.raywenderlich.codingcompanionfinder - -import androidx.annotation.Nullable -import androidx.test.espresso.IdlingResource -import java.util.concurrent.atomic.AtomicInteger - -class SimpleIdlingResource : IdlingResource { - - // 1 - @Nullable - @Volatile - private var callback: IdlingResource.ResourceCallback? = null - - // 2 - // Idleness is controlled with this boolean. - var activeResources = AtomicInteger(0) - - override fun getName(): String { - return this.javaClass.name - } - - // 3 - override fun isIdleNow(): Boolean { - return activeResources.toInt() < 1 - } - - override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback) { - this.callback = callback - } - - // 4 - fun incrementBy(incrementValue: Int) { - if (activeResources.addAndGet(incrementValue) < 1 && callback != null) { - callback!!.onTransitionToIdle() - } - } -} \ No newline at end of file diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/com/raywenderlich/codingcompanionfinder/ViewCompanionTest.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/com/raywenderlich/codingcompanionfinder/ViewCompanionTest.kt deleted file mode 100644 index d7e82ec..0000000 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/java/com/raywenderlich/codingcompanionfinder/ViewCompanionTest.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.raywenderlich.codingcompanionfinder - -import android.app.Activity -import android.app.Instrumentation -import android.content.Intent -import androidx.fragment.app.testing.launchFragmentInContainer -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.intent.Intents -import androidx.test.espresso.intent.matcher.IntentMatchers -import androidx.test.espresso.intent.rule.IntentsTestRule -import androidx.test.espresso.matcher.ViewMatchers.isDisplayed -import androidx.test.espresso.matcher.ViewMatchers.withText -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.rule.GrantPermissionRule -import com.raywenderlich.codingcompanionfinder.models.Address -import com.raywenderlich.codingcompanionfinder.models.Animal -import com.raywenderlich.codingcompanionfinder.models.Breeds -import com.raywenderlich.codingcompanionfinder.models.Contact -import com.raywenderlich.codingcompanionfinder.searchforcompanion.ViewCompanionFragment -import com.raywenderlich.codingcompanionfinder.searchforcompanion.ViewCompanionFragmentArgs -import org.hamcrest.CoreMatchers -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class ViewCompanionTest { - - @get:Rule - val grantPermissionRule: GrantPermissionRule = - GrantPermissionRule.grant(android.Manifest.permission.CALL_PHONE) - @get:Rule - val intentsTestRule = IntentsTestRule(MainActivity::class.java) - - @Before - fun beforeTestsRun() { -// 1 - val animal = Animal( - 22, - Contact( - phone = "(706) 236-4537", - email = "coding.companion@razware.com", - address = Address( - "", - "", - "Atlanta", - "GA", - "30303", - "USA" - ) - ), - "5", - "small", - arrayListOf(), - Breeds("shih tzu", "", false, false), - "Spike", - "male", - "A sweet little guy with spikey teeth!" - ) -// 2 - val bundle = ViewCompanionFragmentArgs(animal).toBundle() -// 3 - launchFragmentInContainer( - bundle, - R.style.AppTheme - ) - } - - @Test - fun check_that_all_values_display_correctly() { - onView(withText("Spike")).check(matches(isDisplayed())) - onView(withText("Atlanta, GA")).check(matches(isDisplayed())) - onView(withText("shih tzu")).check(matches(isDisplayed())) - onView(withText("5")).check(matches(isDisplayed())) - onView(withText("male")).check(matches(isDisplayed())) - onView(withText("small")).check(matches(isDisplayed())) - onView(withText("A sweet little guy with spikey teeth!")).check(matches(isDisplayed())) - onView(withText("(706) 236-4537")).check(matches(isDisplayed())) - onView(withText("coding.companion@razware.com")).check(matches(isDisplayed())) - } - - @Test - fun verify_that_tapping_on_phone_number_dials_phone() { -// 1 - val intent = Intent() - val result = Instrumentation.ActivityResult(Activity.RESULT_OK, intent) - Intents.intending( - CoreMatchers.allOf( - IntentMatchers.hasAction(Intent.ACTION_CALL) - ) - ).respondWith(result) -// 2 - onView(withText("(706) 236-4537")).perform(ViewActions.click()) - // 3 - Intents.intended( - CoreMatchers.allOf( - IntentMatchers.hasAction(Intent.ACTION_CALL), - IntentMatchers.hasData("tel:(706) 236-4537") - ) - ) - } -} diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/resources/mockito-extensions/org.mockito.plugins.MockMaker b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index 1f0955d..0000000 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/androidTest/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/CodingCompanionFinder.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/CodingCompanionFinder.kt index 8fe750d..6a29144 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/CodingCompanionFinder.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/CodingCompanionFinder.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,11 +30,21 @@ package com.raywenderlich.codingcompanionfinder import android.app.Application -import org.koin.android.ext.android.startKoin +import android.util.Log +import org.koin.android.ext.koin.androidContext +import org.koin.core.context.startKoin +import org.koin.core.error.KoinAppAlreadyStartedException -class CodingCompanionFinder: Application(){ +class CodingCompanionFinder : Application() { override fun onCreate() { super.onCreate() - startKoin(this, listOf(appModule, urlsModule)) + try { + startKoin { + androidContext(this@CodingCompanionFinder) + modules(listOf(appModule, urlsModule)) + } + } catch (koinAlreadyStartedException: KoinAppAlreadyStartedException) { + Log.i("CodingCompanionFinder", "KoinAppAlreadyStartedException, should only happen in tests") + } } } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/CodingCompanionGlideModule.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/CodingCompanionGlideModule.kt index 79ab31d..2299c1b 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/CodingCompanionGlideModule.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/CodingCompanionGlideModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/KoinModule.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/KoinModule.kt index 006310f..e57cec4 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/KoinModule.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/KoinModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,22 +29,22 @@ */ package com.raywenderlich.codingcompanionfinder -import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory import com.raywenderlich.codingcompanionfinder.retrofit.AuthorizationInterceptor import com.raywenderlich.codingcompanionfinder.retrofit.PetFinderService import com.raywenderlich.codingcompanionfinder.searchforcompanion.SearchForCompanionViewModel import com.raywenderlich.codingcompanionfinder.searchforcompanion.ViewCompanionViewModel import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor -import org.koin.android.viewmodel.ext.koin.viewModel -import org.koin.dsl.module.module +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.core.qualifier.named +import org.koin.dsl.module import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import java.util.concurrent.TimeUnit const val PETFINDER_URL = "PETFINDER_URL" val urlsModule = module { - single(name = PETFINDER_URL){MainActivity.DEFAULT_PETFINDER_URL} + single(named(PETFINDER_URL)){MainActivity.DEFAULT_PETFINDER_URL} } val appModule = module { single { @@ -56,9 +56,8 @@ val appModule = module { .addInterceptor(AuthorizationInterceptor()) .build() Retrofit.Builder() - .baseUrl(get(PETFINDER_URL) as String) + .baseUrl(get(named(PETFINDER_URL))) .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(CoroutineCallAdapterFactory()) .client(client) .build().create(PetFinderService::class.java) } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/MainActivity.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/MainActivity.kt index 601705f..abdd22b 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/MainActivity.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/MainActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,7 +35,6 @@ import android.os.Bundle import androidx.navigation.Navigation import androidx.navigation.ui.NavigationUI import com.google.android.material.bottomnavigation.BottomNavigationView -import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory import com.raywenderlich.codingcompanionfinder.retrofit.AuthorizationInterceptor import com.raywenderlich.codingcompanionfinder.retrofit.PetFinderService import com.raywenderlich.codingcompanionfinder.testhooks.IdlingEntity @@ -72,7 +71,6 @@ class MainActivity : AppCompatActivity() { petFinderService = Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(CoroutineCallAdapterFactory()) .client(client) .build().create(PetFinderService::class.java) } @@ -110,8 +108,8 @@ class MainActivity : AppCompatActivity() { companion object { val PETFINDER_URI = "petfinder_uri" val PETFINDER_KEY = "petfinder_key" - val API_KEY = "your_key" - val API_SECRET = "your_secret" + val API_KEY = "your_api_key" + val API_SECRET = "your_api_secret" val DEFAULT_PETFINDER_URL = "https://api.petfinder.com/v2/" } } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/SplashActivity.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/SplashActivity.kt index e151326..739afdc 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/SplashActivity.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/SplashActivity.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Address.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Address.kt index 0b55dde..e262d1a 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Address.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Address.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,6 @@ package com.raywenderlich.codingcompanionfinder.models -import java.io.Serializable - data class Address( val address1: String, val address2: String, @@ -39,4 +37,4 @@ data class Address( val state: String, val postcode: String, val country: String -): Serializable +) diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Animal.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Animal.kt index c03a383..9574b81 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Animal.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Animal.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/AnimalResult.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/AnimalResult.kt index 4a96587..f34a726 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/AnimalResult.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/AnimalResult.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Breeds.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Breeds.kt index 9d37fb6..f2a0a09 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Breeds.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Breeds.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,11 +30,9 @@ package com.raywenderlich.codingcompanionfinder.models -import java.io.Serializable - data class Breeds( val primary: String, val secondary: String, val mixed: Boolean, val unknown: Boolean -) : Serializable +) diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Contact.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Contact.kt index d5020a3..9513ea1 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Contact.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Contact.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,8 @@ package com.raywenderlich.codingcompanionfinder.models -import java.io.Serializable - data class Contact( val phone: String = "", val email: String = "", val address: Address -) : Serializable +) diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Photo.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Photo.kt index 64192fb..4405590 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Photo.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Photo.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,12 +30,10 @@ package com.raywenderlich.codingcompanionfinder.models -import java.io.Serializable - data class Photo( val small: String = "", val medium: String = "", val large: String = "", val xlarge: String = "", val full: String = "" -) : Serializable +) diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Token.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Token.kt index 57dd581..8e60b13 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Token.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/models/Token.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/randomcompanion/RandomCompanionFragment.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/randomcompanion/RandomCompanionFragment.kt index be596ba..3ab9f7c 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/randomcompanion/RandomCompanionFragment.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/randomcompanion/RandomCompanionFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -43,7 +43,6 @@ import com.raywenderlich.codingcompanionfinder.MainActivity import com.raywenderlich.codingcompanionfinder.R import com.raywenderlich.codingcompanionfinder.models.Animal import com.synnapps.carouselview.CarouselView -import com.synnapps.carouselview.ViewListener import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -70,8 +69,7 @@ class RandomCompanionFragment : Fragment() { key = (activity as MainActivity).accessToken (activity as MainActivity).petFinderService?.let { petFinderService -> - val animalsRequest = petFinderService.getAnimals((activity as MainActivity).accessToken, 1) - val animalsResponse = animalsRequest.await() + val animalsResponse = petFinderService.getAnimals((activity as MainActivity).accessToken, 1) if (animalsResponse.isSuccessful) { animalsResponse.body()?.let {animalResult -> if (animalResult.animals.size > 0) { @@ -114,17 +112,14 @@ class RandomCompanionFragment : Fragment() { view?.let { petCaroselView = it.findViewById(R.id.petCarouselView) - petCaroselView.setViewListener(object : ViewListener { - - override fun setViewForPosition(position: Int): View { - val carouselItemView = layoutInflater.inflate(R.layout.companion_photo_layout, null) - val imageView = carouselItemView.findViewById(R.id.petImage) - GlideApp.with(randomCompanionFragment).load(petPhotos[position]) - .fitCenter() - .into(imageView) - return carouselItemView - } - }) + petCaroselView.setViewListener { position -> + val carouselItemView = layoutInflater.inflate(R.layout.companion_photo_layout, null) + val imageView = carouselItemView.findViewById(R.id.petImage) + GlideApp.with(randomCompanionFragment).load(petPhotos[position]) + .fitCenter() + .into(imageView) + carouselItemView + } petCaroselView.pageCount = petPhotos.size } } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/retrofit/AuthorizationInterceptor.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/retrofit/AuthorizationInterceptor.kt index 569cfc5..4309ae8 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/retrofit/AuthorizationInterceptor.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/retrofit/AuthorizationInterceptor.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,8 +34,8 @@ import com.raywenderlich.codingcompanionfinder.MainActivity import com.raywenderlich.codingcompanionfinder.models.Token import okhttp3.Interceptor import okhttp3.Response -import org.koin.standalone.KoinComponent -import org.koin.standalone.inject +import org.koin.core.KoinComponent +import org.koin.core.inject import java.io.IOException // 1 @@ -53,13 +53,14 @@ class AuthorizationInterceptor : Interceptor, KoinComponent { val tokenRequest = petFinderService.getToken(clientId = MainActivity.API_KEY, clientSecret = MainActivity.API_SECRET) val tokenResponse = tokenRequest.execute() - if (tokenResponse.isSuccessful()) { + if (tokenResponse.isSuccessful) { tokenResponse.body()?.let { token = it val builder = mainRequest.newBuilder().header("Authorization", "Bearer " + it.accessToken) .method(mainRequest.method(), mainRequest.body()) + mainResponse.close() mainResponse = chain.proceed(builder.build()) } } } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/retrofit/PetFinderService.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/retrofit/PetFinderService.kt index 777e324..7ae6826 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/retrofit/PetFinderService.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/retrofit/PetFinderService.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,7 +31,6 @@ package com.raywenderlich.codingcompanionfinder.retrofit import com.raywenderlich.codingcompanionfinder.models.* -import kotlinx.coroutines.Deferred import retrofit2.Call import retrofit2.Response import retrofit2.http.* @@ -46,9 +45,9 @@ interface PetFinderService { @Field("client_secret") clientSecret: String): Call @GET("animals") - fun getAnimals( + suspend fun getAnimals( @Header("Authorization") accessToken: String, @Query("limit") limit: Int = 20, @Query("location") location: String? = null - ) : Deferred> + ) : Response } \ No newline at end of file diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/CompanionAdapter.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/CompanionAdapter.kt index e717f45..fb0cf14 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/CompanionAdapter.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/CompanionAdapter.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/CompanionViewHolder.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/CompanionViewHolder.kt index 022e59a..01a55fb 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/CompanionViewHolder.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/CompanionViewHolder.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,7 +30,6 @@ package com.raywenderlich.codingcompanionfinder.searchforcompanion -import android.os.Bundle import android.view.View import android.widget.ImageView import android.widget.TextView diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/SearchForCompanionFragment.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/SearchForCompanionFragment.kt index f84ea4a..e06a497 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/SearchForCompanionFragment.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/SearchForCompanionFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,28 +34,14 @@ import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View -import android.view.View.INVISIBLE -import android.view.View.VISIBLE import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.button.MaterialButton -import com.google.android.material.textfield.TextInputEditText import com.raywenderlich.codingcompanionfinder.MainActivity -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch import android.view.inputmethod.InputMethodManager -import android.widget.TextView -import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders -import com.raywenderlich.codingcompanionfinder.R import com.raywenderlich.codingcompanionfinder.databinding.FragmentSearchForCompanionBinding -import com.raywenderlich.codingcompanionfinder.models.Animal -import com.raywenderlich.codingcompanionfinder.testhooks.IdlingEntity -import org.greenrobot.eventbus.EventBus import org.koin.android.viewmodel.ext.android.viewModel class SearchForCompanionFragment : Fragment() { @@ -83,31 +69,24 @@ class SearchForCompanionFragment : Fragment() { } override fun onActivityCreated(savedInstanceState: Bundle?) { -// 1 fragmentSearchForCompanionBinding.searchButton.setOnClickListener { try { val inputMethodManager = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? inputMethodManager!!.hideSoftInputFromWindow( - activity?.getCurrentFocus()?.getWindowToken(), + activity?.currentFocus?.windowToken, 0 ) } catch (e: Exception) { // only happens when the keyboard is already closed } -// 2 searchForCompanionViewModel.searchForCompanions() } -// 3 setupSearchForCompanions() super.onActivityCreated(savedInstanceState) } private fun setupSearchForCompanions() { -// 1 - searchForCompanionViewModel.accessToken = (activity as - MainActivity).accessToken -// 2 viewManager = LinearLayoutManager(context) companionAdapter = CompanionAdapter(searchForCompanionViewModel.animals.value ?: arrayListOf(), this) @@ -116,12 +95,11 @@ class SearchForCompanionFragment : Fragment() { layoutManager = viewManager adapter = companionAdapter } -// 3 - searchForCompanionViewModel.animals.observe(this, - Observer?> { - companionAdapter.animals = it ?: arrayListOf() - companionAdapter.notifyDataSetChanged() - }) + searchForCompanionViewModel.animals.observe(viewLifecycleOwner, + { + companionAdapter.animals = it ?: arrayListOf() + companionAdapter.notifyDataSetChanged() + }) } } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/SearchForCompanionViewModel.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/SearchForCompanionViewModel.kt index fa098cb..524918b 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/SearchForCompanionViewModel.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/SearchForCompanionViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -42,41 +42,34 @@ import kotlinx.coroutines.launch import org.greenrobot.eventbus.EventBus class SearchForCompanionViewModel(val petFinderService: PetFinderService): ViewModel() { - val noResultsViewVisiblity : MutableLiveData = MutableLiveData().apply { INVISIBLE} + val noResultsViewVisiblity : MutableLiveData = MutableLiveData() val companionLocation : MutableLiveData = MutableLiveData() - // 1 - val animals: MutableLiveData> = MutableLiveData>().apply { arrayListOf() } - lateinit var accessToken: String + val animals: MutableLiveData> = MutableLiveData>() + var accessToken: String = "" fun searchForCompanions() { GlobalScope.launch { EventBus.getDefault().post(IdlingEntity(1)) -// 2 - val getAnimalsRequest = petFinderService.getAnimals( + val searchForPetResponse = petFinderService.getAnimals( accessToken, location = companionLocation.value ) - val searchForPetResponse = getAnimalsRequest.await() - GlobalScope.launch(Dispatchers.Main) { if (searchForPetResponse.isSuccessful) { searchForPetResponse.body()?.let { // 3 animals.postValue(it.animals) if (it.animals.size > 0) { -// 3 noResultsViewVisiblity.postValue(INVISIBLE) } else { -// 3 noResultsViewVisiblity.postValue(View.VISIBLE) } } } else { -// 3 noResultsViewVisiblity.postValue(View.VISIBLE) } } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/ViewCompanionFragment.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/ViewCompanionFragment.kt index b5fb8a8..f749a76 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/ViewCompanionFragment.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/ViewCompanionFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,11 +39,14 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView -import android.widget.TextView import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModelProviders +import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.navArgs import com.karumi.dexter.Dexter +import com.karumi.dexter.PermissionToken +import com.karumi.dexter.listener.PermissionDeniedResponse +import com.karumi.dexter.listener.PermissionGrantedResponse +import com.karumi.dexter.listener.PermissionRequest import com.karumi.dexter.listener.single.PermissionListener import com.raywenderlich.codingcompanionfinder.GlideApp @@ -51,101 +54,98 @@ import com.raywenderlich.codingcompanionfinder.R import com.raywenderlich.codingcompanionfinder.databinding.FragmentViewCompanionBinding import com.raywenderlich.codingcompanionfinder.models.Animal import com.synnapps.carouselview.CarouselView -import com.synnapps.carouselview.ViewListener -import com.karumi.dexter.PermissionToken -import com.karumi.dexter.listener.PermissionDeniedResponse -import com.karumi.dexter.listener.PermissionGrantedResponse -import com.karumi.dexter.listener.PermissionRequest - class ViewCompanionFragment : Fragment() { - companion object { - val ANIMAL: String = "ANIMAL" - } - private lateinit var animal: Animal - private lateinit var petPhotos: ArrayList - private lateinit var petCaroselView: CarouselView - private lateinit var viewCompanionFragment: ViewCompanionFragment - private lateinit var fragmentViewCompanionBinding: FragmentViewCompanionBinding - private lateinit var viewCompanionViewModel: ViewCompanionViewModel + companion object { + val ANIMAL: String = "ANIMAL" + } - val args: ViewCompanionFragmentArgs by navArgs() - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - animal = args.animal - viewCompanionFragment = this - // 1 - fragmentViewCompanionBinding = - FragmentViewCompanionBinding.inflate(inflater, container, false) - // 2 - viewCompanionViewModel = ViewModelProviders.of(this).get(ViewCompanionViewModel::class.java) + private lateinit var animal: Animal + private lateinit var petPhotos: ArrayList + private lateinit var petCaroselView: CarouselView + private lateinit var viewCompanionFragment: ViewCompanionFragment + private lateinit var fragmentViewCompanionBinding: FragmentViewCompanionBinding + private lateinit var viewCompanionViewModel: ViewCompanionViewModel + + val args: ViewCompanionFragmentArgs by navArgs() + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + animal = args.animal + viewCompanionFragment = this + // 1 + fragmentViewCompanionBinding = FragmentViewCompanionBinding.inflate(inflater, container, false) + // 2 + viewCompanionViewModel = ViewModelProvider(this).get(ViewCompanionViewModel::class.java) // 3 - viewCompanionViewModel.populateFromAnimal(animal) + viewCompanionViewModel.populateFromAnimal(animal) // 4 - fragmentViewCompanionBinding.viewCompanionViewModel = - viewCompanionViewModel + fragmentViewCompanionBinding.viewCompanionViewModel = + viewCompanionViewModel // 5 - - setupPhonNumberOnClick() - return fragmentViewCompanionBinding.root - } - - override fun onResume() { - populatePhotos() - super.onResume() - } - - private fun populatePhotos() { - petPhotos = ArrayList() - animal.photos.forEach { photo -> - petPhotos.add(photo.full) + setupPhonNumberOnClick() + return fragmentViewCompanionBinding.root } - view?.let { - petCaroselView = it.findViewById(R.id.petCarouselView) - petCaroselView.setViewListener(object : ViewListener { - - override fun setViewForPosition(position: Int): View { - val carouselItemView = layoutInflater.inflate(R.layout.companion_photo_layout, null) - val imageView = carouselItemView.findViewById(R.id.petImage) - GlideApp.with(viewCompanionFragment).load(petPhotos[position]) - .fitCenter() - .into(imageView) - return carouselItemView - } - }) - petCaroselView.pageCount = petPhotos.size + override fun onResume() { + populatePhotos() + super.onResume() } - } - private fun setupPhonNumberOnClick(){ - fragmentViewCompanionBinding.telephone.setOnClickListener { - Dexter.withActivity(activity) - .withPermission(Manifest.permission.CALL_PHONE) - .withListener( - object : PermissionListener { - override fun onPermissionGranted(response: PermissionGrantedResponse) {/* ... */ - val intent = Intent(Intent.ACTION_CALL, Uri.parse("tel:" + viewCompanionViewModel.telephone)) - startActivity(intent) - } - - override fun onPermissionDenied(response: PermissionDeniedResponse) {/* ... */ - } + private fun populatePhotos() { + petPhotos = ArrayList() + animal.photos.forEach { photo -> + petPhotos.add(photo.full) + } - override fun onPermissionRationaleShouldBeShown( - permission: PermissionRequest, - token: PermissionToken - ) {/* ... */ - token.continuePermissionRequest() + view?.let { + petCaroselView = it.findViewById(R.id.petCarouselView) + petCaroselView.setViewListener { position -> + val carouselItemView = layoutInflater.inflate(R.layout.companion_photo_layout, null) + val imageView = carouselItemView.findViewById(R.id.petImage) + GlideApp.with(viewCompanionFragment).load(petPhotos[position]) + .fitCenter() + .into(imageView) + carouselItemView } + petCaroselView.pageCount = petPhotos.size + } + } - }) - .onSameThread() - .check() - + private fun setupPhonNumberOnClick(){ + fragmentViewCompanionBinding.telephone.setOnClickListener { + // 1 + Dexter.withActivity(activity) + .withPermission(Manifest.permission.CALL_PHONE) + .withListener( + object : PermissionListener { + // 3 + override fun onPermissionGranted( + response: PermissionGrantedResponse + ) {/* ... */ + val intent = Intent(Intent.ACTION_CALL, Uri.parse( + "tel:" + viewCompanionViewModel.telephone)) + startActivity(intent) + } + + override fun onPermissionDenied( + response: PermissionDeniedResponse + ) {/* ... */} + + // 2 + override fun onPermissionRationaleShouldBeShown( + permission: PermissionRequest, + token: PermissionToken + ) {/* ... */ + token.continuePermissionRequest() + } + + } + ) + .onSameThread() + .check() + } } - } } diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/ViewCompanionViewModel.kt b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/ViewCompanionViewModel.kt index a13ebbd..66f535c 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/ViewCompanionViewModel.kt +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/java/com/raywenderlich/codingcompanionfinder/searchforcompanion/ViewCompanionViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Razeware LLC + * Copyright (c) 2021 Razeware LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/res/layout/activity_main.xml b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/res/layout/activity_main.xml index a2f61af..b7bb84c 100644 --- a/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/res/layout/activity_main.xml +++ b/18-testing-around-other-components/projects/final/CodingCompanionFinder/app/src/main/res/layout/activity_main.xml @@ -7,7 +7,7 @@ android:layout_height="match_parent" tools:context=".MainActivity"> - - + @@ -36,10 +38,8 @@ type="com.raywenderlich.codingcompanionfinder.searchforcompanion.SearchForCompanionViewModel" /> - @@ -72,14 +72,15 @@ + android:id="@+id/searchButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Find" + app:layout_constraintBottom_toBottomOf="@+id/searchField" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/searchField" + app:layout_constraintTop_toTopOf="@id/searchField" + app:layout_constraintVertical_bias="0.0" /> - + @@ -36,10 +38,8 @@ type="com.raywenderlich.codingcompanionfinder.searchforcompanion.SearchForCompanionViewModel" /> - @@ -72,14 +72,15 @@ + android:id="@+id/searchButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Find" + app:layout_constraintBottom_toBottomOf="@+id/searchField" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/searchField" + app:layout_constraintTop_toTopOf="@id/searchField" + app:layout_constraintVertical_bias="0.0" />