Skip to content

Release: 2.26.1#200

Merged
uc-brunosilva merged 10 commits intomasterfrom
release/2.26.1
Apr 7, 2026
Merged

Release: 2.26.1#200
uc-brunosilva merged 10 commits intomasterfrom
release/2.26.1

Conversation

@uc-brunosilva
Copy link
Copy Markdown
Collaborator

@uc-brunosilva uc-brunosilva commented Apr 7, 2026

CodeAnt-AI Description

Expose the latest privacy settings and keep SDK calls aligned with version 2.26.1

What Changed

  • Adds support for new privacy fields in the React Native bridge, including GPP signaling, GPC status, MSPA coverage, MSPA mode, and the TCF resurfacing period.
  • Updates the GPP consent path to handle empty values safely and pass them through without breaking the call.
  • Aligns the iOS and Android bridge data with the latest SDK shape so apps can read the new settings and keep sample tests working.

Impact

✅ Access to new US privacy settings
✅ Fewer bridge failures after SDK updates
✅ Safer GPP consent updates

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added US National (GPP) privacy framework support
    • Exposed GPP APIs across Flutter/React Native/Unity bridges
    • Added getDpsMetadata() API
    • Made TCF resurfacing period configurable (1–13 months)
  • Bug Fixes

    • Fixed TCF resurfacing period logic
    • Fixed DPS details information display
    • Fixed TCF legitimate interest handling for "Deny All"

uc-brunosilva and others added 10 commits April 6, 2026 17:53
…pe in GPP

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: codeant-ai[bot] <151821869+codeant-ai[bot]@users.noreply.github.com>
…rTCF protocol signature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add gppSignalingEnabled/gpcSignalHonoured to UsercentricsSettings mock,
metadata to UsercentricsService/ServiceConsentTemplate mocks,
and mspaCoveredTransaction/mspaMode to CCPASettings mock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DisposableEvent.callback removed; use init(callback:) instead
- TCF2Settings.resurfacePeriodEnded renamed to resurfacePeriod (Int32)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TCF2Settings: resurfacePeriodEnded (bool) renamed to resurfacePeriod (int)
- CCPASettings: add mspaCoveredTransaction, mspaMode
- UsercentricsSettings: add gppSignalingEnabled, gpcSignalHonoured
- Update iOS/Android serializers and TypeScript models

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uctor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nullable type

UsercentricsDisposableEvent.init(callback:) now expects ((T?) -> Void)? in 2.26.1.
Wrap the non-optional callback to handle the optional payload parameter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codeant-ai
Copy link
Copy Markdown

codeant-ai bot commented Apr 7, 2026

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

Version 2.26.1 release introduces GPP (Global Privacy Platform) support with new DPS metadata APIs and configurable TCF resurfacing periods. Updates version numbers across build configuration and package files. Extends data models with GPP signaling, MSPA, and resurfacing period fields. Updates native bridge serialization and denyAllForTCF API with unsaved vendor LI decisions parameter. Aligns test mocks across platforms.

Changes

Cohort / File(s) Summary
Version & Release Updates
CHANGELOG.md, package.json, android/build.gradle.kts, android/build-legacy.gradle
Bumped version from 2.25.1 to 2.26.1. Added changelog entry documenting new GPP support, DPS metadata API, configurable TCF resurfacing, and bug fixes.
Android Native Serialization
android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt
Extended UsercentricsSettings, CCPASettings, and TCF2Settings serialization with new fields: gppSignalingEnabled, gpcSignalHonoured, mspaCoveredTransaction, mspaMode, and resurfacePeriod (via reflection-based compatibility helpers).
Android Native Bridge
android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt
Modified setGPPConsent to convert null parsedValue to explicit JSONObject.NULL sentinel instead of forwarding null.
iOS Native Serialization
ios/Extensions/UsercentricsCMPData+Dict.swift
Extended UsercentricsSettings, CCPASettings, and TCF2Settings dictionary exports to include gppSignalingEnabled, gpcSignalHonoured, mspaCoveredTransaction, mspaMode, and resurfacePeriod.
iOS Type Bridging
ios/Extensions/GppData+Dict.swift
Added explicit return type annotations to nested map closures and explicit NSArray casting for improved Objective-C bridging compatibility.
TypeScript Data Models
src/models/UsercentricsSettings.tsx, src/models/CCPASettings.tsx, src/models/TCF2Settings.tsx
Added optional properties: gppSignalingEnabled, gpcSignalHonoured to UsercentricsSettings; mspaCoveredTransaction, mspaMode to CCPASettings; changed TCF2Settings from resurfacePeriodEnded: boolean to resurfacePeriod: number.
Test Mocks & Fakes
src/__tests__/mocks.ts, sample/ios/sampleTests/Mock/CMPData+Mock.swift, sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift, sample/ios/sampleTests/RNUsercentricsModuleTests.swift
Updated mock builders and test fixtures to populate new fields (gppSignalingEnabled, gpcSignalHonoured, mspaCoveredTransaction, mspaMode, resurfacePeriod). Extended denyAllForTCF with unsavedVendorLIDecisions parameter and updated corresponding test calls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • #189 — Implements the GPP feature surface (getGPPData/getGPPString/setGPPConsent, onGppSectionChange event, and GppData serialization) through the same RN/native bridge code paths.
  • #190 — Adds the unsavedVendorLIDecisions parameter through the denyAllForTCF API across native bridges, tests, and mock implementations.
  • #184 — Modifies TCF "deny all" handling and expands denyAllForTCF API surface with unsaved LI decisions.

Suggested labels

release, privacy-framework, version-bump, platform-sync

Suggested reviewers

  • rodrigo-leal-usercentrics
  • uc-brunosouza
  • islameldesoky95

Poem

🐰 With GPP now dancing and TCF times set free,
The versions all marching from twenty-five to twenty-six, you see!
MSPA and resurfacing periods aligned,
New models and serialization, all beautifully designed.
The rabbit hops proudly—a release so complete! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Release: 2.26.1' directly and clearly identifies the main purpose of the changeset—a version release. It accurately summarizes the primary change across all modified files, which collectively document and implement the 2.26.1 release.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/2.26.1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Release 2.26.1: Add GPP support and expose new SDK fields

✨ Enhancement 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Upgrade Usercentrics SDK to version 2.26.1 with new GPP framework support
• Expose new SDK fields: resurfacePeriod, gppSignalingEnabled, gpcSignalHonoured, mspaMode,
  mspaCoveredTransaction
• Fix Android nullable type mismatch in setGPPConsent and iOS closure return types
• Update mocks and tests for SDK 2.26.1 API changes including DisposableEvent and denyAllForTCF
  signature
Diagram
flowchart LR
  A["SDK 2.26.1 Upgrade"] --> B["New Fields Exposed"]
  A --> C["Bug Fixes"]
  B --> D["TCF2Settings: resurfacePeriod"]
  B --> E["UsercentricsSettings: gppSignalingEnabled, gpcSignalHonoured"]
  B --> F["CCPASettings: mspaMode, mspaCoveredTransaction"]
  C --> G["Android: Nullable type handling"]
  C --> H["iOS: Closure return types"]
  C --> I["Mock updates for API changes"]
Loading

Grey Divider

File Changes

1. android/build.gradle.kts Dependencies +1/-1

Update Usercentrics SDK version to 2.26.1

android/build.gradle.kts


2. android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt 🐞 Bug fix +2/-1

Fix Android nullable type in setGPPConsent

android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt


3. android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt ✨ Enhancement +37/-5

Add new fields and compatibility methods for SDK 2.26.1

android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt


View more (11)
4. ios/Extensions/GppData+Dict.swift 🐞 Bug fix +3/-3

Fix Swift closure return type annotations

ios/Extensions/GppData+Dict.swift


5. ios/Extensions/UsercentricsCMPData+Dict.swift ✨ Enhancement +6/-1

Expose new SDK 2.26.1 fields in serialization

ios/Extensions/UsercentricsCMPData+Dict.swift


6. sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift 🧪 Tests +8/-4

Update mock for DisposableEvent and denyAllForTCF changes

sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift


7. sample/ios/sampleTests/Mock/CMPData+Mock.swift 🧪 Tests +10/-4

Add new fields to mock data for SDK 2.26.1

sample/ios/sampleTests/Mock/CMPData+Mock.swift


8. sample/ios/sampleTests/RNUsercentricsModuleTests.swift 🧪 Tests +2/-2

Update tests for denyAllForTCF signature change

sample/ios/sampleTests/RNUsercentricsModuleTests.swift


9. src/__tests__/mocks.ts 🧪 Tests +1/-1

Update TypeScript mocks for resurfacePeriod field

src/tests/mocks.ts


10. CHANGELOG.md 📝 Documentation +11/-0

Add release notes for version 2.26.1

CHANGELOG.md


11. package.json ⚙️ Configuration changes +2/-2

Bump version to 2.26.1

package.json


12. src/models/CCPASettings.tsx ✨ Enhancement +7/-1

Add mspaMode and mspaCoveredTransaction fields

src/models/CCPASettings.tsx


13. src/models/TCF2Settings.tsx ✨ Enhancement +3/-3

Rename resurfacePeriodEnded to resurfacePeriod

src/models/TCF2Settings.tsx


14. src/models/UsercentricsSettings.tsx ✨ Enhancement +6/-0

Add gppSignalingEnabled and gpcSignalHonoured fields

src/models/UsercentricsSettings.tsx


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Apr 7, 2026

Code Review by Qodo

🐞 Bugs (3)   📘 Rule violations (0)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (2) ☼ Reliability (1)

Grey Divider


Action required

1. Android CMP mocks outdated 🐞
Description
Android androidTest mocks still use/expect resurfacePeriodEnded and omit newly serialized
fields, but the production Android serializer now emits resurfacePeriod plus new GPP/GPC/MSPA
properties. This will cause androidTest compilation errors (removed constructor arg) and/or
assertion mismatches in getCMPData-related tests.
Code

android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt[R223-229]

        "disabledSpecialFeatures" to disabledSpecialFeatures,
        "firstLayerShowDescriptions" to firstLayerShowDescriptions,
        "hideNonIabOnFirstLayer" to hideNonIabOnFirstLayer,
-        "resurfacePeriodEnded" to getResurfacePeriodEndedCompat(),
+        "resurfacePeriod" to getResurfacePeriodCompat(),
        "resurfacePurposeChanged" to resurfacePurposeChanged,
        "resurfaceVendorAdded" to resurfaceVendorAdded,
        "firstLayerDescription" to firstLayerDescription,
Evidence
Production Android serialization changed: TCF2 key is now resurfacePeriod and additional
properties are always emitted (gppSignalingEnabled, gpcSignalHonoured, mspaCoveredTransaction,
mspaMode). Android androidTest mocks still construct TCF2Settings with resurfacePeriodEnded
and assert a serialized map containing resurfacePeriodEnded and no MSPA/GPP/GPC fields, so tests
are now out of sync with production output.

android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt[37-70]
android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt[167-249]
android/src/androidTest/java/com/usercentrics/reactnative/mock/GetCMPDataMock.kt[201-240]
android/src/androidTest/java/com/usercentrics/reactnative/mock/GetCMPDataMock.kt[451-529]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Android androidTest fixtures are still aligned to the pre-2.26.1 data model/serialization (`resurfacePeriodEnded`, missing MSPA/GPP/GPC fields). With the new serializer, these tests will either not compile (if the SDK removed the `resurfacePeriodEnded` constructor parameter) or will fail assertions due to changed keys/extra fields.

## Issue Context
The production serializer now emits:
- `tcf2.resurfacePeriod` (Int)
- `settings.gppSignalingEnabled`, `settings.gpcSignalHonoured`
- `ccpa.mspaCoveredTransaction`, `ccpa.mspaMode`

## Fix Focus Areas
- android/src/androidTest/java/com/usercentrics/reactnative/mock/GetCMPDataMock.kt[213-277]
- android/src/androidTest/java/com/usercentrics/reactnative/mock/GetCMPDataMock.kt[451-529]

Update:
- `TCF2Settings(...)` construction to use `resurfacePeriod` (or the new SDK API).
- `expectedTCF2Settings` key from `resurfacePeriodEnded` -> `resurfacePeriod`.
- Add expectations for newly serialized keys/values (GPP/GPC/MSPA), matching the serializer defaults/compat behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Android denyAllForTCF test stale 🐞
Description
Android RNUsercentricsModuleTest still uses the old denyAllForTCF arity and mocks/verifies the
old 3-arg UsercentricsSDK.denyAllForTCF call. The module now requires vendor LI decisions too, so
this test will no longer compile or will validate the wrong invocation.
Code

sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift[R174-179]

+  func denyAllForTCF(fromLayer: TCFDecisionUILayer, consentType: UsercentricsConsentType, unsavedPurposeLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedVendorLIDecisions: [KotlinInt: KotlinBoolean]?) -> [UsercentricsServiceConsent] {
    self.denyAllForTCFConsentType = consentType
    self.denyAllForTCFFromLayer = fromLayer
    self.denyAllForTCFUnsavedPurposeLIDecisions = unsavedPurposeLIDecisions
+    self.denyAllForTCFUnsavedVendorLIDecisions = unsavedVendorLIDecisions
    return denyAllForTCFResponse!
Evidence
The Android native module’s denyAllForTCF method now takes both purpose and vendor LI decisions
arrays, but the Android androidTest still calls the previous signature (`denyAllForTCF(fromLayer,
consentType, unsavedPurposeLIDecisions, promise)`) and mocks the SDK method with 3 parameters. This
mismatch will break compilation and/or verification.

android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt[189-196]
android/src/androidTest/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt[515-542]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Android androidTest `testDenyAllForTCF` uses the old `denyAllForTCF` signature and mocks/verifies the old SDK call arity. The production module now requires `unsavedVendorLIDecisions` as well.

## Issue Context
Production module signature includes both:
- `unsavedPurposeLIDecisions`
- `unsavedVendorLIDecisions`

## Fix Focus Areas
- android/src/androidTest/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt[515-542]
- android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt[189-196]

Update the test to:
- Pass an additional `emptyArray` for `unsavedVendorLIDecisions`.
- Update `every { usercentricsSDK.denyAllForTCF(...) }` to the new arity.
- Update `verify { usercentricsSDK.denyAllForTCF(...) }` to include the vendor decisions argument (likely `null` for empty input).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. iOS example suite outdated 🐞
Description
The iOS example test suite still uses the pre-2.26.1 denyAllForTCF signature and old SDK
initializers/fields (resurfacePeriodEnded, missing metadata), while the library now expects the
new API. If the example app/tests are built in CI, this will fail compilation.
Code

ios/Extensions/UsercentricsCMPData+Dict.swift[R237-239]

+            "selectedATPIds": self.selectedATPIds,
+            "resurfacePeriod": self.resurfacePeriod,
        ]
Evidence
Library iOS code now exports resurfacePeriod and expects denyAllForTCF to include both purpose
and vendor LI decisions. The example/ios/exampleTests code still calls denyAllForTCF without
unsavedVendorLIDecisions, implements a fake manager with the old method signature, and constructs
mocks using resurfacePeriodEnded and an older UsercentricsService initializer shape.

ios/Extensions/UsercentricsCMPData+Dict.swift[210-240]
ios/RNUsercentricsModule.swift[195-208]
example/ios/exampleTests/RNUsercentricsModuleTests.swift[319-352]
example/ios/exampleTests/Fake/FakeUsercentricsManager.swift[166-175]
example/ios/exampleTests/Mock/CMPData+Mock.swift[55-105]
example/ios/exampleTests/Mock/CMPData+Mock.swift[282-347]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`example/ios/exampleTests` is still written against the pre-2.26.1 iOS API (old `denyAllForTCF` signature, `resurfacePeriodEnded`, and outdated service initializer). This will break compilation when building the example target against SDK 2.26.1.

## Issue Context
The library iOS module now requires:
- `denyAllForTCF(..., unsavedPurposeLIDecisions, unsavedVendorLIDecisions, ...)`
And the SDK model now exposes `resurfacePeriod` instead of `resurfacePeriodEnded`.

## Fix Focus Areas
- example/ios/exampleTests/RNUsercentricsModuleTests.swift[319-352]
- example/ios/exampleTests/Fake/FakeUsercentricsManager.swift[166-175]
- example/ios/exampleTests/Mock/CMPData+Mock.swift[55-105]
- example/ios/exampleTests/Mock/CMPData+Mock.swift[282-347]

Update the example tests/mocks to:
- Add `unsavedVendorLIDecisions: []` to `denyAllForTCF` calls.
- Update the fake manager method signature to include `unsavedVendorLIDecisions` and store it if needed.
- Replace `resurfacePeriodEnded` with `resurfacePeriod` in mock TCF2Settings construction.
- Add any newly required initializer parameters such as `metadata` where applicable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@codeant-ai codeant-ai bot added the size:L This PR changes 100-499 lines, ignoring generated files label Apr 7, 2026
@pantoaibot
Copy link
Copy Markdown

pantoaibot bot commented Apr 7, 2026

PR Summary:

Release 2.26.1: adds US National (GPP) support, exposes DPS metadata, makes TCF resurface period configurable, and updates cross-platform bridges/serializers and tests. Version bumps and multiple compatibility fixes included.

  • General

    • Bumped SDK version to 2.26.1 (package.json, android build files) and added changelog entry.
    • Added release features: US National (GPP) framework support, extended GPP API to Flutter/React Native/Unity bridges, new getDpsMetadata() API, and Admin-configurable TCF resurfacing period (1–13 months).
    • Fixes: corrected TCF resurfacing logic, DPS details storage display, and TCF maintain legitimate interest logic on Deny All.
  • Android / React Native bridge

    • Exposed new RN methods: getGPPData, getGPPString, setGPPConsent (Kotlin). setGPPConsent now substitutes null with org.json.JSONObject.NULL to avoid passing raw null.
    • Updated Kotlin serialization extensions to include:
      • gppSignalingEnabled, gpcSignalHonoured on UsercentricsSettings
      • CCPA: mspaCoveredTransaction, mspaMode
      • TCF2: resurfacePeriod (int) replacing/resurfacing prior boolean flag
    • Added compatibility helper reflection methods to read new fields across SDK versions.
  • iOS

    • Improved GppData -> NSDictionary bridging for nested arrays/dictionaries.
    • Usercentrics CMP data -> dictionary now includes gppSignalingEnabled, gpcSignalHonoured; CCPA adds mspa fields; TCF adds resurfacePeriod (int).
    • Updated mock/fake Usercentrics manager:
      • Added getDpsMetadata(templateId:)
      • onGppSectionChange now uses callback pattern with disposable event wrapper
      • denyAllForTCF signature extended to accept unsavedVendorLIDecisions
      • Added fields in fake/mocks to cover new properties/metadata.
  • TypeScript models & tests

    • UsercentricsSettings model: added gppSignalingEnabled, gpcSignalHonoured.
    • CCPASettings model: added optional mspaCoveredTransaction and mspaMode.
    • TCF2Settings model: replaced resurfacePeriodEnded (boolean) with resurfacePeriod (number).
    • Tests and sample mocks updated to reflect new fields and changed method signatures.
  • Breaking / notable behavior changes

    • TCF resurface field type changed from boolean (resurfacePeriodEnded) to integer (resurfacePeriod) — consumers must handle numeric months.
    • denyAllForTCF API signature now includes unsavedVendorLIDecisions (added param) — update callsites.
    • RN setGPPConsent behavior: null values are sent as JSONObject.NULL instead of raw null.
    • Data model additions (gpp, mspa, metadata) require consumers reading serialized settings to accept new keys.
  • Misc

    • Updated sample mocks and unit tests to accommodate new fields and API signatures.

Reviewed by Panto AI

@pantoaibot
Copy link
Copy Markdown

pantoaibot bot commented Apr 7, 2026

Reviewed up to commit:33fd8718a678483dc4bc4b6fc79a41df054bc45e

Additional Suggestion
android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt, line:283-287 getMspaModeCompat (lines ~283-287) obtains an enum instance via reflection and then calls ordinal via reflection and casts to Int. Use Number conversion instead of as? Int to be robust across JVM boxing: val ordinal = (mode.javaClass.getMethod("ordinal").invoke(mode) as? Number)?.toInt(). Also consider returning a concrete default (e.g. null vs -1) and document the semantics.
private fun CCPASettings.getMspaModeCompat(): Int? {
    return runCatching {
        val mode = javaClass.getMethod("getMspaMode").invoke(this) ?: return@runCatching null
        (mode.javaClass.getMethod("ordinal").invoke(mode) as? Number)?.toInt()
    }.getOrNull()
}

Reviewed by Panto AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai bot commented Apr 7, 2026

CodeAnt AI finished reviewing your PR.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift (1)

111-116: Keep the stored callback in sync with the subscription lifecycle.

gppSectionChangeCallback is retained independently of the returned subscription, so test code can still trigger the old observer after cleanup. Please clear or gate the stored callback when the subscription is disposed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift` around lines 111 -
116, The stored gppSectionChangeCallback in FakeUsercentricsManager is kept
alive independently of the returned subscription; update onGppSectionChange to
clear or gate that stored callback when the subscription is disposed by
returning a UsercentricsDisposableEvent whose dispose/teardown closure sets
gppSectionChangeCallback = nil (and still forwards payloads while subscribed),
ensuring gppSectionChangeCallback is assigned on subscribe and cleared on
disposal so old observers cannot be invoked after cleanup.
sample/ios/sampleTests/Mock/CMPData+Mock.swift (1)

281-283: Add one non-nil MSPA mode fixture.

mspaMode stays nil in the updated mock, so the new ordinal serialization branch is still untested. Please include at least one mock/assertion with a concrete mode value.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sample/ios/sampleTests/Mock/CMPData`+Mock.swift around lines 281 - 283, The
mock constructor in CMPData+Mock.swift currently sets mspaMode: nil so the
ordinal-serialization branch remains untested; update the mock(s) that build
CMPData (the factory in CMPData+Mock.swift where mspaMode is passed) to include
at least one non-nil concrete value from the MSPAMode enum (e.g., a specific
case) instead of nil, and add/update the corresponding test assertion to
validate the ordinal serialization path for that concrete mspaMode value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt`:
- Line 226: The code currently maps "resurfacePeriod" to
getResurfacePeriodCompat(), which wrongfully converts the legacy boolean
ended-state into a numeric period; update the mapping so "resurfacePeriod" is
only populated from the actual getResurfacePeriod() SDK method when available,
and do not synthesize 0/1 from the legacy flag. Instead, on the fallback path
use the legacy boolean field name (e.g., expose getResurfacePeriodEnded() /
isResurfacePeriodEnded() as "resurfacePeriodEnded") so JS receives the correct
semantics; modify getResurfacePeriodCompat() to stop returning a numeric 0/1 or
remove its use, and apply the same change to the other mapping block covering
the region referenced (lines ~252-263) so only real period values populate
"resurfacePeriod" and legacy booleans are exposed under a distinct key.

In `@src/models/CCPASettings.tsx`:
- Around line 17-18: Replace the mspaMode field's type from number to a new
exported TypeScript enum (e.g., export enum MSPAMode) that mirrors the native
SDK enum ordinals, update any constructor/creation sites and the CCPASettings
type in src/models/CCPASettings.tsx to use MSPAMode instead of number (leave
mspaCoveredTransaction as-is), and add a re-export for MSPAMode (and
CCPASettings if not already) from src/index.tsx so the enum is publicly
available to consumers.

In `@src/models/TCF2Settings.tsx`:
- Around line 38-39: The public payload shape was changed by replacing
resurfacePeriodEnded with resurfacePeriod; restore compatibility by keeping the
legacy boolean alongside the new numeric value: update the TCF2Settings
type/props to include both resurfacePeriod: number and resurfacePeriodEnded:
boolean (mark as deprecated in comments), and update the getCMPData()
implementation to populate resurfacePeriodEnded based on the existing logic (or
derive it from resurfacePeriod if that’s the intended mapping) while still
returning resurfacePeriod; ensure any places that set or read
resurfacePeriodEnded (including where resurfacePurposeChanged is used) continue
to work by writing both fields.

---

Nitpick comments:
In `@sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift`:
- Around line 111-116: The stored gppSectionChangeCallback in
FakeUsercentricsManager is kept alive independently of the returned
subscription; update onGppSectionChange to clear or gate that stored callback
when the subscription is disposed by returning a UsercentricsDisposableEvent
whose dispose/teardown closure sets gppSectionChangeCallback = nil (and still
forwards payloads while subscribed), ensuring gppSectionChangeCallback is
assigned on subscribe and cleared on disposal so old observers cannot be invoked
after cleanup.

In `@sample/ios/sampleTests/Mock/CMPData`+Mock.swift:
- Around line 281-283: The mock constructor in CMPData+Mock.swift currently sets
mspaMode: nil so the ordinal-serialization branch remains untested; update the
mock(s) that build CMPData (the factory in CMPData+Mock.swift where mspaMode is
passed) to include at least one non-nil concrete value from the MSPAMode enum
(e.g., a specific case) instead of nil, and add/update the corresponding test
assertion to validate the ordinal serialization path for that concrete mspaMode
value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5c77709e-7562-4041-babc-6f2e88d99683

📥 Commits

Reviewing files that changed from the base of the PR and between f45a517 and 33fd871.

⛔ Files ignored due to path filters (3)
  • legacy-sample/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
  • sample/ios/Podfile.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • CHANGELOG.md
  • android/build-legacy.gradle
  • android/build.gradle.kts
  • android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt
  • android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt
  • ios/Extensions/GppData+Dict.swift
  • ios/Extensions/UsercentricsCMPData+Dict.swift
  • package.json
  • sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift
  • sample/ios/sampleTests/Mock/CMPData+Mock.swift
  • sample/ios/sampleTests/RNUsercentricsModuleTests.swift
  • src/__tests__/mocks.ts
  • src/models/CCPASettings.tsx
  • src/models/TCF2Settings.tsx
  • src/models/UsercentricsSettings.tsx

@uc-brunosilva uc-brunosilva merged commit 26cba36 into master Apr 7, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants