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

[tests are wip] V4 to v5 upgrade will migrate app ID #2244

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
26 changes: 17 additions & 9 deletions Examples/OneSignalDemo/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
}

android {
namespace 'com.onesignal.sdktest'
compileSdkVersion 34
defaultConfig {
minSdkVersion 21
Expand Down Expand Up @@ -52,21 +53,28 @@ android {

// Forced downgrade to Java 1.8 for compiling the application due to Android N error when building
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}

packagingOptions {
exclude 'androidsupportmultidexversion.txt'
}

task flavorSelection() {
if (getGradle().getStartParameter().getTaskRequests().toString().contains("Gms")) {
apply plugin: 'com.google.gms.google-services'
googleServices { disableVersionCheck = true }
} else {
apply plugin: 'com.huawei.agconnect'
}
androidComponents {
onVariants(selector().all(), { variant ->
println("HERE onVariants")
println(variant.name)
switch (variant.name) {
case "gms":
apply plugin: 'com.google.gms.google-services'
googleServices { disableVersionCheck = true }
break
case "huawei":
apply plugin: 'com.huawei.agconnect'
break
}
})
}
}

Expand Down
3 changes: 1 addition & 2 deletions Examples/OneSignalDemo/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:amazon="http://schemas.amazon.com/apk/res/android"
package="com.onesignal.sdktest">
xmlns:amazon="http://schemas.amazon.com/apk/res/android">

<uses-permission android:name="com.android.vending.BILLING" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.onesignal.notifications.IDisplayableNotification;
import com.onesignal.notifications.INotificationLifecycleListener;
import com.onesignal.notifications.INotificationWillDisplayEvent;
import com.onesignal.sdktest.BuildConfig;
import com.onesignal.sdktest.R;
import com.onesignal.sdktest.constant.Tag;
import com.onesignal.sdktest.constant.Text;
Expand All @@ -38,9 +37,10 @@ public class MainApplication extends MultiDexApplication {
private static final int SLEEP_TIME_TO_MIMIC_ASYNC_OPERATION = 2000;

public MainApplication() {
// run strict mode default in debug mode to surface any potential issues easier
if(BuildConfig.DEBUG)
StrictMode.enableDefaults();

StrictMode.allowThreadDiskReads();
StrictMode.allowThreadDiskWrites();

}

@SuppressLint("NewApi")
Expand Down
2 changes: 1 addition & 1 deletion Examples/OneSignalDemo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ buildscript {
maven { url 'https://developer.huawei.com/repo/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath 'com.android.tools.build:gradle:8.7.0'
classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.huawei.agconnect:agcp:1.6.2.300'

Expand Down
2 changes: 1 addition & 1 deletion OneSignalSDK/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
targetSdkVersion: 34,
minSdkVersion: 21
]
androidGradlePluginVersion = '7.2.0'
androidGradlePluginVersion = '8.7.1'
googleServicesGradlePluginVersion = '4.3.10'
huaweiAgconnectVersion = '1.6.2.300'
huaweiHMSPushVersion = '6.3.0.304'
Expand Down
4 changes: 1 addition & 3 deletions OneSignalSDK/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
# Remove when creating an .aar build.
#android.enableAapt2=false

android.databinding.incremental = false
kapt.incremental.apt = false
android.testConfig.useRelativePath = false
org.gradle.jvmargs=-Xmx1536m

# Enables D8 for all modules.
android.enableD8 = true
Expand Down
2 changes: 1 addition & 1 deletion OneSignalSDK/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
4 changes: 2 additions & 2 deletions OneSignalSDK/onesignal/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ android {
}
// Forced downgrade to Java 8 so SDK is backwards compatible in consuming projects
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
namespace 'com.onesignal'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ServiceProvider(

override fun <T> getServiceOrNull(c: Class<T>): T? {
synchronized(serviceMap) {
Logging.debug("${indent}Retrieving service $c")
// Logging.debug("${indent}Retrieving service $c")
return serviceMap[c]?.last()?.resolve(this) as T?
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ class ServiceRegistrationReflection<T>(

override fun resolve(provider: IServiceProvider): Any? {
if (obj != null) {
Logging.debug("${ServiceProvider.indent}Already instantiated: $obj")
// Logging.debug("${ServiceProvider.indent}Already instantiated: $obj")
return obj
}

// use reflection to try to instantiate the thing
for (constructor in clazz.constructors) {
if (doesHaveAllParameters(constructor, provider)) {
Logging.debug("${ServiceProvider.indent}Found constructor: $constructor")
// Logging.debug("${ServiceProvider.indent}Found constructor: $constructor")
var paramList: MutableList<Any?> = mutableListOf()

for (param in constructor.genericParameterTypes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ object PreferencePlayerPurchasesKeys {
object PreferenceOneSignalKeys {
// Legacy

/**
* (String) The legacy app ID from SDKs prior to 5.
*/
const val PREFS_LEGACY_APP_ID = "GT_APP_ID"

/**
* (String) The legacy player ID from SDKs prior to 5.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
context: Context,
appId: String?,
): Boolean {
println("❌ initWithContext(context: $context, appId: $appId)")
Logging.log(LogLevel.DEBUG, "initWithContext(context: $context, appId: $appId)")

synchronized(initLock) {
Expand Down Expand Up @@ -211,15 +212,29 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
sessionModel = services.getService<SessionModelStore>().model
operationRepo = services.getService<IOperationRepo>()

var forceCreateUser = false

// initWithContext is called by our internal services/receivers/activites but they do not provide
// an appId (they don't know it). If the app has never called the external initWithContext
// prior to our services/receivers/activities we will blow up, as no appId has been established.
if (appId == null && !configModel!!.hasProperty(ConfigModel::appId.name)) {
Logging.warn("initWithContext called without providing appId, and no appId has been established!")
return false
val legacyAppId =
preferencesService!!.getString(
PreferenceStores.ONESIGNAL,
PreferenceOneSignalKeys.PREFS_LEGACY_APP_ID,
)
if (legacyAppId == null) {
println("❌ initWithContext called without providing appId, and no appId has been established!")
Logging.warn("initWithContext called without providing appId, and no appId has been established!")
return false
} else {
println("❌ initWithContext: using cached legacy appId $legacyAppId")
Logging.debug("initWithContext: using cached legacy appId $legacyAppId")
forceCreateUser = true
configModel!!.appId = legacyAppId
}
}

var forceCreateUser = false
// if the app id was specified as input, update the config model with it
if (appId != null) {
if (!configModel!!.hasProperty(ConfigModel::appId.name) || configModel!!.appId != appId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,89 +1,119 @@
package com.onesignal.internal

import android.content.Context
import androidx.test.core.app.ApplicationProvider
import br.com.colman.kotest.android.extensions.robolectric.RobolectricTest
import com.onesignal.core.internal.preferences.PreferenceOneSignalKeys
import com.onesignal.core.internal.preferences.PreferenceStores
import com.onesignal.core.internal.preferences.impl.PreferencesService
// import com.onesignal.notifications.NotificationsModule
import com.onesignal.debug.LogLevel
import com.onesignal.debug.internal.logging.Logging
import com.onesignal.mocks.AndroidMockHelper
import com.onesignal.mocks.MockHelper
import com.onesignal.mocks.MockPreferencesService
import io.kotest.assertions.throwables.shouldThrowUnit
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe

@RobolectricTest
class OneSignalImpTests : FunSpec({
beforeAny {
Logging.logLevel = LogLevel.NONE
Logging.logLevel = LogLevel.VERBOSE
}

test("attempting login before initWithContext throws exception") {
// Given
val os = OneSignalImp()

// When
val exception =
shouldThrowUnit<Exception> {
os.login("login-id")
}
// test("attempting login before initWithContext throws exception") {
// // Given
// val os = OneSignalImp()
//
// // When
// val exception =
// shouldThrowUnit<Exception> {
// os.login("login-id")
// }
//
// // Then
// exception.message shouldBe "Must call 'initWithContext' before 'login'"
// }
//
// test("attempting logout before initWithContext throws exception") {
// // Given
// val os = OneSignalImp()
//
// // When
// val exception =
// shouldThrowUnit<Exception> {
// os.logout()
// }
//
// // Then
// exception.message shouldBe "Must call 'initWithContext' before 'logout'"
// }
//
// // consentRequired probably should have thrown like the other OneSignal methods in 5.0.0,
// // but we can't make a breaking change to an existing API.
// context("consentRequired") {
// context("before initWithContext") {
// test("set should not throw") {
// // Given
// val os = OneSignalImp()
// // When
// os.consentRequired = false
// os.consentRequired = true
// // Then
// // Test fails if the above throws
// }
// test("get should not throw") {
// // Given
// val os = OneSignalImp()
// // When
// println(os.consentRequired)
// // Then
// // Test fails if the above throws
// }
// }
// }
//
// // consentGiven probably should have thrown like the other OneSignal methods in 5.0.0,
// // but we can't make a breaking change to an existing API.
// context("consentGiven") {
// context("before initWithContext") {
// test("set should not throw") {
// // Given
// val os = OneSignalImp()
// // When
// os.consentGiven = true
// os.consentGiven = false
// // Then
// // Test fails if the above throws
// }
// test("get should not throw") {
// // Given
// val os = OneSignalImp()
// // When
// println(os.consentGiven)
// // Then
// // Test fails if the above throws
// }
// }
// }
test("initWithContext called without appId has cached legacy appId should initialize") {
val preferencesService = PreferencesService(AndroidMockHelper.applicationService(), MockHelper.time(1000))

// Then
exception.message shouldBe "Must call 'initWithContext' before 'login'"
}
preferencesService.saveString(PreferenceStores.ONESIGNAL, PreferenceOneSignalKeys.PREFS_LEGACY_APP_ID, "foo")

test("attempting logout before initWithContext throws exception") {
// Given
val os = OneSignalImp()
println("❌ BEFORE isInitialized: ${os.isInitialized}")
val context = ApplicationProvider.getApplicationContext<Context>()
os.initWithContext(context, null)
println("❌ AFTER isInitialized: ${os.isInitialized}")

// When
val exception =
shouldThrowUnit<Exception> {
os.logout()
}

// Then
exception.message shouldBe "Must call 'initWithContext' before 'logout'"
}

// consentRequired probably should have thrown like the other OneSignal methods in 5.0.0,
// but we can't make a breaking change to an existing API.
context("consentRequired") {
context("before initWithContext") {
test("set should not throw") {
// Given
val os = OneSignalImp()
// When
os.consentRequired = false
os.consentRequired = true
// Then
// Test fails if the above throws
}
test("get should not throw") {
// Given
val os = OneSignalImp()
// When
println(os.consentRequired)
// Then
// Test fails if the above throws
}
}
}

// consentGiven probably should have thrown like the other OneSignal methods in 5.0.0,
// but we can't make a breaking change to an existing API.
context("consentGiven") {
context("before initWithContext") {
test("set should not throw") {
// Given
val os = OneSignalImp()
// When
os.consentGiven = true
os.consentGiven = false
// Then
// Test fails if the above throws
}
test("get should not throw") {
// Given
val os = OneSignalImp()
// When
println(os.consentGiven)
// Then
// Test fails if the above throws
}
}
}
// test("initWithContext called without appId does not have cached legacy appId should return early") {
// // Given
// // When
// // Then
// }
})
Loading
Loading