Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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,47 @@
/*
* Copyright (c) 2021 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.global.api

import com.duckduckgo.app.pixels.AppPixelName
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test

class PixelAtbRemovalInterceptorTest {
private lateinit var pixelAtbRemovalInterceptor: PixelAtbRemovalInterceptor

@Before
fun setup() {
pixelAtbRemovalInterceptor = PixelAtbRemovalInterceptor()
}

@Test
fun whenSendPixelTheRedactAtvInfoFromDefinedPixels() {
AppPixelName.values().map { it.pixelName }.forEach { pixelName ->
val pixelUrl = String.format(PIXEL_TEMPLATE, pixelName)
val removalExpected = PixelAtbRemovalInterceptor.pixels.contains(pixelName)

val interceptedUrl = pixelAtbRemovalInterceptor.intercept(FakeChain(pixelUrl)).request.url
assertEquals(removalExpected, interceptedUrl.queryParameter("atb") == null)
}
}

companion object {
private const val PIXEL_TEMPLATE = "https://improving.duckduckgo.com/t/%s_android_phone?atb=v255-7zu&appVersion=5.74.0&test=1"
}

}
14 changes: 14 additions & 0 deletions app/src/main/java/com/duckduckgo/app/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ import dagger.Module
import dagger.Provides
import kotlinx.coroutines.CoroutineScope
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import timber.log.Timber
import java.io.File
import javax.inject.Named
import javax.inject.Singleton
Expand All @@ -72,10 +74,17 @@ class NetworkModule {
fun pixelOkHttpClient(
apiRequestInterceptor: ApiRequestInterceptor,
pixelReQueryInterceptor: PixelReQueryInterceptor,
pixelAtbRemovalInterceptor: PixelAtbRemovalInterceptor
): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(apiRequestInterceptor)
.addInterceptor(pixelReQueryInterceptor)
.addInterceptor(pixelAtbRemovalInterceptor)
// shall be the last one as it is logging the pixel request url that goes out
.addInterceptor { chain: Interceptor.Chain ->
Timber.v("Pixel url request: ${chain.request().url}")
return@addInterceptor chain.proceed(chain.request())
}
.build()
}

Expand Down Expand Up @@ -117,6 +126,11 @@ class NetworkModule {
return PixelReQueryInterceptor()
}

@Provides
fun pixelAtbRemovalInterceptor(): PixelAtbRemovalInterceptor {
return PixelAtbRemovalInterceptor()
}

@Provides
fun trackerListService(@Named("api") retrofit: Retrofit): TrackerListService =
retrofit.create(TrackerListService::class.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 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.global.api

import androidx.annotation.VisibleForTesting
import com.duckduckgo.app.global.AppUrl
import com.duckduckgo.app.pixels.AppPixelName
import okhttp3.Interceptor
import okhttp3.Response

class PixelAtbRemovalInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request().newBuilder()
val pixel = chain.request().url.pathSegments.last()
val url = if (pixels.contains(pixel.substringBefore("_android_"))) {
chain.request().url.newBuilder().removeAllQueryParameters(AppUrl.ParamKey.ATB).build()
} else {
chain.request().url.newBuilder().build()
}

return chain.proceed(request.url(url).build())
}

companion object {
// list of pixels for which we'll remove the ATB information
@VisibleForTesting
val pixels = listOf(
AppPixelName.EMAIL_TOOLTIP_DISMISSED.pixelName,
AppPixelName.EMAIL_USE_ALIAS.pixelName,
AppPixelName.EMAIL_USE_ADDRESS.pixelName
)
}
}