package Ġcom . and res . ny uz uk . presentation . features . search Ċ Ċ import Ġandroidx . appcompat . widget . Search View Ċ import Ġandroidx . core . view . isVisible Ċ import Ġandroidx . lifecycle . Lifecycle Owner Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġassert k . assertThat Ċ import Ġassert k . assertions . isEqualTo Ċ import Ġassert k . assertions . isFalse Ċ import Ġassert k . assertions . isNotNull Ċ import Ġassert k . assertions . isNull Ċ import Ġassert k . assertions . isTrue Ċ import Ġcom . and res . ny uz uk . R Ċ import Ġcom . and res . ny uz uk . presentation . Activity UnitTest Ċ import Ġcom . and res . ny uz uk . presentation . base . Error Dialog Ċ import Ġcom . and res . ny uz uk . presentation . dummy factory . Article Dummy Factory Ċ import Ġcom . and res . ny uz uk . presentation . dummy factory . Error Dummy Factory Ċ import Ġcom . and res . ny uz uk . presentation . entity . Article Ui Ċ import Ġcom . and res . ny uz uk . presentation . extension . isVisible Ċ import Ġcom . and res . ny uz uk . presentation . tools . image loader . Image Loader Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . argument Captor Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . eq Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . verify Ċ import Ġkotlinx . android . synt hetic . main . activity _ search _ articles . layout _ initial Ċ import Ġkotlinx . android . synt hetic . main . activity _ search _ articles . recyclerview _ search _ articles Ċ import Ġkotlinx . android . synt hetic . main . view _ empty . layout _ empty Ċ import Ġkotlinx . android . synt hetic . main . view _ loading . view _ loading Ċ import Ġorg . junit . Test Ċ import Ġorg . k oin . android x . view model . dsl . viewModel Ċ import Ġorg . k oin . dsl . module Ċ import Ġorg . mockito . Argument Matchers Ċ import Ġorg . mockito . Mock Ċ import Ġorg . mockito . Mockito .` when ` Ċ import Ġorg . ro bo lectric . Shadow s Ċ Ċ class ĠArticle Search Activity Test : ĠActivity UnitTest < Article Search ViewState , ĠArticle Search ViewModel , ĠArticle Search Activity >() Ġ{ ĊĠĠĠ Ġprivate Ġval ĠSO ME _ ARTIC LE _ UI Ġ= ĠArticle Dummy Factory . create Article Ui () ĊĠĠĠ Ġprivate Ġval ĠA MOUNT _ OF _ ELEMENT S Ġ= Ġ 3 0 ĊĠĠĠ Ġprivate Ġval ĠSO ME _ SEARCH _ QUERY Ġ= Ġ" technology " ĊĠĠĠ Ġprivate Ġval ĠSO ME _ ERROR _ UI Ġ= ĠError Dummy Factory . create Error Ui () ĊĊĠĠĠ Ġ@ Mock Ġprivate Ġlateinit Ġvar ĠviewModel Mock : ĠArticle Search ViewModel ĊĠĠĠ Ġ@ Mock Ġprivate Ġlateinit Ġvar Ġview State LiveData Mock : ĠMutable LiveData < Article Search ViewState > ĊĠĠĠ Ġ@ Mock Ġprivate Ġlateinit Ġvar Ġimage Loader Mock : ĠImage Loader ĊĠĠĠ Ġ@ Mock Ġprivate Ġlateinit Ġvar Ġerror Dialog Mock : ĠError Dialog ĊĠĠĠ Ġprivate Ġval Ġview State Observer Captor Ġ= Ġargument Captor < Observer < Article Search ViewState >>() ĊĠĠĠ Ġprivate Ġval Ġerror Dialog Dismiss Listener Captor Ġ= Ġargument Captor < () Ġ-> ĠAny >() ĊĊĠĠĠ Ġoverride Ġfun Ġon Setup () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Setup () ĊĠĠĠĠĠĠĠ Ġverify ( view State LiveData Mock ). observe ( Argument Matchers . any ( Lifecycle Owner :: class . java ), Ġview State Observer Captor . capture ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Intent () Ġ= ĠArticle Search Activity . make Intent ( getContext ()) ĊĊĠĠĠ Ġoverride Ġfun Ġsetup Mock ing () Ġ{ ĊĠĠĠĠĠĠĠ Ġ` when `( viewModel Mock . view State ). thenReturn ( view State LiveData Mock ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Module Mock () Ġ= Ġmodule Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel Mock ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsingle Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Loader Mock ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsingle Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Dialog Mock ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġmake Ġthe Ġproper Ġintent `() Ġ{ ĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Ġ= ĠArticle Search Activity . make Intent ( it ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( intent ). isNotNull () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( intent . component . className ). isEqualTo ( Article Search Activity :: class . java . name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġget Ġthe Ġproper Ġlayout Ġresource `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlayout Resource Expected Ġ= ĠR . layout . activity _ search _ articles ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlayout Resource Ġ= Ġit . get Layout Resource () ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( layout Resource ). isEqualTo ( layout Resource Expected ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġtitle Ġbe Ġset Ġwhen Ġcreated `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtitle Expected Ġ= ĠgetContext (). getString ( R . string . search _ articles _ title ) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . title ). isEqualTo ( title Expected ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . recyclerview _ search _ articles . item Animator ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġbe Ġnull Ġitem Animator Ġin Ġre cycler view Ġwhen Ġcreated `() Ġ{ ĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġre cyclerView Ġ= Ġit . recyclerview _ search _ articles ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( re cyclerView . item Animator ). isNull () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġnotify ĠviewModel Ġon Search Click Ġwhen Ġenter Ġquery Ġand Ġsubmit Ġsearch View `() Ġ{ ĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshadow Activity Ġ= ĠShadow s . shadow Of ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsearch MenuItem Ġ= Ġshadow Activity . options Menu . find Item ( R . id . action _ search ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsearch View Ġ= Ġsearch MenuItem . action View Ġas ĠSearch View ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsearch View . set Query ( SO ME _ SEARCH _ QUERY , Ġtrue ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( viewModel Mock ). on Search Click ( eq ( SO ME _ SEARCH _ QUERY )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġnotify ĠviewModel Ġon Search Close Ġwhen Ġcollapse Ġsearch View Ġmenu Item `() Ġ{ ĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshadow Activity Ġ= ĠShadow s . shadow Of ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsearch MenuItem Ġ= Ġshadow Activity . options Menu . find Item ( R . id . action _ search ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsearch MenuItem . collapse Action View () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( viewModel Mock ). on Search Close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġshow Ġview Ġloading Ġwhen Ġset Ġas Ġtrue Ġin Ġview State `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( isLoading Ġ= Ġtrue )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . view _ loading . isVisible ). isTrue () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġhide Ġview Ġloading Ġwhen Ġset Ġas Ġfalse Ġin Ġview State `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( isLoading Ġ= Ġfalse )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . view _ loading . isVisible ). isFalse () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġshow Ġlayout Ġinitial Ġwhen Ġset Ġas Ġtrue Ġin Ġview State `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( is Initial Ġ= Ġtrue )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . layout _ initial . isVisible ). isTrue () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġhide Ġlayout Ġinitial Ġwhen Ġset Ġas Ġfalse Ġin Ġview State `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( is Initial Ġ= Ġfalse )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . layout _ initial . isVisible ). isFalse () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġshow Ġlayout Ġempty Ġwhen Ġset Ġas Ġtrue Ġin Ġview State `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( isEmpty Ġ= Ġtrue )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . layout _ empty . isVisible ). isTrue () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġhide Ġlayout Ġempty Ġwhen Ġset Ġas Ġfalse Ġin Ġview State `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( isEmpty Ġ= Ġfalse )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . layout _ empty . isVisible ). isFalse () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġshow Ġerror Dialog Ġwhen Ġset Ġas Ġtrue Ġin Ġview S ate Ġand Ġalso Ġvalid Ġerror Ui `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( isError Ġ= Ġtrue , Ġerror Ui Ġ= ĠSO ME _ ERROR _ UI )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( error Dialog Mock ). show ( eq ( it ), Ġeq ( SO ME _ ERROR _ UI ), Ġerror Dialog Dismiss Listener Captor . capture ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġnotify ĠviewModel ĠonError Dialog Dismiss Ġwhen Ġdismiss Ġerror Dialog `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( isError Ġ= Ġtrue , Ġerror Ui Ġ= ĠSO ME _ ERROR _ UI )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( error Dialog Mock ). show ( eq ( it ), Ġeq ( SO ME _ ERROR _ UI ), Ġerror Dialog Dismiss Listener Captor . capture ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Dialog Dismiss Listener Captor . first Value . invoke () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( viewModel Mock ). onError Dialog Dismiss () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġbe Ġvisible Ġre cycler view Ġwhen Ġnon Ġempty Ġfound Articles Ui Ġin Ġview State `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( found Articles Ui Ġ= Ġget ListOf Articles Ui ())) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . recyclerview _ search _ articles . isVisible ()). isTrue () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġbe Ġinvisible Ġre cycler view Ġwhen Ġempty Ġfound Articles Ui Ġin Ġview State `() Ġ{ ĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( invalidate List Ġ= Ġtrue , Ġfound Articles Ui Ġ= Ġempty List ())) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( it . recyclerview _ search _ articles . isVisible ()). isFalse () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` should Ġnotify ĠviewModel ĠonLoad More Ġwhen Ġscrolling Ġto Ġthe Ġbottom Ġof Ġthe Ġre cycler view `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠlistOf Articles Ui Ġ= Ġget ListOf Articles Ui () ĊĊĠĠĠĠĠĠĠ Ġview State Observer Captor . first Value . on Changed ( Article Search ViewState ( invalidate List Ġ= Ġfalse , Ġfound Articles Ui Ġ= ĠlistOf Articles Ui )) ĊĊĠĠĠĠĠĠĠ Ġactivity Scenario . on Activity Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . recyclerview _ search _ articles . scrollTo Position ( AMOUNT _ OF _ ELEMENT S Ġ- Ġ 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( viewModel Mock ). on Load More () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget ListOf Articles Ui (): ĠList < Article Ui > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġarticles Ui Ġ= Ġmutable ListOf < Article Ui >() ĊĠĠĠĠĠĠĠ Ġrepeat ( AMOUNT _ OF _ ELEMENT S ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticles Ui . add ( SO ME _ ARTIC LE _ UI ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġarticles Ui ĊĠĠĠ Ġ} Ċ }