Skip to content

Commit

Permalink
adds api errors daily pixels
Browse files Browse the repository at this point in the history
  • Loading branch information
cmonfortep committed Jul 3, 2024
1 parent 2f01d82 commit 99682aa
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@ class RealSyncApiErrorRecorder @Inject constructor(
syncApiErrorRepository.addError(feature, TOO_MANY_REQUESTS)
}
}
syncPixels.fireDailySyncApiErrorPixel(feature, apiError)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ import android.content.SharedPreferences
import androidx.core.content.edit
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.sync.api.engine.SyncableType
import com.duckduckgo.sync.impl.API_CODE
import com.duckduckgo.sync.impl.Result.Error
import com.duckduckgo.sync.impl.pixels.SyncPixelName.SYNC_DAILY
import com.duckduckgo.sync.impl.pixels.SyncPixelName.SYNC_DAILY_SUCCESS_RATE_PIXEL
import com.duckduckgo.sync.impl.pixels.SyncPixelName.SYNC_OBJECT_LIMIT_EXCEEDED_DAILY
import com.duckduckgo.sync.impl.stats.SyncStatsRepository
import com.duckduckgo.sync.store.SharedPrefsProvider
import com.squareup.anvil.annotations.ContributesBinding
Expand Down Expand Up @@ -70,6 +73,11 @@ interface SyncPixels {
result: Error,
type: SyncAccountOperation,
)

fun fireDailySyncApiErrorPixel(
feature: SyncableType,
apiError: Error,
)
}

@ContributesBinding(AppScope::class)
Expand Down Expand Up @@ -132,6 +140,41 @@ class RealSyncPixels @Inject constructor(
}
}

override fun fireDailySyncApiErrorPixel(
feature: SyncableType,
apiError: Error,
) {
when (apiError.code) {
API_CODE.COUNT_LIMIT.code -> {
pixel.fire(
String.format(Locale.US, SYNC_OBJECT_LIMIT_EXCEEDED_DAILY.pixelName, feature.field),
type = Pixel.PixelType.DAILY,
)
}

API_CODE.CONTENT_TOO_LARGE.code -> {
pixel.fire(
String.format(Locale.US, SyncPixelName.SYNC_REQUEST_SIZE_LIMIT_EXCEEDED_DAILY.pixelName, feature.field),
type = Pixel.PixelType.DAILY,
)
}

API_CODE.VALIDATION_ERROR.code -> {
pixel.fire(
String.format(Locale.US, SyncPixelName.SYNC_VALIDATION_ERROR_DAILY.pixelName, feature.field),
type = Pixel.PixelType.DAILY,
)
}

API_CODE.TOO_MANY_REQUESTS_1.code, API_CODE.TOO_MANY_REQUESTS_2.code -> {
pixel.fire(
String.format(Locale.US, SyncPixelName.SYNC_TOO_MANY_REQUESTS_DAILY.pixelName, feature.field),
type = Pixel.PixelType.DAILY,
)
}
}
}

private fun fireSyncAccountErrorPixel(result: Error) {
result.fireAddingErrorAsParams(SyncPixelName.SYNC_ACCOUNT_FAILURE)
}
Expand Down Expand Up @@ -236,6 +279,10 @@ enum class SyncPixelName(override val pixelName: String) : Pixel.PixelName {
SYNC_USER_SIGNED_IN_FAILURE("m_login_existing_account_error"),
SYNC_CREATE_PDF_FAILURE("m_sync_create_recovery_pdf_error"),
SYNC_PATCH_COMPRESS_FAILED("m_sync_patch_compression_failed"),
SYNC_TOO_MANY_REQUESTS_DAILY("m_sync_%s_too_many_requests_daily"),
SYNC_OBJECT_LIMIT_EXCEEDED_DAILY("m_sync_%s_object_limit_exceeded_daily"),
SYNC_REQUEST_SIZE_LIMIT_EXCEEDED_DAILY("m_sync_%s_request_size_limit_exceeded_daily"),
SYNC_VALIDATION_ERROR_DAILY("m_sync_%s_validation_error_daily"),
}

object SyncPixelParameters {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ internal class SyncApiErrorRecorderTest {
apiErrorReporter.record(feature, error)

verify(syncApiErrorRepository).addError(feature, OBJECT_LIMIT_EXCEEDED)
verify(syncPixels).fireDailySyncApiErrorPixel(feature, error)
}

@Test
Expand All @@ -53,6 +54,7 @@ internal class SyncApiErrorRecorderTest {
apiErrorReporter.record(feature, error)

verify(syncApiErrorRepository).addError(feature, REQUEST_SIZE_LIMIT_EXCEEDED)
verify(syncPixels).fireDailySyncApiErrorPixel(feature, error)
}

@Test
Expand All @@ -63,6 +65,7 @@ internal class SyncApiErrorRecorderTest {
apiErrorReporter.record(feature, error)

verify(syncApiErrorRepository).addError(feature, VALIDATION_ERROR)
verify(syncPixels).fireDailySyncApiErrorPixel(feature, error)
}

@Test
Expand All @@ -73,6 +76,7 @@ internal class SyncApiErrorRecorderTest {
apiErrorReporter.record(feature, error)

verify(syncApiErrorRepository).addError(feature, TOO_MANY_REQUESTS)
verify(syncPixels).fireDailySyncApiErrorPixel(feature, error)
}

@Test
Expand All @@ -83,5 +87,6 @@ internal class SyncApiErrorRecorderTest {
apiErrorReporter.record(feature, error)

verify(syncApiErrorRepository).addError(feature, TOO_MANY_REQUESTS)
verify(syncPixels).fireDailySyncApiErrorPixel(feature, error)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import android.content.SharedPreferences
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.common.test.api.InMemorySharedPreferences
import com.duckduckgo.common.utils.formatters.time.DatabaseDateFormatter
import com.duckduckgo.sync.api.engine.SyncableType
import com.duckduckgo.sync.impl.API_CODE
import com.duckduckgo.sync.impl.Result.Error
import com.duckduckgo.sync.impl.stats.DailyStats
import com.duckduckgo.sync.impl.stats.SyncStatsRepository
import com.duckduckgo.sync.store.SharedPrefsProvider
Expand All @@ -31,7 +34,7 @@ import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

class SyncPixelsTest {
class RealSyncPixelsTest {

private var pixel: Pixel = mock()
private var syncStatsRepository: SyncStatsRepository = mock()
Expand Down Expand Up @@ -104,6 +107,35 @@ class SyncPixelsTest {
verify(pixel).fire(SyncPixelName.SYNC_SIGNUP_CONNECT)
}

@Test
fun whenfireDailyApiErrorForObjectLimitExceededThenPixelSent() {
testee.fireDailySyncApiErrorPixel(SyncableType.BOOKMARKS, Error(code = API_CODE.COUNT_LIMIT.code))

verify(pixel).fire("m_sync_bookmarks_object_limit_exceeded_daily", emptyMap(), emptyMap(), type = Pixel.PixelType.DAILY)
}

@Test
fun whenfireDailyApiErrorForRequestSizeLimitExceededThenPixelSent() {
testee.fireDailySyncApiErrorPixel(SyncableType.BOOKMARKS, Error(code = API_CODE.CONTENT_TOO_LARGE.code))

verify(pixel).fire("m_sync_bookmarks_request_size_limit_exceeded_daily", emptyMap(), emptyMap(), type = Pixel.PixelType.DAILY)
}

@Test
fun whenfireDailyApiErrorForValidationErrorThenPixelSent() {
testee.fireDailySyncApiErrorPixel(SyncableType.BOOKMARKS, Error(code = API_CODE.VALIDATION_ERROR.code))

verify(pixel).fire("m_sync_bookmarks_validation_error_daily", emptyMap(), emptyMap(), type = Pixel.PixelType.DAILY)
}

@Test
fun whenfireDailyApiErrorForTooManyRequestsThenPixelSent() {
testee.fireDailySyncApiErrorPixel(SyncableType.BOOKMARKS, Error(code = API_CODE.TOO_MANY_REQUESTS_1.code))
testee.fireDailySyncApiErrorPixel(SyncableType.BOOKMARKS, Error(code = API_CODE.TOO_MANY_REQUESTS_2.code))

verify(pixel, times(2)).fire("m_sync_bookmarks_too_many_requests_daily", emptyMap(), emptyMap(), type = Pixel.PixelType.DAILY)
}

private fun givenSomeDailyStats(): DailyStats {
val date = DatabaseDateFormatter.getUtcIsoLocalDate()
val dailyStats = DailyStats("1", date, emptyMap())
Expand Down

0 comments on commit 99682aa

Please sign in to comment.