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

Release: 1.8.0 #84

Merged
merged 14 commits into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from 11 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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ executors:
ios-executor:
working_directory: ~/ios
macos:
xcode: 12.0
xcode: 12.5.1
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we were getting definition conflicts with previous value errors pointing towards the eTags stuff in purchases-ios for some reason.
it looks like it was either a bug in Xcode 12.0, or in one of the other dependencies associated with the CircleCI instance for xcode 12.0. In any case, it gets fixed by bumping the version number here, and it works correctly locally.


jobs:
test-ios:
Expand Down
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
### 1.8.0

#### Identity V3

##### New methods
- Introduces `logIn`, a new way of identifying users, which also returns whether a new user has been registered in the system.
`logIn` uses a new backend endpoint.
- Introduces `logOut`, a replacement for `reset`.

##### Deprecations
- deprecates `createAlias` in favor of `logIn`
- deprecates `identify` in favor of `logIn`
- deprecates `reset` in favor of `logOut`
- deprecates `allowSharingStoreAccount` in favor of dashboard-side configuration

#### Dependency updates
- Bumps `purchases-ios` to `3.12.0` ([Changelog here](/~https://github.com/RevenueCat/purchases-ios/releases/3.12.0))
- Bumps `purchases-android` to `4.3.0` ([Changelog here](/~https://github.com/RevenueCat/purchases-android/releases/4.3.0))
/~https://github.com/RevenueCat/purchases-hybrid-common/pull/84

#### Bug Fixes
- Added `readableErrorCode` to `UserInfo` when creating `ErrorContainer`, so all errors have `readableErrorCode`
/~https://github.com/RevenueCat/purchases-hybrid-common/pull/82
- Made `underlyingErrorMessage` an empty string if it's missing in iOS
/~https://github.com/RevenueCat/purchases-hybrid-common/pull/71

### 1.7.1

- Fixed dependency specificiation in Podspec to purchases-ios@3.11.1
Expand Down
14 changes: 7 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.1.1)
aws-partitions (1.474.0)
aws-sdk-core (3.116.0)
Comment on lines -10 to -11
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated fastlane

aws-partitions (1.478.0)
aws-sdk-core (3.117.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
Expand All @@ -20,7 +20,7 @@ GEM
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.3)
aws-sigv4 (1.2.4)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.0.3)
Expand All @@ -36,7 +36,7 @@ GEM
dotenv (2.7.6)
emoji_regex (3.2.2)
excon (0.84.0)
faraday (1.5.0)
faraday (1.5.1)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
Expand All @@ -54,7 +54,7 @@ GEM
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.1.0)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday_middleware (1.0.0)
faraday (~> 1.0)
Expand Down Expand Up @@ -122,7 +122,7 @@ GEM
google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.1.0)
google-cloud-storage (1.34.0)
google-cloud-storage (1.34.1)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
Expand Down Expand Up @@ -154,7 +154,7 @@ GEM
os (1.1.1)
plist (3.6.0)
public_suffix (4.0.6)
rake (13.0.4)
rake (13.0.6)
representable (3.1.1)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
Expand Down
4 changes: 2 additions & 2 deletions PurchasesHybridCommon.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "PurchasesHybridCommon"
s.version = "1.7.1"
s.version = "1.8.0"
s.summary = "Common files for hybrid SDKs for RevenueCat's Subscription and in-app-purchase backend service."

s.description = <<-DESC
Expand All @@ -15,7 +15,7 @@ Pod::Spec.new do |s|

s.framework = 'StoreKit'

s.dependency 'Purchases', '3.11.1'
s.dependency 'Purchases', '3.12.0'
s.swift_version = '5.0'

s.ios.deployment_target = '9.0'
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
ext.assertj_version = '3.13.2'
ext.mockk_version = '1.10.0'
ext.gradle_maven_publish = '0.11.1'
ext.purchases_version = '4.2.1'
ext.purchases_version = '4.3.0'

repositories {
google()
Expand Down Expand Up @@ -37,7 +37,7 @@ android {
minSdkVersion 14
targetSdkVersion 29
versionCode 1
versionName "1.7.1"
versionName "1.8.0"

consumerProguardFiles 'consumer-rules.pro'
}
Expand Down
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ kotlin.code.style=official

# Maven
GROUP=com.revenuecat.purchases
VERSION_NAME=1.7.1
VERSION_NAME=1.8.0
POM_NAME=purchases-hybrid-common
POM_PACKAGING=aar
POM_ARTIFACT_ID=purchases-hybrid-common
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import com.revenuecat.purchases.identifyWith
import com.revenuecat.purchases.purchasePackageWith
import com.revenuecat.purchases.purchaseProductWith
import com.revenuecat.purchases.resetWith
import com.revenuecat.purchases.logInWith
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from this point on, the changes had been there merged before, but were removed in #75, because identity v3 wasn't ready to go in the native SDKs

import com.revenuecat.purchases.logOutWith
import com.revenuecat.purchases.restorePurchasesWith
import com.revenuecat.purchases.common.PlatformInfo
import com.revenuecat.purchases.interfaces.Callback
Expand Down Expand Up @@ -182,6 +184,27 @@ fun restoreTransactions(
}
}

fun logIn(
appUserID: String,
onResult: OnResult
) {
Purchases.sharedInstance.logInWith(appUserID,
onError = { onResult.onError(it.map()) },
onSuccess = { purchaserInfo, created ->
val resultMap: Map<String, Any?> = mapOf(
"purchaserInfo" to purchaserInfo.map(),
"created" to created
)
onResult.onReceived(resultMap)
})
}

fun logOut(onResult: OnResult) {
Purchases.sharedInstance.logOutWith(onError = { onResult.onError(it.map()) }) {
onResult.onReceived(it.map())
}
}

fun reset(
onResult: OnResult
) {
Expand Down Expand Up @@ -305,7 +328,7 @@ private fun getPurchaseCompletedFunction(onResult: OnResult): (Purchase?, Purcha
return { purchase, purchaserInfo ->
onResult.onReceived(
mapOf(
"productIdentifier" to purchase?.sku,
"productIdentifier" to purchase?.skus,
Comment on lines -308 to +347
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

related to changes in RevenueCat/purchases-android#335

"purchaserInfo" to purchaserInfo.map()
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ import android.app.Application
import android.content.Context
import com.revenuecat.purchases.BillingFeature
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.PurchaserInfo
import com.revenuecat.purchases.PurchasesError
import com.revenuecat.purchases.common.PlatformInfo
import com.revenuecat.purchases.hybridcommon.mappers.map
import com.revenuecat.purchases.interfaces.Callback
import com.revenuecat.purchases.interfaces.LogInCallback
import com.revenuecat.purchases.interfaces.ReceivePurchaserInfoListener
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
Expand Down Expand Up @@ -187,4 +192,172 @@ internal class CommonKtTests {
onResultAny.onError(any())
}
}

@Test
fun `calling logIn correctly passes call to Purchases`() {
val appUserID = "appUserID"

configure(
context = mockContext,
apiKey = "api_key",
appUserID = "appUserID",
observerMode = true,
platformInfo = PlatformInfo("flavor", "version")
)

every { mockPurchases.logIn(appUserID, any()) } just runs

logIn(appUserID = appUserID, onResult = object : OnResult {
override fun onReceived(map: Map<String?, *>?) {}
override fun onError(errorContainer: ErrorContainer) {}
})

verify(exactly = 1) { mockPurchases.logIn(appUserID, any()) }
}

@Test
fun `calling logIn correctly calls onReceived`() {
val appUserID = "appUserID"

configure(
context = mockContext,
apiKey = "api_key",
appUserID = "appUserID",
observerMode = true,
platformInfo = PlatformInfo("flavor", "version")
)

val mockInfo = mockk<PurchaserInfo>(relaxed = true)
val mockCreated = Random.nextBoolean()

val logInCallback = slot<LogInCallback>()
every {
mockPurchases.logIn(
newAppUserID = appUserID,
capture(logInCallback)
)
} just runs

val onResult = mockk<OnResult>(relaxed = true)

logIn(appUserID = appUserID, onResult = onResult)
logInCallback.captured.onReceived(mockInfo, mockCreated)

val mockInfoMap = mockInfo.map()

verify(exactly = 1) {
onResult.onReceived(mapOf(
"created" to mockCreated,
"purchaserInfo" to mockInfoMap
))
}
}

@Test
fun `calling logIn with error calls onError`() {
val appUserID = "appUserID"

configure(
context = mockContext,
apiKey = "api_key",
appUserID = "appUserID",
observerMode = true,
platformInfo = PlatformInfo("flavor", "version")
)

val mockError = mockk<PurchasesError>(relaxed = true)

val logInCallback = slot<LogInCallback>()
every {
mockPurchases.logIn(
newAppUserID = appUserID,
capture(logInCallback)
)
} just runs

val onResult = mockk<OnResult>()
every { onResult.onReceived(any()) } just runs
every { onResult.onError(any()) } just runs

logIn(appUserID = appUserID, onResult = onResult)
logInCallback.captured.onError(mockError)

val mockErrorMap = mockError.map()
verify(exactly = 1) {
onResult.onError(mockErrorMap)
}
}

@Test
fun `calling logOut correctly passes call to Purchases`() {
configure(
context = mockContext,
apiKey = "api_key",
appUserID = "appUserID",
observerMode = true,
platformInfo = PlatformInfo("flavor", "version")
)

every { mockPurchases.logOut(any()) } just runs

logOut(onResult = object : OnResult {
override fun onReceived(map: Map<String?, *>?) {}
override fun onError(errorContainer: ErrorContainer) {}
})

verify(exactly = 1) { mockPurchases.logOut(any()) }
}

@Test
fun `calling logOut correctly calls onReceived`() {
configure(
context = mockContext,
apiKey = "api_key",
appUserID = "appUserID",
observerMode = true,
platformInfo = PlatformInfo("flavor", "version")
)

val mockInfo = mockk<PurchaserInfo>(relaxed = true)
val receivePurchaserInfoListener = slot<ReceivePurchaserInfoListener>()

every { mockPurchases.logOut(capture(receivePurchaserInfoListener)) } just runs
val onResult = mockk<OnResult>()
every { onResult.onReceived(any()) } just runs
every { onResult.onError(any()) } just runs

logOut(onResult)

receivePurchaserInfoListener.captured.onReceived(mockInfo)

val mockInfoMap = mockInfo.map()
verify(exactly = 1) { onResult.onReceived(mockInfoMap) }
}

@Test
fun `calling logOut with error calls onError`() {
configure(
context = mockContext,
apiKey = "api_key",
appUserID = "appUserID",
observerMode = true,
platformInfo = PlatformInfo("flavor", "version")
)

val mockError = mockk<PurchasesError>(relaxed = true)
val receivePurchaserInfoListener = slot<ReceivePurchaserInfoListener>()

every { mockPurchases.logOut(capture(receivePurchaserInfoListener)) } just runs
val onResult = mockk<OnResult>()
every { onResult.onReceived(any()) } just runs
every { onResult.onError(any()) } just runs

logOut(onResult)

receivePurchaserInfoListener.captured.onError(mockError)

val mockErrorMap = mockError.map()
verify(exactly = 1) { onResult.onError(mockErrorMap) }
}

}
2 changes: 1 addition & 1 deletion fastlane/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ Increment build number

----

This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
2 changes: 1 addition & 1 deletion ios/PurchasesHybridCommon/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.7.1</string>
<string>1.8.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
Expand Down
2 changes: 1 addition & 1 deletion ios/PurchasesHybridCommon/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ target 'PurchasesHybridCommon' do
use_frameworks!

# Pods for PurchasesHybridCommon
pod 'Purchases', '3.11.1'
pod 'Purchases', '3.12.0'

target 'PurchasesHybridCommonTests' do
# Pods for testing
Expand Down
Loading