diff --git a/emby-lib/build.gradle.kts b/emby-lib/build.gradle.kts index b5b51b30d..0bb6fcd68 100644 --- a/emby-lib/build.gradle.kts +++ b/emby-lib/build.gradle.kts @@ -64,7 +64,6 @@ dependencies { debugImplementation(libs.toothpick.smoothie) releaseApi(libs.toothpick.javax.annotations) -// kapt(libs.toothpick.compiler) ksp(libs.toothpick.ksp.compiler) implementation(libs.android.priority.jobqueue) @@ -81,7 +80,9 @@ dependencies { testImplementation(libs.junit) testImplementation(libs.assertj.core) + testImplementation(libs.assertk.jvm) testImplementation(libs.mockito.core) + testImplementation(libs.mockk) testImplementation(libs.robolectric) testImplementation(libs.robolectric.shadows.framework) testImplementation(libs.robolectric.shadows.api) diff --git a/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/EmbyServerDiscoverTest.kt b/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/EmbyServerDiscoverTest.kt index 6940fd49d..4e9665f62 100644 --- a/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/EmbyServerDiscoverTest.kt +++ b/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/EmbyServerDiscoverTest.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Assert.* import org.junit.Before import org.junit.Test +import org.robolectric.shadows.ShadowLog class EmbyServerDiscoverTest { @@ -11,6 +12,7 @@ class EmbyServerDiscoverTest { @Before fun setUp() { + ShadowLog.stream = System.out serverDiscovery = EmbyServerDiscover() } diff --git a/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/EmbyServerJobTest.kt b/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/EmbyServerJobTest.kt index 8ed340d41..fef12dea0 100644 --- a/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/EmbyServerJobTest.kt +++ b/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/EmbyServerJobTest.kt @@ -1,6 +1,7 @@ package us.nineworlds.serenity.emby.server import android.content.Context +import io.mockk.mockk import org.greenrobot.eventbus.EventBus import org.junit.Before import org.junit.Test @@ -10,6 +11,7 @@ import org.mockito.MockitoAnnotations.initMocks import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config +import org.robolectric.shadows.ShadowLog import toothpick.config.Module import us.nineworlds.serenity.common.android.injection.ApplicationContext import us.nineworlds.serenity.emby.test.InjectingTest @@ -18,17 +20,15 @@ import us.nineworlds.serenity.emby.test.InjectingTest @Config(sdk = [28]) class EmbyServerJobTest : InjectingTest() { - @Mock - lateinit var mockEventBus: EventBus - override val modules: List get() = mutableListOf(TestModule()) - lateinit var job: EmbyServerJob + private lateinit var job: EmbyServerJob @Before override fun setUp() { - initMocks(this) + ShadowLog.stream = System.out + super.setUp() job = EmbyServerJob() } diff --git a/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/api/EmbyAPIClientTest.kt b/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/api/EmbyAPIClientTest.kt index 6e3863f0e..f4e7352b5 100644 --- a/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/api/EmbyAPIClientTest.kt +++ b/emby-lib/src/test/kotlin/us/nineworlds/serenity/emby/server/api/EmbyAPIClientTest.kt @@ -1,7 +1,10 @@ package us.nineworlds.serenity.emby.server.api import androidx.test.core.app.ApplicationProvider -import org.assertj.core.api.Assertions.assertThat +import assertk.assertThat +import assertk.assertions.hasSize +import assertk.assertions.isNotEmpty +import assertk.assertions.isNotNull import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -15,37 +18,37 @@ import us.nineworlds.serenity.emby.server.model.AuthenticationResult @Config(sdk = [28]) class EmbyAPIClientTest { - lateinit var client: EmbyAPIClient + private lateinit var client: EmbyAPIClient @Before fun setUp() { ShadowLog.stream = System.out client = EmbyAPIClient(context = ApplicationProvider.getApplicationContext()) - client.updateBaseUrl("http://192.168.86.162:8096") + client.updateBaseUrl("http://192.168.68.95:8096") } @Test fun retrieveAllPublicUsers() { val result = client.fetchAllPublicUsers() - assertThat(result).isNotEmpty.hasSize(2) + assertThat(result).hasSize(2) } @Test fun loginAdminUser() { val authenticateResult = authenticate() assertThat(authenticateResult).isNotNull() - assertThat(authenticateResult.accesToken).isNotBlank() - assertThat(client.serverId).isNotBlank() - assertThat(client.accessToken).isNotBlank() - assertThat(client.userId).isNotBlank() + assertThat(authenticateResult.accesToken).isNotEmpty() + assertThat(client.serverId).isNotEmpty() + assertThat(client.accessToken).isNotNull() + assertThat(client.userId).isNotNull().isNotEmpty() } @Test fun testCurrentUsersViews() { authenticate() val result = client.currentUserViews() - assertThat(result.items).isNotEmpty + assertThat(result.items).isNotEmpty() } @Test fun availableFiltersForCurrentUser() { @@ -61,8 +64,8 @@ class EmbyAPIClientTest { authenticate() val result = client.retrieveRootData() - assertThat(result).isNotNull - assertThat(result!!.directories).isNotEmpty + assertThat(result).isNotNull() + assertThat(result.directories).isNotEmpty() } @Test fun createCategoriesForParentId() { @@ -74,7 +77,7 @@ class EmbyAPIClientTest { val categories = client.retrieveCategoriesById(parentId) - assertThat(categories.directories).isNotEmpty + assertThat(categories.directories).isNotEmpty() } @Test fun fetchAllMovies() { @@ -85,7 +88,7 @@ class EmbyAPIClientTest { val movies = client.retrieveItemByIdCategory(parentId, "all", Types.EPISODE) - assertThat(movies.videos).isNotEmpty + assertThat(movies.videos).isNotEmpty() } @Test fun fetchAllLatestMovies() { @@ -97,7 +100,7 @@ class EmbyAPIClientTest { val itemResult = client.retrieveItemByIdCategory(key, "recentlyAdded", Types.MOVIES) - assertThat(itemResult.videos).isNotEmpty + assertThat(itemResult.videos).isNotEmpty() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index aff391784..533664c45 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ appVersion = "3.0-M1" annotationVersion = "1.9.1" appcompatVersion = "1.7.0" -assertkJvmVersion = "0.24" +assertkJvmVersion = "0.28.1" cardviewVersion = "1.0.0" commonsIo = "2.13.0" commonsLang3Version = "3.7" @@ -17,7 +17,7 @@ juniversalchardetVersion = "1.0.3" kotlinVersion = "1.9.25" kotlinCoroutinesVersion = "1.7.3" kotlinKSPVersion = "1.9.25-1.0.20" -androidPluginVersion = "8.7.3" +androidPluginVersion = "8.6.1" leanbackPreferenceVersion = "1.1.0-rc01" leanbackVersion = "1.1.0-rc02" legacySupportV4Version = "1.0.0" @@ -55,6 +55,7 @@ easydeviceInfoVersion = "2.4.1" androidxTestCoreVersion = "1.6.1" androidxRecyclerViewVersion = "1.3.2" resourcefulVersion = "1.1.0" +mockkVersion = "1.13.13" [libraries] androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "annotationVersion" } @@ -69,7 +70,6 @@ androidx-leanback-preference = { module = "androidx.leanback:leanback-preference androidx-legacy-support-v4 = { module = "androidx.legacy:legacy-support-v4", version.ref = "legacySupportV4Version" } androidx-percentlayout = { module = "androidx.percentlayout:percentlayout", version.ref = "percentlayoutVersion" } androidx-recycler-view = { module = "androidx.recyclerview:recyclerview", version.ref = "androidxRecyclerViewVersion"} -assertk-jvm = { module = "com.willowtreeapps.assertk:assertk-jvm", version.ref = "assertkJvmVersion" } commons-io = { module = "commons-io:commons-io", version.ref = "commonsIo" } commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "commonsLang3Version" } exoplayer-core = { module = "com.google.android.exoplayer:exoplayer-core", version.ref = "exoplayerVersion"} @@ -123,6 +123,7 @@ assertj-core = { group = "org.assertj", name = "assertj-core", version.ref = "as assertj-android = { group = "com.squareup.assertj", name = "assertj-android", version.ref = "assertJAndroidVersion"} mockito-core = { group = "org.mockito", name = "mockito-core", version.ref = "mockitoVersion" } mockito-kotlin = { module = "com.nhaarman.mockitokotlin2:mockito-kotlin", version = "2.2.0"} +mockk = { module = "io.mockk:mockk", version.ref = "mockkVersion" } robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectricVersion" } robolectric-shadows-framework = { group = "org.robolectric", name = "shadows-framework", version.ref = "robolectricVersion" } robolectric-shadows-api = { group = "org.robolectric", name = "shadowapi", version.ref = "robolectricVersion" } @@ -133,5 +134,6 @@ androidx-test-core = { group = "androidx.test", name = "core", version.ref = "an kotlin-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinCoroutinesVersion" } toothpick-testing = { group = "com.github.stephanenicolas.toothpick", name = "toothpick-testing", version.ref = "toothPickVersion"} +assertk-jvm = { module = "com.willowtreeapps.assertk:assertk", version.ref = "assertkJvmVersion" } [plugins] diff --git a/serenity-app/build.gradle.kts b/serenity-app/build.gradle.kts index 02db005ba..4d485890f 100644 --- a/serenity-app/build.gradle.kts +++ b/serenity-app/build.gradle.kts @@ -1,13 +1,13 @@ plugins { - id("com.android.application") id("project-report") + id("com.google.devtools.ksp") + id("com.android.application") id("kotlin-android") id("kotlin-kapt") id("kotlin-allopen") id("org.sonarqube") id("com.google.firebase.crashlytics") id("com.google.gms.google-services") version "4.4.0" - id("com.google.devtools.ksp") } apply(from = "../jacoco.gradle") @@ -30,6 +30,8 @@ allOpen { android { namespace = "us.nineworlds.serenity" + compileSdk = libs.versions.targetSdkVersion.get().toInt() + defaultConfig { versionCode = 3000000 versionName = "3.0.0-M1" @@ -37,18 +39,18 @@ android { targetSdk = libs.versions.targetSdkVersion.get().toInt() multiDexEnabled = true multiDexKeepProguard = file("multidex_keep_file.txt") + } - buildFeatures { - viewBinding = true - } + buildFeatures { + viewBinding = true } + sourceSets { getByName("main").java.srcDirs("src/main/kotlin", "src/main/java") getByName("test").java.srcDirs("src/test/kotlin", "src/test/java") } - compileSdk = libs.versions.targetSdkVersion.get().toInt() if (project.hasProperty("keystore")) { signingConfigs { @@ -96,7 +98,6 @@ android { maxHeapSize = "1512m" setForkEvery(100) maxParallelForks = 2 - jvmArgs("-noverify") testLogging { setExceptionFormat("full") } @@ -191,6 +192,7 @@ dependencies { exclude(group = "xpp3") } + testImplementation(libs.mockk) testImplementation(libs.mockito.core) testImplementation(libs.mockito.kotlin) testImplementation(libs.commons.lang3) diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/EpisodesRetrievalJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/EpisodesRetrievalJob.java deleted file mode 100644 index 613423dbc..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/EpisodesRetrievalJob.java +++ /dev/null @@ -1,51 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.core.logger.Logger; -import us.nineworlds.serenity.events.EpisodesRetrievalEvent; - -public class EpisodesRetrievalJob extends InjectingJob { - - @Inject SerenityClient client; - - EventBus eventBus = EventBus.getDefault(); - - @Inject Logger logger; - - String key; - - public EpisodesRetrievalJob(@NonNull String key) { - this.key = key; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveEpisodes(key); - EpisodesRetrievalEvent event = new EpisodesRetrievalEvent(mediaContainer); - eventBus.post(event); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - logger.error("Episode Retrieval Error: ", throwable); - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieCategoryJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieCategoryJob.java deleted file mode 100644 index 57f69ffae..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieCategoryJob.java +++ /dev/null @@ -1,46 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.events.MainCategoryEvent; - -public class MovieCategoryJob extends InjectingJob { - - EventBus eventBus = EventBus.getDefault(); - - @Inject SerenityClient client; - - String key; - - public MovieCategoryJob(String key) { - this.key = key; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveCategoriesById(key); - eventBus.post(new MainCategoryEvent(mediaContainer, key)); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieRetrievalJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieRetrievalJob.java deleted file mode 100644 index cf702bb00..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieRetrievalJob.java +++ /dev/null @@ -1,51 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.common.rest.Types; -import us.nineworlds.serenity.events.MovieRetrievalEvent; - -public class MovieRetrievalJob extends InjectingJob { - - @Inject SerenityClient client; - - EventBus eventBus = EventBus.getDefault(); - - String key; - String category; - - public MovieRetrievalJob(@NonNull String key, String category) { - this.key = key; - this.category = category; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveItemByIdCategory(key, category, Types.MOVIES); - MovieRetrievalEvent event = new MovieRetrievalEvent(mediaContainer); - - eventBus.post(event); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieSecondaryCategoryJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieSecondaryCategoryJob.java deleted file mode 100644 index 7d5791e45..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/MovieSecondaryCategoryJob.java +++ /dev/null @@ -1,49 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.common.rest.Types; -import us.nineworlds.serenity.events.MovieSecondaryCategoryEvent; - -public class MovieSecondaryCategoryJob extends InjectingJob { - - @Inject SerenityClient client; - - EventBus eventBus = EventBus.getDefault(); - - String key; - String category; - - public MovieSecondaryCategoryJob(String key, String category) { - this.key = key; - this.category = category; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveItemByIdCategory(key, category, Types.MOVIES); - eventBus.post(new MovieSecondaryCategoryEvent(mediaContainer, key, category)); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/RetrieveAllUsersJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/RetrieveAllUsersJob.java deleted file mode 100644 index a5ce82cc2..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/RetrieveAllUsersJob.java +++ /dev/null @@ -1,41 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import java.util.List; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.common.rest.SerenityUser; -import us.nineworlds.serenity.events.users.AllUsersEvent; - -public class RetrieveAllUsersJob extends InjectingJob { - - @Inject SerenityClient client; - EventBus eventBus = EventBus.getDefault(); - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - List serenityUsers = client.allAvailableUsers(); - eventBus.post(new AllUsersEvent(serenityUsers)); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/SeasonsRetrievalJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/SeasonsRetrievalJob.java deleted file mode 100644 index 7dc98c12a..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/SeasonsRetrievalJob.java +++ /dev/null @@ -1,47 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.events.SeasonsRetrievalEvent; - -public class SeasonsRetrievalJob extends InjectingJob { - - @Inject SerenityClient client; - - EventBus eventBus = EventBus.getDefault(); - - String key; - - public SeasonsRetrievalJob(@NonNull String key) { - this.key = key; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveSeasons(key); - SeasonsRetrievalEvent event = new SeasonsRetrievalEvent(mediaContainer); - eventBus.post(event); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/SubtitleJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/SubtitleJob.java deleted file mode 100644 index 12635ed12..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/SubtitleJob.java +++ /dev/null @@ -1,46 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.events.SubtitleEvent; - -public class SubtitleJob extends InjectingJob { - - EventBus eventBus = EventBus.getDefault(); - - @Inject SerenityClient client; - - String metaDataKey; - - public SubtitleJob(String metaDataKey) { - this.metaDataKey = metaDataKey; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveMovieMetaData(metaDataKey); - eventBus.post(new SubtitleEvent(mediaContainer)); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVCategoryJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVCategoryJob.java deleted file mode 100644 index 1a2da8d77..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVCategoryJob.java +++ /dev/null @@ -1,51 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.events.TVCategoryEvent; - -public class TVCategoryJob extends InjectingJob { - - EventBus eventBus = EventBus.getDefault(); - - @Inject SerenityClient client; - - String key; - - public TVCategoryJob(String key) { - this.key = key; - } - - @Override public void onAdded() { - - } - - @VisibleForTesting public String getKey() { - return key; - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveSeriesCategoryById(key); - eventBus.post(new TVCategoryEvent(mediaContainer, key)); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVCategorySecondaryJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVCategorySecondaryJob.java deleted file mode 100644 index a09389497..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVCategorySecondaryJob.java +++ /dev/null @@ -1,49 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.common.rest.Types; -import us.nineworlds.serenity.events.TVCategorySecondaryEvent; - -public class TVCategorySecondaryJob extends InjectingJob { - - EventBus eventBus = EventBus.getDefault(); - - @Inject SerenityClient client; - - String key; - String category; - - public TVCategorySecondaryJob(@NonNull String key, @NonNull String category) { - this.key = key; - this.category = category; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveItemByIdCategory(key, category, Types.SERIES); - eventBus.post(new TVCategorySecondaryEvent(mediaContainer, key, category)); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVShowRetrievalJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVShowRetrievalJob.java deleted file mode 100644 index 4087d5288..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/TVShowRetrievalJob.java +++ /dev/null @@ -1,58 +0,0 @@ -package us.nineworlds.serenity.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import com.birbit.android.jobqueue.RetryConstraint; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.media.model.IMediaContainer; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.events.TVShowRetrievalEvent; - -public class TVShowRetrievalJob extends InjectingJob { - - @Inject SerenityClient client; - - EventBus eventBus = EventBus.getDefault(); - - String key; - String category; - - public TVShowRetrievalJob(@NonNull String key, String category) { - this.key = key; - this.category = category; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - IMediaContainer mediaContainer = client.retrieveSeriesById(key, category); - TVShowRetrievalEvent event = new TVShowRetrievalEvent(mediaContainer, key, category); - eventBus.post(event); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } - - @VisibleForTesting public String getKey() { - return key; - } - - @VisibleForTesting public String getCategory() { - return category; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/StartPlaybackJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/StartPlaybackJob.java deleted file mode 100644 index d755883b6..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/StartPlaybackJob.java +++ /dev/null @@ -1,40 +0,0 @@ -package us.nineworlds.serenity.jobs.video; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.rest.SerenityClient; - -public class StartPlaybackJob extends InjectingJob { - - @Inject SerenityClient serenityClient; - - private String videoId; - - public StartPlaybackJob(String videoId) { - super(); - this.videoId = videoId; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - serenityClient.startPlaying(videoId); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/StopPlaybackJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/StopPlaybackJob.java deleted file mode 100644 index 101b11682..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/StopPlaybackJob.java +++ /dev/null @@ -1,42 +0,0 @@ -package us.nineworlds.serenity.jobs.video; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.rest.SerenityClient; - -public class StopPlaybackJob extends InjectingJob { - - @Inject SerenityClient serenityClient; - - private String videoId; - private long offset; - - public StopPlaybackJob(String videoId, long offset) { - super(); - this.videoId = videoId; - this.offset = offset; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - serenityClient.stopPlaying(videoId, offset); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/UpdatePlaybackPostionJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/UpdatePlaybackPostionJob.java deleted file mode 100644 index 0890b04c5..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/UpdatePlaybackPostionJob.java +++ /dev/null @@ -1,47 +0,0 @@ -package us.nineworlds.serenity.jobs.video; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.rest.SerenityClient; -import us.nineworlds.serenity.core.model.VideoContentInfo; - -public class UpdatePlaybackPostionJob extends InjectingJob { - - @Inject SerenityClient factory; - - private VideoContentInfo video; - - public UpdatePlaybackPostionJob(VideoContentInfo video) { - super(); - this.video = video; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - String videoId = video.id(); - if (video.isWatched()) { - factory.watched(videoId); - factory.progress(videoId, "0"); - } else { - factory.progress(videoId, Long.valueOf(video.getResumeOffset()).toString()); - } - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/WatchedStatusJob.java b/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/WatchedStatusJob.java deleted file mode 100644 index c5ca72070..000000000 --- a/serenity-app/src/main/java/us/nineworlds/serenity/jobs/video/WatchedStatusJob.java +++ /dev/null @@ -1,40 +0,0 @@ -package us.nineworlds.serenity.jobs.video; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.birbit.android.jobqueue.RetryConstraint; - -import javax.inject.Inject; - -import us.nineworlds.serenity.common.android.injection.InjectingJob; -import us.nineworlds.serenity.common.rest.SerenityClient; - -public class WatchedStatusJob extends InjectingJob { - - @Inject SerenityClient serenityClient; - - private String videoId; - - public WatchedStatusJob(String videoId) { - super(); - this.videoId = videoId; - } - - @Override public void onAdded() { - - } - - @Override public void onRun() throws Throwable { - serenityClient.watched(videoId); - } - - @Override protected void onCancel(int cancelReason, @Nullable Throwable throwable) { - - } - - @Override - protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) { - return null; - } -} diff --git a/serenity-app/src/main/kotlin/us/nineworlds/serenity/jobs/AuthenticateUserJob.kt b/serenity-app/src/main/kotlin/us/nineworlds/serenity/jobs/AuthenticateUserJob.kt deleted file mode 100644 index 02e698d61..000000000 --- a/serenity-app/src/main/kotlin/us/nineworlds/serenity/jobs/AuthenticateUserJob.kt +++ /dev/null @@ -1,34 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.birbit.android.jobqueue.RetryConstraint -import org.greenrobot.eventbus.EventBus -import us.nineworlds.serenity.common.android.injection.InjectingJob -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.common.rest.SerenityUser -import us.nineworlds.serenity.events.users.AuthenticatedUserEvent -import javax.inject.Inject - -class AuthenticateUserJob(val user: SerenityUser) : InjectingJob() { - - @Inject - lateinit var client: SerenityClient - - var eventBus = EventBus.getDefault() - - override fun onAdded() { - } - - @Throws(Throwable::class) - override fun onRun() { - val authenticatedUser = client.authenticateUser(user) - - eventBus.post(AuthenticatedUserEvent(authenticatedUser)) - } - - override fun onCancel(cancelReason: Int, throwable: Throwable?) { - } - - override fun shouldReRunOnThrowable(throwable: Throwable, runCount: Int, maxRunCount: Int): RetryConstraint? { - return null - } -} diff --git a/serenity-app/src/main/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerPresenter.kt b/serenity-app/src/main/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerPresenter.kt index af0fbb89b..5e7f64333 100644 --- a/serenity-app/src/main/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerPresenter.kt +++ b/serenity-app/src/main/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerPresenter.kt @@ -4,8 +4,10 @@ import android.view.View import com.birbit.android.jobqueue.JobManager import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.ui.PlayerControlView +import kotlinx.coroutines.launch import moxy.InjectViewState import moxy.MvpPresenter +import moxy.presenterScope import moxy.viewstate.strategy.SkipStrategy import moxy.viewstate.strategy.StateStrategyType import org.greenrobot.eventbus.EventBus @@ -21,10 +23,6 @@ import us.nineworlds.serenity.core.model.VideoContentInfo import us.nineworlds.serenity.core.util.AndroidHelper import us.nineworlds.serenity.events.video.OnScreenDisplayEvent import us.nineworlds.serenity.injection.ForVideoQueue -import us.nineworlds.serenity.jobs.video.StartPlaybackJob -import us.nineworlds.serenity.jobs.video.StopPlaybackJob -import us.nineworlds.serenity.jobs.video.UpdatePlaybackPostionJob -import us.nineworlds.serenity.jobs.video.WatchedStatusJob import us.nineworlds.serenity.ui.video.player.ExoplayerContract.ExoplayerPresenter import us.nineworlds.serenity.ui.video.player.ExoplayerContract.ExoplayerView import java.util.LinkedList @@ -54,6 +52,9 @@ class ExoplayerPresenter : MvpPresenter(), ExoplayerPresenter, @Inject internal lateinit var androidHelper: AndroidHelper + @Inject + internal lateinit var playbackRepository: PlaybackRepository + internal lateinit var video: VideoContentInfo private var onScreenControllerShowing: Boolean = false @@ -70,7 +71,9 @@ class ExoplayerPresenter : MvpPresenter(), ExoplayerPresenter, } override fun updateWatchedStatus() { - jobManager.addJobInBackground(WatchedStatusJob(video.id())) + presenterScope.launch { + playbackRepository.watched(video.id()) + } } override fun onPositionDiscontinuity(reason: Int) = Unit @@ -93,11 +96,15 @@ class ExoplayerPresenter : MvpPresenter(), ExoplayerPresenter, override fun videoId(): String = video.id() override fun stopPlaying(currentPosition: Long) { - jobManager.addJobInBackground(StopPlaybackJob(video.id(), currentPosition)) + presenterScope.launch { + playbackRepository.stopPlaying(video.id(), currentPosition) + } } override fun startPlaying() { - jobManager.addJobInBackground(StartPlaybackJob(video.id())) + presenterScope.launch { + playbackRepository.startPlaying(video.id()) + } } override fun onVisibilityChange(visibility: Int) { @@ -124,8 +131,10 @@ class ExoplayerPresenter : MvpPresenter(), ExoplayerPresenter, } override fun updateServerPlaybackPosition(currentPostion: Long) { - video.resumeOffset = currentPostion.toInt() - jobManager.addJobInBackground(UpdatePlaybackPostionJob(video)) + presenterScope.launch { + video.resumeOffset = currentPostion.toInt() + playbackRepository.updatePlaybackPosition(video) + } } override fun playBackFromVideoQueue(autoResume: Boolean) { diff --git a/serenity-app/src/main/kotlin/us/nineworlds/serenity/ui/video/player/PlaybackRepository.kt b/serenity-app/src/main/kotlin/us/nineworlds/serenity/ui/video/player/PlaybackRepository.kt new file mode 100644 index 000000000..b32d6d1bf --- /dev/null +++ b/serenity-app/src/main/kotlin/us/nineworlds/serenity/ui/video/player/PlaybackRepository.kt @@ -0,0 +1,35 @@ +package us.nineworlds.serenity.ui.video.player + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import toothpick.InjectConstructor +import us.nineworlds.serenity.common.rest.SerenityClient +import us.nineworlds.serenity.core.model.VideoContentInfo + +@InjectConstructor +class PlaybackRepository(private val serenityClient: SerenityClient) { + + suspend fun startPlaying(videoId: String) = withContext(Dispatchers.IO) { + serenityClient.startPlaying(videoId) + } + + suspend fun stopPlaying(videoId: String, offset: Long) = withContext(Dispatchers.IO){ + serenityClient.stopPlaying(videoId, offset) + } + + suspend fun updatePlaybackPosition(video: VideoContentInfo) = withContext(Dispatchers.IO){ + val videoId: String = video.id() + if (video.isWatched()) { + serenityClient.watched(videoId) + serenityClient.progress(videoId, "0") + } else { + serenityClient.progress(videoId, video.getResumeOffset().toString()) + } + } + + suspend fun watched(videoId: String) = withContext(Dispatchers.IO) { + serenityClient.watched(videoId) + } + + +} \ No newline at end of file diff --git a/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/MovieMediaContainerTest.java b/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/MovieMediaContainerTest.java index 9ae91964a..d2fda1d61 100644 --- a/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/MovieMediaContainerTest.java +++ b/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/MovieMediaContainerTest.java @@ -33,6 +33,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; @@ -46,9 +47,8 @@ import us.nineworlds.serenity.emby.model.MediaContainer; import us.nineworlds.serenity.emby.model.Video; import us.nineworlds.serenity.test.InjectingTest; -import us.nineworlds.serenity.testrunner.PlainAndroidRunner; -@RunWith(PlainAndroidRunner.class) +@RunWith(RobolectricTestRunner.class) @Ignore("Rework so that it doesn't use xml serialization") public class MovieMediaContainerTest extends InjectingTest { diff --git a/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/SeasonsMediaContainerTest.java b/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/SeasonsMediaContainerTest.java index bcf4220b3..4c9cc909e 100644 --- a/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/SeasonsMediaContainerTest.java +++ b/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/SeasonsMediaContainerTest.java @@ -33,6 +33,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; @@ -47,9 +48,8 @@ import us.nineworlds.serenity.emby.model.MediaContainer; import us.nineworlds.serenity.emby.model.Video; import us.nineworlds.serenity.test.InjectingTest; -import us.nineworlds.serenity.testrunner.PlainAndroidRunner; -@RunWith(PlainAndroidRunner.class) +@RunWith(RobolectricTestRunner.class) @Ignore("Rework to not require xml serialization") public class SeasonsMediaContainerTest extends InjectingTest { diff --git a/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/SeriesMediaContainerTest.java b/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/SeriesMediaContainerTest.java index eb8998761..4e58fc99e 100644 --- a/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/SeriesMediaContainerTest.java +++ b/serenity-app/src/test/java/us/nineworlds/serenity/core/model/impl/SeriesMediaContainerTest.java @@ -33,6 +33,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; @@ -47,9 +48,8 @@ import us.nineworlds.serenity.emby.model.MediaContainer; import us.nineworlds.serenity.emby.model.Video; import us.nineworlds.serenity.test.InjectingTest; -import us.nineworlds.serenity.testrunner.PlainAndroidRunner; -@RunWith(PlainAndroidRunner.class) +@RunWith(RobolectricTestRunner.class) @Ignore("Rework to not use XML Serialization") public class SeriesMediaContainerTest extends InjectingTest { diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/MockkTestingModule.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/MockkTestingModule.kt new file mode 100644 index 000000000..b903586a4 --- /dev/null +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/MockkTestingModule.kt @@ -0,0 +1,28 @@ +package us.nineworlds.serenity + +import android.content.Context +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import com.birbit.android.jobqueue.JobManager +import io.mockk.mockk +import toothpick.config.Module +import us.nineworlds.serenity.common.rest.SerenityClient +import us.nineworlds.serenity.core.logger.Logger +import us.nineworlds.serenity.core.util.AndroidHelper + +class MockkTestingModule : Module() { + companion object { + val mockJobManager: JobManager = mockk(relaxed = true) + val mockPlexAppFactory: SerenityClient = mockk(relaxed = true) + val mockLocalBroadcastManager: LocalBroadcastManager = mockk(relaxed = true) + var mockLogger: Logger = mockk(relaxed = true) + var mockAndroidHelper: AndroidHelper = mockk(relaxed = true) + } + + init { + bind(JobManager::class.java).toInstance(mockJobManager) + bind(SerenityClient::class.java).toInstance(mockPlexAppFactory) + bind(LocalBroadcastManager::class.java).toInstance(mockLocalBroadcastManager) + bind(Logger::class.java).toInstance(mockLogger) + bind(AndroidHelper::class.java).toInstance(mockAndroidHelper) + } +} \ No newline at end of file diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/EpisodesRetrievalJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/EpisodesRetrievalJobTest.kt deleted file mode 100644 index 258d72186..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/EpisodesRetrievalJobTest.kt +++ /dev/null @@ -1,64 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.EpisodesRetrievalEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class EpisodesRetrievalJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: EpisodesRetrievalJob - - private val expectedId: String = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = EpisodesRetrievalJob(expectedId) - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesEpisodesForTheSpecifiedId() { - job.onRun() - - verify(mockClient).retrieveEpisodes(expectedId) - } - - @Test - fun onRunFetchesEpisodesAndPostsEpisodesEvent() { - job.onRun() - - verify(mockClient).retrieveEpisodes(expectedId) - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } - -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieCategoryJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieCategoryJobTest.kt deleted file mode 100644 index 25096205d..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieCategoryJobTest.kt +++ /dev/null @@ -1,63 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.MainCategoryEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class MovieCategoryJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: MovieCategoryJob - - private val expectedVideoId: String = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = MovieCategoryJob(expectedVideoId) - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesCategoriesForTheSpecifiedId() { - job.onRun() - - verify(mockClient).retrieveCategoriesById(expectedVideoId) - } - - @Test - fun onRunFetchesCategoriesAndPostsMainCategoryEvent() { - job.onRun() - - verify(mockClient).retrieveCategoriesById(expectedVideoId) - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieRetrievalJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieRetrievalJobTest.kt deleted file mode 100644 index 696d545cb..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieRetrievalJobTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.eq -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.MovieRetrievalEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class MovieRetrievalJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: MovieRetrievalJob - - private val expectedVideoId: String = RandomStringUtils.randomAlphanumeric(5) - private val expectedCategory: String = RandomStringUtils.randomAlphabetic(10) - - @Before - override fun setUp() { - super.setUp() - job = MovieRetrievalJob(expectedVideoId, expectedCategory) - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesCategoriesForTheSpecifiedId() { - job.onRun() - - verify(mockClient).retrieveItemByIdCategory(eq(expectedVideoId), eq(expectedCategory), any()) - } - - @Test - fun onRunFetchesCategoriesAndPostsMainCategoryEvent() { - job.onRun() - - verify(mockClient).retrieveItemByIdCategory(eq(expectedVideoId), eq(expectedCategory), any()) - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } - -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieSecondaryCategoryJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieSecondaryCategoryJobTest.kt deleted file mode 100644 index 1948adeb9..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/MovieSecondaryCategoryJobTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.eq -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.MovieSecondaryCategoryEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class MovieSecondaryCategoryJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: MovieSecondaryCategoryJob - - private val expectedVideoId: String = RandomStringUtils.randomAlphanumeric(5) - private val secondaryCategory: String = RandomStringUtils.randomAlphabetic(10) - - @Before - override fun setUp() { - super.setUp() - job = MovieSecondaryCategoryJob(expectedVideoId, secondaryCategory) - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesCategoriesForTheSpecifiedId() { - job.onRun() - - verify(mockClient).retrieveItemByIdCategory(eq(expectedVideoId), eq(secondaryCategory), any()) - } - - @Test - fun onRunFetchesCategoriesAndPostsMainCategoryEvent() { - job.onRun() - - verify(mockClient).retrieveItemByIdCategory(eq(expectedVideoId), eq(secondaryCategory), any()) - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } - -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/RetrieveAllUsersJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/RetrieveAllUsersJobTest.kt deleted file mode 100644 index 1ac1d77aa..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/RetrieveAllUsersJobTest.kt +++ /dev/null @@ -1,61 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.verify -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.users.AllUsersEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class RetrieveAllUsersJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: RetrieveAllUsersJob - - @Before - override fun setUp() { - super.setUp() - job = RetrieveAllUsersJob() - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesAllPublicUsersFromServer() { - job.onRun() - - verify(mockClient).allAvailableUsers() - } - - @Test - fun onRunPostsAllUsersEvent() { - job.onRun() - - verify(mockClient).allAvailableUsers() - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } - -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/SeasonsRetrievalJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/SeasonsRetrievalJobTest.kt deleted file mode 100644 index 24a047176..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/SeasonsRetrievalJobTest.kt +++ /dev/null @@ -1,64 +0,0 @@ -package us.nineworlds.serenity.jobs - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.SeasonsRetrievalEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(AndroidJUnit4::class) -class SeasonsRetrievalJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: SeasonsRetrievalJob - - private val expectedId: String = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = SeasonsRetrievalJob(expectedId) - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesCategoriesForTheSpecifiedId() { - job.onRun() - - verify(mockClient).retrieveSeasons(expectedId) - } - - @Test - fun onRunFetchesCategoriesAndPostsMainCategoryEvent() { - job.onRun() - - verify(mockClient).retrieveSeasons(expectedId) - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } - -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVCategoryJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVCategoryJobTest.kt deleted file mode 100644 index 5a4dd6f57..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVCategoryJobTest.kt +++ /dev/null @@ -1,64 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.TVCategoryEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class TVCategoryJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: TVCategoryJob - - private val expectedId: String = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = TVCategoryJob(expectedId) - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesCategoriesForTheSpecifiedId() { - job.onRun() - - verify(mockClient).retrieveSeriesCategoryById(expectedId) - } - - @Test - fun onRunFetchesCategoriesAndPostsMainCategoryEvent() { - job.onRun() - - verify(mockClient).retrieveSeriesCategoryById(expectedId) - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } - -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVCategorySecondaryJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVCategorySecondaryJobTest.kt deleted file mode 100644 index b815cfc16..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVCategorySecondaryJobTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.eq -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.TVCategorySecondaryEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class TVCategorySecondaryJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: TVCategorySecondaryJob - - private val expectedVideoId: String = RandomStringUtils.randomAlphanumeric(5) - private val secondaryCategory: String = RandomStringUtils.randomAlphabetic(10) - - @Before - override fun setUp() { - super.setUp() - job = TVCategorySecondaryJob(expectedVideoId, secondaryCategory) - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesCategoriesForTheSpecifiedId() { - job.onRun() - - verify(mockClient).retrieveItemByIdCategory(eq(expectedVideoId), eq(secondaryCategory), any()) - } - - @Test - fun onRunFetchesCategoriesAndPostsMainCategoryEvent() { - job.onRun() - - verify(mockClient).retrieveItemByIdCategory(eq(expectedVideoId), eq(secondaryCategory), any()) - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } - -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVShowsRetrievalJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVShowsRetrievalJobTest.kt deleted file mode 100644 index ca2c0173a..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/TVShowsRetrievalJobTest.kt +++ /dev/null @@ -1,64 +0,0 @@ -package us.nineworlds.serenity.jobs - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.events.TVShowRetrievalEvent -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class TVShowsRetrievalJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: TVShowRetrievalJob - - private val expectedVideoId: String = RandomStringUtils.randomAlphanumeric(5) - private val expectedCategory: String = RandomStringUtils.randomAlphabetic(10) - - @Before - override fun setUp() { - super.setUp() - job = TVShowRetrievalJob(expectedVideoId, expectedCategory) - job.eventBus = mockEventBus - } - - @Test - fun onRunFetchesTVShowsFromServer() { - job.onRun() - - verify(mockClient).retrieveSeriesById(expectedVideoId, expectedCategory) - } - - @Test - fun onRunFetchesTVShowsByCategoryAndPostsTVShowRetrievalEvent() { - job.onRun() - - verify(mockClient).retrieveSeriesById(expectedVideoId, expectedCategory) - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/AuthenticateUserJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/AuthenticateUserJobTest.kt deleted file mode 100644 index 17870351d..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/AuthenticateUserJobTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -package us.nineworlds.serenity.jobs.videos - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.greenrobot.eventbus.EventBus -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.common.rest.SerenityUser -import us.nineworlds.serenity.events.users.AuthenticatedUserEvent -import us.nineworlds.serenity.jobs.AuthenticateUserJob -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class AuthenticateUserJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Mock - lateinit var mockUser: SerenityUser - - @Inject - lateinit var mockClient: SerenityClient - - @Mock - lateinit var mockEventBus: EventBus - - lateinit var job: AuthenticateUserJob - - val expectedVideoId = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = AuthenticateUserJob(mockUser) - job.eventBus = mockEventBus - } - - @Test - fun onRunAuthenticatesUser() { - - job.onRun() - - verify(mockClient).authenticateUser(mockUser) - } - - @Test - fun onRunPostsAuthenticationEvent() { - job.onRun() - - verify(mockEventBus).post(any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/StartPlaybackJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/StartPlaybackJobTest.kt deleted file mode 100644 index 8c475b3d4..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/StartPlaybackJobTest.kt +++ /dev/null @@ -1,52 +0,0 @@ -package us.nineworlds.serenity.jobs.videos - -import com.nhaarman.mockitokotlin2.doNothing -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever -import org.apache.commons.lang3.RandomStringUtils -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyString -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.jobs.video.StartPlaybackJob -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class StartPlaybackJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - lateinit var job: StartPlaybackJob - - val expectedVideoId = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = StartPlaybackJob(expectedVideoId) - } - - @Test - fun onRunNotifiesServerThatPlaybackHasStarted() { - doNothing().whenever(mockClient).startPlaying(anyString()) - job.onRun() - - verify(mockClient).startPlaying(expectedVideoId) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/StopPlaybackJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/StopPlaybackJobTest.kt deleted file mode 100644 index a548aa975..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/StopPlaybackJobTest.kt +++ /dev/null @@ -1,55 +0,0 @@ -package us.nineworlds.serenity.jobs.videos - -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.doNothing -import com.nhaarman.mockitokotlin2.eq -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever -import org.apache.commons.lang3.RandomStringUtils -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyLong -import org.mockito.ArgumentMatchers.anyString -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.jobs.video.StopPlaybackJob -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class StopPlaybackJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - lateinit var job: StopPlaybackJob - - val expectedVideoId = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = StopPlaybackJob(expectedVideoId, 55) - } - - @Test - fun onRunNotifiesServerThatPlaybackHasStopped() { - doNothing().whenever(mockClient).stopPlaying(anyString(), anyLong()) - job.onRun() - - verify(mockClient).stopPlaying(eq(expectedVideoId), any()) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/UpdatePlaybackPositionJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/UpdatePlaybackPositionJobTest.kt deleted file mode 100644 index 2cf57655c..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/UpdatePlaybackPositionJobTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -package us.nineworlds.serenity.jobs.videos - -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever -import org.apache.commons.lang3.RandomStringUtils -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.core.model.impl.MoviePosterInfo -import us.nineworlds.serenity.jobs.video.UpdatePlaybackPostionJob -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class UpdatePlaybackPositionJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Mock - lateinit var mockVideoContentInfo: MoviePosterInfo - @Inject - lateinit var mockClient: SerenityClient - - lateinit var job: UpdatePlaybackPostionJob - - val expectedVideoId = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = UpdatePlaybackPostionJob(mockVideoContentInfo) - } - - @Test - fun onRunNotifiesServerThatPlaybackHasStopped() { - doReturn(expectedVideoId).whenever(mockVideoContentInfo).id() - doReturn(2000).whenever(mockVideoContentInfo).resumeOffset - - job.onRun() - - verify(mockClient).progress(expectedVideoId, "2000") - } - - @Test - fun onRunNotifiesServerThatVideHasBeenWatchedAndResetsResumeOffsetToZero() { - doReturn(expectedVideoId).whenever(mockVideoContentInfo).id() - doReturn(true).whenever(mockVideoContentInfo).isWatched - - job.onRun() - - verify(mockClient).watched(expectedVideoId) - verify(mockClient).progress(expectedVideoId, "0") - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/WatchedStatusJobTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/WatchedStatusJobTest.kt deleted file mode 100644 index fa8c0cf57..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/jobs/videos/WatchedStatusJobTest.kt +++ /dev/null @@ -1,48 +0,0 @@ -package us.nineworlds.serenity.jobs.videos - -import com.nhaarman.mockitokotlin2.verify -import org.apache.commons.lang3.RandomStringUtils -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS -import org.robolectric.RobolectricTestRunner -import us.nineworlds.serenity.TestingModule -import us.nineworlds.serenity.common.rest.SerenityClient -import us.nineworlds.serenity.jobs.video.WatchedStatusJob -import us.nineworlds.serenity.test.InjectingTest -import javax.inject.Inject - -@RunWith(RobolectricTestRunner::class) -class WatchedStatusJobTest : InjectingTest() { - - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Inject - lateinit var mockClient: SerenityClient - - lateinit var job: WatchedStatusJob - - val expectedVideoId = RandomStringUtils.randomAlphanumeric(5) - - @Before - override fun setUp() { - super.setUp() - job = WatchedStatusJob(expectedVideoId) - } - - @Test - fun onRunNotifiesServerThatVideoHasBeenWatched() { - job.onRun() - - verify(mockClient).watched(expectedVideoId) - } - - override fun installTestModules() { - scope.installTestModules(TestingModule()) - } -} diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/testrunner/PlainAndroidRunner.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/testrunner/PlainAndroidRunner.kt deleted file mode 100644 index 803361f73..000000000 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/testrunner/PlainAndroidRunner.kt +++ /dev/null @@ -1,32 +0,0 @@ -package us.nineworlds.serenity.testrunner - -import org.junit.runners.model.FrameworkMethod -import org.junit.runners.model.InitializationError -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import org.robolectric.internal.SandboxTestRunner -import org.robolectric.internal.bytecode.Sandbox - -import java.lang.reflect.Method - -class PlainAndroidRunner @Throws(InitializationError::class) -constructor(testClass: Class<*>) : RobolectricTestRunner(testClass) { - - override fun afterTest(method: FrameworkMethod, bootstrappedMethod: Method?) {} - - @Throws(Throwable::class) - override fun beforeTest(sandbox: Sandbox, method: FrameworkMethod, bootstrappedMethod: Method?) { - } - - override fun getHelperTestRunner(bootstrappedTestClass: Class<*>): org.robolectric.internal.SandboxTestRunner.HelperTestRunner { - try { - return SandboxTestRunner.HelperTestRunner(bootstrappedTestClass) - } catch (initializationError: InitializationError) { - throw RuntimeException(initializationError) - } - } - - override fun buildGlobalConfig(): Config { - return Config.Builder().setManifest(Config.NONE).build() - } -} \ No newline at end of file diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/ServerSelectionActivityTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/ServerSelectionActivityTest.kt index fccf3e880..69169d530 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/ServerSelectionActivityTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/ServerSelectionActivityTest.kt @@ -4,24 +4,21 @@ import android.content.SharedPreferences import android.preference.PreferenceManager import android.widget.TextView import androidx.test.core.app.ApplicationProvider -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.whenever +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.mockk import org.assertj.android.api.Assertions import org.assertj.core.api.Assertions.assertThat +import org.junit.After import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import org.robolectric.Shadows.shadowOf -import org.robolectric.annotation.LooperMode import toothpick.config.Module +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.R -import us.nineworlds.serenity.TestingModule import us.nineworlds.serenity.common.Server import us.nineworlds.serenity.core.util.StringPreference import us.nineworlds.serenity.injection.ForMediaServers @@ -36,26 +33,25 @@ import java.util.UUID import java.util.concurrent.ConcurrentHashMap @RunWith(RobolectricTestRunner::class) -@LooperMode(LooperMode.Mode.LEGACY) class ServerSelectionActivityTest : InjectingTest() { + companion object { + private val mockServer = mockk(relaxed = true) + } - @Rule - @JvmField - val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Mock - lateinit var mockServer: Server - - lateinit var activity: ServerSelectionActivity + private lateinit var activity: ServerSelectionActivity @Before override fun setUp() { + clearAllMocks() super.setUp() - Robolectric.getBackgroundThreadScheduler().pause() - Robolectric.getForegroundThreadScheduler().pause() activity = Robolectric.buildActivity(ServerSelectionActivity::class.java).create().visible().get() } + @After + fun tearDown() { + activity.finish() + } + @Test fun serverDelayHandlerIsInitialized() { assertThat(activity.serverDisplayHandler).isNotNull @@ -64,7 +60,6 @@ class ServerSelectionActivityTest : InjectingTest() { @Test fun createServerListHidesProgressBarAndDisplaysServerContainer() { Robolectric.flushForegroundThreadScheduler() - Robolectric.flushBackgroundThreadScheduler() Assertions.assertThat(activity.progressBinding.dataLoadingContainer).isGone Assertions.assertThat(activity.binding.serverContainer).isVisible @@ -75,10 +70,9 @@ class ServerSelectionActivityTest : InjectingTest() { val expectedId = UUID.randomUUID().toString() activity.servers[expectedId] = mockServer - doReturn("Emby").whenever(mockServer).discoveryProtocol() - doReturn("test").whenever(mockServer).serverName + every { mockServer.discoveryProtocol() } returns "Emby" + every { mockServer.serverName } returns "test" - Robolectric.flushBackgroundThreadScheduler() Robolectric.flushForegroundThreadScheduler() Assertions.assertThat(activity.binding.serverContainer).hasChildCount(3) @@ -87,7 +81,6 @@ class ServerSelectionActivityTest : InjectingTest() { @Test fun refreshButtonIsOnlyItemWhenServerListIsEmpty() { Robolectric.flushForegroundThreadScheduler() - Robolectric.flushForegroundThreadScheduler() assertThat(activity.servers).isEmpty() Assertions.assertThat(activity.binding.serverContainer).hasChildCount(2); @@ -98,10 +91,9 @@ class ServerSelectionActivityTest : InjectingTest() { val expectedId = UUID.randomUUID().toString() activity.servers[expectedId] = mockServer - doReturn("Emby").whenever(mockServer).discoveryProtocol() - doReturn("test").whenever(mockServer).serverName + every { mockServer.discoveryProtocol() } returns "Emby" + every { mockServer.serverName } returns "test" - Robolectric.flushBackgroundThreadScheduler() Robolectric.flushForegroundThreadScheduler() val view = activity.binding.serverContainer.getChildAt(1) @@ -115,11 +107,10 @@ class ServerSelectionActivityTest : InjectingTest() { val expectedId = UUID.randomUUID().toString() activity.servers[expectedId] = mockServer - doReturn("Emby").whenever(mockServer).discoveryProtocol() - doReturn("test").whenever(mockServer).serverName - doReturn("testserver").whenever(mockServer).ipAddress + every { mockServer.discoveryProtocol() } returns "Emby" + every { mockServer.serverName } returns "test" + every { mockServer.ipAddress } returns "testserver" - Robolectric.flushBackgroundThreadScheduler() Robolectric.flushForegroundThreadScheduler() val view = activity.binding.serverContainer.getChildAt(1) @@ -130,7 +121,7 @@ class ServerSelectionActivityTest : InjectingTest() { } override fun installTestModules() { - scope.installTestModules(TestingModule(), TestModule()) + scope.installTestModules(MockkTestingModule(), TestModule()) } inner class TestModule : Module() { diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginRepositoryTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginRepositoryTest.kt index 7248a76e7..b41b13e6d 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginRepositoryTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginRepositoryTest.kt @@ -2,14 +2,15 @@ package us.nineworlds.serenity.ui.activity.login import assertk.assertThat import assertk.assertions.isEqualTo -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.setMain import org.junit.After import org.junit.Before @@ -19,15 +20,19 @@ import us.nineworlds.serenity.common.rest.SerenityClient import us.nineworlds.serenity.common.rest.SerenityUser import us.nineworlds.serenity.core.repository.LoginRepository +@OptIn(ExperimentalCoroutinesApi::class) class LoginRepositoryTest { - private val mockSerenityClient = mock() - private val mockSerenityUser = mock() + private companion object { + private val mockSerenityClient = mockk() + private val mockSerenityUser = mockk() + } private lateinit var repository: LoginRepository @Before fun setUp() { + clearAllMocks() Dispatchers.setMain(Dispatchers.Unconfined) repository = LoginRepository(mockSerenityClient) } @@ -38,29 +43,26 @@ class LoginRepositoryTest { } @Test - fun testLoadAllUsersWithSuccess() { + fun testLoadAllUsersWithSuccess() = runTest(UnconfinedTestDispatcher()) { val expectedResult = listOf(mockSerenityUser) - doReturn(expectedResult).whenever(mockSerenityClient).allAvailableUsers() + every { mockSerenityClient.allAvailableUsers() } returns expectedResult - val result = runBlocking { - repository.loadAllUsers() - } + val result = repository.loadAllUsers() assertThat((result as Result.Success>).data).isEqualTo(expectedResult) - verify(mockSerenityClient).allAvailableUsers() + + verify { mockSerenityClient.allAvailableUsers() } } @Test - fun testAuthenticateUser() { + fun testAuthenticateUser() = runTest(UnconfinedTestDispatcher()) { val expectedResult = mockSerenityUser - doReturn(expectedResult).whenever(mockSerenityClient).authenticateUser(any()) + every { mockSerenityClient.authenticateUser(any()) } returns expectedResult - val result = runBlocking { - repository.authenticateUser(expectedResult) - } + val result = repository.authenticateUser(expectedResult) assertThat((result as Result.Success).data).isEqualTo(expectedResult) - verify(mockSerenityClient).authenticateUser(mockSerenityUser) + verify { mockSerenityClient.authenticateUser(expectedResult) } } } \ No newline at end of file diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserActivityTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserActivityTest.kt index 914ee0f95..ec1f87255 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserActivityTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserActivityTest.kt @@ -2,26 +2,25 @@ package us.nineworlds.serenity.ui.activity.login import android.content.Intent import android.view.View.VISIBLE +import assertk.assertThat +import assertk.assertions.isEqualTo +import assertk.assertions.isNotNull +import assertk.assertions.isInstanceOf import com.google.android.flexbox.FlexboxLayoutManager -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.verify +import io.mockk.clearAllMocks +import io.mockk.mockk +import io.mockk.verify import org.assertj.android.api.Assertions -import org.assertj.core.api.Assertions.assertThat import org.junit.After import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoRule -import org.mockito.quality.Strictness import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import org.robolectric.Shadows.shadowOf import toothpick.config.Module import us.nineworlds.serenity.AndroidTV -import us.nineworlds.serenity.TestingModule +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.common.Server import us.nineworlds.serenity.common.rest.SerenityUser import us.nineworlds.serenity.test.InjectingTest @@ -29,23 +28,18 @@ import us.nineworlds.serenity.test.InjectingTest @RunWith(RobolectricTestRunner::class) class LoginUserActivityTest : InjectingTest() { - @Rule - @JvmField - var mockitoRule: MockitoRule = MockitoJUnit.rule().strictness(Strictness.LENIENT) - - @Mock - lateinit var mockPresenter: LoginUserPresenter - @Mock - lateinit var mockServer: Server - @Mock - lateinit var mockSerenityUser: SerenityUser - @Mock - lateinit var mockAdapter: LoginUserAdapter + private companion object { + private val mockPresenter = mockk(relaxed = true) + private val mockServer = mockk(relaxed = true) + private val mockSerenityUser = mockk(relaxed = true) + private val mockAdapter = mockk(relaxed = true) + } - lateinit var activity: LoginUserActivity + private lateinit var activity: LoginUserActivity @Before override fun setUp() { + clearAllMocks() super.setUp() val intent = Intent() @@ -66,11 +60,14 @@ class LoginUserActivityTest : InjectingTest() { @Test fun profileContainerHasContainerSetup() { - assertThat(activity.binding.loginUserContainer).isNotNull - assertThat(activity.binding.loginUserContainer.layoutManager).isInstanceOf(FlexboxLayoutManager::class.java) + assertThat(activity.binding.loginUserContainer).isNotNull() + assertThat(activity.binding.loginUserContainer.layoutManager).isNotNull().isInstanceOf(FlexboxLayoutManager::class) + + verify { + mockPresenter.initPresenter(mockServer) + mockPresenter.retrieveAllUsers() + } - verify(mockPresenter).initPresenter(mockServer) - verify(mockPresenter).retrieveAllUsers() } @Test @@ -80,7 +77,10 @@ class LoginUserActivityTest : InjectingTest() { activity.displayUsers(mutableListOf(mockSerenityUser).toList()) Assertions.assertThat(activity.progressBinding.dataLoadingContainer).isGone - verify(mockAdapter).loadUsers(any()) + + verify { + mockAdapter.loadUsers(any()) + } } @Test @@ -92,7 +92,7 @@ class LoginUserActivityTest : InjectingTest() { } override fun installTestModules() { - scope.installTestModules(TestingModule(), TestModule()) + scope.installTestModules(MockkTestingModule(), TestModule()) } inner class TestModule : Module() { diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserAdapterTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserAdapterTest.kt index e82f4ea9e..bfb040872 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserAdapterTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserAdapterTest.kt @@ -10,39 +10,34 @@ import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isInstanceOf import assertk.assertions.isNotNull -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.atMost -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness import org.robolectric.RobolectricTestRunner import org.robolectric.Shadows.shadowOf +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.R -import us.nineworlds.serenity.TestingModule import us.nineworlds.serenity.common.rest.SerenityUser import us.nineworlds.serenity.test.InjectingTest @RunWith(RobolectricTestRunner::class) class LoginUserAdapterTest : InjectingTest() { - @get:Rule - val rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS) - - private val mockPresenter = mock() - private val mockUser = mock() - private val mockViewHolder = mock() + private companion object { + private val mockPresenter = mockk(relaxed = true) + private val mockUser = mockk(relaxed = true) + private val mockViewHolder = mockk(relaxed = true) + } private lateinit var adapter: LoginUserAdapter @Before override fun setUp() { + clearAllMocks() super.setUp() adapter = LoginUserAdapter(mockPresenter) } @@ -67,13 +62,13 @@ class LoginUserAdapterTest : InjectingTest() { fun onBindViewHolderLoadsTheUserIntoTheView() { val view = FrameLayout(ApplicationProvider.getApplicationContext()) - doReturn(view).whenever(mockViewHolder).getItemView() + every { mockViewHolder.getItemView() } returns view adapter.loadUsers(mutableListOf(mockUser)) adapter.onBindViewHolder(mockViewHolder, 0) - verify(mockViewHolder).loadUser(mockUser) + verify { mockViewHolder.loadUser(mockUser) } val shadowView = shadowOf(view) assertThat(shadowView.onClickListener).isNotNull() @@ -85,40 +80,47 @@ class LoginUserAdapterTest : InjectingTest() { adapter.loadUsers(mutableListOf(mockUser)) adapter.onClicked(0) - verify(mockPresenter).loadUser(mockUser) + verify { mockPresenter.loadUser(mockUser) } } @Test fun onFocusedChangeListenerUpdatesViewSelectionStateWithOutFocus() { - val mockView = mock() + val mockView = mockk(relaxed = true) adapter.loadUsers(mutableListOf(mockUser)) adapter.onFocusChanged(mockView, false) - verify(mockView).clearAnimation() - verify(mockView).background = null + verify { + mockView.clearAnimation() + mockView.background = null + } } @Test fun onFocusedChangeListenerUpdatesViewSelectionStateWithFocus() { - val mockView = mock() + val mockView = mockk(relaxed = true) val context = ContextThemeWrapper( ApplicationProvider.getApplicationContext(), R.style.AppTheme ) - doReturn(context).whenever(mockView).context + every { mockView.context } returns context adapter.loadUsers(mutableListOf(mockUser)) adapter.onFocusChanged(mockView, true) - verify(mockView, atMost(2)).clearAnimation() - verify(mockView).background = null - verify(mockView).context - verify(mockView).background = any() + verify(atMost = 2) { + mockView.clearAnimation() + } + + verify { + mockView.background = null + mockView.context + mockView.background = any() + } } override fun installTestModules() { - scope.installTestModules(TestingModule()) + scope.installTestModules(MockkTestingModule()) } } \ No newline at end of file diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserPresenterTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserPresenterTest.kt index 5e526bdda..c6ebec7ef 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserPresenterTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserPresenterTest.kt @@ -1,26 +1,24 @@ package us.nineworlds.serenity.ui.activity.login -import com.birbit.android.jobqueue.JobManager -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.atLeastOnce -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever +import io.mockk.clearAllMocks +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.setMain import org.junit.After import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness.STRICT_STUBS import org.robolectric.RobolectricTestRunner import toothpick.config.Module -import us.nineworlds.serenity.TestingModule +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.common.Server import us.nineworlds.serenity.common.repository.Result import us.nineworlds.serenity.common.rest.SerenityClient @@ -29,35 +27,25 @@ import us.nineworlds.serenity.core.repository.LoginRepository import us.nineworlds.serenity.test.InjectingTest import javax.inject.Inject +@OptIn(ExperimentalCoroutinesApi::class) @RunWith(RobolectricTestRunner::class) class LoginUserPresenterTest : InjectingTest() { - @Rule - @JvmField - val rule = MockitoJUnit.rule().strictness(STRICT_STUBS) - - @Mock - lateinit var mockView: LoginUserContract.LoginUserView - - @Mock - lateinit var mockServer: Server - - @Mock - lateinit var mockSerenityUser: SerenityUser - - @Mock - lateinit var mockRepository: LoginRepository + private companion object { + private val mockView: LoginUserContract.LoginUserView = mockk(relaxed = true) + private val mockServer = mockk(relaxed = true) + private val mockSerenityUser = mockk(relaxed = true) + private val mockRepository = mockk(relaxed = true) + } @Inject lateinit var mockSerenityClient: SerenityClient - @Inject - lateinit var mockJobManager: JobManager - - lateinit var presenter: LoginUserPresenter + private lateinit var presenter: LoginUserPresenter @Before override fun setUp() { + clearAllMocks() super.setUp() presenter = LoginUserPresenter() Dispatchers.setMain(Dispatchers.Unconfined) @@ -70,51 +58,51 @@ class LoginUserPresenterTest : InjectingTest() { @Test fun initPresenterUpdatesClientWithExpectedUrl() { - doReturn("192.168.0.1").whenever(mockServer).ipAddress + every { mockServer.ipAddress } returns "192.168.0.1" presenter.initPresenter(mockServer) - verify(mockSerenityClient).updateBaseUrl("http://192.168.0.1:8096/") - verify(mockServer).ipAddress + verify { mockSerenityClient.updateBaseUrl(any()) } + verify { mockServer.ipAddress } } @Test fun initPresenterUpdatesClientWithExpectedUrlWhenServerPortIsNotNull() { - doReturn("9999").whenever(mockServer).port - doReturn("192.168.0.1").whenever(mockServer).ipAddress + every { mockServer.port } returns "9999" + every { mockServer.ipAddress } returns "192.168.0.1" presenter.initPresenter(mockServer) - verify(mockSerenityClient).updateBaseUrl("http://192.168.0.1:9999/") - verify(mockServer).ipAddress - verify(mockServer, atLeastOnce()).port + verify { mockSerenityClient.updateBaseUrl("http://192.168.0.1:9999/") } + verify { mockServer.ipAddress } + verify(atLeast = 1) { mockServer.port } } @Test - fun allUsersJobIsCreatedAndAddedToJobManager() = runBlocking { + fun allUsersJobIsCreatedAndAddedToJobManager() = runTest(UnconfinedTestDispatcher()) { val expectedUsers = listOf(mockSerenityUser) - doReturn(Result.Success(expectedUsers)).whenever(mockRepository).loadAllUsers() + coEvery { mockRepository.loadAllUsers() } returns Result.Success(expectedUsers) presenter.attachView(mockView) presenter.retrieveAllUsers() - verify(mockRepository).loadAllUsers() - verify(mockView).displayUsers(expectedUsers) + coVerify { mockRepository.loadAllUsers() } + verify { mockView.displayUsers(expectedUsers) } } @Test - fun loadUserAddsJob() = runBlocking { - doReturn(Result.Success(mockSerenityUser)).whenever(mockRepository).authenticateUser(any()) + fun loadUserAddsJob() = runTest(UnconfinedTestDispatcher()) { + coEvery { mockRepository.authenticateUser(any()) } returns Result.Success(mockSerenityUser) presenter.attachView(mockView) presenter.loadUser(mockSerenityUser) - verify(mockRepository).authenticateUser(mockSerenityUser) - verify(mockView).launchNextScreen() + coVerify { mockRepository.authenticateUser(mockSerenityUser) } + verify { mockView.launchNextScreen() } } override fun installTestModules() { - scope.installTestModules(TestingModule(), TestModule()) + scope.installTestModules(MockkTestingModule(), TestModule()) } inner class TestModule : Module() { diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserViewHolderTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserViewHolderTest.kt index 1cca7cffa..24b2ac31c 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserViewHolderTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/login/LoginUserViewHolderTest.kt @@ -5,22 +5,18 @@ import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout import androidx.test.core.app.ApplicationProvider.getApplicationContext -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.whenever +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.mockk import org.apache.commons.lang3.RandomStringUtils import org.assertj.android.api.Assertions.assertThat import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoRule -import org.mockito.quality.Strictness import org.robolectric.RobolectricTestRunner import toothpick.config.Module +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.R -import us.nineworlds.serenity.TestingModule import us.nineworlds.serenity.common.rest.SerenityClient import us.nineworlds.serenity.common.rest.SerenityUser import us.nineworlds.serenity.test.InjectingTest @@ -28,15 +24,10 @@ import us.nineworlds.serenity.test.InjectingTest @RunWith(RobolectricTestRunner::class) class LoginUserViewHolderTest : InjectingTest() { - @Rule - @JvmField - var mockitoRule: MockitoRule = MockitoJUnit.rule().strictness(Strictness.LENIENT) - - @Mock - internal lateinit var mockUser: SerenityUser - - @Mock - internal lateinit var mockSerenityClient: SerenityClient + private companion object { + private val mockUser = mockk(relaxed = true) + private val mockSerenityClient = mockk(relaxed = true) + } private lateinit var linearLayout: LinearLayout private lateinit var view: View @@ -44,6 +35,7 @@ class LoginUserViewHolderTest : InjectingTest() { @Before override fun setUp() { + clearAllMocks() super.setUp() val context = ContextThemeWrapper(getApplicationContext(), R.style.AppTheme) linearLayout = LinearLayout(context) @@ -54,7 +46,7 @@ class LoginUserViewHolderTest : InjectingTest() { @Test fun loadUserSetsUserName() { val expectedUser = RandomStringUtils.randomAlphabetic(10) - doReturn(expectedUser).whenever(mockUser).userName + every { mockUser.userName } returns expectedUser viewHolder.loadUser(mockUser) @@ -62,7 +54,7 @@ class LoginUserViewHolderTest : InjectingTest() { } override fun installTestModules() { - scope.installTestModules(TestingModule(), TestModule()) + scope.installTestModules(MockkTestingModule(), TestModule()) } inner class TestModule : Module() { diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/manualentry/ManualServerActivityTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/manualentry/ManualServerActivityTest.kt index f19744aaa..378504d69 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/manualentry/ManualServerActivityTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/manualentry/ManualServerActivityTest.kt @@ -5,8 +5,8 @@ import android.view.View import androidx.test.core.app.ApplicationProvider import assertk.assertThat import assertk.assertions.isNotNull -import com.nhaarman.mockitokotlin2.spy -import com.nhaarman.mockitokotlin2.verify +import io.mockk.spyk +import io.mockk.verify import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -23,7 +23,7 @@ class ManualServerActivityTest { @Before fun setUp() { ApplicationProvider.getApplicationContext().setTheme(R.style.AppTheme) - activity = spy(Robolectric.buildActivity(ManualServerActivity::class.java).create().get()) + activity = spyk(Robolectric.buildActivity(ManualServerActivity::class.java).create().get()) } @Test @@ -34,6 +34,7 @@ class ManualServerActivityTest { @Test fun finishSetsResultToMainMenuPreferenceResultCode() { activity.finish() - verify(activity).setResult(MainActivity.MAIN_MENU_PREFERENCE_RESULT_CODE) + + verify { activity.setResult(MainActivity.MAIN_MENU_PREFERENCE_RESULT_CODE) } } } \ No newline at end of file diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/manualentry/ManualServerSettingsFragmentTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/manualentry/ManualServerSettingsFragmentTest.kt index d81d01e9d..c76ea5a75 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/manualentry/ManualServerSettingsFragmentTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/activity/manualentry/ManualServerSettingsFragmentTest.kt @@ -1,11 +1,11 @@ package us.nineworlds.serenity.ui.activity.manualentry import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.doNothing -import com.nhaarman.mockitokotlin2.spy -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever +import io.mockk.Runs +import io.mockk.every +import io.mockk.just +import io.mockk.spyk +import io.mockk.verify import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -23,16 +23,16 @@ class ManualServerSettingsFragmentTest { fun setUp() { Robolectric.getForegroundThreadScheduler().pause() - fragment = spy(ManualServerSettingsFragment()) + fragment = spyk(ManualServerSettingsFragment()) FragmentTestUtil.startFragment(fragment) } @Test fun startsInitialScreen() { - doNothing().whenever(fragment).startPreferenceFragment(any()) + every { fragment.startPreferenceFragment(any()) } just Runs fragment.onPreferenceStartInitialScreen() - verify(fragment).startPreferenceFragment(any()) + verify { fragment.startPreferenceFragment(any()) } } } \ No newline at end of file diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/leanback/search/CardPresenterTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/leanback/search/CardPresenterTest.kt index d4be0bfc7..a77efca50 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/leanback/search/CardPresenterTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/leanback/search/CardPresenterTest.kt @@ -5,21 +5,14 @@ import android.widget.LinearLayout import androidx.core.content.ContextCompat import androidx.leanback.widget.ImageCardView import androidx.test.core.app.ApplicationProvider.getApplicationContext -import com.nhaarman.mockitokotlin2.anyOrNull -import com.nhaarman.mockitokotlin2.atLeast -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.spy -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify import org.assertj.core.api.Assertions.assertThat import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import us.nineworlds.serenity.R @@ -28,18 +21,13 @@ import us.nineworlds.serenity.core.model.VideoContentInfo @RunWith(RobolectricTestRunner::class) class CardPresenterTest { - @Rule - @JvmField - public val rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS) - - @Mock - lateinit var mockImageCardView: ImageCardView - @Mock - lateinit var mockVideoContentInfo: VideoContentInfo - @Mock - lateinit var mockViewHolder: CardPresenter.CardPresenterViewHolder + private companion object { + private val mockImageCardView = mockk(relaxed = true) + private val mockVideoContentInfo = mockk(relaxed = true) + private val mockViewHolder = mockk(relaxed = true) + } - lateinit var presenter: CardPresenter + private lateinit var presenter: CardPresenter @Before fun setUp() { @@ -49,8 +37,8 @@ class CardPresenterTest { @Test fun onCreateViewHolderReturnsExpectedViewHolderInstance() { val linearLayout = LinearLayout(getApplicationContext()) - val spy = spy(presenter) - doReturn(mockImageCardView).whenever(spy).createImageView() + val spy = spyk(presenter) + every { spy.createImageView() } returns mockImageCardView val result = spy.onCreateViewHolder(linearLayout) @@ -60,33 +48,31 @@ class CardPresenterTest { @Test fun imageCardViewHasExpectedValuesSetWhenViewHolderIsCreated() { val linearLayout = LinearLayout(getApplicationContext()) - val spy = spy(presenter) - doReturn(mockImageCardView).whenever(spy).createImageView() + val spy = spyk(presenter) + every { spy.createImageView() } returns mockImageCardView spy.onCreateViewHolder(linearLayout) - verify(mockImageCardView).isFocusable = true - verify(mockImageCardView).isFocusableInTouchMode = true - verify(mockImageCardView).setBackgroundColor(ContextCompat.getColor(linearLayout.context, R.color.holo_color)) + verify { mockImageCardView.isFocusable = true } + verify { mockImageCardView.isFocusableInTouchMode = true } + verify { mockImageCardView.setBackgroundColor(ContextCompat.getColor(linearLayout.context, R.color.holo_color)) } } @Test fun onBindViewHolderSetsExpectedImageDimensions() { val activity = Robolectric.buildActivity(Activity::class.java).create().get() - val spy = spy(presenter) - doReturn(mockImageCardView).whenever(mockViewHolder).cardView - doReturn("").whenever(mockVideoContentInfo).imageURL - doReturn(activity).whenever(spy).getActivity(anyOrNull()) + val spy = spyk(presenter) + every { mockViewHolder.cardView } returns mockImageCardView + every { mockVideoContentInfo.imageURL } returns "" + every { spy.getActivity(any()) } returns activity spy.onBindViewHolder(mockViewHolder, mockVideoContentInfo) - verify(mockViewHolder).movie = mockVideoContentInfo - verify(mockVideoContentInfo, atLeast(2)).imageURL - verify(mockImageCardView).titleText = null - verify(mockImageCardView).contentText = null - verify(spy).getActivity(anyOrNull()) - verify(mockImageCardView).setMainImageDimensions(anyInt(), anyInt()) - verify(mockViewHolder).updateCardViewImage(anyOrNull()) + verify { mockViewHolder.movie = mockVideoContentInfo } + verify(atLeast = 2) { mockVideoContentInfo.imageURL } + verify { spy.getActivity(any()) } + verify { mockImageCardView.setMainImageDimensions(any(), any()) } + verify { mockViewHolder.updateCardViewImage(any()) } } @Test @@ -94,7 +80,6 @@ class CardPresenterTest { presenter.onUnbindViewHolder(mockViewHolder) - verify(mockViewHolder).reset() - + verify { mockViewHolder.reset() } } } diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/util/ImageInfographicUtilsTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/util/ImageInfographicUtilsTest.kt index 74778b18d..03861fd85 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/util/ImageInfographicUtilsTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/util/ImageInfographicUtilsTest.kt @@ -2,23 +2,25 @@ package us.nineworlds.serenity.ui.util import android.content.Context import androidx.test.core.app.ApplicationProvider -import org.assertj.core.api.Assertions.assertThat +import assertk.assertThat +import assertk.assertions.isEqualTo +import assertk.assertions.isNull import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.Shadows.shadowOf import toothpick.config.Module +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.R -import us.nineworlds.serenity.TestingModule import us.nineworlds.serenity.core.util.TimeUtil import us.nineworlds.serenity.test.InjectingTest @RunWith(RobolectricTestRunner::class) class ImageInfographicUtilsTest : InjectingTest() { - lateinit var imageInfographicUtils: ImageInfographicUtils - lateinit var context: Context + private lateinit var imageInfographicUtils: ImageInfographicUtils + private lateinit var context: Context @Before override fun setUp() { @@ -28,7 +30,7 @@ class ImageInfographicUtilsTest : InjectingTest() { } override fun installTestModules() { - scope.installTestModules(TestingModule(), TestModule()) + scope.installTestModules(MockkTestingModule(), TestModule()) } @Test diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/util/VideoPlayerIntentUtilsTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/util/VideoPlayerIntentUtilsTest.kt index 3bc2ee41a..f49a9e787 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/util/VideoPlayerIntentUtilsTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/util/VideoPlayerIntentUtilsTest.kt @@ -2,15 +2,12 @@ package us.nineworlds.serenity.ui.util import android.app.Activity import android.content.SharedPreferences +import io.mockk.mockk import org.assertj.android.api.Assertions.assertThat import org.junit.After import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.quality.Strictness import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import org.robolectric.Shadows.shadowOf @@ -27,18 +24,17 @@ class VideoPlayerIntentUtilsTest : InjectingTest() { scope.installTestModules(TestingModule()) } - @Rule @JvmField val rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS) + private lateinit var videoPlayerIntentUtils: VideoPlayerIntentUtils - lateinit var videoPlayerIntentUtils: VideoPlayerIntentUtils - - @Mock lateinit var mockSharedPreferences: SharedPreferences - @Mock lateinit var mockTimeUtil: TimeUtil - @Mock lateinit var mockVideoContentInfo: VideoContentInfo - @Mock lateinit var mockActivity : Activity + private companion object { + private val mockSharedPreferences = mockk(relaxed = true) + private val mockTimeUtil = mockk(relaxed = true) + private val mockVideoContentInfo = mockk(relaxed = true) + } - val videoQueue = LinkedList() + private val videoQueue = LinkedList() - var activity : Activity? = null + private lateinit var activity : Activity @Before fun setup() { videoQueue.clear() @@ -46,11 +42,7 @@ class VideoPlayerIntentUtilsTest : InjectingTest() { } @After fun tearDown() { - if (activity != null) { - activity!!.finish() - } - - activity = null + activity.finish() } @Test fun playVideoUsingInternalPlayerWhenExternalPlayerIsFalse() { diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerPresenterTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerPresenterTest.kt index aedf7fb7b..342d56e96 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerPresenterTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerPresenterTest.kt @@ -1,33 +1,38 @@ +@file:OptIn(ExperimentalCoroutinesApi::class) + package us.nineworlds.serenity.ui.video.player import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 +import assertk.assertThat +import assertk.assertions.isEmpty +import assertk.assertions.isEqualTo +import assertk.assertions.isFalse +import assertk.assertions.isNotNull +import assertk.assertions.isTrue import com.birbit.android.jobqueue.JobManager -import com.nhaarman.mockitokotlin2.atLeastOnce -import com.nhaarman.mockitokotlin2.doReturn -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.never -import com.nhaarman.mockitokotlin2.spy -import com.nhaarman.mockitokotlin2.verify -import com.nhaarman.mockitokotlin2.whenever +import io.mockk.clearAllMocks +import io.mockk.coVerify + +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain import org.apache.commons.lang3.RandomStringUtils -import org.assertj.core.api.Java6Assertions.assertThat import org.greenrobot.eventbus.EventBus +import org.junit.After import org.junit.Before import org.junit.Ignore -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.ArgumentMatchers.anyString -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mock -import org.mockito.Mockito.any -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoRule -import org.mockito.quality.Strictness.LENIENT import toothpick.config.Module -import us.nineworlds.serenity.TestingModule +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.common.rest.SerenityClient import us.nineworlds.serenity.core.logger.Logger import us.nineworlds.serenity.core.model.VideoContentInfo @@ -35,8 +40,6 @@ import us.nineworlds.serenity.core.model.impl.MoviePosterInfo import us.nineworlds.serenity.core.util.AndroidHelper import us.nineworlds.serenity.events.video.OnScreenDisplayEvent import us.nineworlds.serenity.injection.ForVideoQueue -import us.nineworlds.serenity.jobs.video.UpdatePlaybackPostionJob -import us.nineworlds.serenity.jobs.video.WatchedStatusJob import us.nineworlds.serenity.test.InjectingTest import java.util.LinkedList import java.util.Random @@ -45,72 +48,70 @@ import javax.inject.Inject @RunWith(AndroidJUnit4::class) class ExoplayerPresenterTest : InjectingTest() { - @Rule - @JvmField - var mockitoRule: MockitoRule = MockitoJUnit.rule().strictness(LENIENT) + private companion object { + private val mockVideoContentInfo = mockk(relaxed = true) + private val mockVideoQueue = LinkedList() + private val mockView: ExoplayerContract.ExoplayerView = mockk(relaxed = true) + private val mockEventBus: EventBus = mockk(relaxed = true) + private val mockOnScreenDisplayEvent: OnScreenDisplayEvent = mockk(relaxed = true) + private val mockAndroidHelper: AndroidHelper = mockk(relaxed = true) + private val mockPlaybackRepository: PlaybackRepository = mockk(relaxed = true) + } @Inject - lateinit var mockPlexFactory: SerenityClient - @Inject - lateinit var mockJobManager: JobManager + lateinit var mockSerenityClient: SerenityClient + @Inject lateinit var mockLogger: Logger - private var mockVideoContentInfo = mock() - private var mockVideoQueue = LinkedList() - @Mock - lateinit var mockView: ExoplayerContract.ExoplayerView - @Mock - lateinit var mockEventBus: EventBus - @Mock - lateinit var mockOnScreenDisplayEvent: OnScreenDisplayEvent - - @Mock - lateinit var mockAndroidHelper: AndroidHelper - private lateinit var presenter: ExoplayerPresenter @Before override fun setUp() { + Dispatchers.setMain(Dispatchers.Unconfined) + clearAllMocks() super.setUp() - presenter = spy(ExoplayerPresenter()) + presenter = spyk(ExoplayerPresenter()) + every { presenter.viewState } returns mockView + presenter.attachView(mockView) + } - doReturn(mockView).whenever(presenter).viewState + @After + fun tearDown() { + Dispatchers.resetMain() } @Test - fun updateWatchedStatusAddsJobToJobmanager() { + fun updateWatchedStatusUsingPlaybackRepository() = runTest(UnconfinedTestDispatcher()) { val expectedId = RandomStringUtils.randomNumeric(5) - var videoContentInfo = MoviePosterInfo() + val videoContentInfo = MoviePosterInfo() videoContentInfo.setId(expectedId) presenter.video = videoContentInfo presenter.updateWatchedStatus() - verify(mockJobManager).addJobInBackground(any(WatchedStatusJob::class.java)) + coVerify { mockPlaybackRepository.watched(any()) } } @Test fun onScreenDisplayEventShowsControllerWhenHidden() { - doReturn(false).whenever(mockOnScreenDisplayEvent).isShowing + every { mockOnScreenDisplayEvent.isShowing } returns false presenter.onOnScreenDisplayEvent(mockOnScreenDisplayEvent) - verify(mockView, never()).hideController() - verify(mockView).showController() - verify(mockOnScreenDisplayEvent).isShowing + verify(exactly = 0) { mockView.hideController() } + verify { mockView.showController() } + verify { mockOnScreenDisplayEvent.isShowing } } @Test fun onScreenDisplayEventHidesViewControlWhenShowing() { - doReturn(true).whenever(mockOnScreenDisplayEvent).isShowing - presenter.onOnScreenDisplayEvent(mockOnScreenDisplayEvent) + presenter.onOnScreenDisplayEvent(OnScreenDisplayEvent(true)) - verify(mockView).hideController() - verify(mockView, never()).showController() - verify(mockOnScreenDisplayEvent).isShowing + verify { mockView.hideController() } + verify(exactly = 0) { mockView.showController() } } @Test @@ -118,7 +119,7 @@ class ExoplayerPresenterTest : InjectingTest() { presenter.eventBus = mockEventBus presenter.detachView(mockView) - verify(mockEventBus).unregister(presenter) + verify { mockEventBus.unregister(presenter) } } @Test @@ -137,8 +138,8 @@ class ExoplayerPresenterTest : InjectingTest() { } @Test - fun updateServerPlaybackPositionSetsVideoOffestToExpectedPosition() { - var videoContentInfo = MoviePosterInfo() + fun updateServerPlaybackPositionSetsVideoOffsetToExpectedPosition() = runTest(UnconfinedTestDispatcher()){ + val videoContentInfo = MoviePosterInfo() val expectedPosition = Random().nextInt() presenter.video = videoContentInfo @@ -146,7 +147,7 @@ class ExoplayerPresenterTest : InjectingTest() { assertThat(videoContentInfo.resumeOffset).isEqualTo(expectedPosition) - verify(mockJobManager).addJobInBackground(any(UpdatePlaybackPostionJob::class.java)) + coVerify { mockPlaybackRepository.updatePlaybackPosition(any()) } } @Test @@ -154,7 +155,7 @@ class ExoplayerPresenterTest : InjectingTest() { presenter.playBackFromVideoQueue(true) assertThat(mockVideoQueue).isEmpty() - verify(mockView, never()).initializePlayer(anyString(), eq(0)) + verify (exactly = 0) { mockView.initializePlayer(any(), 0) } } @Test @@ -163,22 +164,23 @@ class ExoplayerPresenterTest : InjectingTest() { val expectedId = RandomStringUtils.randomNumeric(1) val expectedUrl = "http://www.example.com/start.mkv" - doReturn("avi").whenever(mockVideoContentInfo).container - doReturn(expectedId).whenever(mockVideoContentInfo).id() - doReturn(expectedUrl).whenever(mockPlexFactory).createTranscodeUrl(anyString(), anyInt()) + every { mockVideoContentInfo.container } returns "avi" + every { mockVideoContentInfo.id() } returns expectedId + every { mockVideoQueue.poll() } returns mockVideoContentInfo + every { mockSerenityClient.createTranscodeUrl(any(), any()) } returns expectedUrl presenter.playBackFromVideoQueue(true) - assertThat(presenter.video as VideoContentInfo).isNotNull.isEqualTo(mockVideoContentInfo) - //Truth.assertThat(presenter.video).isNotNull().isEqualTo(mockVideoContentInfo) - verify(mockVideoContentInfo, atLeastOnce()).container - verify(mockVideoContentInfo).id() - verify(mockPlexFactory).createTranscodeUrl(expectedId, 0) - verify(mockView).initializePlayer(expectedUrl, 0) + assertThat(presenter.video).isNotNull().isEqualTo(mockVideoContentInfo) + + verify(atLeast = 1) { mockVideoContentInfo.container } + verify { mockVideoContentInfo.id() } + verify { mockSerenityClient.createTranscodeUrl(expectedId, 0)} + verify { mockView.initializePlayer(expectedUrl, 0) } } override fun installTestModules() { - scope.installTestModules(TestingModule(), TestModule()) + scope.installTestModules(MockkTestingModule(), TestModule()) } inner class TestModule : Module() { @@ -187,6 +189,8 @@ class ExoplayerPresenterTest : InjectingTest() { bind(LinkedList::class.java).withName(ForVideoQueue::class.java).toInstance(mockVideoQueue) bind(EventBus::class.java).toInstance(mockEventBus) bind(AndroidHelper::class.java).toInstance(mockAndroidHelper) + bind(JobManager::class.java).toInstance(mockk(relaxed = true)) + bind(PlaybackRepository::class.java).toInstance(mockPlaybackRepository) } } } \ No newline at end of file diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerVideoActivityTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerVideoActivityTest.kt index b3882f72b..ba723215e 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerVideoActivityTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/ExoplayerVideoActivityTest.kt @@ -2,38 +2,33 @@ package us.nineworlds.serenity.ui.video.player import android.net.Uri import android.view.KeyEvent +import assertk.assertThat +import assertk.assertions.isInstanceOf +import assertk.assertions.isNotNull +import assertk.assertions.isTrue import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.SimpleExoPlayer -import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.trackselection.TrackSelectionArray import com.google.android.exoplayer2.trackselection.TrackSelector import com.google.android.exoplayer2.upstream.DataSource -import com.nhaarman.mockitokotlin2.anyOrNull -import com.nhaarman.mockitokotlin2.whenever -import org.assertj.android.api.Assertions -import org.assertj.core.api.Java6Assertions.assertThat +import io.mockk.Runs +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify import org.junit.Before import org.junit.Ignore -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.any -import org.mockito.Mockito.doNothing -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.never -import org.mockito.Mockito.spy -import org.mockito.Mockito.verify -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoRule -import org.mockito.quality.Strictness.LENIENT import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config import toothpick.Scope import toothpick.Toothpick import toothpick.config.Module -import us.nineworlds.serenity.TestingModule +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.common.annotations.InjectionConstants import us.nineworlds.serenity.core.logger.Logger import us.nineworlds.serenity.core.util.AndroidHelper @@ -47,27 +42,14 @@ import javax.inject.Inject @Config(shadows = [ShadowSubtitleView::class]) open class ExoplayerVideoActivityTest : InjectingTest() { - @Rule - @JvmField - var mockitoRule: MockitoRule = MockitoJUnit.rule().strictness(LENIENT) - - @Mock - lateinit var mockExoPlayerPresenter: ExoplayerPresenter - - @Mock - lateinit var mockDataSourceFactory: DataSource.Factory - - @Mock - lateinit var mockMappingTrackSelector: TrackSelector - - @Mock - lateinit var mockLogger: Logger - - @Mock - lateinit var mockPlayer: SimpleExoPlayer - - @Mock - lateinit var mockTimeUtil: TimeUtil + companion object { + private val mockExoPlayerPresenter = mockk(relaxed = true) + private val mockDataSourceFactory = mockk(relaxed = true) + private val mockTrackSelector = mockk(relaxed = true) + private val mockLogger = mockk(relaxed = true) + private val mockPlayer = mockk(relaxed = true) + private val mockTimeUtil = mockk(relaxed = true) + } @Inject lateinit var mockAndroidHelper: AndroidHelper @@ -81,6 +63,7 @@ open class ExoplayerVideoActivityTest : InjectingTest() { @Before override fun setUp() { + clearAllMocks() super.setUp() activity = Robolectric.buildActivity(ExoplayerVideoActivity::class.java).create().get() activity.player = mockPlayer @@ -88,52 +71,50 @@ open class ExoplayerVideoActivityTest : InjectingTest() { @Test fun bindsSimpleExoPlayerView() { - Assertions.assertThat(activity.playerView).isNotNull + assertThat(activity.playerView).isNotNull() } @Test fun onStartDoesNotCallsPresenterPlayBackFromVideoQueueWhenOnAPI19OrHigher() { activity.onStart() - verify(mockExoPlayerPresenter, never()).playBackFromVideoQueue(anyOrNull()) + verify(exactly = 0) { mockExoPlayerPresenter.playBackFromVideoQueue(any()) } } @Test fun onPauseCallsReleasePlayser() { - val spy = spy(activity) - doNothing().whenever(spy).releasePlayer() - spy.onPause() + activity.onPause() - verify(spy).releasePlayer() + verify { mockPlayer.stop() } } @Test fun onPauseDoesNotCallsReleasePlayser() { - doReturn(24).whenever(mockAndroidHelper).buildNumber() - val spy = spy(activity) - doNothing().whenever(spy).releasePlayer() - spy.onPause() + every { mockAndroidHelper.buildNumber() } returns 24 + + activity.onPause() - verify(spy, never()).releasePlayer() + verify(exactly = 0) { mockPlayer.stop() } } @Test fun onStopDCallsReleasePlayser() { - doReturn(24).whenever(mockAndroidHelper).buildNumber() - val spy = spy(activity) - doNothing().whenever(spy).releasePlayer() + every { mockAndroidHelper.buildNumber() } returns 24 + val spy = spyk(activity) + every { spy.releasePlayer() } just Runs spy.onStop() - verify(spy).releasePlayer() + verify { spy.releasePlayer() } } @Test fun onStopDoesNotCallsReleasePlayser() { - val spy = spy(activity) - doNothing().whenever(spy).releasePlayer() + val spy = spyk(activity) + every { spy.releasePlayer() } just Runs + spy.onStop() - verify(spy, never()).releasePlayer() + verify(exactly = 0 ) { spy.releasePlayer() } } @Test @@ -144,24 +125,24 @@ open class ExoplayerVideoActivityTest : InjectingTest() { @Test @Ignore fun initializePlayerSetABunchOfRequiredItems() { - val spy = spy(activity) - doReturn(mockPlayer).whenever(spy).createSimpleExoplayer() - doReturn(TrackSelectionArray()).whenever(mockPlayer).getCurrentTrackSelections() + val spy = spyk(activity) + every { spy.createSimpleExoplayer() } returns mockPlayer + every { mockPlayer.currentTrackSelections } returns TrackSelectionArray() spy.initializePlayer("http://www.example.com/start.mkv", 0) assertThat(spy.player).isInstanceOf(SimpleExoPlayer::class.java) - verify(spy).createSimpleExoplayer() - verify(mockPlayer).addListener(any(Player.Listener::class.java)) - verify(mockPlayer).prepare(any(MediaSource::class.java)) + verify { spy.createSimpleExoplayer() } + verify { mockPlayer.addListener(any()) } + verify { mockPlayer.prepare(any())} } @Test fun releasePlayerReleasesWhenPlayerIsNotNull() { activity.releasePlayer() - verify(mockPlayer).release() + verify { mockPlayer.release() } } @Test @@ -171,43 +152,44 @@ open class ExoplayerVideoActivityTest : InjectingTest() { @Test fun onBackPressedStopsAndReleasesVideoPlayer() { - doReturn(Player.STATE_READY).whenever(mockPlayer).playbackState + every { mockPlayer.playbackState } returns Player.STATE_READY activity.onBackPressed() - verify(mockPlayer).playWhenReady = false - verify(mockExoPlayerPresenter).stopPlaying(anyOrNull()) - verify(mockPlayer).clearVideoSurface() - verify(mockPlayer).release() + verify { mockPlayer.playWhenReady = false } + verify { mockExoPlayerPresenter.stopPlaying(any()) } + verify { mockPlayer.clearVideoSurface() } + verify { mockPlayer.release() } } @Test fun onBackPressedStopsAndReleasesVideoPlayerWhenBuffering() { - doReturn(Player.STATE_BUFFERING).whenever(mockPlayer).playbackState + every { mockPlayer.playbackState } returns Player.STATE_BUFFERING activity.onBackPressed() - verify(mockPlayer).playWhenReady = false - verify(mockExoPlayerPresenter).stopPlaying(anyOrNull()) - verify(mockPlayer).clearVideoSurface() - verify(mockPlayer).release() + verify { mockPlayer.playWhenReady = false } + verify { mockExoPlayerPresenter.stopPlaying(any()) } + verify { mockPlayer.clearVideoSurface() } + verify { mockPlayer.release() } } @Test fun onKeyCodeDownHandlesHomeEvent() { - doReturn(Player.STATE_BUFFERING).whenever(mockPlayer).playbackState + every { mockPlayer.playbackState } returns Player.STATE_BUFFERING val result = activity.onKeyDown(KeyEvent.KEYCODE_HOME, null) assertThat(result).isTrue() - verify(mockPlayer).playWhenReady = false - verify(mockExoPlayerPresenter).stopPlaying(anyOrNull()) - verify(mockPlayer).clearVideoSurface() - verify(mockPlayer).release() + + verify { mockPlayer.playWhenReady = false } + verify { mockExoPlayerPresenter.stopPlaying(any()) } + verify { mockPlayer.clearVideoSurface() } + verify { mockPlayer.release() } } override fun installTestModules() { - scope.installTestModules(TestingModule(), TestModule()) + scope.installTestModules(MockkTestingModule(), TestModule()) } inner class TestModule : Module() { @@ -215,7 +197,7 @@ open class ExoplayerVideoActivityTest : InjectingTest() { init { bind(ExoplayerPresenter::class.java).toInstance(mockExoPlayerPresenter) bind(DataSource.Factory::class.java).toInstance(mockDataSourceFactory) - bind(TrackSelector::class.java).toInstance(mockMappingTrackSelector) + bind(TrackSelector::class.java).toInstance(mockTrackSelector) bind(Logger::class.java).toInstance(mockLogger) bind(TimeUtil::class.java).toInstance(mockTimeUtil) } diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/PlaybackRepositoryTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/PlaybackRepositoryTest.kt new file mode 100644 index 000000000..dc6cbabc4 --- /dev/null +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/PlaybackRepositoryTest.kt @@ -0,0 +1,89 @@ +package us.nineworlds.serenity.ui.video.player + +import io.mockk.Runs +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.After +import org.junit.Before +import org.junit.Test +import us.nineworlds.serenity.common.rest.SerenityClient +import us.nineworlds.serenity.core.model.VideoContentInfo + +@OptIn(ExperimentalCoroutinesApi::class) +class PlaybackRepositoryTest { + + private companion object { + private val mockSerenityClient = mockk() + } + + private lateinit var repository: PlaybackRepository + + @Before + fun setUp() { + clearAllMocks() + Dispatchers.setMain(Dispatchers.Unconfined) + repository = PlaybackRepository(mockSerenityClient) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun startPlayingPlaysExpectedVideoKey() = runTest(UnconfinedTestDispatcher()) { + val expectedId = "12345" + every { mockSerenityClient.startPlaying(any()) } just Runs + + repository.startPlaying(expectedId) + + verify { mockSerenityClient.startPlaying(expectedId) } + } + + @Test + fun stopPlayingStopsExpectedVideoKey() = runTest(UnconfinedTestDispatcher()) { + val expectedId = "12345" + every { mockSerenityClient.stopPlaying(any(), any()) } just Runs + + repository.stopPlaying(expectedId, 0) + + verify { mockSerenityClient.stopPlaying(expectedId, 0) } + } + + @Test + fun updatePlaybackPositionUpdatesVideoForWatchedVideos() = runTest(UnconfinedTestDispatcher()) { + val video = mockk() + every { video.id() } returns "12345" + every { video.isWatched() } returns true + every { mockSerenityClient.watched(any()) } returns true + every { mockSerenityClient.progress(any(), any()) } returns true + + repository.updatePlaybackPosition(video) + + verify { mockSerenityClient.watched("12345") } + verify { mockSerenityClient.progress("12345", "0") } + } + + @Test + fun updatePlaybackPositionUpdatesVideoUnwatchedVideos() = runTest(UnconfinedTestDispatcher()) { + val video = mockk() + every { video.id() } returns "12345" + every { video.isWatched() } returns false + every { video.resumeOffset } returns 123 + every { mockSerenityClient.progress(any(), any()) } returns true + + repository.updatePlaybackPosition(video) + + verify(exactly = 0) { mockSerenityClient.watched("12345") } + verify { mockSerenityClient.progress("12345", "123") } + } +} \ No newline at end of file diff --git a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/VideoKeyCodeHandlerDelegateTest.kt b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/VideoKeyCodeHandlerDelegateTest.kt index a6d41d48f..b97aecb83 100644 --- a/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/VideoKeyCodeHandlerDelegateTest.kt +++ b/serenity-app/src/test/kotlin/us/nineworlds/serenity/ui/video/player/VideoKeyCodeHandlerDelegateTest.kt @@ -2,462 +2,485 @@ package us.nineworlds.serenity.ui.video.player import android.content.SharedPreferences import android.view.KeyEvent +import assertk.assertThat +import assertk.assertions.isFalse +import assertk.assertions.isTrue import com.google.android.exoplayer2.SimpleExoPlayer -import org.assertj.core.api.Java6Assertions.assertThat +import io.mockk.Runs +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.verify import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyLong -import org.mockito.ArgumentMatchers.anyString -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mock -import org.mockito.Mockito.doNothing -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations.initMocks import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.LooperMode import toothpick.config.Module -import us.nineworlds.serenity.TestingModule +import us.nineworlds.serenity.MockkTestingModule import us.nineworlds.serenity.test.InjectingTest @RunWith(RobolectricTestRunner::class) -@LooperMode(LooperMode.Mode.LEGACY) class VideoKeyCodeHandlerDelegateTest : InjectingTest() { - @Mock - internal lateinit var mockPreferences: SharedPreferences - - @Mock - internal lateinit var mockMediaPlayer: SimpleExoPlayer - - @Mock - internal lateinit var mockPresenter: ExoplayerContract.ExoplayerPresenter - - lateinit var keyCodeHandler: VideoKeyCodeHandlerDelegate - - @Mock - lateinit var mockActivity: ExoplayerVideoActivity - - @Before - @Throws(Exception::class) - override fun setUp() { - Robolectric.getBackgroundThreadScheduler().pause() - Robolectric.getForegroundThreadScheduler().pause() - - initMocks(this) - super.setUp() - - doReturn("5000").`when`(mockPreferences).getString("osd_display_time", "5000") - - keyCodeHandler = VideoKeyCodeHandlerDelegate(mockMediaPlayer, mockActivity, mockPresenter) - } - - @After - fun tearDown() { - if (mockActivity != null) { - mockActivity!!.finish() - } - } - - @Test - fun handlesKeyCodeInfo() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_INFO, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeInfoWhenMenuKeyIsPressed() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MENU, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeInfoWhenIIsPressed() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_I, null) - assertThat(result).isTrue() - } - - @Test - fun HandlesKeyCodeInfoWhenGameControllerButtonYIsPressed() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_Y, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodePauseWhenMediaPlayerIsPlaying() { - demandMediaPause() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_PAUSE, - null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodePauseWhenMediaPlayerIsPlayingKeyCodeP() { - demandMediaPause() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_P, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodePauseWhenMediaPlayerIsPlayingKeyCodeSpace() { - demandMediaPause() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_SPACE, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodePauseWhenMediaPlayerIsPlayingKeyCodeButtonA() { - demandMediaPause() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_A, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodePauseWhenMediaPlayerIsPlayingKeyCodeMediaPlayPause() { - demandMediaPause() - val result = keyCodeHandler.onKeyDown( - KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodePauseWhenMediaPlayerIsNotPlaying() { - demandMediaPauseWhenNotPlaying() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_PAUSE, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodePlayPauseWhenMediaPlayerIsNotPlaying() { - demandMediaPauseWhenNotPlaying() - val result = keyCodeHandler.onKeyDown( - KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeMediaNextQueueEntryIsPlaying() { - demandNextQueue() - doReturn("queue").`when`(mockPreferences).getString( - eq("next_prev_behavior"), anyString()) - - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) - assertThat(result).isTrue() - verify(mockPreferences).getString("next_prev_behavior", "queue") - } - - @Test - fun handlesKeyCodeMediaNextQueueEntryIsNotPlaying() { - doReturn("queue").`when`(mockPreferences).getString( - eq("next_prev_behavior"), anyString()) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) - assertThat(result).isTrue() - verify(mockPreferences).getString("next_prev_behavior", "queue") - } - - @Test - fun handlesKeyCodeMediaNextByPercentatage() { - demandByPercentage() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) - - assertThat(result).isTrue() - verify(mockPreferences).getString("next_prev_behavior", "queue") - verify(mockMediaPlayer).seekTo(20) - } - - @Test - fun handlesKeyCodeMediaNextBySecondsUnderDuration() { - demandBySeconds("2000", 1000L) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) - - assertThat(result).isTrue() - verify(mockPreferences).getString("next_prev_behavior", "queue") - verify(mockMediaPlayer).seekTo(3000) - } - - @Test - fun handlesKeyCodeMediaNextBySecondsGreaterThanDuration() { - demandBySeconds("11000", 1000L) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) - - assertThat(result).isTrue() - verify(mockPreferences).getString("next_prev_behavior", "queue") - verify(mockMediaPlayer).seekTo(9999) - } - - @Test - fun handlesKeyCodeMediaNextBySecondsLessThanZero() { - demandBySeconds("-11000", 1000L) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) - - assertThat(result).isTrue() - verify(mockPreferences).getString("next_prev_behavior", "queue") - verify(mockMediaPlayer).seekTo(0) - } - - @Test - fun handlesKeyCodeMediaPreviousWhenUsingPercentage() { - doReturn("10%").`when`(mockPreferences).getString( - eq("next_prev_behavior"), anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - doReturn(10L).`when`(mockMediaPlayer).getCurrentPosition() - doReturn(100L).`when`(mockMediaPlayer).getDuration() - - val result = keyCodeHandler.onKeyDown( - KeyEvent.KEYCODE_MEDIA_PREVIOUS, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(0) - } - - @Test - fun handlesKeyCodeMediaPreviousWhenUsingDuration() { - doReturn("2000").`when`(mockPreferences).getString( - eq("next_prev_behavior"), anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - doReturn(9000L).`when`(mockMediaPlayer).getCurrentPosition() - doReturn(10000L).`when`(mockMediaPlayer).getDuration() - - val result = keyCodeHandler.onKeyDown( - KeyEvent.KEYCODE_MEDIA_PREVIOUS, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(7000) - } - - @Test - fun handlesKeyCodeMediaFastForwardReceived() { - doReturn("0").`when`(mockPreferences).getString(eq("skip_forward_time"), - anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - val result = keyCodeHandler.onKeyDown( - KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeFReceivedSkipsForward() { - doReturn("0").`when`(mockPreferences).getString(eq("skip_forward_time"), - anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_F, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeButtonR1ReceivedSkipsForward() { - doReturn("0").`when`(mockPreferences).getString(eq("skip_forward_time"), - anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_R1, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeButtonR2ReceivedSkipsForward() { - doReturn("0").`when`(mockPreferences).getString(eq("skip_forward_time"), - anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_R2, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeMediaRewindSkipsBack() { - doReturn("0").`when`(mockPreferences).getString(eq("skip_backward_time"), - anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - val result = keyCodeHandler.onKeyDown( - KeyEvent.KEYCODE_MEDIA_REWIND, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeRSkipsBack() { - doReturn("0").`when`(mockPreferences).getString(eq("skip_backward_time"), - anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_R, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeButtonL1SkipsBack() { - doReturn("0").`when`(mockPreferences).getString(eq("skip_backward_time"), - anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_L1, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeButtonL2SkipsBack() { - doReturn("0").`when`(mockPreferences).getString(eq("skip_backward_time"), - anyString()) - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_L2, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeMediaStopPausesCurrentlyPlayingVideo() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_STOP, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeMediaStopPausesCurrentlyPlayingVideoWhenMediaControllerNotShowingShowsMediaController() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_STOP, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeMediaStopWhenMediaControllerShowing() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_STOP, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeMediaStopWhenMediaControllerIsNotPlaying() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_STOP, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCodeSPausesCurrentlyPlayingVideo() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_S, null) - assertThat(result).isTrue() - } - - @Test - fun handlesKeyCode1ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).duration - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_1, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(100L) - } - - @Test - fun handlesKeyCode2ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).duration - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_2, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(200L) - } - - @Test - fun handlesKeyCode3ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).duration - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_3, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(300L) - } - - @Test - fun handlesKeyCode4ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).duration - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_4, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(400L) - } - - @Test - fun handlesKeyCode5ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).duration - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_5, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(500L) - } - - @Test - fun handlesKeyCode6ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).duration - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_6, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(600L) - } - - @Test - fun handlesKeyCode7ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).getDuration() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_7, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(700L) - } - - @Test - fun handlesKeyCode8ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).getDuration() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_8, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(800L) - } - - @Test - fun handlesKeyCode9ForSkipByPercentage() { - doReturn(1000L).`when`(mockMediaPlayer).getDuration() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_9, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(900L) - } - - @Test - fun handlesKeyCode0RestartsAtBeginning() { - doReturn(1000L).`when`(mockMediaPlayer).getDuration() - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_0, null) - assertThat(result).isTrue() - verify(mockMediaPlayer).seekTo(0L) - } - - @Test - fun unhandledKeyCodeReturnsFalse() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_AT, null) - assertThat(result).isFalse() - } - - private fun demandBySeconds(seconds: String, currentPosition: Long) { - doReturn(seconds).`when`(mockPreferences).getString( - eq("next_prev_behavior"), anyString()) - doReturn(currentPosition).`when`(mockMediaPlayer).getCurrentPosition() - doReturn(10000L).`when`(mockMediaPlayer).getDuration() - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - } - - private fun demandByPercentage() { - doReturn("10%").`when`(mockPreferences).getString( - eq("next_prev_behavior"), anyString()) - doReturn(10L).`when`(mockMediaPlayer).currentPosition - doReturn(100L).`when`(mockMediaPlayer).duration - doNothing().`when`(mockMediaPlayer).seekTo(anyLong()) - } - - private fun demandNextQueue() { - doNothing().`when`(mockMediaPlayer).stop() - } - - private fun demandMediaPause() { - } - - private fun demandMediaPauseWhenNotPlaying() { - } - - @Test - fun handlesKeyCodeInfoWhenMediaPlayerControllerIsShowing() { - val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_INFO, null) - assertThat(result).isTrue() - } - - override fun installTestModules() { - scope.installTestModules(TestingModule(), TestModule()) - } - - inner class TestModule : Module() { - - init { - bind(SharedPreferences::class.java).toInstance(mockPreferences) - } - } + companion object { + private val mockPreferences = mockk(relaxed = true) + private val mockMediaPlayer = mockk(relaxed = true) + private val mockPresenter = mockk(relaxed = true) + private val mockActivity = mockk(relaxed = true) + } + + private lateinit var keyCodeHandler: VideoKeyCodeHandlerDelegate + + @Before + @Throws(Exception::class) + override fun setUp() { + clearAllMocks() + + super.setUp() + + every { mockPreferences.getString("osd_display_time", "5000") } returns "5000" + + keyCodeHandler = VideoKeyCodeHandlerDelegate(mockMediaPlayer, mockActivity, mockPresenter) + } + + @After + fun tearDown() { + mockActivity.finish() + } + + @Test + fun handlesKeyCodeInfo() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_INFO, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeInfoWhenMenuKeyIsPressed() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MENU, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeInfoWhenIIsPressed() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_I, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeInfoWhenGameControllerButtonYIsPressed() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_Y, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodePauseWhenMediaPlayerIsPlaying() { + demandMediaPause() + val result = keyCodeHandler.onKeyDown( + KeyEvent.KEYCODE_MEDIA_PAUSE, + null + ) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodePauseWhenMediaPlayerIsPlayingKeyCodeP() { + demandMediaPause() + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_P, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodePauseWhenMediaPlayerIsPlayingKeyCodeSpace() { + demandMediaPause() + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_SPACE, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodePauseWhenMediaPlayerIsPlayingKeyCodeButtonA() { + demandMediaPause() + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_A, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodePauseWhenMediaPlayerIsPlayingKeyCodeMediaPlayPause() { + demandMediaPause() + val result = keyCodeHandler.onKeyDown( + KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, null + ) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodePauseWhenMediaPlayerIsNotPlaying() { + demandMediaPauseWhenNotPlaying() + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_PAUSE, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodePlayPauseWhenMediaPlayerIsNotPlaying() { + demandMediaPauseWhenNotPlaying() + val result = keyCodeHandler.onKeyDown( + KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, null + ) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeMediaNextQueueEntryIsPlaying() { + demandNextQueue() + every { mockPreferences.getString("next_prev_behavior", any()) } returns "queue" + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) + + assertThat(result).isTrue() + verify { mockPreferences.getString("next_prev_behavior", "queue") } + } + + @Test + fun handlesKeyCodeMediaNextQueueEntryIsNotPlaying() { + every { mockPreferences.getString("next_prev_behavior", any()) } returns "queue" + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) + + assertThat(result).isTrue() + verify { mockPreferences.getString("next_prev_behavior", "queue") } + } + + @Test + fun handlesKeyCodeMediaNextByPercentatage() { + demandByPercentage() + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) + + assertThat(result).isTrue() + verify { mockPreferences.getString("next_prev_behavior", "queue") } + verify { mockMediaPlayer.seekTo(20) } + } + + @Test + fun handlesKeyCodeMediaNextBySecondsUnderDuration() { + demandBySeconds("2000", 1000L) + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) + + assertThat(result).isTrue() + + verify { mockPreferences.getString("next_prev_behavior", "queue") } + verify { mockMediaPlayer.seekTo(3000) } + } + + @Test + fun handlesKeyCodeMediaNextBySecondsGreaterThanDuration() { + demandBySeconds("11000", 1000L) + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) + + assertThat(result).isTrue() + + verify { mockPreferences.getString("next_prev_behavior", "queue") } + verify { mockMediaPlayer.seekTo(9999) } + } + + @Test + fun handlesKeyCodeMediaNextBySecondsLessThanZero() { + demandBySeconds("-11000", 1000L) + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_NEXT, null) + + assertThat(result).isTrue() + + verify { mockPreferences.getString("next_prev_behavior", "queue") } + verify { mockMediaPlayer.seekTo(0) } + } + + @Test + fun handlesKeyCodeMediaPreviousWhenUsingPercentage() { + every { mockPreferences.getString("next_prev_behavior", any()) } returns "10%" + every { mockMediaPlayer.seekTo(any()) } just Runs + every { mockMediaPlayer.currentPosition } returns 10L + every { mockMediaPlayer.duration } returns 100L + + val result = keyCodeHandler.onKeyDown( + KeyEvent.KEYCODE_MEDIA_PREVIOUS, null + ) + assertThat(result).isTrue() + + verify { mockMediaPlayer.seekTo(0) } + } + + @Test + fun handlesKeyCodeMediaPreviousWhenUsingDuration() { + every { mockPreferences.getString(eq("next_prev_behavior"), any()) } returns "2000" + every { mockMediaPlayer.seekTo(any()) } just Runs + every { mockMediaPlayer.currentPosition } returns 9000L + every { mockMediaPlayer.duration } returns 10000L + + val result = keyCodeHandler.onKeyDown( + KeyEvent.KEYCODE_MEDIA_PREVIOUS, null + ) + assertThat(result).isTrue() + + verify { mockMediaPlayer.seekTo(7000) } + } + + @Test + fun handlesKeyCodeMediaFastForwardReceived() { + every { mockPreferences.getString(eq("skip_forward_time"), any()) } returns "0" + every { mockMediaPlayer.seekTo(any()) } just Runs + + val result = keyCodeHandler.onKeyDown( + KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, null + ) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeFReceivedSkipsForward() { + every { mockPreferences.getString(eq("skip_forward_time"), any()) } returns "0" + every { mockMediaPlayer.seekTo(any()) } just Runs + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_F, null) + + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeButtonR1ReceivedSkipsForward() { + every { mockPreferences.getString(eq("skip_forward_time"), any()) } returns "0" + every { mockMediaPlayer.seekTo(any()) } just Runs + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_R1, null) + + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeButtonR2ReceivedSkipsForward() { + every { mockPreferences.getString(eq("skip_forward_time"), any()) } returns "0" + every { mockMediaPlayer.seekTo(any()) } just Runs + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_R2, null) + + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeMediaRewindSkipsBack() { + every { mockPreferences.getString(eq("skip_backward_time"), any()) } returns "0" + every { mockMediaPlayer.seekTo(any()) } just Runs + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_REWIND, null) + + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeRSkipsBack() { + every { mockPreferences.getString(eq("skip_backward_time"), any()) } returns "0" + every { mockMediaPlayer.seekTo(any()) } just Runs + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_R, null) + + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeButtonL1SkipsBack() { + every { mockPreferences.getString(eq("skip_backward_time"), any()) } returns "0" + every { mockMediaPlayer.seekTo(any()) } just Runs + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_L1, null) + + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeButtonL2SkipsBack() { + every { mockPreferences.getString(eq("skip_backward_time"), any()) } returns "0" + every { mockMediaPlayer.seekTo(any()) } just Runs + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_BUTTON_L2, null) + + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeMediaStopPausesCurrentlyPlayingVideo() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_STOP, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeMediaStopPausesCurrentlyPlayingVideoWhenMediaControllerNotShowingShowsMediaController() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_STOP, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeMediaStopWhenMediaControllerShowing() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_STOP, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeMediaStopWhenMediaControllerIsNotPlaying() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_MEDIA_STOP, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCodeSPausesCurrentlyPlayingVideo() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_S, null) + assertThat(result).isTrue() + } + + @Test + fun handlesKeyCode1ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_1, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(100L) } + } + + @Test + fun handlesKeyCode2ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_2, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(200L) } + } + + @Test + fun handlesKeyCode3ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_3, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(300L) } + } + + @Test + fun handlesKeyCode4ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_4, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(400L) } + } + + @Test + fun handlesKeyCode5ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_5, null) + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(500L) } + } + + @Test + fun handlesKeyCode6ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_6, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(600L) } + } + + @Test + fun handlesKeyCode7ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_7, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(700L) } + } + + @Test + fun handlesKeyCode8ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_8, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(800L) } + } + + @Test + fun handlesKeyCode9ForSkipByPercentage() { + every { mockMediaPlayer.duration } returns 1000L // Assuming getDuration() is a getter for duration property + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_9, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(900L) } + } + + @Test + fun handlesKeyCode0RestartsAtBeginning() { + every { mockMediaPlayer.duration } returns 1000L // Assuming getDuration() is a getter for duration property + + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_0, null) + + assertThat(result).isTrue() + verify { mockMediaPlayer.seekTo(0L) } + } + + @Test + fun unhandledKeyCodeReturnsFalse() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_AT, null) + assertThat(result).isFalse() + } + + private fun demandBySeconds(seconds: String, currentPosition: Long) { + every { mockPreferences.getString(eq("next_prev_behavior"), any()) } returns seconds + every { mockMediaPlayer.currentPosition } returns currentPosition + every { mockMediaPlayer.duration } returns 10000L + every { mockMediaPlayer.seekTo(any()) } just Runs + } + + private fun demandByPercentage() { + every { mockPreferences.getString(eq("next_prev_behavior"), any()) } returns "10%" + every { mockMediaPlayer.currentPosition } returns 10L + every { mockMediaPlayer.duration } returns 100L + every { mockMediaPlayer.seekTo(any()) } just Runs + } + + private fun demandNextQueue() { + every { mockMediaPlayer.stop() } just Runs + } + + private fun demandMediaPause() { + } + + private fun demandMediaPauseWhenNotPlaying() { + } + + @Test + fun handlesKeyCodeInfoWhenMediaPlayerControllerIsShowing() { + val result = keyCodeHandler.onKeyDown(KeyEvent.KEYCODE_INFO, null) + assertThat(result).isTrue() + } + + override fun installTestModules() { + scope.installTestModules(MockkTestingModule(), TestModule()) + } + + inner class TestModule : Module() { + + init { + bind(SharedPreferences::class.java).toInstance(mockPreferences) + } + } }