PinnedSitesStorageTest.kt 9.37 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package mozilla.components.feature.top.sites

import android.content.Context
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.paging.PagedList
import androidx.room.Room
11
12
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
13
import androidx.test.core.app.ApplicationProvider
14
import androidx.test.platform.app.InstrumentationRegistry
Tiger Oakes's avatar
Tiger Oakes committed
15
16
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
17
import mozilla.components.feature.top.sites.db.Migrations
18
19
20
import mozilla.components.feature.top.sites.db.TopSiteDatabase
import org.junit.After
import org.junit.Assert.assertEquals
21
import org.junit.Assert.assertFalse
22
import org.junit.Assert.assertNotNull
23
import org.junit.Assert.assertTrue
24
25
26
27
28
29
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

30
31
private const val MIGRATION_TEST_DB = "migration-test"

32
@Suppress("LargeClass")
33
class PinnedSitesStorageTest {
34
    private lateinit var context: Context
35
    private lateinit var storage: PinnedSiteStorage
36
37
38
39
40
    private lateinit var executor: ExecutorService

    @get:Rule
    var instantTaskExecutorRule = InstantTaskExecutorRule()

41
42
43
44
45
46
47
    @get:Rule
    val helper: MigrationTestHelper = MigrationTestHelper(
        InstrumentationRegistry.getInstrumentation(),
        TopSiteDatabase::class.java.canonicalName,
        FrameworkSQLiteOpenHelperFactory()
    )

48
49
50
51
52
53
54
    @Before
    fun setUp() {
        executor = Executors.newSingleThreadExecutor()

        context = ApplicationProvider.getApplicationContext()
        val database = Room.inMemoryDatabaseBuilder(context, TopSiteDatabase::class.java).build()

55
        storage = PinnedSiteStorage(context)
56
57
58
59
60
61
62
63
64
65
        storage.database = lazy { database }
    }

    @After
    fun tearDown() {
        executor.shutdown()
    }

    @Test
    fun testAddingTopSite() {
66
67
        storage.addPinnedSite("Mozilla", "https://www.mozilla.org")
        storage.addPinnedSite("Firefox", "https://www.firefox.com", isDefault = true)
68
69
70
71
72
73
74

        val topSites = getAllTopSites()

        assertEquals(2, topSites.size)

        assertEquals("Mozilla", topSites[0].title)
        assertEquals("https://www.mozilla.org", topSites[0].url)
75
        assertFalse(topSites[0].isDefault)
76
77
        assertEquals("Firefox", topSites[1].title)
        assertEquals("https://www.firefox.com", topSites[1].url)
78
        assertTrue(topSites[1].isDefault)
79
80
81
82
    }

    @Test
    fun testRemovingTopSites() {
83
84
        storage.addPinnedSite("Mozilla", "https://www.mozilla.org")
        storage.addPinnedSite("Firefox", "https://www.firefox.com")
85
86
87
88

        getAllTopSites().let { topSites ->
            assertEquals(2, topSites.size)

89
            storage.removePinnedSite(topSites[0])
90
91
92
93
94
95
96
97
98
99
100
        }

        getAllTopSites().let { topSites ->
            assertEquals(1, topSites.size)

            assertEquals("Firefox", topSites[0].title)
            assertEquals("https://www.firefox.com", topSites[0].url)
        }
    }

    @Test
Tiger Oakes's avatar
Tiger Oakes committed
101
    fun testGettingTopSites() = runBlocking {
102
103
        storage.addPinnedSite("Mozilla", "https://www.mozilla.org")
        storage.addPinnedSite("Firefox", "https://www.firefox.com", isDefault = true)
104

105
        val topSites = storage.getPinnedSites().first()
106

107
        assertNotNull(topSites)
108
109
110
111
112
        assertEquals(2, topSites.size)

        with(topSites[0]) {
            assertEquals("Mozilla", title)
            assertEquals("https://www.mozilla.org", url)
113
            assertFalse(isDefault)
114
115
116
117
118
        }

        with(topSites[1]) {
            assertEquals("Firefox", title)
            assertEquals("https://www.firefox.com", url)
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
            assertTrue(isDefault)
        }
    }

    @Test
    fun migrate1to2() {
        val dbVersion1 = helper.createDatabase(MIGRATION_TEST_DB, 1).apply {
            execSQL(
                "INSERT INTO " +
                    "top_sites " +
                    "(title, url, created_at) " +
                    "VALUES " +
                    "('Mozilla','mozilla.org',1)," +
                    "('Top Articles','https://getpocket.com/fenix-top-articles',2)," +
                    "('Wikipedia','https://www.wikipedia.org/',3)," +
                    "('YouTube','https://www.youtube.com/',4)"
            )
        }

        dbVersion1.query("SELECT * FROM top_sites").use { cursor ->
            assertEquals(4, cursor.columnCount)
        }

        val dbVersion2 = helper.runMigrationsAndValidate(
            MIGRATION_TEST_DB, 2, true, Migrations.migration_1_2
        ).apply {
            execSQL(
                "INSERT INTO " +
                    "top_sites " +
148
                    "(title, url, is_default, created_at) " +
149
150
151
152
153
154
155
156
157
                    "VALUES " +
                    "('Firefox','firefox.com',1,5)," +
                    "('Monitor','https://monitor.firefox.com/',0,5)"
            )
        }

        dbVersion2.query("SELECT * FROM top_sites").use { cursor ->
            assertEquals(5, cursor.columnCount)

158
            // Check is_default for Mozilla
159
            cursor.moveToFirst()
160
            assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
161

162
            // Check is_default for Top Articles
163
            cursor.moveToNext()
164
            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
165

166
            // Check is_default for Wikipedia
167
            cursor.moveToNext()
168
            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
169

170
            // Check is_default for YouTube
171
            cursor.moveToNext()
172
            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
173

174
            // Check is_default for Firefox
175
            cursor.moveToNext()
176
            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
177

178
            // Check is_default for Monitor
179
            cursor.moveToNext()
180
            assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
181
182
183
        }
    }

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
    @Test
    fun migrate2to3() {
        val dbVersion2 = helper.createDatabase(MIGRATION_TEST_DB, 2).apply {
            execSQL(
                "INSERT INTO " +
                    "top_sites " +
                    "(title, url, is_default, created_at) " +
                    "VALUES " +
                    "('Mozilla','mozilla.org',0,1)," +
                    "('Top Articles','https://getpocket.com/fenix-top-articles',0,2)," +
                    "('Wikipedia','https://www.wikipedia.org/',0,3)," +
                    "('YouTube','https://www.youtube.com/',0,4)"
            )
        }

        dbVersion2.query("SELECT * FROM top_sites").use { cursor ->
            assertEquals(5, cursor.columnCount)
        }

        val dbVersion3 = helper.runMigrationsAndValidate(
            MIGRATION_TEST_DB, 3, true, Migrations.migration_2_3
        )

        dbVersion3.query("SELECT * FROM top_sites").use { cursor ->
            assertEquals(5, cursor.columnCount)
            assertEquals(4, cursor.count)

            // Check isDefault for Mozilla
            cursor.moveToFirst()
            assertEquals("Mozilla", cursor.getString(cursor.getColumnIndexOrThrow("title")))
            assertEquals("mozilla.org", cursor.getString(cursor.getColumnIndexOrThrow("url")))
            assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("created_at")))

            // Check isDefault for Top Articles
            cursor.moveToNext()
            assertEquals("Top Articles", cursor.getString(cursor.getColumnIndexOrThrow("title")))
            assertEquals(
                "https://getpocket.com/fenix-top-articles",
                cursor.getString(cursor.getColumnIndexOrThrow("url"))
            )
            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
            assertEquals(2, cursor.getInt(cursor.getColumnIndexOrThrow("created_at")))

            // Check isDefault for Wikipedia
            cursor.moveToNext()
            assertEquals("Wikipedia", cursor.getString(cursor.getColumnIndexOrThrow("title")))
            assertEquals(
                "https://www.wikipedia.org/",
                cursor.getString(cursor.getColumnIndexOrThrow("url"))
            )
            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
            assertEquals(3, cursor.getInt(cursor.getColumnIndexOrThrow("created_at")))

            // Check isDefault for YouTube
            cursor.moveToNext()
            assertEquals("YouTube", cursor.getString(cursor.getColumnIndexOrThrow("title")))
            assertEquals(
                "https://www.youtube.com/",
                cursor.getString(cursor.getColumnIndexOrThrow("url"))
            )
            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("is_default")))
            assertEquals(4, cursor.getInt(cursor.getColumnIndexOrThrow("created_at")))
        }
    }

250
251
    private fun getAllTopSites(): List<PinnedSite> {
        val dataSource = storage.getPinnedSitesPaged().create()
252
253
254
255
256
257
258
259
260

        val pagedList = PagedList.Builder(dataSource, 10)
            .setNotifyExecutor(executor)
            .setFetchExecutor(executor)
            .build()

        return pagedList.toList()
    }
}