11package org.schabi.newpipe.local.history
22
33import androidx.test.core.app.ApplicationProvider
4+ import org.assertj.core.api.Assertions.assertThat
45import org.junit.After
56import org.junit.Assert.assertEquals
6- import org.junit.Assert.assertTrue
77import org.junit.Before
88import org.junit.Rule
99import org.junit.Test
10- import org.junit.rules.Timeout
1110import org.schabi.newpipe.database.AppDatabase
1211import org.schabi.newpipe.database.history.model.SearchHistoryEntry
1312import org.schabi.newpipe.testUtil.TestDatabase
1413import org.schabi.newpipe.testUtil.TrampolineSchedulerRule
14+ import java.time.LocalDateTime
1515import java.time.OffsetDateTime
16- import java.util.concurrent.TimeUnit
16+ import java.time.ZoneOffset
1717
1818class HistoryRecordManagerTest {
1919
@@ -23,9 +23,6 @@ class HistoryRecordManagerTest {
2323 @get:Rule
2424 val trampolineScheduler = TrampolineSchedulerRule ()
2525
26- @get:Rule
27- val timeout = Timeout (1 , TimeUnit .SECONDS )
28-
2926 @Before
3027 fun setup () {
3128 database = TestDatabase .createReplacingNewPipeDatabase()
@@ -45,109 +42,137 @@ class HistoryRecordManagerTest {
4542 // that the number of Lists it returns is exactly 1, we can only check if the first List is
4643 // correct. Why on earth has a Flowable been used instead of a Single for getAll()?!?
4744 val entities = database.searchHistoryDAO().all.blockingFirst()
48- assertEquals( 1 , entities.size )
49- assertEquals( 1 , entities[0 ].id)
50- assertEquals( 0 , entities[0 ].serviceId)
51- assertEquals( " Hello " , entities[0 ].search)
45+ assertThat( entities).hasSize( 1 )
46+ assertThat( entities[0 ].id).isEqualTo( 1 )
47+ assertThat( entities[0 ].serviceId).isEqualTo( 0 )
48+ assertThat( entities[0 ].search).isEqualTo( " Hello " )
5249 }
5350
5451 @Test
5552 fun deleteSearchHistory () {
5653 val entries = listOf (
57- SearchHistoryEntry (OffsetDateTime .now( ), 0 , " A" ),
58- SearchHistoryEntry (OffsetDateTime .now( ), 2 , " A" ),
59- SearchHistoryEntry (OffsetDateTime .now( ), 1 , " B" ),
60- SearchHistoryEntry (OffsetDateTime .now( ), 0 , " B" ),
54+ SearchHistoryEntry (time.minusSeconds( 1 ), 0 , " A" ),
55+ SearchHistoryEntry (time.minusSeconds( 2 ), 2 , " A" ),
56+ SearchHistoryEntry (time.minusSeconds( 3 ), 1 , " B" ),
57+ SearchHistoryEntry (time.minusSeconds( 4 ), 0 , " B" ),
6158 )
6259
6360 // make sure all 4 were inserted
6461 database.searchHistoryDAO().insertAll(entries)
65- assertEquals(entries.size, database.searchHistoryDAO().all.blockingFirst().size )
62+ assertThat( database.searchHistoryDAO().all.blockingFirst()).hasSameSizeAs(entries )
6663
6764 // try to delete only "A" entries, "B" entries should be untouched
6865 manager.deleteSearchHistory(" A" ).test().await().assertValue(2 )
6966 val entities = database.searchHistoryDAO().all.blockingFirst()
70- assertEquals( 2 , entities.size )
71- assertTrue(entries[ 2 ]. hasEqualValues(entities[ 0 ]))
72- assertTrue( entries[ 3 ].hasEqualValues(entities[ 1 ] ))
67+ assertThat( entities).hasSize( 2 )
68+ assertThat(entities).usingElementComparator { o1, o2 -> if (o1. hasEqualValues(o2)) 0 else 1 }
69+ .containsExactly( * entries.subList( 2 , 4 ).toTypedArray( ))
7370
7471 // assert that nothing happens if we delete a search query that does exist in the db
7572 manager.deleteSearchHistory(" A" ).test().await().assertValue(0 )
7673 val entities2 = database.searchHistoryDAO().all.blockingFirst()
77- assertEquals( 2 , entities2.size )
78- assertTrue(entries[ 2 ]. hasEqualValues(entities2[ 0 ]))
79- assertTrue( entries[ 3 ].hasEqualValues(entities2[ 1 ] ))
74+ assertThat( entities2).hasSize( 2 )
75+ assertThat(entities2).usingElementComparator { o1, o2 -> if (o1. hasEqualValues(o2)) 0 else 1 }
76+ .containsExactly( * entries.subList( 2 , 4 ).toTypedArray( ))
8077
8178 // delete all remaining entries
8279 manager.deleteSearchHistory(" B" ).test().await().assertValue(2 )
83- assertEquals( 0 , database.searchHistoryDAO().all.blockingFirst().size )
80+ assertThat( database.searchHistoryDAO().all.blockingFirst()).isEmpty( )
8481 }
8582
8683 @Test
8784 fun deleteCompleteSearchHistory () {
8885 val entries = listOf (
89- SearchHistoryEntry (OffsetDateTime .now( ), 1 , " A" ),
90- SearchHistoryEntry (OffsetDateTime .now( ), 2 , " B" ),
91- SearchHistoryEntry (OffsetDateTime .now( ), 0 , " C" ),
86+ SearchHistoryEntry (time.minusSeconds( 1 ), 1 , " A" ),
87+ SearchHistoryEntry (time.minusSeconds( 2 ), 2 , " B" ),
88+ SearchHistoryEntry (time.minusSeconds( 3 ), 0 , " C" ),
9289 )
9390
9491 // make sure all 3 were inserted
9592 database.searchHistoryDAO().insertAll(entries)
96- assertEquals(entries.size, database.searchHistoryDAO().all.blockingFirst().size )
93+ assertThat( database.searchHistoryDAO().all.blockingFirst()).hasSameSizeAs(entries )
9794
9895 // should remove everything
9996 manager.deleteCompleteSearchHistory().test().await().assertValue(entries.size)
100- assertEquals( 0 , database.searchHistoryDAO().all.blockingFirst().size )
97+ assertThat( database.searchHistoryDAO().all.blockingFirst()).isEmpty( )
10198 }
10299
103- @Test
104- fun getRelatedSearches_emptyQuery () {
100+ private fun insertShuffledRelatedSearches (relatedSearches : Collection <SearchHistoryEntry >) {
101+
102+ // shuffle to make sure the order of items returned by queries depends only on
103+ // SearchHistoryEntry.creationDate, not on the actual insertion time, so that we can
104+ // verify that the `ORDER BY` clause does its job
105+ database.searchHistoryDAO().insertAll(relatedSearches.shuffled())
106+
105107 // make sure all entries were inserted
106- database.searchHistoryDAO().insertAll(RELATED_SEARCHES_ENTRIES )
107108 assertEquals(
108- RELATED_SEARCHES_ENTRIES .size,
109+ relatedSearches .size,
109110 database.searchHistoryDAO().all.blockingFirst().size
110111 )
112+ }
113+
114+ @Test
115+ fun getRelatedSearches_emptyQuery () {
116+ insertShuffledRelatedSearches(RELATED_SEARCHES_ENTRIES )
111117
112118 // make sure correct number of searches is returned and in correct order
113119 val searches = manager.getRelatedSearches(" " , 6 , 4 ).blockingFirst()
114- assertEquals(4 , searches.size)
115- assertEquals(RELATED_SEARCHES_ENTRIES [6 ].search, searches[0 ]) // A (even if in two places)
116- assertEquals(RELATED_SEARCHES_ENTRIES [4 ].search, searches[1 ]) // B
117- assertEquals(RELATED_SEARCHES_ENTRIES [5 ].search, searches[2 ]) // AA
118- assertEquals(RELATED_SEARCHES_ENTRIES [2 ].search, searches[3 ]) // BA
120+ assertThat(searches).containsExactly(
121+ RELATED_SEARCHES_ENTRIES [6 ].search, // A (even if in two places)
122+ RELATED_SEARCHES_ENTRIES [4 ].search, // B
123+ RELATED_SEARCHES_ENTRIES [5 ].search, // AA
124+ RELATED_SEARCHES_ENTRIES [2 ].search, // BA
125+ )
119126 }
120127
121128 @Test
122- fun getRelatedSearched_nonEmptyQuery () {
123- // make sure all entries were inserted
124- database.searchHistoryDAO().insertAll(RELATED_SEARCHES_ENTRIES )
125- assertEquals(
126- RELATED_SEARCHES_ENTRIES .size,
127- database.searchHistoryDAO().all.blockingFirst().size
129+ fun getRelatedSearches_emptyQuery_manyDuplicates () {
130+ insertShuffledRelatedSearches(
131+ listOf (
132+ SearchHistoryEntry (time.minusSeconds(9 ), 3 , " A" ),
133+ SearchHistoryEntry (time.minusSeconds(8 ), 3 , " AB" ),
134+ SearchHistoryEntry (time.minusSeconds(7 ), 3 , " A" ),
135+ SearchHistoryEntry (time.minusSeconds(6 ), 3 , " A" ),
136+ SearchHistoryEntry (time.minusSeconds(5 ), 3 , " BA" ),
137+ SearchHistoryEntry (time.minusSeconds(4 ), 3 , " A" ),
138+ SearchHistoryEntry (time.minusSeconds(3 ), 3 , " A" ),
139+ SearchHistoryEntry (time.minusSeconds(2 ), 0 , " A" ),
140+ SearchHistoryEntry (time.minusSeconds(1 ), 2 , " AA" ),
141+ )
128142 )
129143
144+ val searches = manager.getRelatedSearches(" " , 9 , 3 ).blockingFirst()
145+ assertThat(searches).containsExactly(" AA" , " A" , " BA" )
146+ }
147+
148+ @Test
149+ fun getRelatedSearched_nonEmptyQuery () {
150+ insertShuffledRelatedSearches(RELATED_SEARCHES_ENTRIES )
151+
130152 // make sure correct number of searches is returned and in correct order
131153 val searches = manager.getRelatedSearches(" A" , 3 , 5 ).blockingFirst()
132- assertEquals(3 , searches.size)
133- assertEquals(RELATED_SEARCHES_ENTRIES [6 ].search, searches[0 ]) // A (even if in two places)
134- assertEquals(RELATED_SEARCHES_ENTRIES [5 ].search, searches[1 ]) // AA
135- assertEquals(RELATED_SEARCHES_ENTRIES [1 ].search, searches[2 ]) // BA
154+ assertThat(searches).containsExactly(
155+ RELATED_SEARCHES_ENTRIES [6 ].search, // A (even if in two places)
156+ RELATED_SEARCHES_ENTRIES [5 ].search, // AA
157+ RELATED_SEARCHES_ENTRIES [1 ].search, // BA
158+ )
136159
137160 // also make sure that the string comparison is case insensitive
138161 val searches2 = manager.getRelatedSearches(" a" , 3 , 5 ).blockingFirst()
139- assertEquals (searches, searches2)
162+ assertThat (searches).isEqualTo( searches2)
140163 }
141164
142165 companion object {
143- val RELATED_SEARCHES_ENTRIES = listOf (
144- SearchHistoryEntry (OffsetDateTime .now().minusSeconds(7 ), 2 , " AC" ),
145- SearchHistoryEntry (OffsetDateTime .now().minusSeconds(6 ), 0 , " ABC" ),
146- SearchHistoryEntry (OffsetDateTime .now().minusSeconds(5 ), 1 , " BA" ),
147- SearchHistoryEntry (OffsetDateTime .now().minusSeconds(4 ), 3 , " A" ),
148- SearchHistoryEntry (OffsetDateTime .now().minusSeconds(2 ), 0 , " B" ),
149- SearchHistoryEntry (OffsetDateTime .now().minusSeconds(3 ), 2 , " AA" ),
150- SearchHistoryEntry (OffsetDateTime .now().minusSeconds(1 ), 1 , " A" ),
166+ private val time = OffsetDateTime .of(LocalDateTime .of(2000 , 1 , 1 , 1 , 1 ), ZoneOffset .UTC )
167+
168+ private val RELATED_SEARCHES_ENTRIES = listOf (
169+ SearchHistoryEntry (time.minusSeconds(7 ), 2 , " AC" ),
170+ SearchHistoryEntry (time.minusSeconds(6 ), 0 , " ABC" ),
171+ SearchHistoryEntry (time.minusSeconds(5 ), 1 , " BA" ),
172+ SearchHistoryEntry (time.minusSeconds(4 ), 3 , " A" ),
173+ SearchHistoryEntry (time.minusSeconds(2 ), 0 , " B" ),
174+ SearchHistoryEntry (time.minusSeconds(3 ), 2 , " AA" ),
175+ SearchHistoryEntry (time.minusSeconds(1 ), 1 , " A" ),
151176 )
152177 }
153178}
0 commit comments