Skip to content

Commit

Permalink
Update vendors and purposes structure for TCF 2.2, update tests (#96)
Browse files Browse the repository at this point in the history
- Fix Android bridge to get TCF 2.2 vendors
- Update Vendors and Purposes structure
- Use remote config instead of local file in testApp
  • Loading branch information
pmerlet-at-didomi authored Dec 18, 2023
1 parent 1b1a2dd commit 15b31d7
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 190 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ jobs:
gcloud firebase test android run --type instrumentation \
--app android/app/build/outputs/apk/debug/app-debug.apk \
--test android/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
--device model=Pixel2,version=28,locale=en,orientation=portrait \
--num-flaky-test-attempts=1
--device model=Pixel3,version=30,locale=en,orientation=portrait \
--num-flaky-test-attempts=2
ios:
needs: js
Expand Down
11 changes: 10 additions & 1 deletion android/src/main/java/com/reactnativedidomi/DidomiModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,16 @@ class DidomiModule(reactContext: ReactApplicationContext) : ReactContextBaseJava
obj?.serializeToMap()?.entries?.forEach { entry ->
when (val value = entry.value) {
is Map<*, *> -> map.putMap(entry.key, objectToWritableMap(value))
is List<*> -> map.putArray(entry.key, Arguments.fromList(value))
is List<*> -> {
if (value.size > 0 && value[0] is String) {
// String values
map.putArray(entry.key, Arguments.fromList(value))
} else {
// Other objects
val listValues = value.map { objectToWritableMap(it) }
map.putArray(entry.key, Arguments.makeNativeArray(listValues))
}
}
else -> map.putString(entry.key, value.toString())
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@didomi/react-native",
"version": "1.24.0",
"version": "1.23.0",
"description": "Didomi React Native SDK",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
2 changes: 1 addition & 1 deletion src/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// User agent name
export const DIDOMI_USER_AGENT_NAME = "Didomi React-Native SDK"
// User agent version
export const DIDOMI_VERSION = "1.24.0"
export const DIDOMI_VERSION = "1.23.0"
18 changes: 17 additions & 1 deletion src/DidomiTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export interface Vendor {
iabId: string
name: string;
policyUrl: string;
urls: VendorUrls[];
namespace: string;
namespaces: VendorNamespaces;
iabVendor: boolean;
Expand All @@ -65,20 +66,35 @@ export interface Vendor {
specialPurposeIds: string[];
legIntPurposeIds: string[];
specialFeatureIds: string[];
cookieMaxAgeSeconds: number
dataDeclaration: string[];
dataRetention: VendorDataRetention;
cookieMaxAgeSeconds: number;
usesNonCookieAccess: boolean;
}

export interface VendorNamespaces {
iab2: string;
}

export interface VendorUrls {
privacy: string;
legIntClaim: string;
langId: string;
}

export interface VendorDataRetention {
stdRetention: number;
purposes: Map<number>;
specialPurposes: Map<number>;
}

export interface Purpose {
id: string;
iabId: string;
name: string;
description: string;
descriptionLegal: string;
illustrations: string[];
custom: boolean;
essential: boolean;
specialFeature: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ open class BaseUITest {
scrollToTopOfList()
}

private fun scrollToTopOfList() {
protected fun scrollToTopOfList() {
// We scroll back up because scrolling up does not work as expected on all elements.
// We do seem to be able to scroll properly to these text views so we scroll up to the first one (METHODS).
scrollToItem("METHODS")
}

protected fun scrollToBottomOfList() {
// We scroll at the bottom because scrolling down does not work as expected on all elements.
scrollToItem("SETUSERWITHENCRYPTIONAUTHWITHEXPIRATIONANDSETUPUI")
}

protected fun tapButton(name: String) {
val matcher = withText(name.uppercase())
onView(matcher).perform(ScrollToAction())
Expand Down Expand Up @@ -71,7 +76,9 @@ open class BaseUITest {
companion object {
// Considering the tests that we do for the bridge SDKs, using simple a configuration with few vendors
// should be enough. Currently we share the same vendor and purpose configuration across tests classes.
const val ALL_VENDOR_IDS = "28,google"
const val ALL_PURPOSE_IDS = "cookies,create_ads_profile,geolocation_data,select_personalized_ads"
const val ALL_VENDOR_IDS = "1111,217,272"
const val ALL_PURPOSE_IDS = "cookies,create_ads_profile,device_characteristics,geolocation_data," +
"improve_products,market_research,measure_ad_performance,measure_content_performance," +
"select_basic_ads,select_personalized_ads,use_limited_data_to_select_content"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,46 +27,44 @@ class UIGettersParamsTest: BaseUITest() {
tapButton("getPurpose [ID = 'cookies']")

// Android doesn't always keep the same order for the properties.
assertTextContains("\"id\":\"cookies\"")
assertTextContains("\"iabId\":\"1\"")
assertTextContains("\"description\":\"Cookies, device identifiers, or other information can be stored or accessed on your device for the purposes presented to you.\"")
assertTextContains("\"name\":\"Store and/or access information on a device\"")
assertTextContains("\"id\":\"cookies\"")
assertTextContains("\"descriptionLegal\":\"Vendors can:\\n* Store and access information on the device such as cookies and device identifiers presented to a user.\"")
assertTextContains("\"description\":\"Cookies, device or similar online identifiers (e.g. login-based identifiers, randomly assigned identifiers, network based identifiers) together with other information (e.g. browser type and information, language, screen size, supported technologies etc.) can be stored or read on your device to recognise it each time it connects to an app or to a website, for one or several of the purposes presented here.\"")
assertTextContains("\"illustrations\":[\"Most purposes explained in this notice rely on the storage or accessing of information from your device when you use an app or visit a website. For example, a vendor or publisher might need to store a cookie on your device during your first visit on a website, to be able to recognise your device during your next visits (by accessing this cookie each time).\"]")
}

@Test
fun test_GetPurpose_descriptionLegal() {
fun test_GetPurpose_illustrations() {

tapButton("getPurpose [ID = 'cookies'] descriptionLegal")
tapButton("getPurpose [ID = 'cookies'] illustrations[0]")

assertText("\"Vendors can:\\n* Store and access information on the device such as cookies and device identifiers presented to a user.\"")
assertText("\"Most purposes explained in this notice rely on the storage or accessing of information from your device when you use an app or visit a website. For example, a vendor or publisher might need to store a cookie on your device during your first visit on a website, to be able to recognise your device during your next visits (by accessing this cookie each time).\"")
}

@Test
fun test_GetVendor() {

tapButton("getVendor [ID = '755']")
tapButton("getVendor [ID = '217']")

// Android doesn't always keep the same order for the properties.
assertTextContains("\"id\":\"217\"")
assertTextContains("\"name\":\"2KDirect, Inc. (dba iPromote)\"")
assertTextContains("\"purposeIds\":[\"cookies\",\"create_ads_profile\",\"select_personalized_ads\"")
assertTextContains("\"specialPurposeIds\":[\"1\",\"2\"]")
assertTextContains("\"featureIds\":[\"1\",\"2\"]")
assertTextContains("\"policyUrl\":\"https://business.safety.google/privacy/\"")
assertTextContains("\"deviceStorageDisclosureUrl\":\"https://sdk.privacy-center.org/tcf/v2/disclosures/755.json\"")
assertTextContains("\"name\":\"Google Advertising Products\"")
assertTextContains("\"id\":\"google\"")
assertTextContains("\"iabId\":\"755\"")
assertTextContains("\"namespace\":\"didomi\"")
assertTextContains("\"namespaces\":{\"iab2\":\"755\"}")
assertTextContains("\"usesNonCookieAccess\":\"true\"")
assertTextContains("\"purposeIds\":[\"cookies\",\"create_ads_profile\",")
assertTextContains("\"deviceStorageDisclosureUrl\":\"https://sdk.privacy-center.org/tcf/v3/disclosures/217.json\"")
assertTextContains("\"namespace\":\"iab\"")
assertTextContains("\"usesNonCookieAccess\":\"false\"")
}

@Test
fun test_GetPurpose_policyUrl() {
fun test_GetPurpose_urls() {

tapButton("getVendor [ID = '755'] policyUrl")
tapButton("getVendor [ID = '217'] urls[0]")

assertText("\"https://business.safety.google/privacy/\"")
assertTextContains("\"langId\":\"en\"")
assertTextContains("\"privacy\":\"https://www.ipromote.com/privacy-policy/\"")
assertTextContains("\"legIntClaim\":\"https://www.ipromote.com/privacy-policy/\"")
}

@Test
Expand All @@ -93,15 +91,15 @@ class UIGettersParamsTest: BaseUITest() {
fun test_GetUserConsentStatusForVendor() {
agreeToAll()

tapButton("getUserConsentStatusForVendor [ID = '755']")
tapButton("getUserConsentStatusForVendor [ID = '217']")
assertText("true")
}

@Test
fun test_GetUserConsentStatusForVendorAndRequiredPurposes() {
agreeToAll()

tapButton("getUserConsentStatusForVendorAndRequiredPurposes [ID = '755']")
tapButton("getUserConsentStatusForVendorAndRequiredPurposes [ID = '217']")
assertText("true")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ class UIGettersTest: BaseUITest() {
// The text might change every time we call the getUserStatus method
// so we'll only assert the first level parameters of the resulting json string.
assertTextContains("\"addtl_consent\":\"\"".trim())
assertTextContains("\"consent_string\":\"\"".trim())
assertTextContains("\"purposes\":{\"legitimate_interest\":{\"enabled\":[".trim())
assertTextContains("\"vendors\":{\"legitimate_interest\":{\"enabled\":[".trim())
assertTextContains("\"consent_string\":\"".trim())
assertTextContains("\"purposes\":{\"".trim())
assertTextContains("\"vendors\":{\"".trim())
assertTextContains("\"user_id\":\"".trim())
assertTextContains("\"created\":\"".trim())
assertTextContains("\"updated\":\"".trim())
Expand All @@ -137,10 +137,10 @@ class UIGettersTest: BaseUITest() {

// The text might change every time we call the getUserStatus method
// so we'll only assert the first level parameters of the resulting json string.
assertTextContains("{\"legitimate_interest\":{\"enabled\":[".trim())
assertTextContains(",\"global\":{\"enabled\":[".trim())
assertTextContains(",\"essential\":[".trim())
assertTextContains(",\"consent\":{\"enabled\":[".trim())
assertTextContains("\"legitimate_interest\":{\"enabled\":[".trim())
assertTextContains("\"global\":{\"enabled\":[".trim())
assertTextContains("\"essential\":[".trim())
assertTextContains("\"consent\":{\"enabled\":[".trim())
}

@Test
Expand All @@ -152,11 +152,11 @@ class UIGettersTest: BaseUITest() {

// The text might change every time we call the getUserStatus method
// so we'll only assert the first level parameters of the resulting json string.
assertTextContains("{\"legitimate_interest\":{\"enabled\":[".trim())
assertTextContains(",\"global\":{\"enabled\":[".trim())
assertTextContains(",\"global_li\":{\"enabled\":[".trim())
assertTextContains(",\"global_consent\":{\"enabled\":[".trim())
assertTextContains(",\"consent\":{\"enabled\":[".trim())
assertTextContains("\"legitimate_interest\":{\"enabled\":[".trim())
assertTextContains("\"global\":{\"enabled\":[".trim())
assertTextContains("\"global_li\":{\"enabled\":[".trim())
assertTextContains("\"global_consent\":{\"enabled\":[".trim())
assertTextContains("\"consent\":{\"enabled\":[".trim())
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class UIMethodsTest: BaseUITest() {
@Before
fun init() {
waitForSdkToBeReady()
testMethodCall("reset")
}

private fun testMethodCall(method: String) {
Expand All @@ -44,11 +45,6 @@ class UIMethodsTest: BaseUITest() {
testLastEvent("on_ready")
}

@Test
fun test_Reset() {
testMethodCall("reset")
}

@Test
fun test_SetupUI() {
testMethodCall("reset")
Expand All @@ -67,6 +63,9 @@ class UIMethodsTest: BaseUITest() {

testLastEvent("on_hide_notice")
waitForDisplayed(withText("setupUI-OK"))

// Let some time after Didomi UI was closed
Thread.sleep(1_000L)
}

@Test
Expand Down Expand Up @@ -102,6 +101,7 @@ class UIMethodsTest: BaseUITest() {

val agreeButtonText = "Agree & Close"

Thread.sleep(1_000L)
waitForDisplayed(withText(agreeButtonText))
val agreeButton = onView(withText(agreeButtonText))
agreeButton.check(matches(isDisplayed()))
Expand All @@ -110,6 +110,9 @@ class UIMethodsTest: BaseUITest() {
agreeButton.perform(click())

testLastEvent("on_hide_notice")

// Let some time after Didomi UI was closed
Thread.sleep(1_000L)
}

@Test
Expand All @@ -119,6 +122,7 @@ class UIMethodsTest: BaseUITest() {

val agreeButtonText = "Agree to all"

Thread.sleep(1_000L)
waitForDisplayed(withText(agreeButtonText))
val agreeButton = onView(withText(agreeButtonText))
agreeButton.check(matches(isDisplayed()))
Expand All @@ -127,6 +131,9 @@ class UIMethodsTest: BaseUITest() {
agreeButton.perform(click())

testLastEvent("on_hide_notice")

// Let some time after Didomi UI was closed
Thread.sleep(1_000L)
}

@Test
Expand All @@ -136,6 +143,7 @@ class UIMethodsTest: BaseUITest() {

var agreeButtonText = "Save"

Thread.sleep(1_000L)
waitForDisplayed(withText(agreeButtonText))
var agreeButton = onView(withText(agreeButtonText))
agreeButton.check(matches(isDisplayed()))
Expand All @@ -151,5 +159,8 @@ class UIMethodsTest: BaseUITest() {
agreeButton.perform(click())

testLastEvent("on_hide_notice")

// Let some time after Didomi UI was closed
Thread.sleep(1_000L)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ class UISetUserTest: BaseUITest() {
fun test_SetUserWithEncryptionAuthWithExpiration() {
tapButton("setUserWithEncryptionAuthWithExpiration")
Thread.sleep(2_000L)
// Prevent random test failure
scrollToBottomOfList()
Thread.sleep(1_000L)
assertText("setUserWithEncryptionAuthWithExpiration-OK")
}

Expand Down
Loading

0 comments on commit 15b31d7

Please sign in to comment.