Skip to content

Commit

Permalink
Create different PurchasesConfiguration that requires an appUserId pa…
Browse files Browse the repository at this point in the history
…rameter
  • Loading branch information
tonidero committed Jul 20, 2023
1 parent 33341fa commit 4e590d0
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ static void checkConfiguration(final Context context,

final boolean configured = Purchases.isConfigured();

PurchasesConfiguration build = new PurchasesConfiguration.Builder(context, "")
.appUserID("")
PurchasesConfiguration build = new PurchasesConfiguration.Builder(context, "", "")
.observerMode(true)
.observerMode(false)
.service(executorService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,12 @@ private class PurchasesAPI {
val features: List<BillingFeature> = ArrayList()
val configured: Boolean = Purchases.isConfigured

val build = PurchasesConfiguration.Builder(context, apiKey = "")
.appUserID("")
val build = PurchasesConfiguration.Builder(context, apiKey = "", appUserID = "")
.observerMode(true)
.observerMode(false)
.service(executorService)
.diagnosticsEnabled(true)
.entitlementVerificationMode(EntitlementVerificationMode.INFORMATIONAL)
.informationalVerificationModeAndDiagnosticsEnabled(true)
.build()

Purchases.configure(build)
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ task detektAll(type: io.gitlab.arturbosch.detekt.Detekt) {
exclude("**/build/**")
exclude("**/test/**/*.kt")
exclude("**/testDefaults/**/*.kt")
exclude("**/testCustomEntitlementComputation/**/*.kt")
config.setFrom(files("$rootDir/config/detekt/detekt.yml"))
baseline.set(file("$rootDir/config/detekt/detekt-baseline.xml"))
reports {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.revenuecat.purchases.amazon

import android.content.Context
import com.revenuecat.purchases.PurchasesConfiguration
import com.revenuecat.purchases.Store

class AmazonConfiguration(builder: Builder) : PurchasesConfiguration(builder) {

class Builder(
context: Context,
apiKey: String,
appUserId: String,
) : PurchasesConfiguration.Builder(context, apiKey, appUserId) {

init {
this.store(Store.AMAZON)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.revenuecat.purchases

import android.content.Context
import java.util.concurrent.ExecutorService

open class PurchasesConfiguration(builder: Builder) {

val context: Context
val apiKey: String
val appUserID: String
val observerMode: Boolean
val service: ExecutorService?
val store: Store
val diagnosticsEnabled: Boolean
val dangerousSettings: DangerousSettings
val verificationMode: EntitlementVerificationMode

init {
this.context = builder.context
this.apiKey = builder.apiKey
this.appUserID = builder.appUserID
this.observerMode = builder.observerMode
this.service = builder.service
this.store = builder.store
this.diagnosticsEnabled = builder.diagnosticsEnabled
this.verificationMode = builder.verificationMode
this.dangerousSettings = builder.dangerousSettings
}

open class Builder(
@get:JvmSynthetic internal val context: Context,
@get:JvmSynthetic internal val apiKey: String,
@get:JvmSynthetic internal val appUserID: String,
) {
@set:JvmSynthetic @get:JvmSynthetic
internal var observerMode: Boolean = false

@set:JvmSynthetic @get:JvmSynthetic
internal var service: ExecutorService? = null

@set:JvmSynthetic @get:JvmSynthetic
internal var store: Store = Store.PLAY_STORE

@set:JvmSynthetic @get:JvmSynthetic
internal var diagnosticsEnabled: Boolean = false

@set:JvmSynthetic @get:JvmSynthetic
internal var verificationMode: EntitlementVerificationMode = EntitlementVerificationMode.default

// TODO Default to custom entitlement computation mode
@set:JvmSynthetic @get:JvmSynthetic
internal var dangerousSettings: DangerousSettings = DangerousSettings()

fun observerMode(observerMode: Boolean) = apply {
this.observerMode = observerMode
}

fun service(service: ExecutorService) = apply {
this.service = service
}

fun store(store: Store) = apply {
this.store = store
}

/**
* Enabling diagnostics will send some performance and debugging information from the SDK to our servers.
* Examples of this information include response times, cache hits or error codes.
* This information will be anonymized so it can't be traced back to the end-user.
* The default value is false.
*/
fun diagnosticsEnabled(diagnosticsEnabled: Boolean) = apply {
this.diagnosticsEnabled = diagnosticsEnabled
}

/**
* Sets the [EntitlementVerificationMode] to perform signature verification of requests to the
* RevenueCat backend.
*
* When changing from [EntitlementVerificationMode.DISABLED] to other modes, the SDK will clear the
* CustomerInfo cache.
* This means users will need to connect to the internet to get their entitlements back.
*
* The result of the verification can be obtained from [EntitlementInfos.verification] or
* [EntitlementInfo.verification].
*
* Default mode is disabled. Please see https://rev.cat/trusted-entitlements for more info.
*/
fun entitlementVerificationMode(verificationMode: EntitlementVerificationMode) = apply {
this.verificationMode = verificationMode
}

/**
* Only use a Dangerous Setting if suggested by RevenueCat support team.
*/
fun dangerousSettings(dangerousSettings: DangerousSettings) = apply {
// TODO Set custom entitlement computation mode when passing in dangerous settings
this.dangerousSettings = dangerousSettings
}

open fun build(): PurchasesConfiguration {
return PurchasesConfiguration(this)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,43 +145,6 @@ internal class PurchasesCommonTest: BasePurchasesTest() {
}
}

@Test
fun `Setting platform info sets it in the AppConfig when configuring the SDK`() {
val expected = PlatformInfo("flavor", "version")
Purchases.platformInfo = expected
Purchases.configure(PurchasesConfiguration.Builder(mockContext, "api").build())
assertThat(Purchases.sharedInstance.purchasesOrchestrator.appConfig.platformInfo).isEqualTo(expected)
}

@Test
fun `Setting proxy URL info sets it in the HttpClient when configuring the SDK`() {
val expected = URL("https://a-proxy.com")
Purchases.proxyURL = expected
Purchases.configure(PurchasesConfiguration.Builder(mockContext, "api").build())
assertThat(Purchases.sharedInstance.purchasesOrchestrator.appConfig.baseURL).isEqualTo(expected)
}

@Test
fun `Setting observer mode on sets finish transactions to false`() {
val builder = PurchasesConfiguration.Builder(mockContext, "api").observerMode(true)
Purchases.configure(builder.build())
assertThat(Purchases.sharedInstance.purchasesOrchestrator.appConfig.finishTransactions).isFalse()
}

@Test
fun `Setting observer mode off sets finish transactions to true`() {
val builder = PurchasesConfiguration.Builder(mockContext, "api").observerMode(false)
Purchases.configure(builder.build())
assertThat(Purchases.sharedInstance.purchasesOrchestrator.appConfig.finishTransactions).isTrue()
}

@Test
fun `Setting store in the configuration sets it on the Purchases instance`() {
val builder = PurchasesConfiguration.Builder(mockContext, "api").store(Store.PLAY_STORE)
Purchases.configure(builder.build())
assertThat(Purchases.sharedInstance.store).isEqualTo(Store.PLAY_STORE)
}

// endregion

// region get products
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class PurchasesFactoryTest {

@Test
fun `creating purchase checks api key is not empty`() {
val configuration = createConfiguration(apiKey = "")
val configuration = createConfiguration(testApiKey = "")
every {
contextMock.checkCallingOrSelfPermission(Manifest.permission.INTERNET)
} returns PackageManager.PERMISSION_GRANTED
Expand Down Expand Up @@ -84,7 +84,12 @@ class PurchasesFactoryTest {
verify(exactly = 1) { apiKeyValidatorMock.validateAndLog("fakeApiKey", Store.PLAY_STORE) }
}

private fun createConfiguration(apiKey: String = "fakeApiKey"): PurchasesConfiguration {
return PurchasesConfiguration.Builder(contextMock, apiKey).build()
private fun createConfiguration(testApiKey: String = "fakeApiKey"): PurchasesConfiguration {
return mockk<PurchasesConfiguration>().apply {
every { context } returns contextMock
every { apiKey } returns testApiKey
every { appUserID } returns "appUserID"
every { store } returns Store.PLAY_STORE
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.revenuecat.purchases

import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.mockk.mockk
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.util.concurrent.ExecutorService

@RunWith(AndroidJUnit4::class)
class PurchasesConfigurationTest {

private val apiKey = "test-api-key"
private val appUserId = "test-app-user-id"

private lateinit var context: Context

private lateinit var builder: PurchasesConfiguration.Builder

@Before
fun setup() {
context = mockk()

builder = PurchasesConfiguration.Builder(context, apiKey, appUserId)
}

@Test
fun `PurchasesConfiguration has expected default parameters`() {
val purchasesConfiguration = builder.build()
assertThat(purchasesConfiguration.apiKey).isEqualTo(apiKey)
assertThat(purchasesConfiguration.context).isEqualTo(context)
assertThat(purchasesConfiguration.appUserID).isEqualTo(appUserId)
assertThat(purchasesConfiguration.observerMode).isFalse
assertThat(purchasesConfiguration.service).isNull()
assertThat(purchasesConfiguration.store).isEqualTo(Store.PLAY_STORE)
assertThat(purchasesConfiguration.diagnosticsEnabled).isFalse
assertThat(purchasesConfiguration.verificationMode).isEqualTo(EntitlementVerificationMode.DISABLED)
assertThat(purchasesConfiguration.dangerousSettings).isEqualTo(DangerousSettings(autoSyncPurchases = true))
}

@Test
fun `PurchasesConfiguration sets observerMode correctly`() {
val purchasesConfiguration = builder.observerMode(true).build()
assertThat(purchasesConfiguration.observerMode).isTrue
}

@Test
fun `PurchasesConfiguration sets service correctly`() {
val serviceMock: ExecutorService = mockk()
val purchasesConfiguration = builder.service(serviceMock).build()
assertThat(purchasesConfiguration.service).isEqualTo(serviceMock)
}

@Test
fun `PurchasesConfiguration sets store correctly`() {
val purchasesConfiguration = builder.store(Store.AMAZON).build()
assertThat(purchasesConfiguration.store).isEqualTo(Store.AMAZON)
}

@Test
fun `PurchasesConfiguration sets diagnosticsEnabled correctly`() {
val purchasesConfiguration = builder.diagnosticsEnabled(true).build()
assertThat(purchasesConfiguration.diagnosticsEnabled).isTrue
}

@Test
fun `PurchasesConfiguration sets informational mode correctly`() {
val purchasesConfiguration = builder.entitlementVerificationMode(
EntitlementVerificationMode.INFORMATIONAL,
).build()
assertThat(purchasesConfiguration.verificationMode).isEqualTo(EntitlementVerificationMode.INFORMATIONAL)
}

@Test
fun `PurchasesConfiguration sets dangerous settings correctly`() {
// TODO: Add test for custom entitlement computation mode
val dangerousSettings = DangerousSettings(autoSyncPurchases = false)
val purchasesConfiguration = builder.dangerousSettings(dangerousSettings).build()
assertThat(purchasesConfiguration.dangerousSettings).isEqualTo(dangerousSettings)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Purchases
//
// Copyright © 2019 RevenueCat, Inc. All rights reserved.
//

package com.revenuecat.purchases

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.revenuecat.purchases.common.PlatformInfo
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
import java.net.URL

@RunWith(AndroidJUnit4::class)
@Config(manifest = Config.NONE)
@Suppress("DEPRECATION")
internal class PurchasesTest : BasePurchasesTest() {

@Test
fun `Setting platform info sets it in the AppConfig when configuring the SDK`() {
val expected = PlatformInfo("flavor", "version")
Purchases.platformInfo = expected
Purchases.configure(PurchasesConfiguration.Builder(mockContext, "api", "appUserId").build())
assertThat(Purchases.sharedInstance.purchasesOrchestrator.appConfig.platformInfo).isEqualTo(expected)
}

@Test
fun `Setting proxy URL info sets it in the HttpClient when configuring the SDK`() {
val expected = URL("https://a-proxy.com")
Purchases.proxyURL = expected
Purchases.configure(PurchasesConfiguration.Builder(mockContext, "api", "appUserId").build())
assertThat(Purchases.sharedInstance.purchasesOrchestrator.appConfig.baseURL).isEqualTo(expected)
}

@Test
fun `Setting observer mode on sets finish transactions to false`() {
val builder = PurchasesConfiguration.Builder(mockContext, "api", "appUserId").observerMode(true)
Purchases.configure(builder.build())
assertThat(Purchases.sharedInstance.purchasesOrchestrator.appConfig.finishTransactions).isFalse()
}

@Test
fun `Setting observer mode off sets finish transactions to true`() {
val builder = PurchasesConfiguration.Builder(mockContext, "api", "appUserId").observerMode(false)
Purchases.configure(builder.build())
assertThat(Purchases.sharedInstance.purchasesOrchestrator.appConfig.finishTransactions).isTrue()
}

@Test
fun `Setting store in the configuration sets it on the Purchases instance`() {
val builder = PurchasesConfiguration.Builder(mockContext, "api", "appUserId").store(Store.PLAY_STORE)
Purchases.configure(builder.build())
assertThat(Purchases.sharedInstance.store).isEqualTo(Store.PLAY_STORE)
}
}
Loading

0 comments on commit 4e590d0

Please sign in to comment.