1
1
/*
2
- * Copyright (c) 2018 DuckDuckGo
2
+ * Copyright (c) 2024 DuckDuckGo
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
14
14
* limitations under the License.
15
15
*/
16
16
17
- @file:Suppress(" RemoveExplicitTypeArguments" )
18
-
19
- package com.duckduckgo.app.tabs.model
17
+ package com.duckduckgo.tabs.model
20
18
21
19
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
22
20
import androidx.lifecycle.MutableLiveData
23
21
import androidx.room.Room
22
+ import androidx.test.ext.junit.runners.AndroidJUnit4
24
23
import androidx.test.platform.app.InstrumentationRegistry
25
- import com.duckduckgo.app.blockingObserve
26
24
import com.duckduckgo.app.browser.DuckDuckGoUrlDetector
27
25
import com.duckduckgo.app.browser.certificates.BypassedSSLCertificatesRepository
28
26
import com.duckduckgo.app.browser.favicon.FaviconManager
@@ -31,24 +29,42 @@ import com.duckduckgo.app.global.db.AppDatabase
31
29
import com.duckduckgo.app.global.model.SiteFactoryImpl
32
30
import com.duckduckgo.app.privacy.db.UserAllowListRepository
33
31
import com.duckduckgo.app.tabs.db.TabsDao
32
+ import com.duckduckgo.app.tabs.model.TabDataRepository
33
+ import com.duckduckgo.app.tabs.model.TabEntity
34
+ import com.duckduckgo.app.tabs.model.TabSelectionEntity
34
35
import com.duckduckgo.app.tabs.store.TabSwitcherDataStore
35
36
import com.duckduckgo.app.trackerdetection.EntityLookup
36
37
import com.duckduckgo.common.test.CoroutineTestRule
37
38
import com.duckduckgo.common.test.InstantSchedulersRule
39
+ import com.duckduckgo.common.test.blockingObserve
40
+ import com.duckduckgo.common.utils.CurrentTimeProvider
38
41
import com.duckduckgo.duckplayer.api.DuckPlayer
39
42
import com.duckduckgo.privacy.config.api.ContentBlocking
43
+ import java.time.Instant
40
44
import java.time.LocalDateTime
41
45
import java.time.ZoneOffset
42
46
import kotlinx.coroutines.channels.Channel
43
47
import kotlinx.coroutines.flow.consumeAsFlow
44
48
import kotlinx.coroutines.launch
45
49
import kotlinx.coroutines.test.runTest
46
50
import org.junit.After
47
- import org.junit.Assert.*
51
+ import org.junit.Assert.assertEquals
52
+ import org.junit.Assert.assertFalse
53
+ import org.junit.Assert.assertNotNull
54
+ import org.junit.Assert.assertNotSame
55
+ import org.junit.Assert.assertTrue
48
56
import org.junit.Rule
49
57
import org.junit.Test
50
- import org.mockito.kotlin.*
51
-
58
+ import org.junit.runner.RunWith
59
+ import org.mockito.kotlin.any
60
+ import org.mockito.kotlin.anyOrNull
61
+ import org.mockito.kotlin.argumentCaptor
62
+ import org.mockito.kotlin.eq
63
+ import org.mockito.kotlin.mock
64
+ import org.mockito.kotlin.verify
65
+ import org.mockito.kotlin.whenever
66
+
67
+ @RunWith(AndroidJUnit4 ::class )
52
68
class TabDataRepositoryTest {
53
69
54
70
@get:Rule
@@ -206,6 +222,7 @@ class TabDataRepositoryTest {
206
222
val existingTabs = listOf (tab0)
207
223
208
224
whenever(mockDao.tabs()).thenReturn(existingTabs)
225
+ whenever(mockDao.lastTab()).thenReturn(existingTabs.last())
209
226
210
227
testee.add(" http://www.example.com" )
211
228
@@ -468,7 +485,7 @@ class TabDataRepositoryTest {
468
485
@Test
469
486
fun getActiveTabCountReturnsCorrectCountWhenTabsYoungerThanSpecifiedDay () = runTest {
470
487
// Arrange: No tabs in the repository
471
- val now = LocalDateTime . now(ZoneOffset . UTC )
488
+ val now = now()
472
489
val tab1 = TabEntity (tabId = " tab1" , lastAccessTime = now.minusDays(6 ))
473
490
val tab2 = TabEntity (tabId = " tab2" , lastAccessTime = now.minusDays(8 ))
474
491
val tab3 = TabEntity (tabId = " tab3" , lastAccessTime = now.minusDays(10 ))
@@ -497,10 +514,10 @@ class TabDataRepositoryTest {
497
514
@Test
498
515
fun getInactiveTabCountReturnsCorrectCountWhenAllTabsOlderThanSpecifiedDay () = runTest {
499
516
// Arrange: Add some tabs with different last access times
500
- val now = LocalDateTime . now(ZoneOffset . UTC )
517
+ val now = now()
501
518
val tab1 = TabEntity (tabId = " tab1" , lastAccessTime = now.minusDays(8 ))
502
519
val tab2 = TabEntity (tabId = " tab2" , lastAccessTime = now.minusDays(10 ))
503
- val tab3 = TabEntity (tabId = " tab3" , lastAccessTime = now.minusDays(9 ))
520
+ val tab3 = TabEntity (tabId = " tab3" , lastAccessTime = now.minusDays(9 ).minusSeconds( 1 ) )
504
521
val tab4 = TabEntity (tabId = " tab4" )
505
522
whenever(mockDao.tabs()).thenReturn(listOf (tab1, tab2, tab3, tab4))
506
523
val testee = tabDataRepository()
@@ -514,7 +531,7 @@ class TabDataRepositoryTest {
514
531
@Test
515
532
fun getInactiveTabCountReturnsCorrectCountWhenAllTabsInactiveWithinRange () = runTest {
516
533
// Arrange: Add some tabs with different last access times
517
- val now = LocalDateTime . now(ZoneOffset . UTC )
534
+ val now = now()
518
535
val tab1 = TabEntity (tabId = " tab1" , lastAccessTime = now.minusDays(8 ))
519
536
val tab2 = TabEntity (tabId = " tab2" , lastAccessTime = now.minusDays(10 ))
520
537
val tab3 = TabEntity (tabId = " tab3" , lastAccessTime = now.minusDays(9 ))
@@ -531,7 +548,7 @@ class TabDataRepositoryTest {
531
548
@Test
532
549
fun getInactiveTabCountReturnsZeroWhenNoTabsInactiveWithinRange () = runTest {
533
550
// Arrange: Add some tabs with different last access times
534
- val now = LocalDateTime . now(ZoneOffset . UTC )
551
+ val now = now()
535
552
val tab1 = TabEntity (tabId = " tab1" , lastAccessTime = now.minusDays(5 ))
536
553
val tab2 = TabEntity (tabId = " tab2" , lastAccessTime = now.minusDays(6 ))
537
554
val tab3 = TabEntity (tabId = " tab3" , lastAccessTime = now.minusDays(13 ))
@@ -548,7 +565,7 @@ class TabDataRepositoryTest {
548
565
@Test
549
566
fun getInactiveTabCountReturnsCorrectCountWhenSomeTabsInactiveWithinRange () = runTest {
550
567
// Arrange: Add some tabs with different last access times
551
- val now = LocalDateTime . now(ZoneOffset . UTC )
568
+ val now = now()
552
569
val tab1 = TabEntity (tabId = " tab1" , lastAccessTime = now.minusDays(5 ))
553
570
val tab2 = TabEntity (tabId = " tab2" , lastAccessTime = now.minusDays(10 ))
554
571
val tab3 = TabEntity (tabId = " tab3" , lastAccessTime = now.minusDays(15 ))
@@ -572,6 +589,7 @@ class TabDataRepositoryTest {
572
589
faviconManager : FaviconManager = mock(),
573
590
tabSwitcherDataStore : TabSwitcherDataStore = mock(),
574
591
duckDuckGoUrlDetector : DuckDuckGoUrlDetector = mock(),
592
+ timeProvider : CurrentTimeProvider = FakeTimeProvider (),
575
593
): TabDataRepository {
576
594
return TabDataRepository (
577
595
dao,
@@ -588,6 +606,7 @@ class TabDataRepositoryTest {
588
606
webViewPreviewPersister,
589
607
faviconManager,
590
608
tabSwitcherDataStore,
609
+ timeProvider,
591
610
coroutinesTestRule.testScope,
592
611
coroutinesTestRule.testDispatcherProvider,
593
612
)
@@ -608,7 +627,19 @@ class TabDataRepositoryTest {
608
627
return mockDao
609
628
}
610
629
630
+ private fun now (): LocalDateTime {
631
+ return FakeTimeProvider ().localDateTimeNow()
632
+ }
633
+
611
634
companion object {
612
635
const val TAB_ID = " abcd"
613
636
}
637
+
638
+ private class FakeTimeProvider : CurrentTimeProvider {
639
+ var currentTime: Instant = Instant .parse(" 2024-10-16T00:00:00.00Z" )
640
+
641
+ override fun currentTimeMillis (): Long = currentTime.toEpochMilli()
642
+ override fun elapsedRealtime (): Long = throw UnsupportedOperationException ()
643
+ override fun localDateTimeNow (): LocalDateTime = currentTime.atZone(ZoneOffset .UTC ).toLocalDateTime()
644
+ }
614
645
}
0 commit comments