diff --git a/app/build.gradle b/app/build.gradle index c1dd866..c8f6e61 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,6 +15,7 @@ buildscript { } apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' apply plugin: 'io.fabric' apply plugin: 'me.tatarka.retrolambda' @@ -84,6 +85,7 @@ android { sourceSets { androidTest.java.srcDirs = ['src/androidTest/java', 'src/sharedTest/java'] test.java.srcDirs = ['src/test/java', 'src/sharedTest/java'] + main.java.srcDirs += 'src/main/kotlin' } dataBinding { enabled = true @@ -150,6 +152,7 @@ dependencies { compile('com.crashlytics.sdk.android:crashlytics:2.5.2@aar') { transitive = true; } + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" } // Define coverage source. diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/EspressoExecutor.java b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/EspressoExecutor.java deleted file mode 100644 index f2cf9fb..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/EspressoExecutor.java +++ /dev/null @@ -1,69 +0,0 @@ -package it.cosenonjaviste.androidtest.base; - -import android.support.test.espresso.IdlingResource; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import static android.support.test.espresso.Espresso.registerIdlingResources; - -public class EspressoExecutor extends ThreadPoolExecutor implements IdlingResource { - - private int runningTasks; - private ResourceCallback resourceCallback; - - private static EspressoExecutor singleton; - - public EspressoExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); - } - - public static EspressoExecutor newCachedThreadPool() { - if (singleton == null) { - singleton = new EspressoExecutor(0, Integer.MAX_VALUE, - 60L, TimeUnit.SECONDS, - new SynchronousQueue<>()); - registerIdlingResources(singleton); - } - return singleton; - } - - @Override public void execute(final Runnable command) { - super.execute(new Runnable() { - @Override public void run() { - try { - incrementRunningTasks(); - command.run(); - } finally { - decrementRunningTasks(); - } - } - }); - } - - private synchronized void decrementRunningTasks() { - runningTasks--; - if (runningTasks == 0 && resourceCallback != null) { - resourceCallback.onTransitionToIdle(); - } - } - - private synchronized void incrementRunningTasks() { - runningTasks++; - } - - @Override public String getName() { - return "EspressoExecutor"; - } - - @Override public boolean isIdleNow() { - return runningTasks == 0; - } - - @Override - public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { - this.resourceCallback = resourceCallback; - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/EspressoExecutor.kt b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/EspressoExecutor.kt new file mode 100644 index 0000000..cda1707 --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/EspressoExecutor.kt @@ -0,0 +1,51 @@ +package it.cosenonjaviste.androidtest.base + +import android.support.test.espresso.Espresso.registerIdlingResources +import android.support.test.espresso.IdlingResource +import java.util.concurrent.SynchronousQueue +import java.util.concurrent.ThreadPoolExecutor +import java.util.concurrent.TimeUnit + +object EspressoExecutor : ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, SynchronousQueue()), IdlingResource { + + private var runningTasks: Int = 0 + private var resourceCallback: IdlingResource.ResourceCallback? = null + + init { + registerIdlingResources(this) + } + + override fun execute(command: Runnable) { + super.execute(Runnable { + try { + incrementRunningTasks() + command.run() + } finally { + decrementRunningTasks() + } + }) + } + + @Synchronized private fun decrementRunningTasks() { + runningTasks-- + if (runningTasks == 0 && resourceCallback != null) { + resourceCallback!!.onTransitionToIdle() + } + } + + @Synchronized private fun incrementRunningTasks() { + runningTasks++ + } + + override fun getName(): String { + return "EspressoExecutor" + } + + override fun isIdleNow(): Boolean { + return runningTasks == 0 + } + + override fun registerIdleTransitionCallback(resourceCallback: IdlingResource.ResourceCallback) { + this.resourceCallback = resourceCallback + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/FragmentRule.java b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/FragmentRule.java deleted file mode 100644 index 5186023..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/FragmentRule.java +++ /dev/null @@ -1,43 +0,0 @@ -package it.cosenonjaviste.androidtest.base; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.Parcelable; -import android.support.test.InstrumentationRegistry; -import android.support.test.rule.ActivityTestRule; -import android.support.v4.app.Fragment; - -import it.cosenonjaviste.mv2m.ViewModel; -import it.cosenonjaviste.ui.utils.SingleFragmentActivity; - -public class FragmentRule extends ActivityTestRule { - private Class fragmentClass; - - public FragmentRule(Class fragmentClass) { - super(SingleFragmentActivity.class, false, false); - this.fragmentClass = fragmentClass; - } - - public SingleFragmentActivity launchFragment() { - return launchFragment(null); - } - - public void launchFragment(Parcelable model) { - Bundle bundle = new Bundle(); - bundle.putParcelable(ViewModel.MODEL, model); - launchFragment(bundle); - } - - public SingleFragmentActivity launchFragment(Bundle b) { - Intent intent = SingleFragmentActivity.populateIntent(new Intent(), fragmentClass); - if (b != null) { - intent.putExtras(b); - } - return launchActivity(intent); - } - - public T getApplication() { - return (T) InstrumentationRegistry.getTargetContext().getApplicationContext(); - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/FragmentRule.kt b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/FragmentRule.kt new file mode 100644 index 0000000..06fddc7 --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/FragmentRule.kt @@ -0,0 +1,27 @@ +package it.cosenonjaviste.androidtest.base + +import android.content.Intent +import android.os.Bundle +import android.os.Parcelable +import android.support.test.rule.ActivityTestRule +import android.support.v4.app.Fragment + +import it.cosenonjaviste.mv2m.ViewModel +import it.cosenonjaviste.ui.utils.SingleFragmentActivity + +class FragmentRule(private val fragmentClass: Class) : ActivityTestRule(SingleFragmentActivity::class.java, false, false) { + + fun launchFragment(model: Parcelable) { + val bundle = Bundle() + bundle.putParcelable(ViewModel.MODEL, model) + launchFragment(bundle as Bundle?) + } + + @JvmOverloads fun launchFragment(b: Bundle? = null): SingleFragmentActivity { + val intent = SingleFragmentActivity.populateIntent(Intent(), fragmentClass) + if (b != null) { + intent.putExtras(b) + } + return launchActivity(intent) + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/MockWebServerWrapper.java b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/MockWebServerWrapper.java deleted file mode 100644 index 749e642..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/MockWebServerWrapper.java +++ /dev/null @@ -1,85 +0,0 @@ -package it.cosenonjaviste.androidtest.base; - -import com.squareup.okhttp.mockwebserver.Dispatcher; -import com.squareup.okhttp.mockwebserver.MockResponse; -import com.squareup.okhttp.mockwebserver.MockWebServer; -import com.squareup.okhttp.mockwebserver.RecordedRequest; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import rx.functions.Func1; - -public class MockWebServerWrapper { - - private static MockWebServer server; - - private static LinkedList requests = new LinkedList<>(); - - private static Func1 dispatchFunction; - - public MockWebServerWrapper() { - if (server == null) { - server = new MockWebServer(); - try { - server.start(); - } catch (IOException e) { - throw new RuntimeException(e); - } - initDispatcher(); - } - } - - public static void initDispatcher(Func1 dispatchFunction) { - MockWebServerWrapper.dispatchFunction = dispatchFunction; - } - - public void initDispatcher(String responseBody) { - dispatchFunction = recordedRequest -> new MockResponse().setBody(responseBody); - requests = new LinkedList<>(); - } - - private void initDispatcher() { - server.setDispatcher(new Dispatcher() { - @Override public MockResponse dispatch(RecordedRequest request) throws InterruptedException { - requests.add(request); - return dispatchFunction.call(request); - } - }); - } - - public String getUrl(boolean initInBackgroundThread) { - if (initInBackgroundThread) { - try { - ExecutorService executorService = Executors.newSingleThreadExecutor(); - return executorService.submit(this::getUrlSync).get(); - } catch (Throwable e) { - throw new RuntimeException(e); - } - } else { - return getUrlSync(); - } - } - - private String getUrlSync() { - return server.getUrl("/").toString(); - } - - public void shutdown() { - try { - server.shutdown(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public int getRequestCount() { - return requests.size(); - } - - public String getLastUrl() { - return requests.getLast().getPath(); - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/MockWebServerWrapper.kt b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/MockWebServerWrapper.kt new file mode 100644 index 0000000..4847233 --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/MockWebServerWrapper.kt @@ -0,0 +1,81 @@ +package it.cosenonjaviste.androidtest.base + +import com.squareup.okhttp.mockwebserver.Dispatcher +import com.squareup.okhttp.mockwebserver.MockResponse +import com.squareup.okhttp.mockwebserver.MockWebServer +import com.squareup.okhttp.mockwebserver.RecordedRequest +import java.io.IOException +import java.util.* +import java.util.concurrent.Callable +import java.util.concurrent.Executors + +class MockWebServerWrapper { + init { + if (server == null) { + server = MockWebServer() + try { + server!!.start() + } catch (e: IOException) { + throw RuntimeException(e) + } + + initDispatcher() + } + } + + fun initDispatcher(responseBody: String) { + dispatchFunction = { MockResponse().setBody(responseBody) } + requests = LinkedList() + } + + private fun initDispatcher() { + server!!.setDispatcher(object : Dispatcher() { + @Throws(InterruptedException::class) + override fun dispatch(request: RecordedRequest): MockResponse { + requests.add(request) + return dispatchFunction!!.invoke() + } + }) + } + + fun getUrl(initInBackgroundThread: Boolean): String { + if (initInBackgroundThread) { + try { + val executorService = Executors.newSingleThreadExecutor() + return executorService.submit(Callable { urlSync }).get() + } catch (e: Throwable) { + throw RuntimeException(e) + } + + } else { + return urlSync + } + } + + private val urlSync: String + get() = server!!.getUrl("/").toString() + + fun shutdown() { + try { + server!!.shutdown() + } catch (e: IOException) { + throw RuntimeException(e) + } + + } + + val requestCount: Int + get() = requests.size + + val lastUrl: String + get() = requests.last.path + + companion object { + + private var server: MockWebServer? = null + + private var requests = LinkedList() + + private var dispatchFunction: (() -> MockResponse) ? = null + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/OrientationChangeAction.java b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/OrientationChangeAction.java deleted file mode 100644 index 988a44a..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/OrientationChangeAction.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 - Nathan Barraille - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ -package it.cosenonjaviste.androidtest.base; - -import android.app.Activity; -import android.content.pm.ActivityInfo; -import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; -import android.support.test.runner.lifecycle.Stage; -import android.view.View; - -import org.hamcrest.Matcher; - -import java.util.Collection; - -import static android.support.test.espresso.matcher.ViewMatchers.isRoot; - -/** - * An Espresso ViewAction that changes the orientation of the screen - */ -public class OrientationChangeAction implements ViewAction { - private final int orientation; - - private OrientationChangeAction(int orientation) { - this.orientation = orientation; - } - - @Override - public Matcher getConstraints() { - return isRoot(); - } - - @Override - public String getDescription() { - return "change orientation to " + orientation; - } - - @Override - public void perform(UiController uiController, View view) { - uiController.loopMainThreadUntilIdle(); - final Activity activity = (Activity) view.getContext(); - activity.setRequestedOrientation(orientation); - - Collection resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED); - if (resumedActivities.isEmpty()) { - throw new RuntimeException("Could not change orientation"); - } - } - - public static ViewAction orientationLandscape() { - return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } - - public static ViewAction orientationPortrait() { - return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } -} \ No newline at end of file diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/OrientationChangeAction.kt b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/OrientationChangeAction.kt new file mode 100644 index 0000000..66e3c2c --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/androidtest/base/OrientationChangeAction.kt @@ -0,0 +1,71 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - Nathan Barraille + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +package it.cosenonjaviste.androidtest.base + +import android.app.Activity +import android.content.pm.ActivityInfo +import android.support.test.espresso.UiController +import android.support.test.espresso.ViewAction +import android.support.test.espresso.matcher.ViewMatchers.isRoot +import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry +import android.support.test.runner.lifecycle.Stage +import android.view.View +import org.hamcrest.Matcher + +/** + * An Espresso ViewAction that changes the orientation of the screen + */ +class OrientationChangeAction private constructor(private val orientation: Int) : ViewAction { + + override fun getConstraints(): Matcher { + return isRoot() + } + + override fun getDescription(): String { + return "change orientation to " + orientation + } + + override fun perform(uiController: UiController, view: View) { + uiController.loopMainThreadUntilIdle() + val activity = view.context as Activity + activity.requestedOrientation = orientation + + val resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED) + if (resumedActivities.isEmpty()) { + throw RuntimeException("Could not change orientation") + } + } + + companion object { + + fun orientationLandscape(): ViewAction { + return OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) + } + + fun orientationPortrait(): ViewAction { + return OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) + } + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/utils/TestUtils.java b/app/src/androidTest/java/it/cosenonjaviste/androidtest/utils/TestUtils.java deleted file mode 100644 index 4ab07e7..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/androidtest/utils/TestUtils.java +++ /dev/null @@ -1,17 +0,0 @@ -package it.cosenonjaviste.androidtest.utils; - -import rx.functions.Action1; - -public class TestUtils { - - public static Action1 sleepAction() { - return o -> sleep(1); - } - - public static void sleep(int seconds) { -// try { -// Thread.sleep(seconds * 1000); -// } catch (InterruptedException ignored) { -// } - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/androidtest/utils/TestUtils.kt b/app/src/androidTest/java/it/cosenonjaviste/androidtest/utils/TestUtils.kt new file mode 100644 index 0000000..7bd3971 --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/androidtest/utils/TestUtils.kt @@ -0,0 +1,11 @@ +package it.cosenonjaviste.androidtest.utils + +object TestUtils { + + fun sleep(seconds: Int) { + // try { + // Thread.sleep(seconds * 1000); + // } catch (InterruptedException ignored) { + // } + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/CnjDaggerRule.java b/app/src/androidTest/java/it/cosenonjaviste/ui/CnjDaggerRule.java deleted file mode 100644 index d31b7dd..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/ui/CnjDaggerRule.java +++ /dev/null @@ -1,50 +0,0 @@ -package it.cosenonjaviste.ui; - -import android.support.test.InstrumentationRegistry; - -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; - -import it.cosenonjaviste.androidtest.base.EspressoExecutor; -import it.cosenonjaviste.daggermock.DaggerMockRule; -import it.cosenonjaviste.model.TwitterService; -import it.cosenonjaviste.model.WordPressService; -import rx.Scheduler; -import rx.android.plugins.RxAndroidPlugins; -import rx.android.plugins.RxAndroidSchedulersHook; -import rx.plugins.RxJavaHooks; -import rx.schedulers.Schedulers; - -public class CnjDaggerRule extends DaggerMockRule { - public CnjDaggerRule() { - super(ApplicationComponent.class, new AppModule(getApp())); - providesMock(WordPressService.class, TwitterService.class); - set(component -> getApp().setComponent(component)); - } - - public static CoseNonJavisteApp getApp() { - return (CoseNonJavisteApp) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); - } - - @Override public Statement apply(Statement base, FrameworkMethod method, Object target) { - Statement superStatement = super.apply(base, method, target); - return new Statement() { - @Override public void evaluate() throws Throwable { - RxJavaHooks.setOnIOScheduler(scheduler -> Schedulers.immediate()); - RxJavaHooks.setOnComputationScheduler(scheduler -> Schedulers.immediate()); - RxJavaHooks.setOnNewThreadScheduler(scheduler -> Schedulers.immediate()); - RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() { - @Override public Scheduler getMainThreadScheduler() { - return Schedulers.from(EspressoExecutor.newCachedThreadPool()); - } - }); - try { - superStatement.evaluate(); - } finally { - RxJavaHooks.reset(); - RxAndroidPlugins.getInstance().reset(); - } - } - }; - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/CnjDaggerRule.kt b/app/src/androidTest/java/it/cosenonjaviste/ui/CnjDaggerRule.kt new file mode 100644 index 0000000..e664ee4 --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/ui/CnjDaggerRule.kt @@ -0,0 +1,50 @@ +package it.cosenonjaviste.ui + +import android.support.test.InstrumentationRegistry +import it.cosenonjaviste.androidtest.base.EspressoExecutor +import it.cosenonjaviste.daggermock.DaggerMockRule +import it.cosenonjaviste.model.TwitterService +import it.cosenonjaviste.model.WordPressService +import org.junit.runners.model.FrameworkMethod +import org.junit.runners.model.Statement +import rx.Scheduler +import rx.android.plugins.RxAndroidPlugins +import rx.android.plugins.RxAndroidSchedulersHook +import rx.plugins.RxJavaHooks +import rx.schedulers.Schedulers + +class CnjDaggerRule : DaggerMockRule(ApplicationComponent::class.java, AppModule(app)) { + init { + providesMock(WordPressService::class.java, TwitterService::class.java) + set { component -> app.component = component } + } + + override fun apply(base: Statement, method: FrameworkMethod?, target: Any): Statement { + val superStatement = super.apply(base, method, target) + return object : Statement() { + @Throws(Throwable::class) + override fun evaluate() { + RxJavaHooks.setOnIOScheduler { scheduler -> Schedulers.immediate() } + RxJavaHooks.setOnComputationScheduler { scheduler -> Schedulers.immediate() } + RxJavaHooks.setOnNewThreadScheduler { scheduler -> Schedulers.immediate() } + RxAndroidPlugins.getInstance().registerSchedulersHook(object : RxAndroidSchedulersHook() { + override fun getMainThreadScheduler(): Scheduler { + return Schedulers.from(EspressoExecutor) + } + }) + try { + superStatement.evaluate() + } finally { + RxJavaHooks.reset() + RxAndroidPlugins.getInstance().reset() + } + } + } + } + + companion object { + + val app: CoseNonJavisteApp + get() = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as CoseNonJavisteApp + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/author/AuthorListFragmentTest.java b/app/src/androidTest/java/it/cosenonjaviste/ui/author/AuthorListFragmentTest.java deleted file mode 100644 index 6f6ab20..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/ui/author/AuthorListFragmentTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package it.cosenonjaviste.ui.author; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.androidtest.base.FragmentRule; -import it.cosenonjaviste.core.author.AuthorListModel; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.CnjDaggerRule; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.mockito.Mockito.when; - -public class AuthorListFragmentTest { - - @Mock WordPressService wordPressService; - - @Rule public FragmentRule fragmentRule = new FragmentRule(AuthorListFragment.class); - - @Rule public final CnjDaggerRule daggerRule = new CnjDaggerRule(); - - @Test - public void testAuthorList() { - when(wordPressService.listAuthors()) - .thenReturn(TestData.authorResponse(8)); - - fragmentRule.launchFragment(new AuthorListModel()); - - onView(withText("name 1")).check(matches(isDisplayed())); - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/author/AuthorListFragmentTest.kt b/app/src/androidTest/java/it/cosenonjaviste/ui/author/AuthorListFragmentTest.kt new file mode 100644 index 0000000..c3e8856 --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/ui/author/AuthorListFragmentTest.kt @@ -0,0 +1,34 @@ +package it.cosenonjaviste.ui.author + +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.support.test.espresso.matcher.ViewMatchers.withText +import it.cosenonjaviste.TestData +import it.cosenonjaviste.androidtest.base.FragmentRule +import it.cosenonjaviste.core.author.AuthorListModel +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.CnjDaggerRule +import org.junit.Rule +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.`when` + +class AuthorListFragmentTest { + + @Mock lateinit var wordPressService: WordPressService + + @get:Rule var fragmentRule = FragmentRule(AuthorListFragment::class.java) + + @get:Rule val daggerRule = CnjDaggerRule() + + @Test + fun testAuthorList() { + `when`(wordPressService.listAuthors()) + .thenReturn(TestData.authorResponse(8)) + + fragmentRule.launchFragment(AuthorListModel()) + + onView(withText("name 1")).check(matches(isDisplayed())) + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/category/CategoryListFragmentTest.java b/app/src/androidTest/java/it/cosenonjaviste/ui/category/CategoryListFragmentTest.java deleted file mode 100644 index 8036a9f..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/ui/category/CategoryListFragmentTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package it.cosenonjaviste.ui.category; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import java.io.IOException; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.androidtest.base.FragmentRule; -import it.cosenonjaviste.core.category.CategoryListModel; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.CnjDaggerRule; -import rx.Observable; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class CategoryListFragmentTest { - - @Mock WordPressService wordPressService; - - @Rule public FragmentRule fragmentRule = new FragmentRule(CategoryListFragment.class); - - @Rule public final CnjDaggerRule daggerRule = new CnjDaggerRule(); - - @Test public void testCategoryList() { - when(wordPressService.listCategories()) - .thenReturn(TestData.categoryResponse(3)); - - fragmentRule.launchFragment(new CategoryListModel()); - - onView(withText("cat 1")).check(matches(isDisplayed())); - } - - @Test public void testCategoryError() { - when(wordPressService.listCategories()) - .thenReturn(Observable.error(new IOException("bla bla bla"))); - - fragmentRule.launchFragment(new CategoryListModel()); - - verify(wordPressService).listCategories(); - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/category/CategoryListFragmentTest.kt b/app/src/androidTest/java/it/cosenonjaviste/ui/category/CategoryListFragmentTest.kt new file mode 100644 index 0000000..d5dd5bb --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/ui/category/CategoryListFragmentTest.kt @@ -0,0 +1,46 @@ +package it.cosenonjaviste.ui.category + +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.support.test.espresso.matcher.ViewMatchers.withText +import it.cosenonjaviste.TestData +import it.cosenonjaviste.androidtest.base.FragmentRule +import it.cosenonjaviste.core.category.CategoryListModel +import it.cosenonjaviste.model.CategoryResponse +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.CnjDaggerRule +import org.junit.Rule +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import rx.Observable +import java.io.IOException + +class CategoryListFragmentTest { + + @Mock lateinit var wordPressService: WordPressService + + @get:Rule var fragmentRule = FragmentRule(CategoryListFragment::class.java) + + @get:Rule val daggerRule = CnjDaggerRule() + + @Test fun testCategoryList() { + `when`(wordPressService.listCategories()) + .thenReturn(TestData.categoryResponse(3)) + + fragmentRule.launchFragment(CategoryListModel()) + + onView(withText("cat 1")).check(matches(isDisplayed())) + } + + @Test fun testCategoryError() { + `when`(wordPressService.listCategories()) + .thenReturn(Observable.error(IOException("bla bla bla"))) + + fragmentRule.launchFragment(CategoryListModel()) + + verify(wordPressService).listCategories() + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/contact/ContactFragmentTest.java b/app/src/androidTest/java/it/cosenonjaviste/ui/contact/ContactFragmentTest.java deleted file mode 100644 index 5785621..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/ui/contact/ContactFragmentTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package it.cosenonjaviste.ui.contact; - -import android.support.test.espresso.action.ViewActions; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import it.cosenonjaviste.R; -import it.cosenonjaviste.androidtest.base.FragmentRule; -import it.cosenonjaviste.androidtest.utils.TestUtils; -import it.cosenonjaviste.model.MailJetService; -import it.cosenonjaviste.ui.CnjDaggerRule; -import retrofit.client.Response; -import rx.Observable; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.scrollTo; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.when; - -public class ContactFragmentTest { - @Rule public FragmentRule fragmentRule = new FragmentRule(ContactFragment.class); - - @Mock MailJetService mailJetService; - - @Rule public final CnjDaggerRule daggerRule = new CnjDaggerRule(); - - @Before public void setUp() { - when(mailJetService.sendEmail(anyString(), anyString(), anyString(), anyString())) - .thenReturn(Observable.just(null).doOnNext(TestUtils.sleepAction())); - } - - @Test public void testContactFragment() { - fragmentRule.launchFragment(); - - onView(withId(R.id.name)).perform(ViewActions.typeText("name")); - onView(withId(R.id.email)).perform(ViewActions.typeText("email@email.it")); - onView(withId(R.id.message)).perform(ViewActions.typeText("message")); - - onView(withId(R.id.send_button)).perform(scrollTo(), click()); - } -} \ No newline at end of file diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/contact/ContactFragmentTest.kt b/app/src/androidTest/java/it/cosenonjaviste/ui/contact/ContactFragmentTest.kt new file mode 100644 index 0000000..138df5d --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/ui/contact/ContactFragmentTest.kt @@ -0,0 +1,43 @@ +package it.cosenonjaviste.ui.contact + +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.action.ViewActions +import android.support.test.espresso.action.ViewActions.click +import android.support.test.espresso.action.ViewActions.scrollTo +import android.support.test.espresso.matcher.ViewMatchers.withId +import it.cosenonjaviste.R +import it.cosenonjaviste.androidtest.base.FragmentRule +import it.cosenonjaviste.androidtest.utils.TestUtils +import it.cosenonjaviste.model.MailJetService +import it.cosenonjaviste.ui.CnjDaggerRule +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.Matchers.anyString +import org.mockito.Mock +import org.mockito.Mockito.`when` +import retrofit.client.Response +import rx.Observable + +class ContactFragmentTest { + @get:Rule var fragmentRule = FragmentRule(ContactFragment::class.java) + + @Mock lateinit var mailJetService: MailJetService + + @get:Rule val daggerRule = CnjDaggerRule() + + @Before fun setUp() { + `when`(mailJetService!!.sendEmail(anyString(), anyString(), anyString(), anyString())) + .thenReturn(Observable.just(null).doOnNext { a -> TestUtils.sleep(1) }) + } + + @Test fun testContactFragment() { + fragmentRule.launchFragment() + + onView(withId(R.id.name)).perform(ViewActions.typeText("name")) + onView(withId(R.id.email)).perform(ViewActions.typeText("email@email.it")) + onView(withId(R.id.message)).perform(ViewActions.typeText("message")) + + onView(withId(R.id.send_button)).perform(scrollTo(), click()) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/page/PageFragmentTest.java b/app/src/androidTest/java/it/cosenonjaviste/ui/page/PageFragmentTest.java deleted file mode 100644 index f494177..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/ui/page/PageFragmentTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package it.cosenonjaviste.ui.page; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.androidtest.base.FragmentRule; -import it.cosenonjaviste.androidtest.base.MockWebServerWrapper; -import it.cosenonjaviste.androidtest.utils.TestUtils; -import it.cosenonjaviste.ui.CnjDaggerRule; - -public class PageFragmentTest { - - MockWebServerWrapper server = new MockWebServerWrapper(); - - @Rule public FragmentRule fragmentRule = new FragmentRule(PageFragment.class); - - @Rule public final CnjDaggerRule daggerRule = new CnjDaggerRule(); - - @Before public void setUp() { - server.initDispatcher("CoseNonJaviste
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A"); - } - - @Test public void testDetailFragment() { - fragmentRule.launchFragment(TestData.createPost(1, server.getUrl(false) + "abc")); - TestUtils.sleep(100); - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/page/PageFragmentTest.kt b/app/src/androidTest/java/it/cosenonjaviste/ui/page/PageFragmentTest.kt new file mode 100644 index 0000000..4227c73 --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/ui/page/PageFragmentTest.kt @@ -0,0 +1,28 @@ +package it.cosenonjaviste.ui.page + +import it.cosenonjaviste.TestData +import it.cosenonjaviste.androidtest.base.FragmentRule +import it.cosenonjaviste.androidtest.base.MockWebServerWrapper +import it.cosenonjaviste.androidtest.utils.TestUtils +import it.cosenonjaviste.ui.CnjDaggerRule +import org.junit.Before +import org.junit.Rule +import org.junit.Test + +class PageFragmentTest { + + internal var server = MockWebServerWrapper() + + @get:Rule val fragmentRule = FragmentRule(PageFragment::class.java) + + @get:Rule val daggerRule = CnjDaggerRule() + + @Before fun setUp() { + server.initDispatcher("CoseNonJaviste
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A
A") + } + + @Test fun testDetailFragment() { + fragmentRule.launchFragment(TestData.createPost(1, server.getUrl(false) + "abc")) + TestUtils.sleep(100) + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/post/PostListFragmentTest.java b/app/src/androidTest/java/it/cosenonjaviste/ui/post/PostListFragmentTest.java deleted file mode 100644 index a5da543..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/ui/post/PostListFragmentTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package it.cosenonjaviste.ui.post; - -import android.support.test.espresso.contrib.RecyclerViewActions; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import it.cosenonjaviste.R; -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.androidtest.base.FragmentRule; -import it.cosenonjaviste.core.post.PostListModel; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.CnjDaggerRule; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; - -public class PostListFragmentTest { - - @Mock WordPressService wordPressService; - - @Rule public FragmentRule fragmentRule = new FragmentRule(PostListFragment.class); - - @Rule public final CnjDaggerRule daggerRule = new CnjDaggerRule(); - - @Before public void setUp() { - when(wordPressService.listPosts(eq(1))) - .thenReturn(TestData.postResponse(0, 10)); - when(wordPressService.listPosts(eq(2))) - .thenReturn(TestData.postResponse(10, 10)); - } - - @Test public void testPostList() throws InterruptedException { - fragmentRule.launchFragment(new PostListModel()); - - onView(withText("post title 1")).check(matches(isDisplayed())); - } - - @Test public void testGoToPostDetail() { - fragmentRule.launchFragment(new PostListModel()); - - onView(withId(R.id.list)) - .perform(RecyclerViewActions.actionOnItemAtPosition(3, click())); - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/post/PostListFragmentTest.kt b/app/src/androidTest/java/it/cosenonjaviste/ui/post/PostListFragmentTest.kt new file mode 100644 index 0000000..d0242ba --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/ui/post/PostListFragmentTest.kt @@ -0,0 +1,50 @@ +package it.cosenonjaviste.ui.post + +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.action.ViewActions.click +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.contrib.RecyclerViewActions +import android.support.test.espresso.matcher.ViewMatchers.* +import android.support.v7.widget.RecyclerView +import it.cosenonjaviste.R +import it.cosenonjaviste.TestData +import it.cosenonjaviste.androidtest.base.FragmentRule +import it.cosenonjaviste.core.post.PostListModel +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.CnjDaggerRule +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.Matchers.eq +import org.mockito.Mock +import org.mockito.Mockito.`when` + +class PostListFragmentTest { + + @Mock lateinit var wordPressService: WordPressService + + @get:Rule var fragmentRule = FragmentRule(PostListFragment::class.java) + + @get:Rule val daggerRule = CnjDaggerRule() + + @Before fun setUp() { + `when`(wordPressService.listPosts(eq(1))) + .thenReturn(TestData.postResponse(0, 10)) + `when`(wordPressService.listPosts(eq(2))) + .thenReturn(TestData.postResponse(10, 10)) + } + + @Test @Throws(InterruptedException::class) + fun testPostList() { + fragmentRule.launchFragment(PostListModel()) + + onView(withText("post title 1")).check(matches(isDisplayed())) + } + + @Test fun testGoToPostDetail() { + fragmentRule.launchFragment(PostListModel()) + + onView(withId(R.id.list)) + .perform(RecyclerViewActions.actionOnItemAtPosition(3, click())) + } +} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/twitter/TweetListFragmentTest.java b/app/src/androidTest/java/it/cosenonjaviste/ui/twitter/TweetListFragmentTest.java deleted file mode 100644 index e85d40b..0000000 --- a/app/src/androidTest/java/it/cosenonjaviste/ui/twitter/TweetListFragmentTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package it.cosenonjaviste.ui.twitter; - -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.androidtest.base.FragmentRule; -import it.cosenonjaviste.core.twitter.TweetListModel; -import it.cosenonjaviste.model.TwitterService; -import it.cosenonjaviste.ui.CnjDaggerRule; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; - -@RunWith(AndroidJUnit4.class) -public class TweetListFragmentTest { - - @Mock TwitterService twitterService; - - @Rule public FragmentRule fragmentRule = new FragmentRule(TweetListFragment.class); - - @Rule public final CnjDaggerRule daggerRule = new CnjDaggerRule(); - - @Test public void testTweetList() { - when(twitterService.loadTweets(eq(1))) - .thenReturn(TestData.tweets(10)); - - fragmentRule.launchFragment(new TweetListModel()); - - onView(withText("tweet text 1")).check(matches(isDisplayed())); - } -} diff --git a/app/src/androidTest/java/it/cosenonjaviste/ui/twitter/TweetListFragmentTest.kt b/app/src/androidTest/java/it/cosenonjaviste/ui/twitter/TweetListFragmentTest.kt new file mode 100644 index 0000000..727fd67 --- /dev/null +++ b/app/src/androidTest/java/it/cosenonjaviste/ui/twitter/TweetListFragmentTest.kt @@ -0,0 +1,34 @@ +package it.cosenonjaviste.ui.twitter + +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.support.test.espresso.matcher.ViewMatchers.withText +import it.cosenonjaviste.TestData +import it.cosenonjaviste.androidtest.base.FragmentRule +import it.cosenonjaviste.core.twitter.TweetListModel +import it.cosenonjaviste.model.TwitterService +import it.cosenonjaviste.ui.CnjDaggerRule +import org.junit.Rule +import org.junit.Test +import org.mockito.Matchers.eq +import org.mockito.Mock +import org.mockito.Mockito.`when` + +class TweetListFragmentTest { + + @Mock lateinit var twitterService: TwitterService + + @get:Rule val fragmentRule = FragmentRule(TweetListFragment::class.java) + + @get:Rule val daggerRule = CnjDaggerRule() + + @Test fun testTweetList() { + `when`(twitterService.loadTweets(eq(1))) + .thenReturn(TestData.tweets(10)) + + fragmentRule.launchFragment(TweetListModel()) + + onView(withText("tweet text 1")).check(matches(isDisplayed())) + } +} diff --git a/app/src/sharedTest/java/it/cosenonjaviste/TestData.java b/app/src/sharedTest/java/it/cosenonjaviste/TestData.java deleted file mode 100644 index 44efb15..0000000 --- a/app/src/sharedTest/java/it/cosenonjaviste/TestData.java +++ /dev/null @@ -1,67 +0,0 @@ -package it.cosenonjaviste; - -import java.util.Date; -import java.util.List; - -import it.cosenonjaviste.model.Author; -import it.cosenonjaviste.model.AuthorResponse; -import it.cosenonjaviste.model.Category; -import it.cosenonjaviste.model.CategoryResponse; -import it.cosenonjaviste.model.Post; -import it.cosenonjaviste.model.PostResponse; -import it.cosenonjaviste.model.Tweet; -import rx.Observable; - -public class TestData { - - public static Observable postResponse(int size) { - return postResponse(0, size); - } - - public static Observable postResponse(int start, int size) { - return Observable.range(start, size) - .map(TestData::createPost) - .toList() - .map(PostResponse::create); - } - - public static Post createPost(int i) { - return createPost(i, "url " + i); - } - - public static Post createPost(int i, String url) { - return Post.create(i, createAuthor(i), "post title " + i, new Date(), url, "excerpt " + i); - } - - public static Author createAuthor(int i) { - return Author.create(i, "name " + i, "last name " + i, "email " + i); - } - - public static Observable authorResponse(int size) { - return Observable.range(0, size) - .map(TestData::createAuthor) - .toList() - .map(AuthorResponse::create); - } - - public static Observable categoryResponse(int size) { - return Observable.range(0, size) - .map(TestData::createCategory) - .toList() - .map(CategoryResponse::create); - } - - private static Category createCategory(int i) { - return Category.create(i, "cat " + i, 10 + i); - } - - public static Observable> tweets(int count) { - return Observable.range(0, count) - .map(TestData::createTweet) - .toList(); - } - - public static Tweet createTweet(int i) { - return Tweet.create(123, "tweet text " + i, new Date(), "image", "author"); - } -} diff --git a/app/src/sharedTest/java/it/cosenonjaviste/TestData.kt b/app/src/sharedTest/java/it/cosenonjaviste/TestData.kt new file mode 100644 index 0000000..741f7c5 --- /dev/null +++ b/app/src/sharedTest/java/it/cosenonjaviste/TestData.kt @@ -0,0 +1,56 @@ +package it.cosenonjaviste + +import it.cosenonjaviste.model.* +import rx.Observable +import rx.functions.Func1 +import java.util.* + +object TestData { + + fun postResponse(size: Int): Observable { + return postResponse(0, size) + } + + fun postResponse(start: Int, size: Int): Observable { + return Observable.range(start, size) + .map(Func1 { createPost(it.toLong()) }) + .toList() + .map(Func1, PostResponse> { PostResponse.create(it) }) + } + + @JvmOverloads fun createPost(i: Long, url: String = "url " + i): Post { + return Post.create(i, createAuthor(i), "post title " + i, Date(), url, "excerpt " + i) + } + + fun createAuthor(i: Long): Author { + return Author.create(i, "name " + i, "last name " + i, "email " + i) + } + + fun authorResponse(size: Int): Observable { + return Observable.range(0, size) + .map(Func1 { createAuthor(it.toLong()) }) + .toList() + .map(Func1, AuthorResponse> { AuthorResponse.create(it) }) + } + + fun categoryResponse(size: Int): Observable { + return Observable.range(0, size) + .map(Func1 { createCategory(it) }) + .toList() + .map(Func1, CategoryResponse> { CategoryResponse.create(it) }) + } + + private fun createCategory(i: Int): Category { + return Category.create(i.toLong(), "cat " + i, 10 + i) + } + + fun tweets(count: Int): Observable> { + return Observable.range(0, count) + .map(Func1 { createTweet(it) }) + .toList() + } + + fun createTweet(i: Int): Tweet { + return Tweet.create(123, "tweet text " + i, Date(), "image", "author") + } +} diff --git a/app/src/test/java/it/cosenonjaviste/core/CnjJUnitDaggerRule.java b/app/src/test/java/it/cosenonjaviste/core/CnjJUnitDaggerRule.java deleted file mode 100644 index 44bab19..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/CnjJUnitDaggerRule.java +++ /dev/null @@ -1,44 +0,0 @@ -package it.cosenonjaviste.core; - -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; - -import it.cosenonjaviste.daggermock.DaggerMockRule; -import it.cosenonjaviste.model.TwitterService; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.AppModule; -import it.cosenonjaviste.ui.ApplicationComponent; -import rx.Scheduler; -import rx.android.plugins.RxAndroidPlugins; -import rx.android.plugins.RxAndroidSchedulersHook; -import rx.plugins.RxJavaHooks; -import rx.schedulers.Schedulers; - -public class CnjJUnitDaggerRule extends DaggerMockRule { - public CnjJUnitDaggerRule() { - super(ApplicationComponent.class, new AppModule(null)); - providesMock(WordPressService.class, TwitterService.class); - } - - @Override public Statement apply(Statement base, FrameworkMethod method, Object target) { - Statement superStatement = super.apply(base, method, target); - return new Statement() { - @Override public void evaluate() throws Throwable { - RxJavaHooks.setOnIOScheduler(scheduler -> Schedulers.immediate()); - RxJavaHooks.setOnComputationScheduler(scheduler -> Schedulers.immediate()); - RxJavaHooks.setOnNewThreadScheduler(scheduler -> Schedulers.immediate()); - RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() { - @Override public Scheduler getMainThreadScheduler() { - return Schedulers.immediate(); - } - }); - try { - superStatement.evaluate(); - } finally { - RxJavaHooks.reset(); - RxAndroidPlugins.getInstance().reset(); - } - } - }; - } -} diff --git a/app/src/test/java/it/cosenonjaviste/core/CnjJUnitDaggerRule.kt b/app/src/test/java/it/cosenonjaviste/core/CnjJUnitDaggerRule.kt new file mode 100644 index 0000000..a5c486a --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/CnjJUnitDaggerRule.kt @@ -0,0 +1,43 @@ +package it.cosenonjaviste.core + +import it.cosenonjaviste.daggermock.DaggerMockRule +import it.cosenonjaviste.model.TwitterService +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.AppModule +import it.cosenonjaviste.ui.ApplicationComponent +import org.junit.runners.model.FrameworkMethod +import org.junit.runners.model.Statement +import rx.Scheduler +import rx.android.plugins.RxAndroidPlugins +import rx.android.plugins.RxAndroidSchedulersHook +import rx.plugins.RxJavaHooks +import rx.schedulers.Schedulers + +class CnjJUnitDaggerRule : DaggerMockRule(ApplicationComponent::class.java, AppModule(null)) { + init { + providesMock(WordPressService::class.java, TwitterService::class.java) + } + + override fun apply(base: Statement, method: FrameworkMethod?, target: Any): Statement { + val superStatement = super.apply(base, method, target) + return object : Statement() { + @Throws(Throwable::class) + override fun evaluate() { + RxJavaHooks.setOnIOScheduler { scheduler -> Schedulers.immediate() } + RxJavaHooks.setOnComputationScheduler { scheduler -> Schedulers.immediate() } + RxJavaHooks.setOnNewThreadScheduler { scheduler -> Schedulers.immediate() } + RxAndroidPlugins.getInstance().registerSchedulersHook(object : RxAndroidSchedulersHook() { + override fun getMainThreadScheduler(): Scheduler { + return Schedulers.immediate() + } + }) + try { + superStatement.evaluate() + } finally { + RxJavaHooks.reset() + RxAndroidPlugins.getInstance().reset() + } + } + } + } +} diff --git a/app/src/test/java/it/cosenonjaviste/core/ParcelableTester.java b/app/src/test/java/it/cosenonjaviste/core/ParcelableTester.java deleted file mode 100644 index d2987b4..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/ParcelableTester.java +++ /dev/null @@ -1,168 +0,0 @@ -package it.cosenonjaviste.core; - -import android.os.BadParcelableException; -import android.os.Parcel; -import android.os.Parcelable; -import android.support.annotation.NonNull; - -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyByte; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.when; - -public class ParcelableTester { - public static void check(T parcelable, Parcelable.Creator creator) { -// Parcel parcel = createParcel(); -// -// parcelable.writeToParcel(parcel, 0); -// -// T loadedData = creator.createFromParcel(parcel); -// -// Gson gson = new Gson(); -// String s1 = gson.toJson(parcelable); -// String s2 = gson.toJson(loadedData); -// -// assertThat(s2).isEqualTo(s1); -// -// assertThat(parcelable.describeContents()).isEqualTo(0); -// assertThat(creator.newArray(2)).hasSize(2); - } - - @NonNull public static Parcel createParcel() { - Parcel parcel = Mockito.mock(Parcel.class); - - LinkedList parcelData = new LinkedList<>(); - - Answer writeAnswer = invocation -> { - parcelData.add(invocation.getArguments()[0]); - return null; - }; - Answer readAnswer = invocation -> parcelData.removeFirst(); - - doAnswer(writeAnswer).when(parcel).writeInt(anyInt()); - when(parcel.readInt()).thenAnswer(readAnswer); - - doAnswer(writeAnswer).when(parcel).writeLong(anyLong()); - when(parcel.readLong()).thenAnswer(readAnswer); - - doAnswer(writeAnswer).when(parcel).writeString(anyString()); - when(parcel.readString()).thenAnswer(readAnswer); - - doAnswer(writeAnswer).when(parcel).writeByte(anyByte()); - when(parcel.readByte()).thenAnswer(readAnswer); - - doAnswer(invocation -> { - List list = (List) invocation.getArguments()[0]; - writeList(parcelData, invocation, list); - return null; - }).when(parcel).writeList(any()); - doAnswer(invocation -> { - List list = (List) invocation.getArguments()[0]; - readList(parcelData, invocation, list); - return null; - }).when(parcel).readList(any(), any()); - - doAnswer(invocation -> { - Parcelable[] parcelables = (Parcelable[]) invocation.getArguments()[0]; - writeList(parcelData, invocation, parcelables == null ? null : Arrays.asList(parcelables)); - return null; - }).when(parcel).writeParcelableArray(any(), anyInt()); - doAnswer(invocation -> { - List list = new ArrayList<>(); - readList(parcelData, invocation, list); - return list.toArray(new Parcelable[list.size()]); - }).when(parcel).readParcelableArray(any()); - - doAnswer(invocation -> { - Parcelable parcelable = (Parcelable) invocation.getArguments()[0]; - writeParcelable(parcelData, parcelable, (Parcel) invocation.getMock()); - return null; - }).when(parcel).writeParcelable(any(), anyInt()); - when(parcel.readParcelable(any())).thenAnswer(invocation -> readParcelable(parcelData, (Parcel) invocation.getMock())); - - return parcel; - } - - private static void readList(LinkedList parcelData, InvocationOnMock invocation, List list) { - int size = (int) parcelData.removeFirst(); - if (size > 0) { - for (int i = 0; i < size; i++) { - list.add(readParcelable(parcelData, (Parcel) invocation.getMock())); - } - } - } - - private static void writeList(LinkedList parcelData, InvocationOnMock invocation, List list) { - if (list == null) { - parcelData.add(-1); - } else { - parcelData.add(list.size()); - for (Parcelable item : list) { - writeParcelable(parcelData, item, (Parcel) invocation.getMock()); - } - } - } - - private static Parcelable readParcelable(LinkedList parcelData, Parcel parcel1) { - Class parcelableClass = (Class) parcelData.removeFirst(); - if (parcelableClass == null) { - return null; - } else { - Parcelable.Creator parcelableCreator = readParcelableCreator(parcelableClass); - parcelableCreator.newArray(2); - return parcelableCreator.createFromParcel(parcel1); - } - } - - private static void writeParcelable(LinkedList parcelData, Parcelable parcelable, Parcel parcel1) { - if (parcelable == null) { - parcelData.add(null); - } else { - parcelable.describeContents(); - parcelData.add(parcelable.getClass()); - parcelable.writeToParcel(parcel1, 0); - } - } - - private static Parcelable.Creator readParcelableCreator(Class c) { - Parcelable.Creator creator; - try { - Field f = c.getField("CREATOR"); - creator = (Parcelable.Creator) f.get(null); - } catch (IllegalAccessException e) { - throw new BadParcelableException( - "IllegalAccessException when unmarshalling: " + c.getName()); - } catch (ClassCastException e) { - throw new BadParcelableException("Parcelable protocol requires a " - + "Parcelable.Creator object called " - + " CREATOR on class " + c.getName()); - } catch (NoSuchFieldException e) { - throw new BadParcelableException("Parcelable protocol requires a " - + "Parcelable.Creator object called " - + " CREATOR on class " + c.getName()); - } catch (NullPointerException e) { - throw new BadParcelableException("Parcelable protocol requires " - + "the CREATOR object to be static on class " + c.getName()); - } - if (creator == null) { - throw new BadParcelableException("Parcelable protocol requires a " - + "Parcelable.Creator object called " - + " CREATOR on class " + c.getName()); - } - - return creator; - } -} diff --git a/app/src/test/java/it/cosenonjaviste/core/author/AuthorListViewModelTest.java b/app/src/test/java/it/cosenonjaviste/core/author/AuthorListViewModelTest.java deleted file mode 100644 index bfa628c..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/author/AuthorListViewModelTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package it.cosenonjaviste.core.author; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import java.util.Arrays; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.core.Navigator; -import it.cosenonjaviste.core.ParcelableTester; -import it.cosenonjaviste.core.post.PostListArgument; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.author.AuthorListFragment; -import rx.Observable; - -import static it.cosenonjaviste.TestData.authorResponse; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class AuthorListViewModelTest { - - @Rule public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @InjectFromComponent(AuthorListFragment.class) AuthorListViewModel viewModel; - - @Mock WordPressService wordPressService; - - @Mock Navigator navigator; - - @Test - public void testParcelable() { - AuthorListModel model = new AuthorListModel(); - ParcelableTester.check(model, AuthorListModel.CREATOR); - - model.done(Arrays.asList(TestData.createAuthor(1), TestData.createAuthor(2))); - ParcelableTester.check(model, AuthorListModel.CREATOR); - } - - @Test - public void testLoad() { - when(wordPressService.listAuthors()) - .thenReturn(authorResponse(10)); - - AuthorListModel model = viewModel.initAndResume(); - - assertThat(model.size()).isEqualTo(10); - } - - @Test - public void testRetryAfterError() { - when(wordPressService.listAuthors()) - .thenReturn( - Observable.error(new RuntimeException()), - authorResponse(2) - ); - - AuthorListModel model = viewModel.initAndResume(); - - assertThat(model.size()).isEqualTo(0); - - viewModel.reloadData(); - - assertThat(model.size()).isEqualTo(2); - } - - @Test - public void testGoToDetail() { - when(wordPressService.listAuthors()) - .thenReturn(authorResponse(2)); - - AuthorListModel authorListModel = viewModel.initAndResume(); - - viewModel.goToAuthorDetail(1); - - verify(navigator).openPostList(PostListArgument.create(authorListModel.get(1))); - } -} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/author/AuthorListViewModelTest.kt b/app/src/test/java/it/cosenonjaviste/core/author/AuthorListViewModelTest.kt new file mode 100644 index 0000000..e926497 --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/author/AuthorListViewModelTest.kt @@ -0,0 +1,67 @@ +package it.cosenonjaviste.core.author + +import it.cosenonjaviste.TestData.authorResponse +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.core.Navigator +import it.cosenonjaviste.core.post.PostListArgument +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.AuthorResponse +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.author.AuthorListFragment +import org.assertj.core.api.Assertions.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.BDDMockito.given +import org.mockito.Mock +import org.mockito.Mockito.verify +import rx.Observable + +class AuthorListViewModelTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @InjectFromComponent(AuthorListFragment::class) lateinit var viewModel: AuthorListViewModel + + @Mock lateinit var wordPressService : WordPressService + + @Mock lateinit var navigator : Navigator + + @Test + fun testLoad() { + given(wordPressService.listAuthors()) + .willReturn(authorResponse(10)) + + val model = viewModel.initAndResume() + + assertThat(model.size()).isEqualTo(10) + } + + @Test + fun testRetryAfterError() { + given(wordPressService.listAuthors()) + .willReturn( + Observable.error(RuntimeException()), + authorResponse(2) + ) + + val model = viewModel.initAndResume() + + assertThat(model.size()).isEqualTo(0) + + viewModel.reloadData() + + assertThat(model.size()).isEqualTo(2) + } + + @Test + fun testGoToDetail() { + given(wordPressService.listAuthors()) + .willReturn(authorResponse(2)) + + val authorListModel = viewModel.initAndResume() + + viewModel.goToAuthorDetail(1) + + verify(navigator).openPostList(PostListArgument.create(authorListModel.get(1))) + } +} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/category/CategoryListViewModelTest.java b/app/src/test/java/it/cosenonjaviste/core/category/CategoryListViewModelTest.java deleted file mode 100644 index 9e4a0ac..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/category/CategoryListViewModelTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package it.cosenonjaviste.core.category; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import java.util.Arrays; - -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.core.Navigator; -import it.cosenonjaviste.core.ParcelableTester; -import it.cosenonjaviste.core.post.PostListArgument; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.Category; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.category.CategoryListFragment; -import rx.Observable; - -import static it.cosenonjaviste.TestData.categoryResponse; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class CategoryListViewModelTest { - - @Rule public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @Mock WordPressService wordPressService; - - @Mock Navigator navigator; - - @InjectFromComponent(CategoryListFragment.class) CategoryListViewModel viewModel; - - @Test - public void testParcelable() { - CategoryListModel model = new CategoryListModel(); - ParcelableTester.check(model, CategoryListModel.CREATOR); - - model.done(Arrays.asList(Category.create(123, "abc", 3), Category.create(123456, "abcdef", 6))); - ParcelableTester.check(model, CategoryListModel.CREATOR); - } - - @Test - public void testLoad() { - when(wordPressService.listCategories()) - .thenReturn(categoryResponse(3)); - - CategoryListModel model = viewModel.initAndResume(); - - assertThat(model.getItems()).hasSize(3); - Category category = model.get(2); - assertThat(category.id()).isEqualTo(2); - assertThat(category.title()).isEqualTo("cat 2"); - assertThat(category.postCount()).isEqualTo(12); - } - - @Test - public void testLoadAndPullToRefresh() { - when(wordPressService.listCategories()) - .thenReturn(categoryResponse(3), categoryResponse(2)); - - CategoryListModel model = viewModel.initAndResume(); - - assertThat(model.getItems()).hasSize(3); - - viewModel.loadDataPullToRefresh(); - - assertThat(model.getItems()).hasSize(2); - } - - @Test - public void testRetryAfterError() { - when(wordPressService.listCategories()) - .thenReturn(Observable.error(new RuntimeException())); - - CategoryListModel model = viewModel.initAndResume(); - - when(wordPressService.listCategories()) - .thenReturn(categoryResponse(3)); - - viewModel.reloadData(); - - assertThat(model.getItems()).hasSize(3); - } - - @Test - public void testGoToPosts() { - when(wordPressService.listCategories()) - .thenReturn(categoryResponse(3)); - - CategoryListModel categoryListModel = viewModel.initAndResume(); - - viewModel.goToPosts(1); - - verify(navigator).openPostList(PostListArgument.create(categoryListModel.get(1))); - } -} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/category/CategoryListViewModelTest.kt b/app/src/test/java/it/cosenonjaviste/core/category/CategoryListViewModelTest.kt new file mode 100644 index 0000000..7e4807c --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/category/CategoryListViewModelTest.kt @@ -0,0 +1,83 @@ +package it.cosenonjaviste.core.category + +import it.cosenonjaviste.TestData +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.core.Navigator +import it.cosenonjaviste.core.post.PostListArgument +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.CategoryResponse +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.category.CategoryListFragment +import org.assertj.core.api.Assertions.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.BDDMockito.given +import org.mockito.Mock +import org.mockito.Mockito.verify +import rx.Observable + +class CategoryListViewModelTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @Mock lateinit var wordPressService: WordPressService + + @Mock lateinit var navigator: Navigator + + @InjectFromComponent(CategoryListFragment::class) lateinit var viewModel: CategoryListViewModel + + @Test + fun testLoad() { + given(wordPressService.listCategories()) + .willReturn(TestData.categoryResponse(3)) + + val model = viewModel.initAndResume() + + assertThat(model.getItems()).hasSize(3) + val category = model.get(2) + assertThat(category.id()).isEqualTo(2) + assertThat(category.title()).isEqualTo("cat 2") + assertThat(category.postCount()).isEqualTo(12) + } + + @Test + fun testLoadAndPullToRefresh() { + given(wordPressService.listCategories()) + .willReturn(TestData.categoryResponse(3), TestData.categoryResponse(2)) + + val model = viewModel.initAndResume() + + assertThat(model.getItems()).hasSize(3) + + viewModel.loadDataPullToRefresh() + + assertThat(model.getItems()).hasSize(2) + } + + @Test + fun testRetryAfterError() { + given(wordPressService.listCategories()) + .willReturn(Observable.error(RuntimeException())) + + val model = viewModel.initAndResume() + + given(wordPressService.listCategories()) + .willReturn(TestData.categoryResponse(3)) + + viewModel.reloadData() + + assertThat(model.getItems()).hasSize(3) + } + + @Test + fun testGoToPosts() { + given(wordPressService.listCategories()) + .willReturn(TestData.categoryResponse(3)) + + val categoryListModel = viewModel.initAndResume() + + viewModel.goToPosts(1) + + verify(navigator).openPostList(PostListArgument.create(categoryListModel.get(1))) + } +} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/contact/ContactViewModelTest.java b/app/src/test/java/it/cosenonjaviste/core/contact/ContactViewModelTest.java deleted file mode 100644 index 5e9458b..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/contact/ContactViewModelTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package it.cosenonjaviste.core.contact; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import it.cosenonjaviste.R; -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.core.Navigator; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.MailJetService; -import it.cosenonjaviste.ui.contact.ContactFragment; -import rx.Observable; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class ContactViewModelTest { - - @Rule public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @Mock MailJetService mailJetService; - - @Mock Navigator navigator; - - @InjectFromComponent(ContactFragment.class) ContactViewModel viewModel; - - @Test - public void testEmailError() { - ContactModel model = viewModel.initAndResume(); - - compileForm(model, "aaa", "aaa", "aaa"); - viewModel.send(); - - checkErrors(model, 0, R.string.invalid_email, 0); - } - - @Test - public void testMandatoryFields() { - ContactModel model = viewModel.initAndResume(); - - compileForm(model, "", null, ""); - viewModel.send(); - - checkErrors(model, R.string.mandatory_field, R.string.mandatory_field, R.string.mandatory_field); - } - - @Test - public void testSend() { - when(mailJetService.sendEmail(anyString(), anyString(), anyString(), anyString())) - .thenReturn(Observable.just(null)); - - ContactModel model = viewModel.initAndResume(); - - compileForm(model, "aaa", "aaa@aaa.it", "aaabbb"); - viewModel.send(); - - checkErrors(model, 0, 0, 0); - verify(navigator).showMessage(R.string.message_sent); - } - - @Test - public void testSendError() { - when(mailJetService.sendEmail(anyString(), anyString(), anyString(), anyString())) - .thenReturn(Observable.error(new Exception("aaa"))); - - ContactModel model = viewModel.initAndResume(); - - compileForm(model, "aaa", "aaa@aaa.it", "aaabbb"); - viewModel.send(); - - checkErrors(model, 0, 0, 0); - verify(navigator).showMessage(R.string.error_sending_message); - } - - private void compileForm(ContactModel model, String name, String email, String message) { - model.name.set(name); - model.email.set(email); - model.message.set(message); - } - - - private void checkErrors(ContactModel model, int name, int email, int message) { - assertThat(model.nameError.get()).isEqualTo(name); - assertThat(model.emailError.get()).isEqualTo(email); - assertThat(model.messageError.get()).isEqualTo(message); - } -} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/contact/ContactViewModelTest.kt b/app/src/test/java/it/cosenonjaviste/core/contact/ContactViewModelTest.kt new file mode 100644 index 0000000..eb3b535 --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/contact/ContactViewModelTest.kt @@ -0,0 +1,88 @@ +package it.cosenonjaviste.core.contact + +import it.cosenonjaviste.R +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.core.Navigator +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.MailJetService +import it.cosenonjaviste.ui.contact.ContactFragment +import org.assertj.core.api.Assertions.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.Matchers.anyString +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import rx.Observable + +class ContactViewModelTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @Mock lateinit var mailJetService: MailJetService + + @Mock lateinit var navigator: Navigator + + @InjectFromComponent(ContactFragment::class) lateinit var viewModel: ContactViewModel + + @Test + fun testEmailError() { + val model = viewModel.initAndResume() + + compileForm(model, "aaa", "aaa", "aaa") + viewModel.send() + + checkErrors(model, 0, R.string.invalid_email, 0) + } + + @Test + fun testMandatoryFields() { + val model = viewModel.initAndResume() + + compileForm(model, "", null, "") + viewModel.send() + + checkErrors(model, R.string.mandatory_field, R.string.mandatory_field, R.string.mandatory_field) + } + + @Test + fun testSend() { + `when`(mailJetService.sendEmail(anyString(), anyString(), anyString(), anyString())) + .thenReturn(Observable.just(null)) + + val model = viewModel.initAndResume() + + compileForm(model, "aaa", "aaa@aaa.it", "aaabbb") + viewModel.send() + + checkErrors(model, 0, 0, 0) + verify(navigator).showMessage(R.string.message_sent) + } + + @Test + fun testSendError() { + `when`(mailJetService.sendEmail(anyString(), anyString(), anyString(), anyString())) + .thenReturn(Observable.error(Exception("aaa"))) + + val model = viewModel.initAndResume() + + compileForm(model, "aaa", "aaa@aaa.it", "aaabbb") + viewModel.send() + + checkErrors(model, 0, 0, 0) + verify(navigator).showMessage(R.string.error_sending_message) + } + + private fun compileForm(model: ContactModel, name: String, email: String?, message: String) { + model.name.set(name) + model.email.set(email) + model.message.set(message) + } + + + private fun checkErrors(model: ContactModel, name: Int, email: Int, message: Int) { + assertThat(model.nameError.get()).isEqualTo(name) + assertThat(model.emailError.get()).isEqualTo(email) + assertThat(model.messageError.get()).isEqualTo(message) + } +} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/model/JsonStubs.java b/app/src/test/java/it/cosenonjaviste/core/model/JsonStubs.kt similarity index 86% rename from app/src/test/java/it/cosenonjaviste/core/model/JsonStubs.java rename to app/src/test/java/it/cosenonjaviste/core/model/JsonStubs.kt index 8d876ff..54d71c0 100644 --- a/app/src/test/java/it/cosenonjaviste/core/model/JsonStubs.java +++ b/app/src/test/java/it/cosenonjaviste/core/model/JsonStubs.kt @@ -1,11 +1,10 @@ -package it.cosenonjaviste.core.model; +package it.cosenonjaviste.core.model -import com.annimon.stream.Stream; +import com.annimon.stream.Collectors.joining +import com.annimon.stream.Stream -import static com.annimon.stream.Collectors.joining; - -public class JsonStubs { - private static final String SINGLE_POST = "{\n" + +object JsonStubs { + private val SINGLE_POST = "{\n" + " \"id\": 12831,\n" + " \"type\": \"post\",\n" + " \"slug\": \"gestione-di-una-form-con-il-data-binding-android\",\n" + @@ -51,10 +50,10 @@ public class JsonStubs { " ],\n" + " \"comment_count\": 2,\n" + " \"comment_status\": \"open\"\n" + - " }"; + " }" - private static final String POSTS = "{\n" + + private val POSTS = "{\n" + "status: \"ok\",\n" + "count: 6,\n" + "count_total: 183,\n" + @@ -62,20 +61,20 @@ public class JsonStubs { "posts: [\n" + "%s" + "]\n" + - "}"; + "}" - public static String getPostList(int numberOfPost) { - return getPostList(0, numberOfPost); + fun getPostList(numberOfPost: Int): String { + return getPostList(0, numberOfPost) } - public static String getPostList(int firstPost, int numberOfPost) { - String s = Stream.ofRange(0, numberOfPost) - .map(i -> SINGLE_POST.replace("%TITLE%", "post title " + (firstPost + i))) - .collect(joining(",")); - return String.format(POSTS, s); + fun getPostList(firstPost: Int, numberOfPost: Int): String { + val s = Stream.ofRange(0, numberOfPost) + .map({ i -> SINGLE_POST.replace("%TITLE%", "post title " + (firstPost + i)) }) + .collect(joining(",")) + return String.format(POSTS, s) } - public static final String AUTHORS = "{\n" + + val AUTHORS = "{\n" + "status: \"ok\",\n" + "count: 14,\n" + "authors: [\n" + @@ -102,9 +101,9 @@ public static String getPostList(int firstPost, int numberOfPost) { "\t\temail: \"bbb@gmail.com\"\n" + "\t}\n" + "]\n" + - "}"; + "}" - public static final String CATEGORIES = "{\n" + + val CATEGORIES = "{\n" + "status: \"ok\",\n" + "count: 3,\n" + "categories: [\n" + @@ -133,6 +132,6 @@ public static String getPostList(int firstPost, int numberOfPost) { "post_count: 4\n" + "}" + "]" + - "}"; + "}" } diff --git a/app/src/test/java/it/cosenonjaviste/core/model/WordPressServiceTest.java b/app/src/test/java/it/cosenonjaviste/core/model/WordPressServiceTest.java deleted file mode 100644 index a45fdf7..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/model/WordPressServiceTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package it.cosenonjaviste.core.model; - -import com.google.gson.Gson; - -import org.junit.Rule; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.Attachment; -import it.cosenonjaviste.model.Post; -import it.cosenonjaviste.model.PostResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; - -public class WordPressServiceTest { - - @Rule - public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @InjectFromComponent Gson gson; - - @Test - public void testLoadPosts() throws IOException { - PostResponse postResponse = gson.fromJson(JsonStubs.getPostList(1), PostResponse.class); - List posts = postResponse.posts(); - assertThat(posts).hasSize(1); - Post post = posts.get(0); - assertEquals(12831, post.id()); - assertThat(post.date()).isNotNull(); - assertThat(post.title()).isNotEmpty(); - assertThat(post.url()).isNotEmpty(); - assertThat(post.excerptHtml()).isNotEmpty(); - assertThat(post.author()).isNotNull(); - assertThat(post.author().imageUrl()).isNotEmpty(); - assertEquals(2, post.author().id()); - assertThat(post.author().name()).isNotEmpty(); - - List attachments = post.attachments(); - assertThat(attachments).hasSize(1); - assertThat(attachments.get(0).url()).isNotEmpty(); - assertThat(post.imageUrl()).isNotEmpty(); - } -} diff --git a/app/src/test/java/it/cosenonjaviste/core/model/WordPressServiceTest.kt b/app/src/test/java/it/cosenonjaviste/core/model/WordPressServiceTest.kt new file mode 100644 index 0000000..a72c973 --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/model/WordPressServiceTest.kt @@ -0,0 +1,41 @@ +package it.cosenonjaviste.core.model + +import com.google.gson.Gson +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.PostResponse +import org.assertj.core.api.Assertions.assertThat +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test +import java.io.IOException + +class WordPressServiceTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @InjectFromComponent lateinit var gson: Gson + + @Test + @Throws(IOException::class) + fun testLoadPosts() { + val postResponse = gson.fromJson(JsonStubs.getPostList(1), PostResponse::class.java) + val posts = postResponse.posts() + assertThat(posts).hasSize(1) + val post = posts[0] + assertEquals(12831, post.id()) + assertThat(post.date()).isNotNull() + assertThat(post.title()).isNotEmpty() + assertThat(post.url()).isNotEmpty() + assertThat(post.excerptHtml()).isNotEmpty() + assertThat(post.author()).isNotNull() + assertThat(post.author().imageUrl()).isNotEmpty() + assertEquals(2, post.author().id()) + assertThat(post.author().name()).isNotEmpty() + + val attachments = post.attachments() + assertThat(attachments).hasSize(1) + assertThat(attachments[0].url()).isNotEmpty() + assertThat(post.imageUrl()).isNotEmpty() + } +} diff --git a/app/src/test/java/it/cosenonjaviste/core/page/PageViewModelTest.java b/app/src/test/java/it/cosenonjaviste/core/page/PageViewModelTest.java deleted file mode 100644 index 6f5c113..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/page/PageViewModelTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package it.cosenonjaviste.core.page; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.core.Navigator; -import it.cosenonjaviste.core.ParcelableTester; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.Attachment; -import it.cosenonjaviste.model.Author; -import it.cosenonjaviste.model.Post; -import it.cosenonjaviste.ui.page.PageFragment; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.verify; - -public class PageViewModelTest { - - @Rule public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @Mock Navigator navigator; - - @InjectFromComponent(PageFragment.class) PageViewModel viewModel; - - @Test - public void testParcelable() { - PageModel model = new PageModel(); - model.setPost(Post.create(1, Author.create(1, "name", "last", "email"), "title", null, "url", null, Attachment.create("http://aaaa.aa"))); - ParcelableTester.check(model, PageModel.CREATOR); - } - - @Test - public void testLoad() { - viewModel.initAndResume(Post.create(1, Author.create(1, "name", "last", "email"), "title", null, "url", null)); - - assertThat(viewModel.getPost().url()).isEqualTo("url"); - } - - @Test - public void testShare() { - viewModel.initAndResume(TestData.createPost(1)); - - viewModel.share(); - - verify(navigator).share(anyString(), anyString()); - } -} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/page/PageViewModelTest.kt b/app/src/test/java/it/cosenonjaviste/core/page/PageViewModelTest.kt new file mode 100644 index 0000000..624871d --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/page/PageViewModelTest.kt @@ -0,0 +1,40 @@ +package it.cosenonjaviste.core.page + +import it.cosenonjaviste.TestData +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.core.Navigator +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.Author +import it.cosenonjaviste.model.Post +import it.cosenonjaviste.ui.page.PageFragment +import org.assertj.core.api.Assertions.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.Matchers.anyString +import org.mockito.Mock +import org.mockito.Mockito.verify + +class PageViewModelTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @Mock lateinit var navigator: Navigator + + @InjectFromComponent(PageFragment::class) lateinit var viewModel: PageViewModel + + @Test + fun testLoad() { + viewModel.initAndResume(Post.create(1, Author.create(1, "name", "last", "email"), "title", null, "url", null)) + + assertThat(viewModel.post.url()).isEqualTo("url") + } + + @Test + fun testShare() { + viewModel.initAndResume(TestData.createPost(1)) + + viewModel.share() + + verify(navigator).share(anyString(), anyString()) + } +} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/post/AuthorPostListViewModelTest.java b/app/src/test/java/it/cosenonjaviste/core/post/AuthorPostListViewModelTest.java deleted file mode 100644 index bbe5dd2..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/post/AuthorPostListViewModelTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package it.cosenonjaviste.core.post; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import java.util.Arrays; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.core.ParcelableTester; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.post.PostListFragment; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class AuthorPostListViewModelTest { - - @Rule public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @Mock WordPressService wordPressService; - - @InjectFromComponent(PostListFragment.class) PostListViewModel viewModel; - - @Test - public void testParcelable() { - PostListModel model = new PostListModel(); - ParcelableTester.check(model, PostListModel.CREATOR); - - model.done(Arrays.asList(TestData.createPost(1), TestData.createPost(2))); - ParcelableTester.check(model, PostListModel.CREATOR); - } - - @Test - public void testLoad() throws InterruptedException { - when(wordPressService.listAuthorPosts(anyLong(), anyInt())) - .thenReturn(TestData.postResponse(1)); - - PostListModel model = viewModel.initAndResume(PostListArgument.create(TestData.createAuthor(145))); - - assertThat(model.getItems().size()).isEqualTo(1); - verify(wordPressService).listAuthorPosts(eq(145L), eq(1)); - } -} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/post/AuthorPostListViewModelTest.kt b/app/src/test/java/it/cosenonjaviste/core/post/AuthorPostListViewModelTest.kt new file mode 100644 index 0000000..55ce485 --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/post/AuthorPostListViewModelTest.kt @@ -0,0 +1,35 @@ +package it.cosenonjaviste.core.post + +import it.cosenonjaviste.TestData +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.post.PostListFragment +import org.assertj.core.api.Assertions.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.Matchers.* +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify + +class AuthorPostListViewModelTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @Mock lateinit var wordPressService: WordPressService + + @InjectFromComponent(PostListFragment::class) lateinit var viewModel: PostListViewModel + + @Test + @Throws(InterruptedException::class) + fun testLoad() { + `when`(wordPressService.listAuthorPosts(anyLong(), anyInt())) + .thenReturn(TestData.postResponse(1)) + + val model = viewModel.initAndResume(PostListArgument.create(TestData.createAuthor(145))) + + assertThat(model.getItems().size).isEqualTo(1) + verify(wordPressService).listAuthorPosts(eq(145L), eq(1)) + } +} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/post/CategoryPostListViewModelTest.java b/app/src/test/java/it/cosenonjaviste/core/post/CategoryPostListViewModelTest.java deleted file mode 100644 index e6a2214..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/post/CategoryPostListViewModelTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package it.cosenonjaviste.core.post; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.Category; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.post.PostListFragment; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; - -public class CategoryPostListViewModelTest { - - @Rule public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @Mock WordPressService wordPressService; - - @InjectFromComponent(PostListFragment.class) PostListViewModel viewModel; - - @Test - public void testLoad() throws InterruptedException { - when(wordPressService.listCategoryPosts(eq(1L), eq(1))) - .thenReturn(TestData.postResponse(1)); - - PostListModel model = viewModel.initAndResume(PostListArgument.create(Category.create(1, "cat", 10))); - - assertThat(model.getItems().size()).isEqualTo(1); - } - - @Test - public void testLoadMore() { - when(wordPressService.listCategoryPosts(eq(1L), eq(1))) - .thenReturn(TestData.postResponse(10)); - when(wordPressService.listCategoryPosts(eq(1L), eq(2))) - .thenReturn(TestData.postResponse(5)); - - PostListModel model = viewModel.initAndResume(PostListArgument.create(Category.create(1, "cat", 10))); - viewModel.loadNextPage(); - - assertThat(model.getItems().size()).isEqualTo(15); - } -} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/post/CategoryPostListViewModelTest.kt b/app/src/test/java/it/cosenonjaviste/core/post/CategoryPostListViewModelTest.kt new file mode 100644 index 0000000..2d13c5c --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/post/CategoryPostListViewModelTest.kt @@ -0,0 +1,47 @@ +package it.cosenonjaviste.core.post + +import it.cosenonjaviste.TestData +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.Category +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.post.PostListFragment +import org.assertj.core.api.Assertions.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.Matchers.eq +import org.mockito.Mock +import org.mockito.Mockito.`when` + +class CategoryPostListViewModelTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @Mock lateinit var wordPressService: WordPressService + + @InjectFromComponent(PostListFragment::class) lateinit var viewModel: PostListViewModel + + @Test + @Throws(InterruptedException::class) + fun testLoad() { + `when`(wordPressService.listCategoryPosts(eq(1L), eq(1))) + .thenReturn(TestData.postResponse(1)) + + val model = viewModel.initAndResume(PostListArgument.create(Category.create(1, "cat", 10))) + + assertThat(model.getItems().size).isEqualTo(1) + } + + @Test + fun testLoadMore() { + `when`(wordPressService.listCategoryPosts(eq(1L), eq(1))) + .thenReturn(TestData.postResponse(10)) + `when`(wordPressService.listCategoryPosts(eq(1L), eq(2))) + .thenReturn(TestData.postResponse(5)) + + val model = viewModel.initAndResume(PostListArgument.create(Category.create(1, "cat", 10))) + viewModel.loadNextPage() + + assertThat(model.getItems().size).isEqualTo(15) + } +} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/post/PostListViewModelTest.java b/app/src/test/java/it/cosenonjaviste/core/post/PostListViewModelTest.java deleted file mode 100644 index fbf0178..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/post/PostListViewModelTest.java +++ /dev/null @@ -1,121 +0,0 @@ -package it.cosenonjaviste.core.post; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; - -import java.util.List; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.core.Navigator; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.Category; -import it.cosenonjaviste.model.Post; -import it.cosenonjaviste.model.WordPressService; -import it.cosenonjaviste.ui.post.PostListFragment; -import rx.Observable; - -import static it.cosenonjaviste.TestData.postResponse; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class PostListViewModelTest { - - @Rule public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @Mock WordPressService wordPressService; - - @Mock Navigator navigator; - - @Captor ArgumentCaptor captor; - - @InjectFromComponent(PostListFragment.class) PostListViewModel viewModel; - - @Test - public void testLoad() throws InterruptedException { - when(wordPressService.listPosts(eq(1))) - .thenReturn(postResponse(1)); - - PostListModel model = viewModel.initAndResume(); - - assertThat(model.getItems().size()).isEqualTo(1); - } - - @Test - public void testLoadMore() { - when(wordPressService.listPosts(eq(1))) - .thenReturn(postResponse(10)); - when(wordPressService.listPosts(eq(2))) - .thenReturn(postResponse(6)); - - PostListModel model = viewModel.initAndResume(); - viewModel.loadNextPage(); - - List items = model.getItems(); - assertThat(items.size()).isEqualTo(16); - } - - @Test - public void testRetryAfterError() { - when(wordPressService.listPosts(eq(1))) - .thenReturn(Observable.error(new RuntimeException())); - - PostListModel model = viewModel.initAndResume(); - assertThat(viewModel.isError().get()).isTrue(); - - when(wordPressService.listPosts(eq(1))) - .thenReturn(postResponse(6)); - - viewModel.reloadData(); - - assertThat(viewModel.isError().get()).isFalse(); - assertThat(model.getItems().size()).isEqualTo(6); - } - - @Test - public void testGoToDetails() { - when(wordPressService.listPosts(eq(1))) - .thenReturn(postResponse(1)); - - PostListModel model = viewModel.initAndResume(); - Post firstPost = model.getItems().get(0); - - viewModel.goToDetail(0); - - verify(navigator).openDetail(captor.capture()); - Post detailPost = captor.getValue(); - String url = detailPost.url(); - - assertThat(url).isNotNull(); - assertThat(url).isEqualTo(firstPost.url()); - } - - @Test - public void testToolbalTitleNotVisible() { - viewModel.initAndResume(); - - assertThat(viewModel.isToolbarVisible()).isFalse(); - assertThat(viewModel.getToolbarTitle()).isNull(); - } - - @Test - public void testToolbalTitleAuthor() { - viewModel.initAndResume(PostListArgument.create(TestData.createAuthor(1))); - - assertThat(viewModel.isToolbarVisible()).isTrue(); - assertThat(viewModel.getToolbarTitle()).isEqualTo("name 1 last name 1"); - } - - @Test - public void testToolbalTitle() { - viewModel.initAndResume(PostListArgument.create(Category.create(123, "aaa", 1))); - - assertThat(viewModel.isToolbarVisible()).isTrue(); - assertThat(viewModel.getToolbarTitle()).isEqualTo("aaa"); - } -} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/post/PostListViewModelTest.kt b/app/src/test/java/it/cosenonjaviste/core/post/PostListViewModelTest.kt new file mode 100644 index 0000000..207205f --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/post/PostListViewModelTest.kt @@ -0,0 +1,118 @@ +package it.cosenonjaviste.core.post + +import it.cosenonjaviste.TestData +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.core.Navigator +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.Category +import it.cosenonjaviste.model.Post +import it.cosenonjaviste.model.PostResponse +import it.cosenonjaviste.model.WordPressService +import it.cosenonjaviste.ui.post.PostListFragment +import org.assertj.core.api.Assertions.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.ArgumentCaptor +import org.mockito.Captor +import org.mockito.Matchers.eq +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import rx.Observable + +class PostListViewModelTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @Mock lateinit var wordPressService: WordPressService + + @Mock lateinit var navigator: Navigator + + @Captor lateinit var captor: ArgumentCaptor + + @InjectFromComponent(PostListFragment::class) lateinit var viewModel: PostListViewModel + + @Test + @Throws(InterruptedException::class) + fun testLoad() { + `when`(wordPressService.listPosts(eq(1))) + .thenReturn(TestData.postResponse(1)) + + val model = viewModel.initAndResume() + + assertThat(model.getItems().size).isEqualTo(1) + } + + @Test + fun testLoadMore() { + `when`(wordPressService.listPosts(eq(1))) + .thenReturn(TestData.postResponse(10)) + `when`(wordPressService.listPosts(eq(2))) + .thenReturn(TestData.postResponse(6)) + + val model = viewModel.initAndResume() + viewModel.loadNextPage() + + val items = model.getItems() + assertThat(items.size).isEqualTo(16) + } + + @Test + fun testRetryAfterError() { + `when`(wordPressService.listPosts(eq(1))) + .thenReturn(Observable.error(RuntimeException())) + + val model = viewModel.initAndResume() + assertThat(viewModel.isError.get()).isTrue() + + `when`(wordPressService.listPosts(eq(1))) + .thenReturn(TestData.postResponse(6)) + + viewModel.reloadData() + + assertThat(viewModel.isError.get()).isFalse() + assertThat(model.getItems().size).isEqualTo(6) + } + + @Test + fun testGoToDetails() { + `when`(wordPressService.listPosts(eq(1))) + .thenReturn(TestData.postResponse(1)) + + val model = viewModel.initAndResume() + val firstPost = model.getItems()[0] + + viewModel.goToDetail(0) + + verify(navigator).openDetail(captor.capture()) + val detailPost = captor.value + val url = detailPost.url() + + assertThat(url).isNotNull() + assertThat(url).isEqualTo(firstPost.url()) + } + + @Test + fun testToolbalTitleNotVisible() { + viewModel.initAndResume() + + assertThat(viewModel.isToolbarVisible).isFalse() + assertThat(viewModel.toolbarTitle).isNull() + } + + @Test + fun testToolbalTitleAuthor() { + viewModel.initAndResume(PostListArgument.create(TestData.createAuthor(1))) + + assertThat(viewModel.isToolbarVisible).isTrue() + assertThat(viewModel.toolbarTitle).isEqualTo("name 1 last name 1") + } + + @Test + fun testToolbalTitle() { + viewModel.initAndResume(PostListArgument.create(Category.create(123, "aaa", 1))) + + assertThat(viewModel.isToolbarVisible).isTrue() + assertThat(viewModel.toolbarTitle).isEqualTo("aaa") + } +} \ No newline at end of file diff --git a/app/src/test/java/it/cosenonjaviste/core/twitter/TweetListViewModelTest.java b/app/src/test/java/it/cosenonjaviste/core/twitter/TweetListViewModelTest.java deleted file mode 100644 index ef35e34..0000000 --- a/app/src/test/java/it/cosenonjaviste/core/twitter/TweetListViewModelTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package it.cosenonjaviste.core.twitter; - -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; - -import java.util.Arrays; - -import it.cosenonjaviste.TestData; -import it.cosenonjaviste.core.CnjJUnitDaggerRule; -import it.cosenonjaviste.core.ParcelableTester; -import it.cosenonjaviste.daggermock.InjectFromComponent; -import it.cosenonjaviste.model.TwitterService; -import it.cosenonjaviste.ui.twitter.TweetListFragment; -import rx.Observable; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TweetListViewModelTest { - - @Rule public final CnjJUnitDaggerRule daggerRule = new CnjJUnitDaggerRule(); - - @Mock TwitterService twitterService; - - @InjectFromComponent(TweetListFragment.class) TweetListViewModel viewModel; - - @Test - public void testParcelable() { - TweetListModel model = new TweetListModel(); - ParcelableTester.check(model, TweetListModel.CREATOR); - - model.done(Arrays.asList(TestData.createTweet(1), TestData.createTweet(2))); - ParcelableTester.check(model, TweetListModel.CREATOR); - } - - @Test public void testLoadTweets() { - Mockito.when(twitterService.loadTweets(Matchers.eq(1))) - .thenReturn(TestData.tweets(10)); - - TweetListModel model = viewModel.initAndResume(); - - assertThat(model.getItems()).hasSize(10); - } - - @Test public void testRetryAfterError() { - Mockito.when(twitterService.loadTweets(Matchers.eq(1))) - .thenReturn(Observable.error(new RuntimeException())); - - TweetListModel model = viewModel.initAndResume(); - - assertThat(viewModel.isError().get()).isTrue(); - - Mockito.when(twitterService.loadTweets(Matchers.eq(1))) - .thenReturn(TestData.tweets(10)); - - viewModel.reloadData(); - - assertThat(viewModel.isError().get()).isFalse(); - assertThat(model.getItems()).hasSize(10); - } - - @Test public void testLoadMoreTweets() { - Mockito.when(twitterService.loadTweets(Matchers.eq(1))) - .thenReturn(TestData.tweets(20)); - Mockito.when(twitterService.loadTweets(Matchers.eq(2))) - .thenReturn(TestData.tweets(8)); - - TweetListModel tweetListModel = viewModel.initAndResume(); - - assertThat(tweetListModel.getItems()).hasSize(20); - - viewModel.loadNextPage(); - - assertThat(tweetListModel.getItems()).hasSize(28); - } -} diff --git a/app/src/test/java/it/cosenonjaviste/core/twitter/TweetListViewModelTest.kt b/app/src/test/java/it/cosenonjaviste/core/twitter/TweetListViewModelTest.kt new file mode 100644 index 0000000..a10df2b --- /dev/null +++ b/app/src/test/java/it/cosenonjaviste/core/twitter/TweetListViewModelTest.kt @@ -0,0 +1,65 @@ +package it.cosenonjaviste.core.twitter + +import it.cosenonjaviste.TestData +import it.cosenonjaviste.core.CnjJUnitDaggerRule +import it.cosenonjaviste.daggermock.InjectFromComponent +import it.cosenonjaviste.model.Tweet +import it.cosenonjaviste.model.TwitterService +import it.cosenonjaviste.ui.twitter.TweetListFragment +import org.assertj.core.api.Assertions.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.Matchers +import org.mockito.Mock +import org.mockito.Mockito +import rx.Observable + +class TweetListViewModelTest { + + @get:Rule val daggerRule = CnjJUnitDaggerRule() + + @Mock lateinit var twitterService: TwitterService + + @InjectFromComponent(TweetListFragment::class) lateinit var viewModel: TweetListViewModel + + @Test fun testLoadTweets() { + Mockito.`when`(twitterService.loadTweets(Matchers.eq(1))) + .thenReturn(TestData.tweets(10)) + + val model = viewModel.initAndResume() + + assertThat(model.getItems()).hasSize(10) + } + + @Test fun testRetryAfterError() { + Mockito.`when`(twitterService.loadTweets(Matchers.eq(1))) + .thenReturn(Observable.error>(RuntimeException())) + + val model = viewModel.initAndResume() + + assertThat(viewModel.isError.get()).isTrue() + + Mockito.`when`(twitterService.loadTweets(Matchers.eq(1))) + .thenReturn(TestData.tweets(10)) + + viewModel.reloadData() + + assertThat(viewModel.isError.get()).isFalse() + assertThat(model.getItems()).hasSize(10) + } + + @Test fun testLoadMoreTweets() { + Mockito.`when`(twitterService.loadTweets(Matchers.eq(1))) + .thenReturn(TestData.tweets(20)) + Mockito.`when`(twitterService.loadTweets(Matchers.eq(2))) + .thenReturn(TestData.tweets(8)) + + val tweetListModel = viewModel.initAndResume() + + assertThat(tweetListModel.getItems()).hasSize(20) + + viewModel.loadNextPage() + + assertThat(tweetListModel.getItems()).hasSize(28) + } +} diff --git a/build.gradle b/build.gradle index 4a7deb6..cb3dccf 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.0.6' repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.3.0-beta2' classpath 'me.tatarka:gradle-retrolambda:3.4.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files