Skip to content

Commit

Permalink
Adds Clear User Session feature (#93)
Browse files Browse the repository at this point in the history
* exposing clear user session in dart

* implementig method on fake

* ready status serializer fix

* exposing clear user session in android

* removed moreBtn

* added clear user session implementation for ios

* linting

* changelog

* updates to 2.13.2

---------

Co-authored-by: leonardo briotto <[email protected]>
  • Loading branch information
uc-franciscocunha and uc-leo authored Mar 13, 2024
1 parent cc52f0d commit fe34aed
Show file tree
Hide file tree
Showing 31 changed files with 594 additions and 36 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
[Release Notes](https://docs.usercentrics.com/cmp_in_app_sdk/latest/about/history/)

### 2.13.2 - March 13, 2024

## Features

**Clear User Session** - Introducing a new API designed to simplify the process of clearing user sessions

## Improvements

**Google Consent Mode Granular Choices** - Enhances integration with Google SDKs by updating to the latest changes.

**Adjust Granular Consent** - By Using Consent Mediation, we have fully integrated with Adjust SDK updates associated with the DMA

## iOS Bug Fixes

**[Fix]** Adjusts in landscape mode where labels were not fully aligned with other elements of the screen
**[tvOS Fix]** Numerous layout modifications have been made to address the arrangement of titles and the rendering of other elements in languages that result in larger text sizes

## Other Fixes

**[Fix]** Removes deprecated field TCFVendor::deviceStorage
**[Fix]** In certain scenarios, the 'Save Settings' button color was not customizable


### 2.13.1 - March 05, 2024

## Hotfix
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def usercentrics_version = "2.13.0"
def usercentrics_version = "2.13.2"

group 'com.usercentrics.sdk.flutter'
version usercentrics_version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class UsercentricsPlugin : FlutterPlugin,
SetABTestingVariantBridge(),
TrackBridge(),
GetAdditionalConsentModeDataBridge(),
ClearUserSessionBridge()
).associateBy { it.name }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.usercentrics.sdk.flutter.bridge

import com.usercentrics.sdk.flutter.api.FlutterMethodCall
import com.usercentrics.sdk.flutter.api.FlutterResult
import com.usercentrics.sdk.flutter.api.UsercentricsProxy
import com.usercentrics.sdk.flutter.api.UsercentricsProxySingleton
import com.usercentrics.sdk.flutter.serializer.serialize

internal class ClearUserSessionBridge(
private val usercentrics: UsercentricsProxy = UsercentricsProxySingleton
) : MethodBridge {

companion object {
private const val clearUserSessionErrorCode =
"usercentrics_flutter_clearUserSession_error"
}

override val name: String
get() = "clearUserSession"

override fun invoke(call: FlutterMethodCall, result: FlutterResult) {
assert(name == call.method)
usercentrics.instance.clearUserSession(
onSuccess = {
result.success(it.serialize())
},
onError = {
result.error(
clearUserSessionErrorCode,
it.message,
it
)
},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,6 @@ private fun CustomizationColor.serialize(): Any {
"toggleDisabledBackground" to toggleDisabledBackground,
"toggleDisabledIcon" to toggleDisabledIcon,
"secondLayerTab" to secondLayerTab,
"moreBtnBackground" to moreBtnBackground,
"moreBtnText" to moreBtnText,
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.usercentrics.sdk.flutter.bridge

import com.usercentrics.sdk.UsercentricsReadyStatus
import com.usercentrics.sdk.UsercentricsSDK
import com.usercentrics.sdk.errors.UsercentricsError
import com.usercentrics.sdk.flutter.api.FakeFlutterMethodCall
import com.usercentrics.sdk.flutter.api.FakeFlutterResult
import com.usercentrics.sdk.flutter.api.FakeUsercentricsProxy
import com.usercentrics.sdk.flutter.mock.ClearUserSessionMock
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.junit.Assert.assertEquals
import org.junit.Assert.assertThrows
import org.junit.Test

class ClearUserSessionBridgeTest {

@Test
fun testName() {
val instance = ClearUserSessionBridge(FakeUsercentricsProxy())
assertEquals("clearUserSession", instance.name)
}

@Test
fun testInvokeWithOtherName() {
val instance = ClearUserSessionBridge(FakeUsercentricsProxy())
val call = FakeFlutterMethodCall(method = "otherName", arguments = null)

assertThrows(AssertionError::class.java) {
instance.invoke(call, FakeFlutterResult())
}
}

@Test
fun testInvokeWithSuccess() {
val usercentricsSDK = mockk<UsercentricsSDK>()
every { usercentricsSDK.clearUserSession(any(), any()) }
.answers() {
(arg(0) as (UsercentricsReadyStatus) -> Unit)(ClearUserSessionMock.fake)
}
val usercentricsProxy = FakeUsercentricsProxy(instanceAnswer = usercentricsSDK)
val instance = ClearUserSessionBridge(usercentricsProxy)
val result = FakeFlutterResult()

instance.invoke(ClearUserSessionMock.call, result)

verify(exactly = 1) { usercentricsSDK.clearUserSession(any(), any()) }

assertEquals(1, result.successCount)
assertEquals(ClearUserSessionMock.expected, result.successResultArgument)
}

@Test
fun testInvokeWithError() {
val error = mockk<UsercentricsError>(relaxed = true)
val errorMessage = "The error message"
every { error.message }.returns(errorMessage)

val usercentricsSDK = mockk<UsercentricsSDK>()
every { usercentricsSDK.clearUserSession(any(), any()) }
.answers() {
(arg(1) as (UsercentricsError) -> Unit)(error)
}

val usercentricsProxy = FakeUsercentricsProxy(usercentricsSDK)
val instance = ClearUserSessionBridge(usercentricsProxy)
val result = FakeFlutterResult()

instance.invoke(ClearUserSessionMock.call, result)

verify(exactly = 1) { usercentricsSDK.clearUserSession(any(), any()) }

assertEquals(1, result.errorCount)
assertEquals("usercentrics_flutter_clearUserSession_error", result.errorCodeArgument)
assertEquals(errorMessage, result.errorMessageArgument)
assertEquals(error, result.errorDetailsArgument)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.usercentrics.sdk.flutter.mock

import com.usercentrics.sdk.GeolocationRuleset
import com.usercentrics.sdk.UsercentricsConsentHistoryEntry
import com.usercentrics.sdk.UsercentricsReadyStatus
import com.usercentrics.sdk.UsercentricsServiceConsent
import com.usercentrics.sdk.flutter.api.FakeFlutterMethodCall
import com.usercentrics.sdk.models.settings.UsercentricsConsentType
import com.usercentrics.sdk.v2.location.data.UsercentricsLocation

internal object ClearUserSessionMock {
val fake = UsercentricsReadyStatus(
shouldCollectConsent = true,
consents = listOf(
UsercentricsServiceConsent(
templateId = "ocv9HNX_g",
status = false,
dataProcessor = "Facebook SDK",
type = UsercentricsConsentType.EXPLICIT,
version = "1.0.1",
isEssential = true,
history = listOf(
UsercentricsConsentHistoryEntry(
status = true,
type = UsercentricsConsentType.EXPLICIT,
timestampInMillis = 123,
)
)
)
),
geolocationRuleset = GeolocationRuleset(activeSettingsId = "settingsId", bannerRequiredAtLocation = true),
location = UsercentricsLocation(countryCode = "PT", regionCode = "PT11")
)

// From the debugger
val call =
FakeFlutterMethodCall(
method = "clearUserSession",
arguments = ""
)
val expected = mapOf(
"shouldCollectConsent" to true,
"consents" to listOf(
mapOf(
"templateId" to "ocv9HNX_g",
"status" to false,
"type" to "EXPLICIT",
"version" to "1.0.1",
"dataProcessor" to "Facebook SDK",
"isEssential" to true,
"history" to listOf(
mapOf(
"status" to true, "timestampInMillis" to 123L, "type" to "EXPLICIT",
)
)
)
),
"geolocationRuleset" to mapOf("activeSettingsId" to "settingsId", "bannerRequiredAtLocation" to true),
"location" to mapOf(
"countryCode" to "PT", "regionCode" to "PT11", "isInEU" to true, "isInUS" to false, "isInCalifornia" to false
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,7 @@ internal object GetCMPDataMock {
"toggleActiveIcon" to null,
"toggleDisabledBackground" to null,
"toggleDisabledIcon" to null,
"secondLayerTab" to null,
"moreBtnBackground" to null,
"moreBtnText" to null,
"secondLayerTab" to null
),
"font" to mapOf(
"family" to "BlinkMacSystemFont,-apple-system,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Helvetica,Arial,sans-serif",
Expand Down
16 changes: 8 additions & 8 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
PODS:
- Flutter (1.0.0)
- Usercentrics (2.13.0)
- usercentrics_sdk (2.13.0):
- Usercentrics (2.13.2)
- usercentrics_sdk (2.13.2):
- Flutter
- UsercentricsUI (= 2.13.0)
- UsercentricsUI (2.13.0):
- Usercentrics (= 2.13.0)
- UsercentricsUI (= 2.13.2)
- UsercentricsUI (2.13.2):
- Usercentrics (= 2.13.2)
- webview_flutter_wkwebview (0.0.1):
- Flutter

Expand All @@ -29,9 +29,9 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
Usercentrics: d434a8e69dc40584a35d884895b8b918aaf34317
usercentrics_sdk: 854a8448c3f31a21f71aa59ccb8fcbaa16fc47a9
UsercentricsUI: 2340d7a8c0c2bf6aee9a3bc90f245aef01d62409
Usercentrics: 03f848172a7bc4ddf9e94f4e0809e1ba6025f9fb
usercentrics_sdk: 98f41a4241300e820948cec831af9814fc62ba8d
UsercentricsUI: 4e0d44300ae27be020974f2e2d2a8691c3819ad7
webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f

PODFILE CHECKSUM: 723de1cf6e2f18b51eb3426c945e31134a750097
Expand Down
4 changes: 4 additions & 0 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
17F28FC4AC3BF66FC4301149 /* Pods_Runner_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 760C9E4CB26E7DAC6C729A22 /* Pods_Runner_RunnerTests.framework */; };
3453DCAF2B3D971200EFE874 /* GetAdditionalConsentModeBridgeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3453DCAE2B3D971200EFE874 /* GetAdditionalConsentModeBridgeTest.swift */; };
34E8AE5B2B9B7375001242FE /* ClearUserSessionBridgeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E8AE5A2B9B7375001242FE /* ClearUserSessionBridgeTest.swift */; };
3735A4C22A582462001666E4 /* TrackBridgeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3735A4C12A582462001666E4 /* TrackBridgeTest.swift */; };
3735A4C42A582C54001666E4 /* UsercentricsAnalyticsEventTypeSerializerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3735A4C32A582C54001666E4 /* UsercentricsAnalyticsEventTypeSerializerTest.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
Expand Down Expand Up @@ -64,6 +65,7 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3453DCAE2B3D971200EFE874 /* GetAdditionalConsentModeBridgeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetAdditionalConsentModeBridgeTest.swift; sourceTree = "<group>"; };
34E8AE5A2B9B7375001242FE /* ClearUserSessionBridgeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearUserSessionBridgeTest.swift; sourceTree = "<group>"; };
3735A4C12A582462001666E4 /* TrackBridgeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackBridgeTest.swift; sourceTree = "<group>"; };
3735A4C32A582C54001666E4 /* UsercentricsAnalyticsEventTypeSerializerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsercentricsAnalyticsEventTypeSerializerTest.swift; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -221,6 +223,7 @@
AD9067DF29439C86008B4204 /* GetABTestingVariantBridgeTest.swift */,
AD9067E129439D5F008B4204 /* SetABTestingVariantBridgeTest.swift */,
3735A4C32A582C54001666E4 /* UsercentricsAnalyticsEventTypeSerializerTest.swift */,
34E8AE5A2B9B7375001242FE /* ClearUserSessionBridgeTest.swift */,
);
path = Bridge;
sourceTree = "<group>";
Expand Down Expand Up @@ -507,6 +510,7 @@
3453DCAF2B3D971200EFE874 /* GetAdditionalConsentModeBridgeTest.swift in Sources */,
A297F3FE2717097A00F7AF8A /* GetControllerIdBridgeTest.swift in Sources */,
AD7CFFD427BA8FD300567D62 /* ShowSecondLayerBridgeTest.swift in Sources */,
34E8AE5B2B9B7375001242FE /* ClearUserSessionBridgeTest.swift in Sources */,
3735A4C22A582462001666E4 /* TrackBridgeTest.swift in Sources */,
A28883ED271824C4007E0C44 /* RestoreUserSessionBridgeTest.swift in Sources */,
A298576C2716DE6A0062F7F8 /* FakeUsercentricsSDK.swift in Sources */,
Expand Down
Loading

0 comments on commit fe34aed

Please sign in to comment.