Skip to content

Commit

Permalink
Remove api dependencies from privacy-config-api and vpn-api modules (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
marcosholgado authored Jul 28, 2022
1 parent 5dd7fc2 commit 009f1a4
Show file tree
Hide file tree
Showing 72 changed files with 241 additions and 297 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4185,7 +4185,7 @@ class BrowserTabViewModelTest {

private fun givenUrlCannotUseGpc(url: String) {
val exceptions = CopyOnWriteArrayList<GpcException>().apply { add(GpcException(url)) }
whenever(mockFeatureToggle.isFeatureEnabled(eq(PrivacyFeatureName.GpcFeatureName), any())).thenReturn(true)
whenever(mockFeatureToggle.isFeatureEnabled(eq(PrivacyFeatureName.GpcFeatureName.value), any())).thenReturn(true)
whenever(mockGpcRepository.isGpcEnabled()).thenReturn(true)
whenever(mockGpcRepository.exceptions).thenReturn(exceptions)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class EmailInjectorJsTest {
testee =
EmailInjectorJs(mockEmailManager, DuckDuckGoUrlDetector(), mockDispatcherProvider, mockFeatureToggle, javascriptInjector, mockAutofill)

whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName)).thenReturn(true)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName.value)).thenReturn(true)
whenever(mockAutofill.isAnException(any())).thenReturn(false)
}

Expand All @@ -68,7 +68,7 @@ class EmailInjectorJsTest {
@Test
@SdkSuppress(minSdkVersion = 24)
fun whenInjectAddressAndFeatureIsDisabledThenJsCodeNotInjected() {
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName)).thenReturn(false)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName.value)).thenReturn(false)

val address = "address"
val webView = spy(WebView(InstrumentationRegistry.getInstrumentation().targetContext))
Expand Down Expand Up @@ -123,7 +123,7 @@ class EmailInjectorJsTest {
@SdkSuppress(minSdkVersion = 24)
fun whenNotifyWebAppSignEventAndUrlIsFromDuckDuckGoAndFeatureIsDisabledAndEmailIsNotSignedInThenDoNotEvaluateJsCode() {
whenever(mockEmailManager.isSignedIn()).thenReturn(false)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName)).thenReturn(false)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName.value)).thenReturn(false)

val jsToEvaluate = getNotifySignOutJsToEvaluate()
val webView = spy(WebView(InstrumentationRegistry.getInstrumentation().targetContext))
Expand All @@ -138,7 +138,7 @@ class EmailInjectorJsTest {
@SdkSuppress(minSdkVersion = 24)
fun whenNotifyWebAppSignEventAndUrlIsFromDuckDuckGoAndFeatureIsEnabledAndEmailIsNotSignedInThenEvaluateJsCode() {
whenever(mockEmailManager.isSignedIn()).thenReturn(false)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName)).thenReturn(true)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName.value)).thenReturn(true)

val jsToEvaluate = getNotifySignOutJsToEvaluate()
val webView = spy(WebView(InstrumentationRegistry.getInstrumentation().targetContext))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@

package com.duckduckgo.app.fakes

import com.duckduckgo.feature.toggles.api.FeatureName
import com.duckduckgo.feature.toggles.api.FeatureToggle

class FeatureToggleFake : FeatureToggle {
override fun isFeatureEnabled(
featureName: FeatureName,
featureName: String,
defaultValue: Boolean
): Boolean = true
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ class HttpsUpgraderTest {
@Before
fun before() {
whenever(mockHttpsBloomFilterFactory.create()).thenReturn(bloomFilter)
whenever(mockFeatureToggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName)).thenReturn(true)
whenever(mockFeatureToggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName.value)).thenReturn(true)
testee = HttpsUpgraderImpl(mockHttpsBloomFilterFactory, mockBloomFalsePositiveListDao, mockUserAllowlistDao, mockFeatureToggle, mockHttps)
testee.reloadData()
}

@Test
fun whenFeatureIsDisableTheShouldNotUpgrade() {
whenever(mockFeatureToggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName)).thenReturn(false)
whenever(mockFeatureToggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName.value)).thenReturn(false)
bloomFilter.add("www.local.url")
assertFalse(testee.shouldUpgrade(Uri.parse("http://www.local.url")))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class HttpsReferenceTest(private val testCase: TestCase) {
val isEnabled = httpsFeature?.state == "enabled"
val exceptionsUnprotectedTemporary = CopyOnWriteArrayList(config?.unprotectedTemporary ?: emptyList())

whenever(mockFeatureToggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName, isEnabled)).thenReturn(isEnabled)
whenever(mockFeatureToggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName.value, isEnabled)).thenReturn(isEnabled)
whenever(mockHttpsRepository.exceptions).thenReturn(CopyOnWriteArrayList(httpsExceptions))
whenever(mockUnprotectedTemporaryRepository.exceptions).thenReturn(exceptionsUnprotectedTemporary)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class HttpsEmbeddedDataIntegrationTest {

@Before
fun before() {
whenever(mockFeatureToggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName)).thenReturn(true)
whenever(mockFeatureToggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName.value)).thenReturn(true)

db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
.allowMainThreadQueries()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class BrokenSiteSubmitter(
) : BrokenSiteSender {

override fun submitBrokenSiteFeedback(brokenSite: BrokenSite) {
val isGpcEnabled = (featureToggle.isFeatureEnabled(PrivacyFeatureName.GpcFeatureName) && gpc.isEnabled()).toString()
val isGpcEnabled = (featureToggle.isFeatureEnabled(PrivacyFeatureName.GpcFeatureName.value) && gpc.isEnabled()).toString()
val absoluteUrl = Uri.parse(brokenSite.siteUrl).absoluteString

appCoroutineScope.launch(dispatcherProvider.io()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class UserAgentProvider constructor(

val isDomainInUserAllowList = isHostInUserAllowedList(host)

if (isDomainInUserAllowList || !toggle.isFeatureEnabled(PrivacyFeatureName.UserAgentFeatureName) || shouldUseDefaultUserAgent) {
if (isDomainInUserAllowList || !toggle.isFeatureEnabled(PrivacyFeatureName.UserAgentFeatureName.value) || shouldUseDefaultUserAgent) {
return if (isDesktop) {
defaultUserAgent.get().replace(AgentRegex.platform, desktopPrefix)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class EmailInjectorJs(
}
}

private fun isFeatureEnabled() = featureToggle.isFeatureEnabled(PrivacyFeatureName.AutofillFeatureName, defaultValue = true)
private fun isFeatureEnabled() = featureToggle.isFeatureEnabled(PrivacyFeatureName.AutofillFeatureName.value, defaultValue = true)

private fun isDuckDuckGoUrl(url: String?): Boolean = (url != null && urlDetector.isDuckDuckGoEmailUrl(url))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class EmailJavascriptInterface(
return (url != null && urlDetector.isDuckDuckGoEmailUrl(url))
}

private fun isFeatureEnabled() = featureToggle.isFeatureEnabled(PrivacyFeatureName.AutofillFeatureName, defaultValue = true)
private fun isFeatureEnabled() = featureToggle.isFeatureEnabled(PrivacyFeatureName.AutofillFeatureName.value, defaultValue = true)

@JavascriptInterface
fun isSignedIn(): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class GlobalPrivacyControlViewModel @Inject constructor(
init {
_viewState.value = ViewState(
globalPrivacyControlEnabled = gpc.isEnabled(),
globalPrivacyControlFeatureEnabled = featureToggle.isFeatureEnabled(PrivacyFeatureName.GpcFeatureName, true)
globalPrivacyControlFeatureEnabled = featureToggle.isFeatureEnabled(PrivacyFeatureName.GpcFeatureName.value, true)
)
pixel.fire(SETTINGS_DO_NOT_SELL_SHOWN)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class HttpsUpgraderImpl @Inject constructor(
override fun shouldUpgrade(uri: Uri): Boolean {
val host = uri.host ?: return false

if (!toggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName)) {
if (!toggle.isFeatureEnabled(PrivacyFeatureName.HttpsFeatureName.value)) {
Timber.d("https is disabled in the remote config and so $host is not upgradable")
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class SettingsViewModel @Inject constructor(
automaticallyClearData = AutomaticallyClearData(automaticallyClearWhat, automaticallyClearWhen, automaticallyClearWhenEnabled),
appIcon = settingsDataStore.appIcon,
selectedFireAnimation = settingsDataStore.selectedFireAnimation,
globalPrivacyControlEnabled = gpc.isEnabled() && featureToggle.isFeatureEnabled(PrivacyFeatureName.GpcFeatureName) == true,
globalPrivacyControlEnabled = gpc.isEnabled() && featureToggle.isFeatureEnabled(PrivacyFeatureName.GpcFeatureName.value),
appLinksSettingType = getAppLinksSettingsState(settingsDataStore.appLinksEnabled, settingsDataStore.showAppLinksPrompt),
appTrackingProtectionEnabled = TrackerBlockingVpnService.isServiceRunning(appContext),
appTrackingProtectionWaitlistState = atpRepository.getState(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class UserAgentProviderTest {
@Before
fun before() {
whenever(deviceInfo.majorAppVersion).thenReturn("5")
whenever(toggle.isFeatureEnabled(PrivacyFeatureName.UserAgentFeatureName)).thenReturn(true)
whenever(toggle.isFeatureEnabled(PrivacyFeatureName.UserAgentFeatureName.value)).thenReturn(true)
whenever(userAgentRepository.defaultExceptions).thenReturn(defaultExceptions)
whenever(userAgentRepository.omitApplicationExceptions).thenReturn(applicationExceptions)
whenever(userAgentRepository.omitVersionExceptions).thenReturn(versionExceptions)
Expand Down Expand Up @@ -174,7 +174,7 @@ class UserAgentProviderTest {

@Test
fun whenFeatureIsDisabledThenUaIsDefault() {
whenever(toggle.isFeatureEnabled(PrivacyFeatureName.UserAgentFeatureName)).thenReturn(false)
whenever(toggle.isFeatureEnabled(PrivacyFeatureName.UserAgentFeatureName.value)).thenReturn(false)
testee = getUserAgentProvider(Agent.DEFAULT, deviceInfo)
val actual = testee.userAgent(DOMAIN)
assertTrue("$actual does not match expected regex", ValidationRegex.default.matches(actual))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class EmailJavascriptInterfaceTest {
mockAutofill
) { counter++ }

whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName)).thenReturn(true)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName.value)).thenReturn(true)
whenever(mockAutofill.isAnException(any())).thenReturn(false)
}

Expand Down Expand Up @@ -130,7 +130,7 @@ class EmailJavascriptInterfaceTest {
@Test
fun whenShowTooltipAndFeatureDisabledThenLambdaNotCalled() {
whenever(mockWebView.url).thenReturn(NON_EMAIL_URL)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName)).thenReturn(false)
whenever(mockFeatureToggle.isFeatureEnabled(AutofillFeatureName.value)).thenReturn(false)

testee.showTooltip()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class SettingsViewModelTest {

@Test
fun whenStartIfGpcToggleDisabledAndGpcEnabledThenGpgDisabled() = runTest {
whenever(mockFeatureToggle.isFeatureEnabled(eq(PrivacyFeatureName.GpcFeatureName), any())).thenReturn(false)
whenever(mockFeatureToggle.isFeatureEnabled(eq(PrivacyFeatureName.GpcFeatureName.value), any())).thenReturn(false)
whenever(mockGpc.isEnabled()).thenReturn(true)

testee.start()
Expand All @@ -173,7 +173,7 @@ class SettingsViewModelTest {

@Test
fun whenStartIfGpcToggleEnabledAndGpcDisabledThenGpgDisabled() = runTest {
whenever(mockFeatureToggle.isFeatureEnabled(eq(PrivacyFeatureName.GpcFeatureName), any())).thenReturn(true)
whenever(mockFeatureToggle.isFeatureEnabled(eq(PrivacyFeatureName.GpcFeatureName.value), any())).thenReturn(true)
whenever(mockGpc.isEnabled()).thenReturn(false)
testee.start()

Expand All @@ -185,7 +185,7 @@ class SettingsViewModelTest {

@Test
fun whenStartIfGpcToggleEnabledAndGpcEnabledThenGpgEnabled() = runTest {
whenever(mockFeatureToggle.isFeatureEnabled(eq(PrivacyFeatureName.GpcFeatureName), any())).thenReturn(true)
whenever(mockFeatureToggle.isFeatureEnabled(eq(PrivacyFeatureName.GpcFeatureName.value), any())).thenReturn(true)
whenever(mockGpc.isEnabled()).thenReturn(true)
testee.start()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,7 @@ interface FeatureToggle {
* @throws [IllegalArgumentException] if the feature is not implemented
*/
fun isFeatureEnabled(
featureName: FeatureName,
featureName: String,
defaultValue: Boolean = true
): Boolean
}

/**
* Each feature toggle created needs a [FeatureName] which can be implemented using this interface
*/
interface FeatureName {
val value: String

companion object {
/**
* Utility function to create a [FeatureName] from the passed in [block] lambda
* instead of using the anonymous `object : FeatureName` syntax.
*
* Usage:
*
* ```kotlin
* val feature = FeatureName {
*
* }
* ```
*/
inline operator fun invoke(crossinline block: () -> String): FeatureName {
return object : FeatureName {
override val value: String
get() = block()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ interface FeatureTogglesPlugin {
* know the featureName. [defaultValue] if the plugin knows featureName but is not set
*/
fun isEnabled(
featureName: FeatureName,
featureName: String,
defaultValue: Boolean
): Boolean?
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import com.duckduckgo.app.global.plugins.PluginPoint
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.feature.toggles.api.FeatureToggle
import com.duckduckgo.feature.toggles.api.FeatureTogglesPlugin
import com.duckduckgo.feature.toggles.api.FeatureName
import com.squareup.anvil.annotations.ContributesBinding
import javax.inject.Inject
import dagger.SingleInstanceIn
Expand All @@ -32,14 +31,14 @@ class RealFeatureToggleImpl @Inject constructor(private val featureTogglesPlugin
FeatureToggle {

override fun isFeatureEnabled(
featureName: FeatureName,
featureName: String,
defaultValue: Boolean
): Boolean {
featureTogglesPluginPoint.getPlugins().forEach { plugin ->
plugin.isEnabled(featureName, defaultValue)?.let { return it }
}

throw IllegalArgumentException("Unknown feature: ${featureName.value}")
throw IllegalArgumentException("Unknown feature: $featureName")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package com.duckduckgo.feature.toggles.impl

import com.duckduckgo.app.global.plugins.PluginPoint
import com.duckduckgo.feature.toggles.api.FeatureName
import com.duckduckgo.feature.toggles.api.FeatureTogglesPlugin
import org.junit.Assert.*
import org.junit.Test
Expand All @@ -29,22 +28,22 @@ class RealFeatureToggleImplTest {

@Test
fun whenFeatureNameCanBeHandledByPluginThenReturnTheCorrectValue() {
val result = testee.isFeatureEnabled(TrueFeatureName(), false)
val result = testee.isFeatureEnabled(TrueFeatureName().value, false)
assertNotNull(result)
assertTrue(result)
}

@Test(expected = IllegalArgumentException::class)
fun whenFeatureNameCannotBeHandledByAnyPluginThenThrowException() {
testee.isFeatureEnabled(NullFeatureName(), false)
testee.isFeatureEnabled(NullFeatureName().value, false)
}

class FakeTruePlugin : FeatureTogglesPlugin {
override fun isEnabled(
featureName: FeatureName,
featureName: String,
defaultValue: Boolean
): Boolean? {
return if (featureName is TrueFeatureName) {
return if (featureName == TrueFeatureName().value) {
true
} else {
null
Expand All @@ -58,6 +57,6 @@ class RealFeatureToggleImplTest {
}
}

data class TrueFeatureName(override val value: String = "true") : FeatureName
data class NullFeatureName(override val value: String = "null") : FeatureName
data class TrueFeatureName(val value: String = "true")
data class NullFeatureName(val value: String = "null")
}
3 changes: 0 additions & 3 deletions privacy-config/privacy-config-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ java {
}

dependencies {

implementation project(path: ':feature-toggles-api')

implementation Google.dagger
implementation Kotlin.stdlib.jdk7
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@

package com.duckduckgo.privacy.config.api

import com.duckduckgo.feature.toggles.api.FeatureName

/** List of [FeatureName] that belong to the Privacy Configuration */
enum class PrivacyFeatureName(override val value: String) : FeatureName {
/** List of [PrivacyFeatureName] that belong to the Privacy Configuration */
enum class PrivacyFeatureName(val value: String) {
ContentBlockingFeatureName("contentBlocking"),
GpcFeatureName("gpc"),
HttpsFeatureName("https"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package com.duckduckgo.privacy.config.api

import com.duckduckgo.feature.toggles.api.FeatureName

/**
* Implement this interface and contribute it as a multibinding to get called upon downloading remote privacy config
*
Expand All @@ -32,15 +30,15 @@ import com.duckduckgo.feature.toggles.api.FeatureName
*/
interface PrivacyFeaturePlugin {
/**
* @return `true` when the feature config was stored, otherwise `false`
* @return `true` when the feature was stored, otherwise `false`
*/
fun store(
name: FeatureName,
featureName: String,
jsonString: String
): Boolean

/**
* @return the [FeatureName] of this feature
* @return the [featureName] of this feature
*/
val featureName: FeatureName
val featureName: String
}
Loading

0 comments on commit 009f1a4

Please sign in to comment.