Skip to content

Commit

Permalink
CMP-4269 - Implement getCurrentUserStatus function (#101)
Browse files Browse the repository at this point in the history
* update native SDKs

* update AGP and gradle wrapper for sampleApp

* update AGP and gradle wrapper for testApp

* setup test orchestrator for local tests

* suppress deprecation warning

* update `getUserStatus` scenario to prevent flaky result

* use latest iPhone for local UI tests / don't specify iOS version (will use the latest available)

* add sleep to prevent flaky result

* implement `CurrentUserStatus` object and `getCurrentUserStatus` function + tests

* fix property name
  • Loading branch information
nicolas-chaix-didomi authored Jan 25, 2024
1 parent 126faca commit def102b
Show file tree
Hide file tree
Showing 24 changed files with 197 additions and 25 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,5 @@ dependencies {

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

implementation "io.didomi.sdk:android:1.88.0"
implementation "io.didomi.sdk:android:1.89.0"
}
10 changes: 10 additions & 0 deletions android/src/main/java/com/reactnativedidomi/DidomiModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,15 @@ class DidomiModule(reactContext: ReactApplicationContext) : ReactContextBaseJava
}
}

@ReactMethod
fun getCurrentUserStatus(promise: Promise) {
try {
promise.resolve(objectToWritableMap(Didomi.getInstance().currentUserStatus))
} catch (e: DidomiNotReadyException) {
promise.reject(e)
}
}

@ReactMethod
fun getUserStatus(promise: Promise) {
try {
Expand Down Expand Up @@ -1082,6 +1091,7 @@ class DidomiModule(reactContext: ReactApplicationContext) : ReactContextBaseJava
@ReactMethod
fun shouldConsentBeCollected(promise: Promise) {
try {
@Suppress("DEPRECATION")
promise.resolve(Didomi.getInstance().shouldConsentBeCollected())
} catch (e: DidomiNotReadyException) {
promise.reject(e)
Expand Down
3 changes: 3 additions & 0 deletions ios/Didomi.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ @interface RCT_EXTERN_MODULE(Didomi, RCTEventEmitter)
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(getCurrentUserStatus:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(getUserStatus:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)

Expand Down
7 changes: 7 additions & 0 deletions ios/RNDidomi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ class RNDidomi: RCTEventEmitter {
resolve(consentStatus.rawValue.consentStatusBool)
}

@objc(getCurrentUserStatus:reject:)
func getCurrentUserStatus(resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) {
let encoder = JSONEncoder()
let currentUserStatus = try? JSONSerialization.jsonObject(with: encoder.encode(Didomi.shared.getCurrentUserStatus())) as? [String: Any]
resolve(currentUserStatus)
}

@objc(getUserStatus:reject:)
func getUserStatus(resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) {
let encoder = JSONEncoder()
Expand Down
2 changes: 1 addition & 1 deletion react-native-didomi.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ Pod::Spec.new do |s|
s.source_files = "ios/**/*.{h,m,mm,swift}"

s.dependency "React-Core"
s.dependency "Didomi-XCFramework", "1.97.0"
s.dependency "Didomi-XCFramework", "1.98.0"
end
3 changes: 3 additions & 0 deletions sampleApp/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@ android {
}
}
}
buildFeatures {
buildConfig = true
}
}

dependencies {
Expand Down
2 changes: 1 addition & 1 deletion sampleApp/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.0.4")
classpath("com.android.tools.build:gradle:7.4.2")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:4.1.2")
// NOTE: Do not place your application dependencies here; they belong
Expand Down
Binary file modified sampleApp/android/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion sampleApp/android/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-7.5-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
6 changes: 6 additions & 0 deletions sampleApp/android/gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"

# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi

# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
Expand Down
14 changes: 8 additions & 6 deletions sampleApp/android/gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@rem limitations under the License.
@rem

@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
Expand All @@ -25,7 +25,7 @@
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

Expand All @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Expand Down Expand Up @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%

:mainEnd
if "%OS%"=="Windows_NT" endlocal
Expand Down
10 changes: 10 additions & 0 deletions sampleApp/src/Getters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ export default function Getters() {
}}
/>

<Getter
name="getCurrentUserStatus"
call={async () => {
return await Didomi.getCurrentUserStatus();
}}
test={() => {
return true;
}}
/>

{/*
getJavaScriptForWebView
getQueryStringForWebView
Expand Down
8 changes: 7 additions & 1 deletion src/Didomi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NativeModules } from 'react-native';
import { DidomiListener } from './DidomiListener';
import { DidomiEventType, Purpose, UserStatus, Vendor } from './DidomiTypes';
import { DidomiEventType, Purpose, Vendor, UserStatus, CurrentUserStatus } from './DidomiTypes';
import { DIDOMI_USER_AGENT_NAME, DIDOMI_VERSION } from './Constants';

const { Didomi: RNDidomi } = NativeModules;
Expand Down Expand Up @@ -318,6 +318,12 @@ export const Didomi = {
*/
getUserLegitimateInterestStatusForVendorAndRequiredPurposes: (vendorId: string): boolean => RNDidomi.getUserLegitimateInterestStatusForVendorAndRequiredPurposes(vendorId),

/**
* Get the current user consent status.
* @returns: status that represents current user consent.
*/
getCurrentUserStatus: (): Promise<CurrentUserStatus> => RNDidomi.getCurrentUserStatus(),

/**
* Get the user consent status.
* @returns: status that represents user consent.
Expand Down
22 changes: 22 additions & 0 deletions src/DidomiTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,25 @@ export interface UserStatusIds {
disabled: string[];
enabled: string[];
}

export interface CurrentUserStatus {
purposes: Map<PurposeStatus>;
vendors: Map<VendorStatus>;
user_id: string;
created: string;
updated: string;
consent_string: string;
addtl_consent: string;
didomi_dcs: string;
regulation: string;
}

export interface PurposeStatus {
id: string;
enabled: boolean;
}

export interface VendorStatus {
id: string;
enabled: boolean;
}
15 changes: 13 additions & 2 deletions testApp/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,10 @@ android {
versionCode 1
versionName "1.0"

multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled = true

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["clearPackageData"] = "true"

buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
if (isNewArchitectureEnabled()) {
Expand Down Expand Up @@ -256,6 +258,13 @@ android {
}
}
}
buildFeatures {
buildConfig = true
}
testOptions {
animationsDisabled = true
execution = "ANDROIDX_TEST_ORCHESTRATOR"
}
}

dependencies {
Expand Down Expand Up @@ -302,6 +311,8 @@ dependencies {
androidTestImplementation "androidx.test.ext:junit-ktx:1.1.5"
androidTestImplementation "androidx.test:rules:1.5.0"
androidTestImplementation "androidx.test:runner:1.5.2"

androidTestUtil("androidx.test:orchestrator:1.4.2")
}

if (isNewArchitectureEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,17 @@ class UIGettersTest: BaseUITest() {
tapButton("reset")

tapButton("isUserStatusPartial")

// There might be a delay to get this string.
Thread.sleep(500L)
assertText("true")

disagreeToAll()

tapButton("isUserStatusPartial")

// There might be a delay to get this string.
Thread.sleep(500L)
assertText("false")
}

Expand All @@ -126,14 +132,22 @@ class UIGettersTest: BaseUITest() {
tapButton("reset")

tapButton("shouldUserStatusBeCollected")

// There might be a delay to get this string.
Thread.sleep(500L)
assertText("true")

disagreeToAll()

tapButton("shouldUserStatusBeCollected")

// There might be a delay to get this string.
Thread.sleep(500L)
assertText("false")
}

/** getUserStatus */

@Test
fun test_getUserStatus() {
tapButton("getUserStatus")
Expand Down Expand Up @@ -198,4 +212,26 @@ class UIGettersTest: BaseUITest() {
assertTextContains(",\"disabled\":[".trim())
assertTextContains("]}".trim())
}

/** getCurrentUserStatus */

@Test
fun test_getCurrentUserStatus() {
tapButton("getCurrentUserStatus")

// There might be a delay to get this string.
Thread.sleep(1_000L)

// The text might change every time we call the getCurrentUserStatus 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\":{\"".trim())
assertTextContains("\"vendors\":{\"".trim())
assertTextContains("\"user_id\":\"".trim())
assertTextContains("\"created\":\"".trim())
assertTextContains("\"updated\":\"".trim())
assertTextContains("\"didomi_dcs\":\"\"".trim()) // DCS feature flag is disabled (empty string)
assertTextContains("\"regulation\":\"gdpr\"".trim())
}
}
2 changes: 1 addition & 1 deletion testApp/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.0.4")
classpath("com.android.tools.build:gradle:7.4.2")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:4.1.2")
// NOTE: Do not place your application dependencies here; they belong
Expand Down
Binary file modified testApp/android/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion testApp/android/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-7.5-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
6 changes: 6 additions & 0 deletions testApp/android/gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"

# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi

# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
Expand Down
14 changes: 8 additions & 6 deletions testApp/android/gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@rem limitations under the License.
@rem

@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
Expand All @@ -25,7 +25,7 @@
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

Expand All @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Expand Down Expand Up @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%

:mainEnd
if "%OS%"=="Windows_NT" endlocal
Expand Down
Loading

0 comments on commit def102b

Please sign in to comment.