Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
a6a45f3
(wip) removing cookies manually based on bookmarks
cmonfortep Apr 17, 2020
bdfbdd3
(wip) tidy up and fallback to previous logic when manual process fails
cmonfortep Apr 17, 2020
4a4ed29
(wip) prototype - send pixels for errors and remove cookie duration
cmonfortep Apr 17, 2020
28530da
Merge branch 'develop' into feature/cristian/webview_database_datasource
cmonfortep Apr 17, 2020
4719e7f
prototype version
cmonfortep Apr 20, 2020
fb18f01
Create new database table to persist sites where cookies should be pr…
cmonfortep Apr 20, 2020
2110a51
* Removed divider from bookmarks list
cmonfortep Apr 20, 2020
2ee0153
bookmarks title show in single line
cmonfortep Apr 20, 2020
0111b3d
background favicon compatible with dark theme
cmonfortep Apr 20, 2020
f4825a3
Include fireproof websites entry cell in settings
cmonfortep Apr 20, 2020
3b463a3
introduce methods to insert or remove preserver cookies entities
cmonfortep Apr 20, 2020
e5cb752
inject dao into viewmodel
cmonfortep Apr 20, 2020
61e15b1
add untranslated strings
cmonfortep Apr 20, 2020
11f27d6
introduce fireproof site option menu and logic for actions
cmonfortep Apr 20, 2020
2cabcd4
Fireproof option menu reacts to database state.
cmonfortep Apr 21, 2020
018dedc
persist original url in order to show favicon in fireproof websites s…
cmonfortep Apr 21, 2020
9e2fbfb
extract original url when fireproof website clicked
cmonfortep Apr 21, 2020
829f112
Fireproof website screen created + logic
cmonfortep Apr 21, 2020
d0a0863
observe fireproof websites dao
cmonfortep Apr 21, 2020
1bd99ee
Big naming refactor. Keeping consistent the domain language to firepr…
cmonfortep Apr 21, 2020
d92fc84
Revert non related work committed
cmonfortep Apr 21, 2020
9db51ef
Merge branch 'develop' into feature/cristian/preserve_sites_ui
cmonfortep Apr 21, 2020
2a09e31
adding more copies to untranslated strings
cmonfortep Apr 23, 2020
7a508d2
Showing single action on Fireproof websites screen item overflow menu
cmonfortep Apr 23, 2020
7b15941
showing snackbar with fireproof website in bold
cmonfortep Apr 23, 2020
1eff472
delete confirmation dialog when removing fireproof website shows webs…
cmonfortep Apr 23, 2020
b6dac2d
clean up
cmonfortep Apr 23, 2020
c628796
renaming on activity layout for fireproof website screen
cmonfortep Apr 23, 2020
25e7d2e
apply code style
cmonfortep Apr 24, 2020
5e81a05
change from coroutine to sync code using local list
cmonfortep Apr 24, 2020
984d825
Fireproof websites adapter shows description
cmonfortep Apr 24, 2020
df650aa
apply ui fixes to bookmarks
cmonfortep Apr 24, 2020
82a3e29
apply ui fixes to fireproof websites
cmonfortep Apr 24, 2020
c0382e7
Merge branch 'develop' into feature/cristian/preserve_sites_ui
cmonfortep Apr 24, 2020
4c19500
removing unused view
cmonfortep Apr 24, 2020
37ed7f9
moving to data package database and adapter to ui
cmonfortep Apr 27, 2020
bd66a9c
removing title and original url from database
cmonfortep Apr 27, 2020
37836ec
command renaming
cmonfortep Apr 27, 2020
baa1786
remove bookmark strings usage from fireproof websites
cmonfortep Apr 27, 2020
79ddd5b
renaming drawable resource bookmark reference
cmonfortep Apr 27, 2020
6632c39
fireproofwebsite title light/dark colors
cmonfortep Apr 27, 2020
249abc6
changed test text neutral
cmonfortep Apr 27, 2020
2edec3d
Merge branch 'develop' into feature/cristian/preserve_sites_ui
cmonfortep Apr 27, 2020
8178ca5
tidy up browsertTabViewModel
cmonfortep Apr 27, 2020
7d51f31
unused method remove
cmonfortep Apr 27, 2020
027aba9
rename favicon background color as it's used in multiple lists
cmonfortep Apr 27, 2020
ace4dd6
Introduced changes on BrowserTabViewModel covered
cmonfortep Apr 27, 2020
b00dda5
fireproofWebsitesViewModel unit tests
cmonfortep Apr 27, 2020
bddca3d
import clean up
cmonfortep Apr 27, 2020
065f011
drop www. prefix when displaying fireproof websites
cmonfortep Apr 29, 2020
acec70e
Merge branch 'feature/cristian/preserve_sites_ui' into feature/cristi…
cmonfortep Apr 29, 2020
1502dfa
Split into different strategies cookie removal and start using firepr…
cmonfortep Apr 29, 2020
b48b272
Inject collaborators into WebViewCookieManager
cmonfortep Apr 29, 2020
d2c75a5
Update WebViewCookieManagerTest
cmonfortep Apr 29, 2020
aaf7a03
Ensure interaction follow concrete order and only DDG are reinjected
cmonfortep Apr 29, 2020
e3d388e
format file
cmonfortep Apr 29, 2020
b09ff60
move logic to remove cookies into an strategy
cmonfortep Apr 30, 2020
0b9baff
Unit testing Remove cookies concrete strategy
cmonfortep Apr 30, 2020
367f72f
extract collaborators from SQLCookieRemover into concrete classes
cmonfortep Apr 30, 2020
4a18299
Testing sqlCookieRemover
cmonfortep Apr 30, 2020
3577871
move class to concrete file
cmonfortep Apr 30, 2020
b325306
WebViewDatabaseLocator tested
cmonfortep Apr 30, 2020
a9c1403
Test GetHostToPreserve
cmonfortep May 1, 2020
5d93af4
Merge branch 'feature/cristian/fireproof_websites' into feature/crist…
cmonfortep May 1, 2020
e7fe76d
remove cookies version name from build.gradle
cmonfortep May 1, 2020
092b0c9
fix test case naming
cmonfortep May 1, 2020
716c21e
fix compile error due to not menu item found
cmonfortep May 1, 2020
00316ca
tidy up unused method in bookmarks dao
cmonfortep May 1, 2020
faa35d5
inject dispatcher into WebViewCookieManager
cmonfortep May 1, 2020
96367e2
unused param remove
cmonfortep May 1, 2020
e324d6d
Class renamed to make explicit reference to cookies
cmonfortep May 2, 2020
dbf42f8
tidiy up imports
cmonfortep May 2, 2020
54f75c8
Use timber.e
cmonfortep May 2, 2020
f8ad402
remove file warnings
cmonfortep May 11, 2020
7453667
removing times(1) as it's default behavior for verify
cmonfortep May 11, 2020
ede0250
grammar suggestion for comment
cmonfortep May 11, 2020
dc58e4c
Replace usage of UncaughtExceptionRepository for ExceptionPixel to re…
cmonfortep May 12, 2020
e55427d
keeping an real counter for unexpected cookie database exceptions and…
cmonfortep May 12, 2020
4708797
Send pixels on database corruption
cmonfortep May 12, 2020
ccf9335
rename for new assert
cmonfortep May 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2020 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.duckduckgo.app.fire

import androidx.room.Room
import androidx.test.platform.app.InstrumentationRegistry
import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteEntity
import com.duckduckgo.app.global.db.AppDatabase
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test

class GetCookieHostsToPreserveTest {

private val context = InstrumentationRegistry.getInstrumentation().targetContext
private val db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build()
private val fireproofWebsiteDao = db.fireproofWebsiteDao()
private val getHostsToPreserve = GetCookieHostsToPreserve(fireproofWebsiteDao)

@Test
fun whenSubDomainFireproofWebsiteThenExpectedListReturned() {
givenFireproofWebsitesStored(FireproofWebsiteEntity("mobile.twitter.com"))
val expectedList = listOf(
".mobile.twitter.com",
"mobile.twitter.com",
".twitter.com",
".com"
)

val hostsToPreserve = getHostsToPreserve()

assertTrue(expectedList.all { hostsToPreserve.contains(it) })
}

@Test
fun whenFireproofWebsiteThenExpectedListReturned() {
givenFireproofWebsitesStored(FireproofWebsiteEntity("twitter.com"))
val expectedList = listOf("twitter.com", ".twitter.com", ".com")

val hostsToPreserve = getHostsToPreserve()

assertTrue(expectedList.all { hostsToPreserve.contains(it) })
}

@Test
fun whenMultipleFireproofWebsiteWithSameTopLevelThenExpectedListReturned() {
givenFireproofWebsitesStored(FireproofWebsiteEntity("twitter.com"))
givenFireproofWebsitesStored(FireproofWebsiteEntity("example.com"))
val expectedList = listOf(
".example.com",
"example.com",
"twitter.com",
".twitter.com",
".com"
)

val hostsToPreserve = getHostsToPreserve()

assertEquals(expectedList.size, hostsToPreserve.size)
assertTrue(expectedList.all { hostsToPreserve.contains(it) })
}

private fun givenFireproofWebsitesStored(fireproofWebsiteEntity: FireproofWebsiteEntity) {
fireproofWebsiteDao.insert(fireproofWebsiteEntity)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2020 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.duckduckgo.app.fire

import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
import com.nhaarman.mockitokotlin2.whenever
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Test

class RemoveCookiesTest {

private val selectiveCookieRemover = mock<CookieRemover>()
private val cookieManagerRemover = mock<CookieRemover>()
private val removeCookies = RemoveCookies(cookieManagerRemover, selectiveCookieRemover)

@Test
fun whenSelectiveCookieRemoverSucceedsThenNoMoreInteractions() = runBlockingTest {
selectiveCookieRemover.succeeds()

removeCookies.removeCookies()

verifyZeroInteractions(cookieManagerRemover)
}

@Test
fun whenSelectiveCookieRemoverFailsThenFallbackToCookieManagerRemover() = runBlockingTest {
selectiveCookieRemover.fails()

removeCookies.removeCookies()

verify(cookieManagerRemover).removeCookies()
}

private suspend fun CookieRemover.succeeds() {
whenever(this.removeCookies()).thenReturn(true)
}

private suspend fun CookieRemover.fails() {
whenever(this.removeCookies()).thenReturn(false)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2020 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.duckduckgo.app.fire

import android.webkit.CookieManager
import androidx.room.Room
import androidx.test.platform.app.InstrumentationRegistry
import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteEntity
import com.duckduckgo.app.global.DefaultDispatcherProvider
import com.duckduckgo.app.global.DispatcherProvider
import com.duckduckgo.app.global.db.AppDatabase
import com.duckduckgo.app.global.exception.RootExceptionFinder
import com.duckduckgo.app.statistics.pixels.ExceptionPixel
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.app.statistics.store.OfflinePixelCountDataStore
import com.nhaarman.mockitokotlin2.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.junit.After
import org.junit.Assert.assertTrue
import org.junit.Test
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

class SQLCookieRemoverTest {

private val context = InstrumentationRegistry.getInstrumentation().targetContext
private val db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build()
private val cookieManager = CookieManager.getInstance()
private val fireproofWebsiteDao = db.fireproofWebsiteDao()
private val mockPixel = mock<Pixel>()
private val mockOfflinePixelCountDataStore = mock<OfflinePixelCountDataStore>()
private val webViewDatabaseLocator = WebViewDatabaseLocator(context)
private val getHostsToPreserve = GetCookieHostsToPreserve(fireproofWebsiteDao)

@After
fun after() = runBlocking {
removeExistingCookies()
db.close()
}

@Test
fun whenCookiesStoredAndRemoveExecutedThenResultTrue() = runBlocking {
givenDatabaseWithCookies()
val sqlCookieRemover = givenSQLCookieRemover()

val success = sqlCookieRemover.removeCookies()

assertTrue(success)
}

@Test
fun whenNoCookiesStoredAndRemoveExecutedThenResultTrue() = runBlocking {
val sqlCookieRemover = givenSQLCookieRemover()

val success = sqlCookieRemover.removeCookies()

assertTrue(success)
}

@Test
fun whenUserHasFireproofWebsitesAndRemoveExecutedThenResultTrue() = runBlocking {
val sqlCookieRemover = givenSQLCookieRemover()
givenDatabaseWithCookies()
givenFireproofWebsitesStored()

val success = sqlCookieRemover.removeCookies()

assertTrue(success)
}

@Test
fun whenDatabasePathNotFoundThenPixelFired() = runBlocking {
val mockDatabaseLocator = mock<DatabaseLocator> {
on { getDatabasePath() } doReturn ""
}
val sqlCookieRemover = givenSQLCookieRemover(databaseLocator = mockDatabaseLocator)

sqlCookieRemover.removeCookies()

verify(mockOfflinePixelCountDataStore).cookieDatabaseNotFoundCount = 1
}

@Test
fun whenUnableToOpenDatabaseThenPixelFiredAndSaveOfflineCount() = runBlocking {
val mockDatabaseLocator = mock<DatabaseLocator> {
on { getDatabasePath() } doReturn "fakePath"
}
val sqlCookieRemover = givenSQLCookieRemover(databaseLocator = mockDatabaseLocator)

sqlCookieRemover.removeCookies()

verify(mockOfflinePixelCountDataStore).cookieDatabaseOpenErrorCount = 1
verify(mockPixel).fire(eq(Pixel.PixelName.COOKIE_DATABASE_EXCEPTION_OPEN_ERROR), any(), any())
}

private fun givenFireproofWebsitesStored() {
fireproofWebsiteDao.insert(FireproofWebsiteEntity("example.com"))
}

private fun givenDatabaseWithCookies() {
cookieManager.setCookie("example.com", "da=da")
cookieManager.flush()
}

private suspend fun removeExistingCookies() {
withContext(Dispatchers.Main) {
suspendCoroutine<Unit> { continuation ->
cookieManager.removeAllCookies { continuation.resume(Unit) }
}
}
}

private fun givenSQLCookieRemover(
databaseLocator: DatabaseLocator = webViewDatabaseLocator,
cookieHostsToPreserve: GetCookieHostsToPreserve = getHostsToPreserve,
offlinePixelCountDataStore: OfflinePixelCountDataStore = mockOfflinePixelCountDataStore,
exceptionPixel: ExceptionPixel = ExceptionPixel(mockPixel, RootExceptionFinder()),
dispatcherProvider: DispatcherProvider = DefaultDispatcherProvider()
): SQLCookieRemover {
return SQLCookieRemover(
databaseLocator,
cookieHostsToPreserve,
offlinePixelCountDataStore,
exceptionPixel,
dispatcherProvider
)
}
}
Loading