Skip to content

Commit 7956de9

Browse files
committed
Add tests
1 parent 56bb1b7 commit 7956de9

File tree

9 files changed

+211
-56
lines changed

9 files changed

+211
-56
lines changed

firebase-sessions/firebase-sessions.gradle.kts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ dependencies {
5252
runtimeOnly("com.google.firebase:firebase-installations:17.1.3")
5353

5454
implementation("com.google.android.datatransport:transport-api:3.0.0")
55-
// implementation("com.google.android.datatransport:transport-runtime:3.1.8")
56-
// implementation("com.google.android.datatransport:transport-backend-cct:3.1.8")
5755

5856
testImplementation(libs.androidx.test.junit)
5957
testImplementation(libs.androidx.test.runner)

firebase-sessions/src/main/kotlin/com/google/firebase/sessions/EventGDTLogger.kt

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,46 @@
1616

1717
package com.google.firebase.sessions
1818

19-
import com.google.android.datatransport.Encoding
20-
import com.google.android.datatransport.Event
19+
import com.google.android.datatransport.*
2120
import com.google.android.datatransport.TransportFactory
2221

23-
internal class EventGDTLogger(private val transportFactory: TransportFactory) {
22+
/**
23+
* The [EventGDTLoggerInterface] is for testing purposes so that we can mock EventGDTLogger in other
24+
* classes that depend on it.
25+
*
26+
* @hide
27+
*/
28+
internal interface EventGDTLoggerInterface {
29+
fun log(sessionEvent: SessionEvent)
30+
}
31+
32+
/**
33+
* The [EventGDTLogger] is responsible for encoding and logging events to the Google Data Transport
34+
* library.
35+
*
36+
* @hide
37+
*/
38+
internal class EventGDTLogger(private val transportFactory: TransportFactory) :
39+
EventGDTLoggerInterface {
2440

25-
fun log(sessionEvent: SessionEvent) {
41+
// Logs a [SessionEvent] to FireLog
42+
override fun log(sessionEvent: SessionEvent) {
2643
transportFactory
2744
.getTransport(
2845
EventGDTLogger.AQS_LOG_SOURCE,
2946
SessionEvent::class.java,
3047
Encoding.of("json"),
31-
this::apply,
48+
this::encode,
3249
)
3350
.send(Event.ofData(sessionEvent))
3451
}
3552

36-
private fun apply(value: SessionEvent): ByteArray {
53+
private fun encode(value: SessionEvent): ByteArray {
3754
return SessionEvents.SESSION_EVENT_ENCODER.encode(value).toByteArray()
3855
}
3956

4057
companion object {
41-
// TODO AQS Log Source
58+
// TODO What do we put for the AQS Log Source
4259
private const val AQS_LOG_SOURCE = "AQS_LOG_SOURCE"
4360
}
4461
}

firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionCoordinator.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,12 @@
1717
package com.google.firebase.sessions
1818

1919
import android.util.Log
20-
import com.google.android.datatransport.Encoding
21-
import com.google.android.datatransport.Event
22-
import com.google.android.datatransport.TransportFactory
2320
import com.google.firebase.installations.FirebaseInstallationsApi
2421
import kotlinx.coroutines.CoroutineDispatcher
2522
import kotlinx.coroutines.CoroutineScope
2623
import kotlinx.coroutines.launch
2724
import kotlinx.coroutines.tasks.await
2825

29-
3026
/**
3127
* [SessionCoordinator] is responsible for coordinating the systems in this SDK involved with
3228
* sending a [SessionEvent].
@@ -36,7 +32,7 @@ import kotlinx.coroutines.tasks.await
3632
internal class SessionCoordinator(
3733
private val firebaseInstallations: FirebaseInstallationsApi,
3834
backgroundDispatcher: CoroutineDispatcher,
39-
private val eventGDTLogger: EventGDTLogger,
35+
private val eventGDTLogger: EventGDTLoggerInterface,
4036
) {
4137
private val scope = CoroutineScope(backgroundDispatcher)
4238

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.sessions
18+
19+
import com.google.android.datatransport.Encoding
20+
import com.google.android.datatransport.Event
21+
import com.google.common.truth.Truth.assertThat
22+
import com.google.firebase.FirebaseApp
23+
import com.google.firebase.sessions.testing.FakeFirebaseApp
24+
import com.google.firebase.sessions.testing.FakeTransportFactory
25+
import com.google.firebase.sessions.testing.TestSessionEventData
26+
import org.junit.After
27+
import org.junit.Test
28+
import org.junit.runner.RunWith
29+
import org.robolectric.RobolectricTestRunner
30+
31+
@RunWith(RobolectricTestRunner::class)
32+
class EventGDTLoggerTest {
33+
34+
@Test
35+
fun event_logsToGoogleDataTransport() {
36+
val sessionEvent =
37+
SessionEvents.startSession(
38+
FakeFirebaseApp.fakeFirebaseApp(),
39+
TestSessionEventData.TEST_SESSION_DETAILS
40+
)
41+
val fakeTransportFactory = FakeTransportFactory()
42+
val eventGDTLogger = EventGDTLogger(transportFactory = fakeTransportFactory)
43+
44+
eventGDTLogger.log(sessionEvent = sessionEvent)
45+
46+
assertThat(fakeTransportFactory.name).isEqualTo("AQS_LOG_SOURCE")
47+
assertThat(fakeTransportFactory.payloadEncoding).isEqualTo(Encoding.of("json"))
48+
assertThat(fakeTransportFactory.fakeTransport!!.sentEvent)
49+
.isEqualTo(Event.ofData(TestSessionEventData.EXPECTED_DEFAULT_SESSION_EVENT))
50+
}
51+
52+
@After
53+
fun cleanUp() {
54+
FirebaseApp.clearInstancesForTest()
55+
}
56+
}

firebase-sessions/src/test/kotlin/com/google/firebase/sessions/SessionCoordinatorTest.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package com.google.firebase.sessions
1818

1919
import androidx.test.ext.junit.runners.AndroidJUnit4
2020
import com.google.common.truth.Truth.assertThat
21+
import com.google.firebase.sessions.testing.FakeEventGDTLogger
2122
import com.google.firebase.sessions.testing.FakeFirebaseInstallations
22-
import com.google.firebase.sessions.testing.FakeTransportFactory
2323
import kotlinx.coroutines.ExperimentalCoroutinesApi
2424
import kotlinx.coroutines.test.StandardTestDispatcher
2525
import kotlinx.coroutines.test.runCurrent
@@ -32,11 +32,12 @@ import org.junit.runner.RunWith
3232
class SessionCoordinatorTest {
3333
@Test
3434
fun attemptLoggingSessionEvent_populatesFid() = runTest {
35+
val fakeEventGDTLogger = FakeEventGDTLogger()
3536
val sessionCoordinator =
3637
SessionCoordinator(
3738
firebaseInstallations = FakeFirebaseInstallations("FaKeFiD"),
3839
backgroundDispatcher = StandardTestDispatcher(testScheduler),
39-
transportFactory = FakeTransportFactory(),
40+
eventGDTLogger = fakeEventGDTLogger,
4041
)
4142

4243
// Construct an event with no fid set.
@@ -64,5 +65,7 @@ class SessionCoordinatorTest {
6465
runCurrent()
6566

6667
assertThat(sessionEvent.sessionData.firebaseInstallationId).isEqualTo("FaKeFiD")
68+
assertThat(fakeEventGDTLogger.loggedEvent!!.sessionData.firebaseInstallationId)
69+
.isEqualTo("FaKeFiD")
6770
}
6871
}

firebase-sessions/src/test/kotlin/com/google/firebase/sessions/SessionEventTest.kt

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@
1616

1717
package com.google.firebase.sessions
1818

19-
import android.content.Context
20-
import androidx.test.core.app.ApplicationProvider
2119
import com.google.common.truth.Truth.assertThat
2220
import com.google.firebase.FirebaseApp
2321
import com.google.firebase.sessions.testing.FakeFirebaseApp
22+
import com.google.firebase.sessions.testing.TestSessionEventData
2423
import org.junit.After
2524
import org.junit.Test
2625
import org.junit.runner.RunWith
@@ -30,38 +29,13 @@ import org.robolectric.RobolectricTestRunner
3029
class SessionEventTest {
3130
@Test
3231
fun sessionStart_populatesSessionDetailsCorrectly() {
33-
val sessionDetails =
34-
SessionDetails(
35-
sessionId = "a1b2c3",
36-
firstSessionId = "a1a1a1",
37-
collectEvents = true,
38-
sessionIndex = 3,
32+
val sessionEvent =
33+
SessionEvents.startSession(
34+
FakeFirebaseApp.fakeFirebaseApp(),
35+
TestSessionEventData.TEST_SESSION_DETAILS
3936
)
40-
val sessionEvent = SessionEvents.startSession(FakeFirebaseApp.fakeFirebaseApp(), sessionDetails)
4137

42-
assertThat(sessionEvent)
43-
.isEqualTo(
44-
SessionEvent(
45-
eventType = EventType.SESSION_START,
46-
sessionData =
47-
SessionInfo(
48-
sessionId = "a1b2c3",
49-
firstSessionId = "a1a1a1",
50-
sessionIndex = 3,
51-
),
52-
applicationInfo =
53-
ApplicationInfo(
54-
appId = FakeFirebaseApp.MOCK_APP_ID,
55-
deviceModel = "",
56-
sessionSdkVersion = BuildConfig.VERSION_NAME,
57-
logEnvironment = LogEnvironment.LOG_ENVIRONMENT_PROD,
58-
AndroidApplicationInfo(
59-
packageName = ApplicationProvider.getApplicationContext<Context>().packageName,
60-
versionName = FakeFirebaseApp.MOCK_APP_VERSION
61-
),
62-
)
63-
)
64-
)
38+
assertThat(sessionEvent).isEqualTo(TestSessionEventData.EXPECTED_DEFAULT_SESSION_EVENT)
6539
}
6640

6741
@After
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.sessions.testing
18+
19+
import com.google.firebase.sessions.EventGDTLogger
20+
import com.google.firebase.sessions.EventGDTLoggerInterface
21+
import com.google.firebase.sessions.SessionEvent
22+
23+
/**
24+
* The [FakeEventGDTLogger] is for mocking [EventGDTLogger].
25+
*
26+
* @hide
27+
*/
28+
internal class FakeEventGDTLogger : EventGDTLoggerInterface {
29+
30+
// Lets tests assert the right event was logged.
31+
var loggedEvent: SessionEvent? = null
32+
33+
override fun log(sessionEvent: SessionEvent) {
34+
loggedEvent = sessionEvent
35+
}
36+
}

firebase-sessions/src/test/kotlin/com/google/firebase/sessions/testing/FakeTransportFactory.kt

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,48 @@
1616

1717
package com.google.firebase.sessions.testing
1818

19-
import com.google.android.datatransport.Encoding
20-
import com.google.android.datatransport.Transformer
21-
import com.google.android.datatransport.Transport
22-
import com.google.android.datatransport.TransportFactory
19+
import com.google.android.datatransport.*
20+
import com.google.firebase.sessions.SessionEvent
2321

24-
/** Fake [FakeTransportFactory] that implements [getTransport]. */
22+
/** Fake [Transport] that implements [send]. */
23+
internal class FakeTransport<T>() : Transport<T> {
24+
25+
var sentEvent: Event<T>? = null
26+
27+
override fun send(event: Event<T>?) {
28+
this.sentEvent = event
29+
}
30+
31+
override fun schedule(p0: Event<T>?, p1: TransportScheduleCallback?) {
32+
return
33+
}
34+
}
35+
36+
/** Fake [TransportFactory] that implements [getTransport]. */
2537
internal class FakeTransportFactory() : TransportFactory {
26-
@Deprecated("This is deprecated in the API")
38+
39+
var name: String? = null
40+
var payloadEncoding: Encoding? = null
41+
var fakeTransport: FakeTransport<SessionEvent>? = null
42+
2743
override fun <T> getTransport(
2844
name: String?,
2945
payloadType: java.lang.Class<T>?,
46+
payloadEncoding: Encoding?,
3047
payloadTransformer: Transformer<T, ByteArray?>?
3148
): Transport<T>? {
32-
return null
49+
this.name = name
50+
this.payloadEncoding = payloadEncoding
51+
val fakeTransport = FakeTransport<T>()
52+
@Suppress("UNCHECKED_CAST")
53+
this.fakeTransport = fakeTransport as FakeTransport<SessionEvent>
54+
return fakeTransport
3355
}
3456

57+
@Deprecated("This is deprecated in the API. Don't use or expect on this function.")
3558
override fun <T> getTransport(
3659
name: String?,
3760
payloadType: java.lang.Class<T>?,
38-
payloadEncoding: Encoding?,
3961
payloadTransformer: Transformer<T, ByteArray?>?
4062
): Transport<T>? {
4163
return null
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.sessions.testing
18+
19+
import android.content.Context
20+
import androidx.test.core.app.ApplicationProvider
21+
import com.google.firebase.sessions.*
22+
23+
internal object TestSessionEventData {
24+
val TEST_SESSION_DETAILS =
25+
SessionDetails(
26+
sessionId = "a1b2c3",
27+
firstSessionId = "a1a1a1",
28+
collectEvents = true,
29+
sessionIndex = 3,
30+
)
31+
32+
val EXPECTED_DEFAULT_SESSION_EVENT =
33+
SessionEvent(
34+
eventType = EventType.SESSION_START,
35+
sessionData =
36+
SessionInfo(
37+
sessionId = "a1b2c3",
38+
firstSessionId = "a1a1a1",
39+
sessionIndex = 3,
40+
),
41+
applicationInfo =
42+
ApplicationInfo(
43+
appId = FakeFirebaseApp.MOCK_APP_ID,
44+
deviceModel = "",
45+
sessionSdkVersion = BuildConfig.VERSION_NAME,
46+
logEnvironment = LogEnvironment.LOG_ENVIRONMENT_PROD,
47+
AndroidApplicationInfo(
48+
packageName = ApplicationProvider.getApplicationContext<Context>().packageName,
49+
versionName = FakeFirebaseApp.MOCK_APP_VERSION
50+
),
51+
)
52+
)
53+
}

0 commit comments

Comments
 (0)