From 31d3d0595cad80a2e2abfd35fc994075f35001a7 Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 11 Jul 2023 11:40:41 -0400 Subject: [PATCH 01/11] test commit --- firebase-common/firebase-common.gradle.kts | 1 + .../main/java/com/google/firebase/Firebase.kt | 82 +++++++++++++++++++ .../google/firebase/functions/Functions.kt | 70 ++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 firebase-common/src/main/java/com/google/firebase/Firebase.kt create mode 100644 firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt diff --git a/firebase-common/firebase-common.gradle.kts b/firebase-common/firebase-common.gradle.kts index ae4fd4292ec..f21d7d58106 100644 --- a/firebase-common/firebase-common.gradle.kts +++ b/firebase-common/firebase-common.gradle.kts @@ -14,6 +14,7 @@ plugins { id("firebase-library") + id("kotlin-android") } firebaseLibrary { diff --git a/firebase-common/src/main/java/com/google/firebase/Firebase.kt b/firebase-common/src/main/java/com/google/firebase/Firebase.kt new file mode 100644 index 00000000000..e1e1187828f --- /dev/null +++ b/firebase-common/src/main/java/com/google/firebase/Firebase.kt @@ -0,0 +1,82 @@ +// Copyright 2019 Google LLC +// +// 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.google.firebase + +import android.content.Context +import androidx.annotation.Keep +import com.google.firebase.annotations.concurrent.Background +import com.google.firebase.annotations.concurrent.Blocking +import com.google.firebase.annotations.concurrent.Lightweight +import com.google.firebase.annotations.concurrent.UiThread +import com.google.firebase.components.Component +import com.google.firebase.components.ComponentRegistrar +import com.google.firebase.components.Dependency +import com.google.firebase.components.Qualified +import com.google.firebase.platforminfo.LibraryVersionComponent +import java.util.concurrent.Executor +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.asCoroutineDispatcher + +/** + * Single access point to all firebase SDKs from Kotlin. + * + *

Acts as a target for extension methods provided by sdks. + */ +object Firebase + +/** Returns the default firebase app instance. */ +val Firebase.app: FirebaseApp + get() = FirebaseApp.getInstance() + +/** Returns a named firebase app instance. */ +fun Firebase.app(name: String): FirebaseApp = FirebaseApp.getInstance(name) + +/** Initializes and returns a FirebaseApp. */ +fun Firebase.initialize(context: Context): FirebaseApp? = FirebaseApp.initializeApp(context) + +/** Initializes and returns a FirebaseApp. */ +fun Firebase.initialize(context: Context, options: FirebaseOptions): FirebaseApp = + FirebaseApp.initializeApp(context, options) + +/** Initializes and returns a FirebaseApp. */ +fun Firebase.initialize(context: Context, options: FirebaseOptions, name: String): FirebaseApp = + FirebaseApp.initializeApp(context, options, name) + +/** Returns options of default FirebaseApp */ +val Firebase.options: FirebaseOptions + get() = Firebase.app.options + +internal const val LIBRARY_NAME: String = "fire-core-ktx" + +/** @suppress */ +@Keep +class FirebaseCommonKtxRegistrar : ComponentRegistrar { + override fun getComponents(): List> { + return listOf( + LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME), + coroutineDispatcher(), + coroutineDispatcher(), + coroutineDispatcher(), + coroutineDispatcher() + ) + } +} + +private inline fun coroutineDispatcher(): Component = + Component.builder(Qualified.qualified(T::class.java, CoroutineDispatcher::class.java)) + .add(Dependency.required(Qualified.qualified(T::class.java, Executor::class.java))) + .factory { c -> + c.get(Qualified.qualified(T::class.java, Executor::class.java)).asCoroutineDispatcher() + } + .build() diff --git a/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt b/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt new file mode 100644 index 00000000000..f63a4b87f96 --- /dev/null +++ b/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt @@ -0,0 +1,70 @@ +// Copyright 2019 Google LLC +// +// 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.google.firebase.functions + +import androidx.annotation.Keep +import com.google.firebase.FirebaseApp +import com.google.firebase.components.Component +import com.google.firebase.components.ComponentRegistrar +import com.google.firebase.functions.FirebaseFunctions +import com.google.firebase.functions.HttpsCallableOptions +import com.google.firebase.functions.HttpsCallableReference +import com.google.firebase.ktx.Firebase +import com.google.firebase.platforminfo.LibraryVersionComponent +import java.net.URL + +/** Returns the [FirebaseFunctions] instance of the default [FirebaseApp]. */ +val Firebase.functions: FirebaseFunctions + get() = com.google.firebase.functions.FirebaseFunctions.getInstance() + +/** Returns the [FirebaseFunctions] instance of a given [regionOrCustomDomain]. */ +fun Firebase.functions(regionOrCustomDomain: String): FirebaseFunctions = + com.google.firebase.functions.FirebaseFunctions.getInstance(regionOrCustomDomain) + +/** Returns the [FirebaseFunctions] instance of a given [FirebaseApp]. */ +fun Firebase.functions(app: FirebaseApp): FirebaseFunctions = com.google.firebase.functions.FirebaseFunctions.getInstance(app) + +/** Returns the [FirebaseFunctions] instance of a given [FirebaseApp] and [regionOrCustomDomain]. */ +fun Firebase.functions(app: FirebaseApp, regionOrCustomDomain: String): FirebaseFunctions = + com.google.firebase.functions.FirebaseFunctions.getInstance(app, regionOrCustomDomain) + +internal const val LIBRARY_NAME: String = "fire-fun-ktx" + +/** @suppress */ +@Keep +class FirebaseFunctionsKtxRegistrar : ComponentRegistrar { + override fun getComponents(): List> = + listOf(LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME)) +} + +/** Returns a reference to the Callable HTTPS trigger with the given name and call options. */ +fun FirebaseFunctions.getHttpsCallable( + name: String, + init: HttpsCallableOptions.Builder.() -> Unit +): HttpsCallableReference { + val builder = HttpsCallableOptions.Builder() + builder.init() + return getHttpsCallable(name, builder.build()) +} + +/** Returns a reference to the Callable HTTPS trigger with the given URL and call options. */ +fun FirebaseFunctions.getHttpsCallableFromUrl( + url: URL, + init: HttpsCallableOptions.Builder.() -> Unit +): HttpsCallableReference { + val builder = HttpsCallableOptions.Builder() + builder.init() + return getHttpsCallableFromUrl(url, builder.build()) +} From 319cfe19523315626b0d85dc7827e960b21033df Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 11 Jul 2023 11:51:08 -0400 Subject: [PATCH 02/11] prototype packaging --- firebase-common/firebase-common.gradle.kts | 2 + .../firebase-functions.gradle.kts | 3 +- .../google/firebase/functions/Functions.kt | 38 +++++++++---------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/firebase-common/firebase-common.gradle.kts b/firebase-common/firebase-common.gradle.kts index f21d7d58106..40068deaafa 100644 --- a/firebase-common/firebase-common.gradle.kts +++ b/firebase-common/firebase-common.gradle.kts @@ -57,6 +57,8 @@ dependencies { implementation(libs.androidx.futures) implementation(libs.playservices.basement) implementation(libs.playservices.tasks) + api(libs.kotlin.coroutines.tasks) + implementation(libs.kotlin.stdlib) annotationProcessor(libs.autovalue) diff --git a/firebase-functions/firebase-functions.gradle.kts b/firebase-functions/firebase-functions.gradle.kts index f3d09f893c3..410449983b5 100644 --- a/firebase-functions/firebase-functions.gradle.kts +++ b/firebase-functions/firebase-functions.gradle.kts @@ -15,6 +15,7 @@ plugins { id("firebase-library") id("firebase-vendor") + id("kotlin-android") } firebaseLibrary { @@ -46,7 +47,7 @@ android { dependencies { implementation("com.google.firebase:firebase-annotations:16.2.0") - implementation("com.google.firebase:firebase-common:20.3.1") + implementation(project(":firebase-common")) implementation("com.google.firebase:firebase-components:17.1.0") implementation(project(":appcheck:firebase-appcheck-interop")) implementation(libs.playservices.base) diff --git a/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt b/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt index f63a4b87f96..8131d491fec 100644 --- a/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt +++ b/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt @@ -15,56 +15,54 @@ package com.google.firebase.functions import androidx.annotation.Keep +import com.google.firebase.Firebase import com.google.firebase.FirebaseApp import com.google.firebase.components.Component import com.google.firebase.components.ComponentRegistrar -import com.google.firebase.functions.FirebaseFunctions -import com.google.firebase.functions.HttpsCallableOptions -import com.google.firebase.functions.HttpsCallableReference -import com.google.firebase.ktx.Firebase import com.google.firebase.platforminfo.LibraryVersionComponent import java.net.URL /** Returns the [FirebaseFunctions] instance of the default [FirebaseApp]. */ val Firebase.functions: FirebaseFunctions - get() = com.google.firebase.functions.FirebaseFunctions.getInstance() + get() = com.google.firebase.functions.FirebaseFunctions.getInstance() /** Returns the [FirebaseFunctions] instance of a given [regionOrCustomDomain]. */ fun Firebase.functions(regionOrCustomDomain: String): FirebaseFunctions = - com.google.firebase.functions.FirebaseFunctions.getInstance(regionOrCustomDomain) + com.google.firebase.functions.FirebaseFunctions.getInstance(regionOrCustomDomain) /** Returns the [FirebaseFunctions] instance of a given [FirebaseApp]. */ -fun Firebase.functions(app: FirebaseApp): FirebaseFunctions = com.google.firebase.functions.FirebaseFunctions.getInstance(app) +fun Firebase.functions(app: FirebaseApp): FirebaseFunctions = + com.google.firebase.functions.FirebaseFunctions.getInstance(app) /** Returns the [FirebaseFunctions] instance of a given [FirebaseApp] and [regionOrCustomDomain]. */ fun Firebase.functions(app: FirebaseApp, regionOrCustomDomain: String): FirebaseFunctions = - com.google.firebase.functions.FirebaseFunctions.getInstance(app, regionOrCustomDomain) + com.google.firebase.functions.FirebaseFunctions.getInstance(app, regionOrCustomDomain) internal const val LIBRARY_NAME: String = "fire-fun-ktx" /** @suppress */ @Keep class FirebaseFunctionsKtxRegistrar : ComponentRegistrar { - override fun getComponents(): List> = - listOf(LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME)) + override fun getComponents(): List> = + listOf(LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME)) } /** Returns a reference to the Callable HTTPS trigger with the given name and call options. */ fun FirebaseFunctions.getHttpsCallable( - name: String, - init: HttpsCallableOptions.Builder.() -> Unit + name: String, + init: HttpsCallableOptions.Builder.() -> Unit ): HttpsCallableReference { - val builder = HttpsCallableOptions.Builder() - builder.init() - return getHttpsCallable(name, builder.build()) + val builder = HttpsCallableOptions.Builder() + builder.init() + return getHttpsCallable(name, builder.build()) } /** Returns a reference to the Callable HTTPS trigger with the given URL and call options. */ fun FirebaseFunctions.getHttpsCallableFromUrl( - url: URL, - init: HttpsCallableOptions.Builder.() -> Unit + url: URL, + init: HttpsCallableOptions.Builder.() -> Unit ): HttpsCallableReference { - val builder = HttpsCallableOptions.Builder() - builder.init() - return getHttpsCallableFromUrl(url, builder.build()) + val builder = HttpsCallableOptions.Builder() + builder.init() + return getHttpsCallableFromUrl(url, builder.build()) } From 8985e56b30e83e8da29a97e12bfca9e091105372 Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 11 Jul 2023 12:57:46 -0400 Subject: [PATCH 03/11] add unit tests --- firebase-common/firebase-common.gradle.kts | 2 + firebase-common/src/main/AndroidManifest.xml | 6 +- .../test/java/com/google/firebase/Tests.kt | 140 ++++++++++++++++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 firebase-common/src/test/java/com/google/firebase/Tests.kt diff --git a/firebase-common/firebase-common.gradle.kts b/firebase-common/firebase-common.gradle.kts index 40068deaafa..18ac5764ce9 100644 --- a/firebase-common/firebase-common.gradle.kts +++ b/firebase-common/firebase-common.gradle.kts @@ -76,6 +76,8 @@ dependencies { testImplementation(libs.org.json) testImplementation(libs.robolectric) testImplementation(libs.truth) + testImplementation(libs.androidx.test.core) + testImplementation(libs.kotlin.coroutines.test) androidTestImplementation(libs.androidx.test.junit) androidTestImplementation(libs.androidx.test.runner) diff --git a/firebase-common/src/main/AndroidManifest.xml b/firebase-common/src/main/AndroidManifest.xml index a2913a3a915..718739377e5 100644 --- a/firebase-common/src/main/AndroidManifest.xml +++ b/firebase-common/src/main/AndroidManifest.xml @@ -29,6 +29,10 @@ android:name="com.google.firebase.components.ComponentDiscoveryService" android:directBootAware="true" android:exported="false" - tools:targetApi="n" /> + tools:targetApi="n" > + + + diff --git a/firebase-common/src/test/java/com/google/firebase/Tests.kt b/firebase-common/src/test/java/com/google/firebase/Tests.kt new file mode 100644 index 00000000000..76b561159a2 --- /dev/null +++ b/firebase-common/src/test/java/com/google/firebase/Tests.kt @@ -0,0 +1,140 @@ +// Copyright 2019 Google LLC +// +// 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.google.firebase + +import androidx.test.core.app.ApplicationProvider +import com.google.android.gms.tasks.Tasks +import com.google.common.truth.Truth.assertThat +import com.google.firebase.platforminfo.UserAgentPublisher +import kotlinx.coroutines.tasks.await +import kotlinx.coroutines.test.runTest +import org.junit.Assert.fail +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +fun withApp(name: String, block: FirebaseApp.() -> Unit) { + val app = + Firebase.initialize( + ApplicationProvider.getApplicationContext(), + FirebaseOptions.Builder().setApplicationId("appId").build(), + name + ) + try { + block(app) + } finally { + app.delete() + } +} + +class TestException(message: String) : Exception(message) + +@RunWith(RobolectricTestRunner::class) +class VersionTests { + @Test + fun libraryVersions_shouldBeRegisteredWithRuntime() { + withApp("ktxTestApp") { + val uaPublisher = get(UserAgentPublisher::class.java) + assertThat(uaPublisher.userAgent).contains("kotlin") + assertThat(uaPublisher.userAgent).contains(LIBRARY_NAME) + } + } +} + +@RunWith(RobolectricTestRunner::class) +class KtxTests { + @Test + fun `Firebase#app should delegate to FirebaseApp#getInstance()`() { + withApp(FirebaseApp.DEFAULT_APP_NAME) { + assertThat(Firebase.app).isSameInstanceAs(FirebaseApp.getInstance()) + } + } + + @Test + fun `Firebase#app(String) should delegate to FirebaseApp#getInstance(String)`() { + val appName = "testApp" + withApp(appName) { + assertThat(Firebase.app(appName)).isSameInstanceAs(FirebaseApp.getInstance(appName)) + } + } + + @Test + fun `Firebase#options should delegate to FirebaseApp#getInstance()#options`() { + withApp(FirebaseApp.DEFAULT_APP_NAME) { + assertThat(Firebase.options).isSameInstanceAs(FirebaseApp.getInstance().options) + } + } + + @Test + fun `Firebase#initialize(Context, FirebaseOptions) should initialize the app correctly`() { + val options = FirebaseOptions.Builder().setApplicationId("appId").build() + val app = Firebase.initialize(ApplicationProvider.getApplicationContext(), options) + try { + assertThat(app).isNotNull() + assertThat(app.name).isEqualTo(FirebaseApp.DEFAULT_APP_NAME) + assertThat(app.options).isSameInstanceAs(options) + assertThat(app.applicationContext) + .isSameInstanceAs(ApplicationProvider.getApplicationContext()) + } finally { + app.delete() + } + } + + @Test + fun `Firebase#initialize(Context, FirebaseOptions, String) should initialize the app correctly`() { + val options = FirebaseOptions.Builder().setApplicationId("appId").build() + val name = "appName" + val app = Firebase.initialize(ApplicationProvider.getApplicationContext(), options, name) + try { + assertThat(app).isNotNull() + assertThat(app.name).isEqualTo(name) + assertThat(app.options).isSameInstanceAs(options) + assertThat(app.applicationContext) + .isSameInstanceAs(ApplicationProvider.getApplicationContext()) + } finally { + app.delete() + } + } +} + +class CoroutinesPlayServicesTests { + // We are only interested in the await() function offered by kotlinx-coroutines-play-services + // So we're not testing the other functions provided by that library. + + @Test + fun `Task#await() resolves to the same result as Task#getResult()`() = runTest { + val task = Tasks.forResult(21) + + val expected = task.result + val actual = task.await() + + assertThat(actual).isEqualTo(expected) + assertThat(task.isSuccessful).isTrue() + assertThat(task.exception).isNull() + } + + @Test + fun `Task#await() throws an Exception for failing Tasks`() = runTest { + val task = Tasks.forException(TestException("some error happened")) + + try { + task.await() + fail("Task#await should throw an Exception") + } catch (e: Exception) { + assertThat(e).isInstanceOf(TestException::class.java) + assertThat(task.isSuccessful).isFalse() + } + } +} From 3afcb15c531292541dccdecc3d59fc172af61f30 Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 11 Jul 2023 13:26:38 -0400 Subject: [PATCH 04/11] update ktx --- firebase-common/ktx/ktx.gradle.kts | 2 -- .../com/google/firebase/ktx/Firebase.kt | 21 ------------------- 2 files changed, 23 deletions(-) diff --git a/firebase-common/ktx/ktx.gradle.kts b/firebase-common/ktx/ktx.gradle.kts index eb0218a0948..f945372b204 100644 --- a/firebase-common/ktx/ktx.gradle.kts +++ b/firebase-common/ktx/ktx.gradle.kts @@ -47,11 +47,9 @@ dependencies { implementation("com.google.firebase:firebase-annotations:16.2.0") implementation(project(":firebase-common")) implementation("com.google.firebase:firebase-components:17.1.0") - implementation(libs.androidx.annotation) // We"re exposing this library as a transitive dependency so developers can // get Kotlin Coroutines support out-of-the-box for methods that return a Task - api(libs.kotlin.coroutines.tasks) testImplementation(libs.robolectric) testImplementation(libs.junit) diff --git a/firebase-common/ktx/src/main/kotlin/com/google/firebase/ktx/Firebase.kt b/firebase-common/ktx/src/main/kotlin/com/google/firebase/ktx/Firebase.kt index 058c0f20626..ee7cffb8212 100644 --- a/firebase-common/ktx/src/main/kotlin/com/google/firebase/ktx/Firebase.kt +++ b/firebase-common/ktx/src/main/kotlin/com/google/firebase/ktx/Firebase.kt @@ -17,18 +17,9 @@ import android.content.Context import androidx.annotation.Keep import com.google.firebase.FirebaseApp import com.google.firebase.FirebaseOptions -import com.google.firebase.annotations.concurrent.Background -import com.google.firebase.annotations.concurrent.Blocking -import com.google.firebase.annotations.concurrent.Lightweight -import com.google.firebase.annotations.concurrent.UiThread import com.google.firebase.components.Component import com.google.firebase.components.ComponentRegistrar -import com.google.firebase.components.Dependency -import com.google.firebase.components.Qualified import com.google.firebase.platforminfo.LibraryVersionComponent -import java.util.concurrent.Executor -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.asCoroutineDispatcher /** * Single access point to all firebase SDKs from Kotlin. @@ -67,18 +58,6 @@ class FirebaseCommonKtxRegistrar : ComponentRegistrar { override fun getComponents(): List> { return listOf( LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME), - coroutineDispatcher(), - coroutineDispatcher(), - coroutineDispatcher(), - coroutineDispatcher() ) } } - -private inline fun coroutineDispatcher(): Component = - Component.builder(Qualified.qualified(T::class.java, CoroutineDispatcher::class.java)) - .add(Dependency.required(Qualified.qualified(T::class.java, Executor::class.java))) - .factory { c -> - c.get(Qualified.qualified(T::class.java, Executor::class.java)).asCoroutineDispatcher() - } - .build() From c23c0f94adadd6556fab05c35dbd6d7e6f7e9edb Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 11 Jul 2023 14:06:56 -0400 Subject: [PATCH 05/11] update gradle ktx --- firebase-functions/ktx/ktx.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firebase-functions/ktx/ktx.gradle.kts b/firebase-functions/ktx/ktx.gradle.kts index fc16e4fd407..cca53063725 100644 --- a/firebase-functions/ktx/ktx.gradle.kts +++ b/firebase-functions/ktx/ktx.gradle.kts @@ -44,9 +44,9 @@ android { } dependencies { - implementation("com.google.firebase:firebase-common:20.3.1") + implementation(project(":firebase-common")) implementation("com.google.firebase:firebase-components:17.1.0") - implementation("com.google.firebase:firebase-common-ktx:20.3.1") + implementation(project(":firebase-common:ktx")) implementation(project(":firebase-functions")) implementation(libs.kotlin.stdlib) implementation(libs.androidx.annotation) From 034fbe6030fce352d321f604d8b4c752cba24fa8 Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 11 Jul 2023 14:12:09 -0400 Subject: [PATCH 06/11] copy tests for functions --- .../google/firebase/functions/CallTests.kt | 91 +++++++++++++++++++ .../firebase/functions/TestVisibilityUtil.kt | 20 ++++ 2 files changed, 111 insertions(+) create mode 100644 firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt create mode 100644 firebase-functions/src/test/java/com/google/firebase/functions/TestVisibilityUtil.kt diff --git a/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt b/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt new file mode 100644 index 00000000000..33d7be6eb8e --- /dev/null +++ b/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt @@ -0,0 +1,91 @@ +// Copyright 2019 Google LLC +// +// 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.google.firebase.functions + +import androidx.test.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 +import com.google.android.gms.tasks.Tasks +import com.google.common.truth.Truth.assertThat +import com.google.firebase.FirebaseApp +import com.google.firebase.ktx.Firebase +import com.google.firebase.ktx.app +import com.google.firebase.ktx.initialize +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.Test +import org.junit.runner.RunWith + +const val APP_ID = "APP_ID" +const val API_KEY = "API_KEY" + +@RunWith(AndroidJUnit4::class) +class CallTests { + companion object { + lateinit var app: FirebaseApp + + @BeforeClass + @JvmStatic + fun setup() { + app = Firebase.initialize(InstrumentationRegistry.getContext())!! + } + + @AfterClass + @JvmStatic + fun cleanup() { + app.delete() + } + } + + @Test + fun testDataCall() { + val functions = Firebase.functions(app) + val input = + hashMapOf( + "bool" to true, + "int" to 2, + "long" to 3L, + "string" to "four", + "array" to listOf(5, 6), + "null" to null + ) + + var function = functions.getHttpsCallable("dataTest") + val actual = Tasks.await(function.call(input)).getData() + + assertThat(actual).isInstanceOf(Map::class.java) + @Suppress("UNCHECKED_CAST") val map = actual as Map + assertThat(map["message"]).isEqualTo("stub response") + assertThat(map["code"]).isEqualTo(42) + assertThat(map["long"]).isEqualTo(420L) + } + + @Test + fun testNullDataCall() { + val functions = Firebase.functions(app) + var function = functions.getHttpsCallable("nullTest") + val actual = Tasks.await(function.call(null)).getData() + + assertThat(actual).isNull() + } + + @Test + fun testEmptyDataCall() { + val functions = Firebase.functions(app) + var function = functions.getHttpsCallable("nullTest") + val actual = Tasks.await(function.call()).getData() + + assertThat(actual).isNull() + } +} diff --git a/firebase-functions/src/test/java/com/google/firebase/functions/TestVisibilityUtil.kt b/firebase-functions/src/test/java/com/google/firebase/functions/TestVisibilityUtil.kt new file mode 100644 index 00000000000..ead456bb9e3 --- /dev/null +++ b/firebase-functions/src/test/java/com/google/firebase/functions/TestVisibilityUtil.kt @@ -0,0 +1,20 @@ +// Copyright 2023 Google LLC +// +// 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.google.firebase.functions + +/** + * Returns true if the {@link HttpsCallableReference} is configured to use FAC limited-use tokens. + */ +fun HttpsCallableReference.usesLimitedUseFacTokens() = options.getLimitedUseAppCheckTokens() From b7c1be5a62f4efc362d84b5e499fc506bbbe9068 Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 11 Jul 2023 14:26:43 -0400 Subject: [PATCH 07/11] update --- .../java/com/google/firebase/functions/CallTests.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt b/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt index 33d7be6eb8e..4e3770c2bce 100644 --- a/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt +++ b/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt @@ -19,9 +19,9 @@ import androidx.test.runner.AndroidJUnit4 import com.google.android.gms.tasks.Tasks import com.google.common.truth.Truth.assertThat import com.google.firebase.FirebaseApp -import com.google.firebase.ktx.Firebase -import com.google.firebase.ktx.app -import com.google.firebase.ktx.initialize +import com.google.firebase.Firebase +import com.google.firebase.app +import com.google.firebase.initialize import org.junit.AfterClass import org.junit.BeforeClass import org.junit.Test From 9cc3ce5adcecf08efc90a1235336aea3b2eca23f Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 11 Jul 2023 14:35:39 -0400 Subject: [PATCH 08/11] update --- .../androidTest/java/com/google/firebase/functions/CallTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt b/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt index 4e3770c2bce..54b547bb1c0 100644 --- a/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt +++ b/firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTests.kt @@ -18,8 +18,8 @@ import androidx.test.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 import com.google.android.gms.tasks.Tasks import com.google.common.truth.Truth.assertThat -import com.google.firebase.FirebaseApp import com.google.firebase.Firebase +import com.google.firebase.FirebaseApp import com.google.firebase.app import com.google.firebase.initialize import org.junit.AfterClass From 806db8f05fbf88e8873e55a3dc1625a32e997648 Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 18 Jul 2023 11:57:47 -0400 Subject: [PATCH 09/11] update prototype --- firebase-common/ktx/ktx.gradle.kts | 6 +----- firebase-common/ktx/src/main/AndroidManifest.xml | 11 ----------- .../main/java}/com/google/firebase/ktx/Firebase.kt | 5 +---- .../test/java}/com/google/firebase/ktx/Tests.kt | 0 4 files changed, 2 insertions(+), 20 deletions(-) delete mode 100644 firebase-common/ktx/src/main/AndroidManifest.xml rename firebase-common/{ktx/src/main/kotlin => src/main/java}/com/google/firebase/ktx/Firebase.kt (92%) rename firebase-common/{ktx/src/test/kotlin => src/test/java}/com/google/firebase/ktx/Tests.kt (100%) diff --git a/firebase-common/ktx/ktx.gradle.kts b/firebase-common/ktx/ktx.gradle.kts index f945372b204..2fbd7e06062 100644 --- a/firebase-common/ktx/ktx.gradle.kts +++ b/firebase-common/ktx/ktx.gradle.kts @@ -42,11 +42,7 @@ android { } dependencies { - implementation(libs.kotlin.stdlib) - - implementation("com.google.firebase:firebase-annotations:16.2.0") - implementation(project(":firebase-common")) - implementation("com.google.firebase:firebase-components:17.1.0") + api(project(":firebase-common")) // We"re exposing this library as a transitive dependency so developers can // get Kotlin Coroutines support out-of-the-box for methods that return a Task diff --git a/firebase-common/ktx/src/main/AndroidManifest.xml b/firebase-common/ktx/src/main/AndroidManifest.xml deleted file mode 100644 index 05858c6eb7b..00000000000 --- a/firebase-common/ktx/src/main/AndroidManifest.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/firebase-common/ktx/src/main/kotlin/com/google/firebase/ktx/Firebase.kt b/firebase-common/src/main/java/com/google/firebase/ktx/Firebase.kt similarity index 92% rename from firebase-common/ktx/src/main/kotlin/com/google/firebase/ktx/Firebase.kt rename to firebase-common/src/main/java/com/google/firebase/ktx/Firebase.kt index ee7cffb8212..9620d1bb010 100644 --- a/firebase-common/ktx/src/main/kotlin/com/google/firebase/ktx/Firebase.kt +++ b/firebase-common/src/main/java/com/google/firebase/ktx/Firebase.kt @@ -19,7 +19,6 @@ import com.google.firebase.FirebaseApp import com.google.firebase.FirebaseOptions import com.google.firebase.components.Component import com.google.firebase.components.ComponentRegistrar -import com.google.firebase.platforminfo.LibraryVersionComponent /** * Single access point to all firebase SDKs from Kotlin. @@ -56,8 +55,6 @@ internal const val LIBRARY_NAME: String = "fire-core-ktx" @Keep class FirebaseCommonKtxRegistrar : ComponentRegistrar { override fun getComponents(): List> { - return listOf( - LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME), - ) + return listOf() } } diff --git a/firebase-common/ktx/src/test/kotlin/com/google/firebase/ktx/Tests.kt b/firebase-common/src/test/java/com/google/firebase/ktx/Tests.kt similarity index 100% rename from firebase-common/ktx/src/test/kotlin/com/google/firebase/ktx/Tests.kt rename to firebase-common/src/test/java/com/google/firebase/ktx/Tests.kt From b9aca18ba14f1aa71275c24886182cee6c790abf Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 18 Jul 2023 14:23:01 -0400 Subject: [PATCH 10/11] update --- .../com/google/firebase/functions/{ => ktx}/Functions.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) rename firebase-functions/src/main/java/com/google/firebase/functions/{ => ktx}/Functions.kt (91%) diff --git a/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt b/firebase-functions/src/main/java/com/google/firebase/functions/ktx/Functions.kt similarity index 91% rename from firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt rename to firebase-functions/src/main/java/com/google/firebase/functions/ktx/Functions.kt index 8131d491fec..63c636f945a 100644 --- a/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt +++ b/firebase-functions/src/main/java/com/google/firebase/functions/ktx/Functions.kt @@ -12,13 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.firebase.functions +package com.google.firebase.functions.ktx import androidx.annotation.Keep import com.google.firebase.Firebase import com.google.firebase.FirebaseApp import com.google.firebase.components.Component import com.google.firebase.components.ComponentRegistrar +import com.google.firebase.functions.BuildConfig +import com.google.firebase.functions.FirebaseFunctions +import com.google.firebase.functions.HttpsCallableOptions +import com.google.firebase.functions.HttpsCallableReference import com.google.firebase.platforminfo.LibraryVersionComponent import java.net.URL From 172314240f1e8a0b1cb5172d3f7c744121bff2b6 Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Tue, 18 Jul 2023 14:54:18 -0400 Subject: [PATCH 11/11] packaging prototype latest version --- firebase-functions/ktx/ktx.gradle.kts | 15 +-- .../ktx/src/main/AndroidManifest.xml | 11 --- .../firebase/functions/ktx/FunctionsTests.kt | 2 +- .../firebase/functions/ktx/CallTests.kt | 91 +++++++++++++++++++ .../src/main/AndroidManifest.xml | 2 + .../google/firebase/functions}/Functions.kt | 7 +- .../firebase/functions/ktx/Functions.kt | 2 +- 7 files changed, 105 insertions(+), 25 deletions(-) delete mode 100644 firebase-functions/ktx/src/main/AndroidManifest.xml create mode 100644 firebase-functions/src/androidTest/java/com/google/firebase/functions/ktx/CallTests.kt rename firebase-functions/{ktx/src/main/kotlin/com/google/firebase/functions/ktx => src/main/java/com/google/firebase/functions}/Functions.kt (91%) diff --git a/firebase-functions/ktx/ktx.gradle.kts b/firebase-functions/ktx/ktx.gradle.kts index cca53063725..cda586a2d2e 100644 --- a/firebase-functions/ktx/ktx.gradle.kts +++ b/firebase-functions/ktx/ktx.gradle.kts @@ -44,18 +44,19 @@ android { } dependencies { - implementation(project(":firebase-common")) - implementation("com.google.firebase:firebase-components:17.1.0") - implementation(project(":firebase-common:ktx")) - implementation(project(":firebase-functions")) - implementation(libs.kotlin.stdlib) - implementation(libs.androidx.annotation) - implementation(libs.playservices.tasks) + api(project(":firebase-functions")) + androidTestImplementation(project(":firebase-common")) + androidTestImplementation("com.google.firebase:firebase-components:17.1.0") + androidTestImplementation(project(":firebase-common:ktx")) androidTestImplementation(libs.junit) androidTestImplementation(libs.truth) androidTestImplementation(libs.androidx.test.runner) + testImplementation(project(":firebase-common")) + testImplementation("com.google.firebase:firebase-components:17.1.0") + testImplementation(project(":firebase-common:ktx")) + testImplementation(libs.robolectric) testImplementation(libs.junit) testImplementation(libs.truth) diff --git a/firebase-functions/ktx/src/main/AndroidManifest.xml b/firebase-functions/ktx/src/main/AndroidManifest.xml deleted file mode 100644 index 28c8c25d8cd..00000000000 --- a/firebase-functions/ktx/src/main/AndroidManifest.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/firebase-functions/ktx/src/test/kotlin/com/google/firebase/functions/ktx/FunctionsTests.kt b/firebase-functions/ktx/src/test/kotlin/com/google/firebase/functions/ktx/FunctionsTests.kt index 7c5655902e1..671ac2a2d59 100644 --- a/firebase-functions/ktx/src/test/kotlin/com/google/firebase/functions/ktx/FunctionsTests.kt +++ b/firebase-functions/ktx/src/test/kotlin/com/google/firebase/functions/ktx/FunctionsTests.kt @@ -99,7 +99,7 @@ class LibraryVersionTest : BaseTestCase() { @Test fun `library version should be registered with runtime`() { val publisher = Firebase.app.get(UserAgentPublisher::class.java) - assertThat(publisher.userAgent).contains(LIBRARY_NAME) + assertThat(publisher.userAgent).contains("fire-fun-ktx") } } diff --git a/firebase-functions/src/androidTest/java/com/google/firebase/functions/ktx/CallTests.kt b/firebase-functions/src/androidTest/java/com/google/firebase/functions/ktx/CallTests.kt new file mode 100644 index 00000000000..45361539f1b --- /dev/null +++ b/firebase-functions/src/androidTest/java/com/google/firebase/functions/ktx/CallTests.kt @@ -0,0 +1,91 @@ +// Copyright 2019 Google LLC +// +// 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.google.firebase.functions.ktx + +import androidx.test.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 +import com.google.android.gms.tasks.Tasks +import com.google.common.truth.Truth.assertThat +import com.google.firebase.Firebase +import com.google.firebase.FirebaseApp +import com.google.firebase.app +import com.google.firebase.initialize +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.Test +import org.junit.runner.RunWith + +const val APP_ID = "APP_ID" +const val API_KEY = "API_KEY" + +@RunWith(AndroidJUnit4::class) +class CallTests { + companion object { + lateinit var app: FirebaseApp + + @BeforeClass + @JvmStatic + fun setup() { + app = Firebase.initialize(InstrumentationRegistry.getContext())!! + } + + @AfterClass + @JvmStatic + fun cleanup() { + app.delete() + } + } + + @Test + fun testDataCall() { + val functions = Firebase.functions(app) + val input = + hashMapOf( + "bool" to true, + "int" to 2, + "long" to 3L, + "string" to "four", + "array" to listOf(5, 6), + "null" to null + ) + + var function = functions.getHttpsCallable("dataTest") + val actual = Tasks.await(function.call(input)).getData() + + assertThat(actual).isInstanceOf(Map::class.java) + @Suppress("UNCHECKED_CAST") val map = actual as Map + assertThat(map["message"]).isEqualTo("stub response") + assertThat(map["code"]).isEqualTo(42) + assertThat(map["long"]).isEqualTo(420L) + } + + @Test + fun testNullDataCall() { + val functions = Firebase.functions(app) + var function = functions.getHttpsCallable("nullTest") + val actual = Tasks.await(function.call(null)).getData() + + assertThat(actual).isNull() + } + + @Test + fun testEmptyDataCall() { + val functions = Firebase.functions(app) + var function = functions.getHttpsCallable("nullTest") + val actual = Tasks.await(function.call()).getData() + + assertThat(actual).isNull() + } +} diff --git a/firebase-functions/src/main/AndroidManifest.xml b/firebase-functions/src/main/AndroidManifest.xml index 241d9ae04ea..9402a26cb1d 100644 --- a/firebase-functions/src/main/AndroidManifest.xml +++ b/firebase-functions/src/main/AndroidManifest.xml @@ -8,6 +8,8 @@ + diff --git a/firebase-functions/ktx/src/main/kotlin/com/google/firebase/functions/ktx/Functions.kt b/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt similarity index 91% rename from firebase-functions/ktx/src/main/kotlin/com/google/firebase/functions/ktx/Functions.kt rename to firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt index 65464fd9906..3435737f980 100644 --- a/firebase-functions/ktx/src/main/kotlin/com/google/firebase/functions/ktx/Functions.kt +++ b/firebase-functions/src/main/java/com/google/firebase/functions/Functions.kt @@ -12,16 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.firebase.functions.ktx +package com.google.firebase.functions import androidx.annotation.Keep +import com.google.firebase.Firebase import com.google.firebase.FirebaseApp import com.google.firebase.components.Component import com.google.firebase.components.ComponentRegistrar -import com.google.firebase.functions.FirebaseFunctions -import com.google.firebase.functions.HttpsCallableOptions -import com.google.firebase.functions.HttpsCallableReference -import com.google.firebase.ktx.Firebase import com.google.firebase.platforminfo.LibraryVersionComponent import java.net.URL diff --git a/firebase-functions/src/main/java/com/google/firebase/functions/ktx/Functions.kt b/firebase-functions/src/main/java/com/google/firebase/functions/ktx/Functions.kt index 63c636f945a..df329157486 100644 --- a/firebase-functions/src/main/java/com/google/firebase/functions/ktx/Functions.kt +++ b/firebase-functions/src/main/java/com/google/firebase/functions/ktx/Functions.kt @@ -15,7 +15,6 @@ package com.google.firebase.functions.ktx import androidx.annotation.Keep -import com.google.firebase.Firebase import com.google.firebase.FirebaseApp import com.google.firebase.components.Component import com.google.firebase.components.ComponentRegistrar @@ -23,6 +22,7 @@ import com.google.firebase.functions.BuildConfig import com.google.firebase.functions.FirebaseFunctions import com.google.firebase.functions.HttpsCallableOptions import com.google.firebase.functions.HttpsCallableReference +import com.google.firebase.ktx.Firebase import com.google.firebase.platforminfo.LibraryVersionComponent import java.net.URL