Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Technical Analytics: Milestone 2 - Add Ability To Log Feature Flags #5240

Open
wants to merge 118 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
3fee528
feat: Add a FeatureFlagConstants file to host feature flags
kkmurerwa Oct 18, 2023
9c09fbf
feat: Add constant names for easy retrieval of the feature flags from…
kkmurerwa Oct 18, 2023
b0d1572
feat: Add newly status flags to the Platform Parameter dependency mod…
kkmurerwa Oct 18, 2023
7e13530
feat: Add ability to insert sync statuses to the cache store
kkmurerwa Oct 20, 2023
6c06ea5
feat: Add ability to save flag statuses for every feature flag
kkmurerwa Oct 23, 2023
5e26d8e
Merge branch 'oppia:develop' into technical-analytics-milestone-1
kkmurerwa Oct 23, 2023
1f0fa64
fix: Fix linting and styling checks
kkmurerwa Oct 23, 2023
f4f5ff2
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Oct 24, 2023
795e90c
fix: Fix comments made on the previous review
kkmurerwa Oct 26, 2023
dd5c5b2
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Oct 26, 2023
da852b4
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Oct 29, 2023
9da1607
fix: Fix nit
kkmurerwa Oct 29, 2023
0c0cd75
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Oct 30, 2023
4dae83c
fix: Fix lint issues causing build failure
kkmurerwa Oct 30, 2023
81d968b
fix: Move test sync status flag booleans to the TestBooleanPlatformPa…
kkmurerwa Oct 30, 2023
d8f14bd
chore: Move all test constants from individual type-organized files t…
kkmurerwa Nov 1, 2023
7918da5
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Nov 1, 2023
7bcbdcf
fix: Fix failing text file checks
kkmurerwa Nov 1, 2023
ed2b7ac
Merge branch 'technical-analytics-milestone-1' of github.com:kkmurerw…
kkmurerwa Nov 1, 2023
5638b31
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Nov 1, 2023
a1846ce
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Nov 6, 2023
b49df60
feat: Add a isSynced variable in the platform parameter variable to s…
kkmurerwa Nov 7, 2023
7ee1fd8
fix: Fix failing EventBundleCreator tests
kkmurerwa Nov 7, 2023
b9f28ba
feat: Make Sync status an enum
kkmurerwa Nov 14, 2023
c0338b0
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Nov 14, 2023
501ae40
feat: Add feature flag names to all flags lacking one
kkmurerwa Nov 14, 2023
91c526d
Merge branch 'technical-analytics-milestone-1' of github.com:kkmurerw…
kkmurerwa Nov 14, 2023
551fd4a
fix: Fix failing check and linting issue
kkmurerwa Nov 15, 2023
e6d748f
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Nov 15, 2023
3b19e3f
merge: Merge from develop and fix conflicts
kkmurerwa Nov 17, 2023
df983b9
chore: Remove unused feature flag
kkmurerwa Nov 17, 2023
d3ca9d0
Merge branch 'develop' into technical-analytics-milestone-1
kkmurerwa Nov 21, 2023
a5dbf3a
feat: Add ability to log feature flag statuses
kkmurerwa Nov 21, 2023
e93ff75
feat: Add tests for the FeatureFlagLogger
kkmurerwa Nov 21, 2023
8ae088c
feat: add a feature flag test
kkmurerwa Nov 22, 2023
2b7aad4
fix: Fix bazel build issues
kkmurerwa Nov 22, 2023
fd81350
fix: Fix failing tests
kkmurerwa Nov 22, 2023
4de5981
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Nov 22, 2023
493d4c1
fix: Fix minor linting issues
kkmurerwa Nov 24, 2023
f8f0062
Merge branch 'technical-analytics-milestone-2' of github.com:kkmurerw…
kkmurerwa Nov 24, 2023
574fda3
feat: Merge from develop
kkmurerwa Nov 30, 2023
989a915
feat: Fix changes suggested in the self-review
kkmurerwa Nov 30, 2023
cc6f1d0
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 3, 2023
f3fe5a0
fix: Make some of the suggested changes from preliminary review
kkmurerwa Dec 3, 2023
8825a38
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 5, 2023
99295f6
feat: Modify the approach used to compile feature flags for logging
kkmurerwa Dec 5, 2023
a688839
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 6, 2023
154bd42
feat: Make changes requested by Adhiambo
kkmurerwa Dec 6, 2023
4d830ac
Merge from develop
kkmurerwa Dec 6, 2023
42a56d3
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 6, 2023
9e8754f
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 8, 2023
2440c53
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 16, 2023
79b3527
fix: Make latest requested changes
kkmurerwa Dec 18, 2023
c17dab5
feat: Made some changes to the feature flag tests
kkmurerwa Dec 20, 2023
758135a
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 20, 2023
77a3d29
fix: Fix failing kdoc validation checks
kkmurerwa Dec 20, 2023
cbb3b28
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 21, 2023
f40e9ca
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Dec 23, 2023
829f7df
merge: Merge changes from develop
kkmurerwa Jan 4, 2024
ed41b4a
merge: Fix lint issues from merging changes
kkmurerwa Jan 4, 2024
4ddda14
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Jan 11, 2024
31a26ea
feat: Make suggested changes
kkmurerwa Jan 11, 2024
d0d359e
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Jan 15, 2024
a6f915d
fix: Make changes and fixes requested after review
kkmurerwa Jan 17, 2024
4ed581c
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Jan 23, 2024
5151a2e
feat: Merge from develop
kkmurerwa Jan 26, 2024
178d8b5
feat: Move feature_flag_item_context from feature_flag_context
kkmurerwa Jan 26, 2024
9b1f82f
fix: Fix linting issues
kkmurerwa Jan 26, 2024
0515950
fix: Fix failing build and tests
kkmurerwa Jan 26, 2024
c63f5b5
feat: Change how FeatureFlagItemContextSubject tests are run
kkmurerwa Jan 26, 2024
4efc186
merge changes from develop
kkmurerwa Jan 29, 2024
e76f813
chore: Fix nits and make changes requested in latest review
kkmurerwa Jan 29, 2024
352e7d7
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Feb 1, 2024
b98dd13
fix: Make changes requested in review
kkmurerwa Feb 3, 2024
e25a47c
Merge from develop
kkmurerwa Feb 9, 2024
0ac776b
fix: Fix failing build from merge
kkmurerwa Feb 9, 2024
58ce67d
fix: Fix failing build from merge
kkmurerwa Feb 9, 2024
fcb05dd
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Feb 13, 2024
bf3605a
feat: Modify the feature flag context into a list of properties
kkmurerwa Feb 14, 2024
35e4467
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Feb 15, 2024
a935022
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Feb 20, 2024
5ce5241
feat: Add tests to check if all feature flags were logged and improve…
kkmurerwa Feb 26, 2024
e01e250
fix: Fix lint issues
kkmurerwa Feb 26, 2024
12da7d7
merge from develop
kkmurerwa Feb 26, 2024
ad4872b
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Feb 27, 2024
a3176a1
fix: Fix failing bazel test
kkmurerwa Feb 27, 2024
9485d78
chore: Add TODO comment for future reference
kkmurerwa Feb 29, 2024
033e92a
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Mar 6, 2024
34cade6
chore: rename sessionId to appSessionId
kkmurerwa Mar 6, 2024
5dead31
feat: Add application session id and add it to the feature flags logger
kkmurerwa Mar 6, 2024
af6a3b2
fix: Fix lint issues
kkmurerwa Mar 6, 2024
ad28181
fix: Fix failing tests
kkmurerwa Mar 6, 2024
4749c39
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Mar 13, 2024
3e87141
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Mar 25, 2024
e8503b7
feat: Add tests for the appSessionId and the user UUID
kkmurerwa Apr 1, 2024
6d20011
merge from develop
kkmurerwa Apr 14, 2024
46d5484
test: Add parameterized test for FeatureFlagsLoggerTest
kkmurerwa Apr 14, 2024
4f03d9a
fix: Fix failing parameterized tests and checks
kkmurerwa Apr 14, 2024
97dcc02
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Apr 23, 2024
5f1af8d
chore: Make changes made in last review.
kkmurerwa May 1, 2024
3fa23aa
chore: Add test to ensure app session id changes on each request.
kkmurerwa May 3, 2024
1a7cb3d
fix: Fix failing todos check.
kkmurerwa May 3, 2024
c140838
fix: Fix failing todos check.
kkmurerwa May 5, 2024
e4d6b57
feat: Make some of the changes.
kkmurerwa May 14, 2024
bd3f2de
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa May 14, 2024
c7184c7
fix: Remove unnecessary test.
kkmurerwa May 18, 2024
c248b65
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa May 26, 2024
c6b9c60
feat: Add test to check that appSessionId changes after app restart
kkmurerwa May 30, 2024
92af458
Merge branch 'technical-analytics-milestone-2' of github.com:kkmurerw…
kkmurerwa May 30, 2024
7eda529
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa May 30, 2024
82b1275
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa May 30, 2024
3765671
fix: Fix failing test on feature flag logger.
kkmurerwa May 30, 2024
df7a08c
fix: Fix failing test on feature flags logger.
kkmurerwa May 30, 2024
92113cc
Merge branch 'develop' into technical-analytics-milestone-2
kkmurerwa Jun 4, 2024
22509fa
test: Simplify the test for the second app open on AppSessionId gener…
kkmurerwa Jun 4, 2024
f02d466
Merge branch 'develop' into technical-analytics-milestone-2
BenHenning Jun 13, 2024
fa3122b
fix: Fix failing test on feature flags logger test
kkmurerwa Jun 15, 2024
34743c6
Merge branch 'technical-analytics-milestone-2' of github.com:kkmurerw…
kkmurerwa Jun 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class ApplicationLifecycleObserver @Inject constructor(

private fun logAllFeatureFlags() {
CoroutineScope(backgroundDispatcher).launch {
// TODO(#5240): Replace appSessionId generation to the modified Twitter snowflake algorithm.
BenHenning marked this conversation as resolved.
Show resolved Hide resolved
val appSessionId = loggingIdentifierController.getAppSessionIdFlow().value
featureFlagsLogger.logAllFeatureFlags(appSessionId)
}.invokeOnCompletion { failure ->
Expand All @@ -189,6 +190,30 @@ class ApplicationLifecycleObserver @Inject constructor(
}
}

private fun logAppInForegroundTime() {
CoroutineScope(backgroundDispatcher).launch {
val sessionId = loggingIdentifierController.getSessionIdFlow().value
val installationId = loggingIdentifierController.fetchInstallationId()
val timeInForeground = oppiaClock.getCurrentTimeMs() - appStartTimeMillis
analyticsController.logLowPriorityEvent(
oppiaLogger.createAppInForegroundTimeContext(
installationId = installationId,
appSessionId = sessionId,
foregroundTime = timeInForeground
),
profileId = null
)
}.invokeOnCompletion { failure ->
if (failure != null) {
oppiaLogger.e(
"ApplicationLifecycleObserver",
"Encountered error while trying to log app's time in the foreground.",
failure
)
}
}
}

private fun getStartupLatencyMillis(initialTimestampMillis: Long): Long =
oppiaClock.getCurrentTimeMs() - initialTimestampMillis

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,44 @@ class LoggingIdentifierControllerTest {
assertThat(sessionIdFlow.value).isEqualTo("59aea8d4-af4b-3249-b889-dfeba06d0495")
}

@Test
fun testGetAppSessionId_initialState_returnsRandomId() {
BenHenning marked this conversation as resolved.
Show resolved Hide resolved
val appSessionIdProvider = loggingIdentifierController.getAppSessionId()

val appSessionId = monitorFactory.waitForNextSuccessfulResult(appSessionIdProvider)
assertThat(appSessionId).isEqualTo("2a11efe0-70f8-3a40-8d94-4fc3a2bd4f14")
}

@Test
fun testGetAppSessionId_secondCall_returnsSameRandomId() {
monitorFactory.ensureDataProviderExecutes(loggingIdentifierController.getAppSessionId())

val sessionIdProvider = loggingIdentifierController.getAppSessionId()

// The second call should return the same ID (since the ID doesn't automatically change).
val appSessionId = monitorFactory.waitForNextSuccessfulResult(sessionIdProvider)
assertThat(appSessionId).isEqualTo("2a11efe0-70f8-3a40-8d94-4fc3a2bd4f14")
}

@Test
fun testGetAppSessionIdFlow_initialState_returnsFlowWithRandomId() {
val appSessionIdFlow = loggingIdentifierController.getAppSessionIdFlow()

val appSessionId = appSessionIdFlow.waitForLatestValue()
assertThat(appSessionId).isEqualTo("2a11efe0-70f8-3a40-8d94-4fc3a2bd4f14")
}

@Test
fun testGetAppSessionIdFlow_secondCall_returnsFlowWithSameRandomId() {
loggingIdentifierController.getSessionIdFlow().waitForLatestValue()

val appSessionIdFlow = loggingIdentifierController.getAppSessionIdFlow()

// The second call should return the same ID (since the ID doesn't automatically change).
val appSessionId = appSessionIdFlow.waitForLatestValue()
assertThat(appSessionId).isEqualTo("2a11efe0-70f8-3a40-8d94-4fc3a2bd4f14")
}

private fun <T : MessageLite> writeFileCache(cacheName: String, value: T) {
getCacheFile(cacheName).writeBytes(value.toByteArray())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ class ApplicationLifecycleObserverTest {
@Inject
lateinit var fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger

@Inject
lateinit var fakeConsoleLogger: ConsoleLogger

@Inject
lateinit var networkLoggingInterceptor: NetworkLoggingInterceptor

@Inject
lateinit var featureFlagsLogger: FeatureFlagsLogger

Expand Down Expand Up @@ -420,6 +426,7 @@ class ApplicationLifecycleObserverTest {
mapOf(TEST_FEATURE_FLAG to testFeatureFlag)
)

// TODO(#5240): Replace appSessionId generation to the modified Twitter snowflake algorithm.
val sessionIdProvider = loggingIdentifierController.getAppSessionId()
val sessionId = monitorFactory.waitForNextSuccessfulResult(sessionIdProvider)

Expand All @@ -439,6 +446,111 @@ class ApplicationLifecycleObserverTest {
}
}

@Test
fun testObserver_onAppInForeground_thenInBackground_logsAppInForegroundTime() {
setUpTestApplicationComponent()
fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_UPTIME_MILLIS)

applicationLifecycleObserver.onCreate()
applicationLifecycleObserver.onAppInForeground()
testCoroutineDispatchers.runCurrent()

val sessionIdProvider = loggingIdentifierController.getSessionId()
val sessionId = monitorFactory.waitForNextSuccessfulResult(sessionIdProvider)
val installationIdProvider = loggingIdentifierController.getInstallationId()
val installationId = monitorFactory.waitForNextSuccessfulResult(installationIdProvider)

testCoroutineDispatchers.advanceTimeBy(TEST_TIMESTAMP_APP_IN_FOREGROUND_MILLIS)
applicationLifecycleObserver.onAppInBackground()
testCoroutineDispatchers.runCurrent()

val eventLog = getOneOfLastTwoEventsLogged(APP_IN_FOREGROUND_TIME)
val eventLogContext = eventLog.context

assertThat(eventLogContext.activityContextCase)
.isEqualTo(APP_IN_FOREGROUND_TIME)
assertThat(eventLogContext.appInForegroundTime.foregroundTime.toLong())
.isEqualTo(TEST_TIMESTAMP_APP_IN_FOREGROUND_MILLIS)
assertThat(eventLogContext.appInForegroundTime.appSessionId).isEqualTo(sessionId)
assertThat(eventLogContext.appInForegroundTime.installationId).isEqualTo(installationId)
}

@Test
fun testObserver_onAppInForeground_onConsoleError_logsConsoleErrors() {
setUpTestApplicationComponent()

applicationLifecycleObserver.onCreate()
applicationLifecycleObserver.onAppInForeground()
testCoroutineDispatchers.runCurrent()

val testTag = "TestObserver"
val testMessage = "Test error message"

fakeConsoleLogger.e(testTag, testMessage)
testCoroutineDispatchers.runCurrent()

val eventLog = fakeAnalyticsEventLogger.getMostRecentEvent()
val eventLogContext = eventLog.context

assertThat(eventLogContext.activityContextCase).isEqualTo(ActivityContextCase.CONSOLE_LOG)
assertThat(eventLogContext.consoleLog.fullErrorLog).isEqualTo(testMessage)
assertThat(eventLogContext.consoleLog.logLevel).isEqualTo(LogLevel.ERROR.toString())
assertThat(eventLogContext.consoleLog.logTag).isEqualTo(testTag)
}

@Test
fun testObserver_onAppInForeground_onNetworkCall_logsNetworkCalls() {
setUpTestApplicationComponent()
setUpRetrofitApiCall()

applicationLifecycleObserver.onCreate()
applicationLifecycleObserver.onAppInForeground()
testCoroutineDispatchers.runCurrent()

mockWebServer.enqueue(MockResponse().setBody(testResponseBody))
client.newCall(request).execute()
testCoroutineDispatchers.runCurrent()

val eventLog = fakeAnalyticsEventLogger.getMostRecentEvent()
val eventLogContext = eventLog.context
val retrofitCallContext = eventLogContext.retrofitCallContext

assertThat(eventLogContext.activityContextCase)
.isEqualTo(ActivityContextCase.RETROFIT_CALL_CONTEXT)
assertThat(retrofitCallContext.requestUrl).isEqualTo(mockWebServerUrl.toString())
assertThat(retrofitCallContext.responseStatusCode).isEqualTo(HttpURLConnection.HTTP_OK)
assertThat(retrofitCallContext.headers).contains(headerString)
assertThat(retrofitCallContext.body).isEqualTo(testResponseBody)
}

@Test
fun testObserver_onAppInForeground_onNetworkCall_logsFailedNetworkCalls() {
setUpTestApplicationComponent()
setUpRetrofitApiCall()

applicationLifecycleObserver.onCreate()
applicationLifecycleObserver.onAppInForeground()
testCoroutineDispatchers.runCurrent()

val pageNotFound = HttpURLConnection.HTTP_NOT_FOUND
val mockResponse = MockResponse()
.setResponseCode(pageNotFound)
.setBody(testResponseBody)

mockWebServer.enqueue(mockResponse)
client.newCall(request).execute()
testCoroutineDispatchers.runCurrent()

val eventLog = getOneOfLastTwoEventsLogged(ActivityContextCase.RETROFIT_CALL_FAILED_CONTEXT)
val eventLogContext = eventLog.context
val retrofitCallFailedContext = eventLogContext.retrofitCallFailedContext

assertThat(eventLogContext.activityContextCase)
.isEqualTo(ActivityContextCase.RETROFIT_CALL_FAILED_CONTEXT)
assertThat(retrofitCallFailedContext.requestUrl).isEqualTo(mockWebServerUrl.toString())
assertThat(retrofitCallFailedContext.responseStatusCode).isEqualTo(pageNotFound)
}

private fun waitInBackgroundFor(millis: Long) {
applicationLifecycleObserver.onAppInBackground()
testCoroutineDispatchers.runCurrent()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ oppia_android_test(
"//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics:prod_module",
"//testing",
"//testing/src/main/java/org/oppia/android/testing/data:data_provider_test_monitor",
"//testing/src/main/java/org/oppia/android/testing/junit:oppia_parameterized_test_runner",
"//testing/src/main/java/org/oppia/android/testing/junit:parameterized_robolectric_test_runner",
"//testing/src/main/java/org/oppia/android/testing/logging:event_log_subject",
"//testing/src/main/java/org/oppia/android/testing/logging:sync_status_test_module",
"//testing/src/main/java/org/oppia/android/testing/platformparameter:test_module",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package org.oppia.android.domain.oppialogger.analytics

import android.app.Application
import android.content.Context
import android.os.Build
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import dagger.BindsInstance
import dagger.Component
import dagger.Module
Expand All @@ -18,6 +18,12 @@ import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.testing.FakeAnalyticsEventLogger
import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Iteration
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Parameter
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.RunParameterized
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.SelectRunnerPlatform
import org.oppia.android.testing.junit.ParameterizedRobolectricTestRunner
import org.oppia.android.testing.logging.EventLogSubject.Companion.assertThat
import org.oppia.android.testing.logging.SyncStatusTestModule
import org.oppia.android.testing.platformparameter.EnableTestFeatureFlag
Expand All @@ -38,7 +44,19 @@ import org.oppia.android.util.logging.EnableFileLog
import org.oppia.android.util.logging.GlobalLogLevel
import org.oppia.android.util.logging.LogLevel
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
import org.oppia.android.util.platformparameter.APP_AND_OS_DEPRECATION
import org.oppia.android.util.platformparameter.DOWNLOADS_SUPPORT
import org.oppia.android.util.platformparameter.EDIT_ACCOUNTS_OPTIONS_UI
import org.oppia.android.util.platformparameter.ENABLE_NPS_SURVEY
import org.oppia.android.util.platformparameter.ENABLE_ONBOARDING_FLOW_V2
import org.oppia.android.util.platformparameter.ENABLE_PERFORMANCE_METRICS_COLLECTION
import org.oppia.android.util.platformparameter.EXTRA_TOPIC_TABS_UI
import org.oppia.android.util.platformparameter.FAST_LANGUAGE_SWITCHING_IN_LESSON
import org.oppia.android.util.platformparameter.INTERACTION_CONFIG_CHANGE_STATE_RETENTION
import org.oppia.android.util.platformparameter.LEARNER_STUDY_ANALYTICS
import org.oppia.android.util.platformparameter.LOGGING_LEARNER_STUDY_IDS
import org.oppia.android.util.platformparameter.PlatformParameterValue
import org.oppia.android.util.platformparameter.SPOTLIGHT_UI
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
Expand All @@ -47,9 +65,13 @@ import javax.inject.Singleton
/** Tests for [FeatureFlagsLogger]. */
// FunctionName: test names are conventionally named with underscores.
@Suppress("FunctionName")
@RunWith(AndroidJUnit4::class)
@RunWith(OppiaParameterizedTestRunner::class)
@SelectRunnerPlatform(ParameterizedRobolectricTestRunner::class)
@LooperMode(LooperMode.Mode.PAUSED)
@Config(application = FeatureFlagsLoggerTest.TestApplication::class)
@Config(
application = FeatureFlagsLoggerTest.TestApplication::class,
sdk = [Build.VERSION_CODES.O]
)
class FeatureFlagsLoggerTest {
BenHenning marked this conversation as resolved.
Show resolved Hide resolved
@Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
@Inject lateinit var featureFlagsLogger: FeatureFlagsLogger
Expand All @@ -60,11 +82,25 @@ class FeatureFlagsLoggerTest {
@field:[Inject EnableTestFeatureFlagWithEnabledDefault]
lateinit var testFeatureFlagWithEnabledDefault: PlatformParameterValue<Boolean>

@Parameter var index: Int = Int.MIN_VALUE
@Parameter lateinit var flagName: String

@Before
fun setup() {
BenHenning marked this conversation as resolved.
Show resolved Hide resolved
setUpTestApplicationComponent()
}

@Test
fun testLogFeatureFlags_logFeatureFlags_hasCorrectUserUUID() {
BenHenning marked this conversation as resolved.
Show resolved Hide resolved
featureFlagsLogger.logAllFeatureFlags(TEST_SESSION_ID)
testCoroutineDispatchers.runCurrent()

val eventLog = fakeAnalyticsEventLogger.getMostRecentEvent()
assertThat(eventLog).hasFeatureFlagContextThat {
hasUniqueUserUuidThat().isEqualTo("")
BenHenning marked this conversation as resolved.
Show resolved Hide resolved
}
}

@Test
fun testLogFeatureFlags_logFeatureFlags_hasCorrectSessionId() {
featureFlagsLogger.logAllFeatureFlags(TEST_SESSION_ID)
Expand Down Expand Up @@ -115,7 +151,7 @@ class FeatureFlagsLoggerTest {
}

@Test
fun testLogFeatureFlags_ensuresAllAnnotatedClassesAreLogged() {
fun testLogFeatureFlags_correctNumberOfFeatureFlagsIsLogged() {
val expectedClassNames = 12
BenHenning marked this conversation as resolved.
Show resolved Hide resolved

featureFlagsLogger.logAllFeatureFlags(TEST_SESSION_ID)
Expand All @@ -127,6 +163,43 @@ class FeatureFlagsLoggerTest {
}
}

@Test
@RunParameterized(
Iteration("downloads_support", "index=0", "flagName=$DOWNLOADS_SUPPORT"),
Iteration("extra_topic_tabs_ui", "index=1", "flagName=$EXTRA_TOPIC_TABS_UI"),
Iteration("learner_study_analytics", "index=2", "flagName=$LEARNER_STUDY_ANALYTICS"),
Iteration(
"fast_language_switching_in_lesson", "index=3",
"flagName=$FAST_LANGUAGE_SWITCHING_IN_LESSON"
),
Iteration("logging_learner_study_ids", "index=4", "flagName=$LOGGING_LEARNER_STUDY_IDS"),
Iteration("edit_accounts_options_ui", "index=5", "flagName=$EDIT_ACCOUNTS_OPTIONS_UI"),
Iteration(
"enable_performance_metrics_collection", "index=6",
"flagName=$ENABLE_PERFORMANCE_METRICS_COLLECTION"
),
Iteration("spotlight_ui", "index=7", "flagName=$SPOTLIGHT_UI"),
Iteration(
"interaction_config_change_state_retention", "index=8",
"flagName=$INTERACTION_CONFIG_CHANGE_STATE_RETENTION"
),
Iteration("app_and_os_deprecation", "index=9", "flagName=$APP_AND_OS_DEPRECATION"),
Iteration("enable_nps_survey", "index=10", "flagName=$ENABLE_NPS_SURVEY"),
Iteration("enable_onboarding_flow_v2", "index=11", "flagName=$ENABLE_ONBOARDING_FLOW_V2"),
)
fun testLogFeatureFlags_allFeatureFlagNamesAreLogged() {
featureFlagsLogger.logAllFeatureFlags(TEST_SESSION_ID)

testCoroutineDispatchers.runCurrent()

val eventLog = fakeAnalyticsEventLogger.getMostRecentEvent()
assertThat(eventLog).hasFeatureFlagContextThat {
hasFeatureFlagItemContextThatAtIndex(index) {
hasFeatureFlagNameThat().isEqualTo(flagName)
}
}
}

private fun setUpTestApplicationComponent() {
ApplicationProvider.getApplicationContext<TestApplication>().inject(this)
}
Expand Down