package Ġcom . ste ves ol ty s . seed vault . plugins . saf Ċ Ċ import Ġandroid . database . Content Observer Ċ import Ġandroid . database . Cursor Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . provider . Documents Contract . EXTRA _ LOADING Ċ import Ġandroidx . document file . provider . Document File Ċ import Ġandroidx . test . ext . junit . runners . Android JUnit 4 Ċ import Ġandroidx . test . platform . app . Instrumentation Registry Ċ import Ġcom . ste ves ol ty s . seed vault . assert Read Equals Ċ import Ġcom . ste ves ol ty s . seed vault . co Assert Throws Ċ import Ġcom . ste ves ol ty s . seed vault . getRandom Base 6 4 Ċ import Ġcom . ste ves ol ty s . seed vault . getRandom ByteArray Ċ import Ġcom . ste ves ol ty s . seed vault . settings . Settings Manager Ċ import Ġcom . ste ves ol ty s . seed vault . write And Close Ċ import Ġio . mock k . Runs Ċ import Ġio . mock k . every Ċ import Ġio . mock k . just Ċ import Ġio . mock k . mock k Ċ import Ġio . mock k . slot Ċ import Ġio . mock k . verify Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . Timeout Cancellation Exception Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġorg . junit . After Ċ import Ġorg . junit . Assert . assertArrayEquals Ċ import Ġorg . junit . Assert . assertEquals Ċ import Ġorg . junit . Assert . assertFalse Ċ import Ġorg . junit . Assert . assertNotNull Ċ import Ġorg . junit . Assert . assertTrue Ċ import Ġorg . junit . Before Ċ import Ġorg . junit . Test Ċ import Ġorg . junit . runner . RunWith Ċ import Ġorg . k oin . core . K oin Component Ċ import Ġorg . k oin . core . inject Ċ import Ġjava . io . IOException Ċ import Ġkotlin . random . Random Ċ Ċ @ RunWith ( Android JUnit 4 :: class ) Ċ @ Suppress (" Blocking Method In Non Blocking Context ") Ċ class ĠDocuments Storage Test Ġ: ĠK oin Component Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġcontext Ġ= ĠInstrument ation Registry . get Instrumentation (). target Context ĊĠĠĠ Ġprivate Ġval Ġsettings Manager Ġby Ġinject < Settings Manager >() ĊĠĠĠ Ġprivate Ġval Ġstorage Ġ= ĠDocuments Storage ( context , Ġsettings Manager ) ĊĊĠĠĠ Ġprivate Ġval Ġfilename Ġ= ĠgetRandom Base 6 4 () ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġfile : ĠDocument File ĊĊĠĠĠ Ġ@ Before ĊĠĠĠ Ġfun Ġsetup () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ ĠassertNotNull (" Select Ġa Ġstorage Ġlocation Ġin Ġthe Ġapp Ġfirst !", Ġstorage . root Backup Dir ) ĊĠĠĠĠĠĠĠ Ġfile Ġ= Ġstorage . root Backup Dir ?. create Or Get File ( context , Ġfilename ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġerror (" Could Ġnot Ġcreate Ġtest Ġfile ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ After ĊĠĠĠ Ġfun ĠtearDown () Ġ{ ĊĠĠĠĠĠĠĠ Ġfile . delete () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Writing And Reading File () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġwrite Ġto Ġoutput Ġstream ĊĠĠĠĠĠĠĠ Ġval ĠoutputStream Ġ= Ġstorage . get OutputStream ( file ) ĊĠĠĠĠĠĠĠ Ġval Ġcontent Ġ= ĠByteArray ( 1 3 3 7 ). apply Ġ{ ĠRandom . next Bytes ( this ) Ġ} ĊĠĠĠĠĠĠĠ ĠoutputStream . write ( content ) ĊĠĠĠĠĠĠĠ ĠoutputStream . flush () ĊĠĠĠĠĠĠĠ ĠoutputStream . close () ĊĊĠĠĠĠĠĠĠ Ġ// Ġread Ġwritten Ġdata Ġfrom Ġinput Ġstream ĊĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġstorage . getInputStream ( file ) ĊĠĠĠĠĠĠĠ Ġval Ġread Content Ġ= ĠinputStream . read Bytes () ĊĠĠĠĠĠĠĠ ĠinputStream . close () ĊĠĠĠĠĠĠĠ Ġassert ArrayEquals ( content , Ġread Content ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġwrite Ġsmaller Ġcontent Ġto Ġsame Ġfile ĊĠĠĠĠĠĠĠ Ġval ĠoutputStream 2 Ġ= Ġstorage . get OutputStream ( file ) ĊĠĠĠĠĠĠĠ Ġval Ġcontent 2 Ġ= ĠByteArray ( 4 2 ). apply Ġ{ ĠRandom . next Bytes ( this ) Ġ} ĊĠĠĠĠĠĠĠ ĠoutputStream 2 . write ( content 2 ) ĊĠĠĠĠĠĠĠ ĠoutputStream 2 . flush () ĊĠĠĠĠĠĠĠ ĠoutputStream 2 . close () ĊĊĠĠĠĠĠĠĠ Ġ// Ġread Ġwritten Ġdata Ġfrom Ġinput Ġstream ĊĠĠĠĠĠĠĠ Ġval ĠinputStream 2 Ġ= Ġstorage . getInputStream ( file ) ĊĠĠĠĠĠĠĠ Ġval Ġread Content 2 Ġ= ĠinputStream 2 . read Bytes () ĊĠĠĠĠĠĠĠ ĠinputStream 2 . close () ĊĠĠĠĠĠĠĠ Ġassert ArrayEquals ( content 2 , Ġread Content 2 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Find File () Ġ= Ġrun Blocking ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfound File Ġ= Ġstorage . root Backup Dir !!. find File Blocking ( context , Ġfile . name !! ) ĊĠĠĠĠĠĠĠ ĠassertNotNull ( found File ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( filename , Ġfound File !!. name ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( storage . root Backup Dir !!. uri , Ġfound File . parent File ?. uri ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Create File () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġcreate Ġtest Ġfile ĊĠĠĠĠĠĠĠ Ġval Ġdir Ġ= Ġstorage . root Backup Dir !! ĊĠĠĠĠĠĠĠ Ġval Ġcreated File Ġ= Ġdir . create File (" text ", ĠgetRandom Base 6 4 ()) ĊĠĠĠĠĠĠĠ ĠassertNotNull ( created File ) ĊĠĠĠĠĠĠĠ ĠassertNotNull ( created File !!. name ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġwrite Ġsome Ġdata Ġinto Ġit ĊĠĠĠĠĠĠĠ Ġval Ġdata Ġ= ĠgetRandom ByteArray () ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . open OutputStream ( created File . uri ) !!. write And Close ( data ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġdata Ġshould Ġstill Ġbe Ġthere ĊĠĠĠĠĠĠĠ Ġassert Read Equals ( data , Ġcontext . content Resolver . open InputStream ( created File . uri )) ĊĊĠĠĠĠĠĠĠ Ġ// Ġdelete Ġagain ĊĠĠĠĠĠĠĠ Ġcreated File . delete () ĊĠĠĠĠĠĠĠ ĠassertFalse ( created File . exists ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Create Two Files () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠmimeType Ġ= Ġ" application / octet - stream " ĊĠĠĠĠĠĠĠ Ġval Ġdir Ġ= Ġstorage . root Backup Dir !! ĊĊĠĠĠĠĠĠĠ Ġ// Ġcreate Ġtest Ġfile ĊĠĠĠĠĠĠĠ Ġval Ġname 1 Ġ= ĠgetRandom Base 6 4 ( Random . nextInt ( 1 , Ġ 1 0 )) ĊĠĠĠĠĠĠĠ Ġval Ġfile 1 Ġ= Ġrequire NotNull ( dir . create File ( mime Type , Ġname 1 )) ĊĠĠĠĠĠĠĠ ĠassertTrue ( file 1 . exists ()) ĊĠĠĠĠĠĠĠ ĠassertEquals ( name 1 , Ġfile 1 . name ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 0 L , Ġfile 1 . length ()) ĊĊĠĠĠĠĠĠĠ Ġassert Read Equals ( getRandom ByteArray ( 0 ), Ġcontext . content Resolver . open InputStream ( file 1 . uri )) ĊĊĠĠĠĠĠĠĠ Ġ// Ġwrite Ġsome Ġdata Ġinto Ġit ĊĠĠĠĠĠĠĠ Ġval Ġdata 1 Ġ= ĠgetRandom ByteArray ( 5 Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 0 2 4 ) ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . open OutputStream ( file 1 . uri ) !!. write And Close ( data 1 ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( data 1 . size . to Long (), Ġfile 1 . length ()) ĊĊĠĠĠĠĠĠĠ Ġ// Ġdata Ġshould Ġstill Ġbe Ġthere ĊĠĠĠĠĠĠĠ Ġassert Read Equals ( data 1 , Ġcontext . content Resolver . open InputStream ( file 1 . uri )) ĊĊĠĠĠĠĠĠĠ Ġ// Ġcreate Ġtest Ġfile ĊĠĠĠĠĠĠĠ Ġval Ġname 2 Ġ= ĠgetRandom Base 6 4 ( Random . nextInt ( 1 , Ġ 1 0 )) ĊĠĠĠĠĠĠĠ Ġval Ġfile 2 Ġ= Ġrequire NotNull ( dir . create File ( mime Type , Ġname 2 )) ĊĠĠĠĠĠĠĠ ĠassertTrue ( file 2 . exists ()) ĊĠĠĠĠĠĠĠ ĠassertEquals ( name 2 , Ġfile 2 . name ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġwrite Ġsome Ġdata Ġinto Ġit ĊĠĠĠĠĠĠĠ Ġval Ġdata 2 Ġ= ĠgetRandom ByteArray ( 1 2 Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 0 2 4 ) ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . open OutputStream ( file 2 . uri ) !!. write And Close ( data 2 ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( data 2 . size . to Long (), Ġfile 2 . length ()) ĊĊĠĠĠĠĠĠĠ Ġ// Ġdata Ġshould Ġstill Ġbe Ġthere ĊĠĠĠĠĠĠĠ Ġassert Read Equals ( data 2 , Ġcontext . content Resolver . open InputStream ( file 2 . uri )) ĊĊĠĠĠĠĠĠĠ Ġ// Ġdelete Ġfiles Ġagain ĊĠĠĠĠĠĠĠ Ġfile 1 . delete () ĊĠĠĠĠĠĠĠ Ġfile 2 . delete () ĊĠĠĠĠĠĠĠ ĠassertFalse ( file 1 . exists ()) ĊĠĠĠĠĠĠĠ ĠassertFalse ( file 2 . exists ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun ĠtestGet Loaded Cursor () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġempty Ġcursor Ġextras Ġare Ġlike Ġnot Ġloading , Ġreturns Ġsame Ġcursor Ġright Ġaway ĊĠĠĠĠĠĠĠ Ġval Ġcursor 1 : ĠCursor Ġ= Ġmock k () ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 1 . extras Ġ} Ġreturns ĠBundle () ĊĠĠĠĠĠĠĠ ĠassertEquals ( cursor 1 , Ġget Loaded Cursor Ġ{ Ġcursor 1 Ġ}) ĊĊĠĠĠĠĠĠĠ Ġ// Ġexplicitly Ġnot Ġloading , Ġreturns Ġsame Ġcursor Ġright Ġaway ĊĠĠĠĠĠĠĠ Ġval Ġcursor 2 : ĠCursor Ġ= Ġmock k () ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 2 . extras Ġ} Ġreturns ĠBundle (). apply Ġ{ Ġput Boolean ( EXTRA _ LOADING , Ġfalse ) Ġ} ĊĠĠĠĠĠĠĠ ĠassertEquals ( cursor 2 , Ġget Loaded Cursor Ġ{ Ġcursor 2 Ġ}) ĊĊĠĠĠĠĠĠĠ Ġ// Ġloading Ġcursor Ġregisters Ġcontent Ġobserver , Ġtimes Ġout Ġand Ġcloses Ġcursor ĊĠĠĠĠĠĠĠ Ġval Ġcursor 3 : ĠCursor Ġ= Ġmock k () ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 3 . extras Ġ} Ġreturns ĠBundle (). apply Ġ{ Ġput Boolean ( EXTRA _ LOADING , Ġtrue ) Ġ} ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 3 . register Content Observer ( any ()) Ġ} Ġjust ĠRuns ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 3 . close () Ġ} Ġjust ĠRuns ĊĠĠĠĠĠĠĠ Ġco Assert Throws ( Timeout Cancellation Exception :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Loaded Cursor ( 1 0 0 0 ) Ġ{ Ġcursor 3 Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġverify Ġ{ Ġcursor 3 . register Content Observer ( any ()) Ġ} ĊĠĠĠĠĠĠĠ Ġverify Ġ{ Ġcursor 3 . close () Ġ} Ġ// Ġensure Ġthat Ġcursor Ġgets Ġclosed ĊĊĠĠĠĠĠĠĠ Ġ// Ġloading Ġcursor Ġregisters Ġcontent Ġobserver , Ġbut Ġre - query Ġfails ĊĠĠĠĠĠĠĠ Ġval Ġcursor 4 : ĠCursor Ġ= Ġmock k () ĊĠĠĠĠĠĠĠ Ġval Ġobserver 4 Ġ= Ġslot < Content Observer >() ĊĠĠĠĠĠĠĠ Ġval Ġquery : Ġ() Ġ-> ĠCursor ? Ġ= Ġ{ Ġif Ġ( observer 4 . is Capt ured ) Ġnull Ġelse Ġcursor 4 Ġ} ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 4 . extras Ġ} Ġreturns ĠBundle (). apply Ġ{ Ġput Boolean ( EXTRA _ LOADING , Ġtrue ) Ġ} ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 4 . register Content Observer ( capture ( observer 4 )) Ġ} Ġanswers Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobserver 4 . captured . onChange ( false , ĠUri . parse (" foo :// bar ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 4 . close () Ġ} Ġjust ĠRuns ĊĠĠĠĠĠĠĠ Ġco Assert Throws ( IOException :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Loaded Cursor ( 1 0 _ 0 0 0 , Ġquery ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertTrue ( observer 4 . is Capt ured ) ĊĠĠĠĠĠĠĠ Ġverify Ġ{ Ġcursor 4 . close () Ġ} Ġ// Ġensure Ġthat Ġcursor Ġgets Ġclosed ĊĊĠĠĠĠĠĠĠ Ġ// Ġloading Ġcursor Ġregisters Ġcontent Ġobserver , Ġre - queries Ġand Ġreturns Ġnew Ġresult ĊĠĠĠĠĠĠĠ Ġval Ġcursor 5 : ĠCursor Ġ= Ġmock k () ĊĠĠĠĠĠĠĠ Ġval Ġresult 5 : ĠCursor Ġ= Ġmock k () ĊĠĠĠĠĠĠĠ Ġval Ġobserver 5 Ġ= Ġslot < Content Observer >() ĊĠĠĠĠĠĠĠ Ġval Ġquery 5 : Ġ() Ġ-> ĠCursor ? Ġ= Ġ{ Ġif Ġ( observer 5 . is Capt ured ) Ġresult 5 Ġelse Ġcursor 5 Ġ} ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 5 . extras Ġ} Ġreturns ĠBundle (). apply Ġ{ Ġput Boolean ( EXTRA _ LOADING , Ġtrue ) Ġ} ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 5 . register Content Observer ( capture ( observer 5 )) Ġ} Ġanswers Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobserver 5 . captured . onChange ( false , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġevery Ġ{ Ġcursor 5 . close () Ġ} Ġjust ĠRuns ĊĠĠĠĠĠĠĠ ĠassertEquals ( result 5 , Ġget Loaded Cursor ( 1 0 _ 0 0 0 , Ġquery 5 )) ĊĠĠĠĠĠĠĠ ĠassertTrue ( observer 5 . is Capt ured ) ĊĠĠĠĠĠĠĠ Ġverify Ġ{ Ġcursor 5 . close () Ġ} Ġ// Ġensure Ġthat Ġinitial Ġcursor Ġgot Ġclosed ĊĠĠĠ Ġ} Ċ Ċ } Ċ