Skip to content

feat(MSDK-4514): Propagate isExempt to the ServiceConsent bridge model - #234

Merged
islameldesoky95 merged 3 commits into
masterfrom
feat/MSDK-4514-propagate-statistical-exception
Aug 6, 2026
Merged

feat(MSDK-4514): Propagate isExempt to the ServiceConsent bridge model#234
islameldesoky95 merged 3 commits into
masterfrom
feat/MSDK-4514-propagate-statistical-exception

Conversation

@islameldesoky95

@islameldesoky95 islameldesoky95 commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

User description

Threads the isExempt field (added to the native UsercentricsServiceConsent in MSDK-4513) through the TS model, iOS Swift and Android Kotlin serialization extensions, and their mock/test fixtures.

Summary by CodeRabbit

  • New Features

    • Consent status data now includes whether each consent is exempt.
    • The new exemption status is available consistently across Android, iOS, and JavaScript outputs.
    • Existing integrations remain compatible, with the exemption status defaulting to false.
  • Tests

    • Updated consent fixtures and validation coverage to include exemption status.

CodeAnt-AI Description

Expose consent exemption status across JavaScript, Android, and iOS

What Changed

  • Consent results now include an isExempt value across all supported platforms
  • Existing JavaScript consent constructors remain compatible, defaulting isExempt to false
  • Consent fixtures and serialization expectations now cover the exemption status

Impact

✅ Consistent exemption status across platforms
✅ Backward-compatible consent object creation
✅ Clearer consent compliance data

💡 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.

Threads the isExempt field (added to the native UsercentricsServiceConsent
in MSDK-4513) through the TS model, iOS Swift and Android Kotlin
serialization extensions, and their mock/test fixtures.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The consent model now exposes isExempt, defaulting to false. Android and iOS serializers include the field. Native and TypeScript test fixtures now provide and expect the field.

Changes

Consent exemption field

Layer / File(s) Summary
Consent model contract
src/models/UsercentricsServiceConsent.tsx
UsercentricsServiceConsent now declares isExempt and accepts an optional constructor value that defaults to false.
Platform serialization and validation
android/src/main/java/..., ios/Extensions/..., android/src/androidTest/..., sample/ios/sampleTests/..., src/__tests__/index.test.ts
Android and iOS consent serialization now includes isExempt. Native and TypeScript fixtures now provide and expect false.

Estimated code review effort: 1 (Trivial) | ~5 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes propagating isExempt through the ServiceConsent bridge model.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/MSDK-4514-propagate-statistical-exception

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.

@pantoaibot

pantoaibot Bot commented Jul 30, 2026

Copy link
Copy Markdown

PR Summary:

Propagate isExempt on ServiceConsent objects across native-to-JS bridge so the RN layer receives the new boolean field.

Changes:

  • JS model: added isExempt:boolean to UsercentricsServiceConsent and extended constructor to accept isExempt.
  • Android:
    • Include "isExempt" in UsercentricsServiceConsent.toWritableMap().
    • Updated android test mocks/expected maps to include isExempt (false).
  • iOS:
    • Include "isExempt" in UsercentricsServiceConsent.toDictionary().
    • Updated sample tests and mocks to set isExempt (false).
  • Tests: updated unit tests/mocks across src/tests, androidTest and sample iOS tests to include isExempt where service consents are created/serialized.
  • Breaking change: UsercentricsServiceConsent constructor signature in the JS model now requires the additional isExempt argument — update any instantiations accordingly.
  • No dependency, performance, or behavioral changes beyond exposing the new field.

Reviewed by Panto AI

Comment thread src/models/UsercentricsServiceConsent.tsx
Comment thread src/__tests__/index.test.ts
@pantoaibot

pantoaibot Bot commented Jul 30, 2026

Copy link
Copy Markdown

Reviewed up to commit:fd35f3cc94b4494978a3ec262ec485b46b4b2d04

Reviewed by Panto AI

…ctor change

isExempt was added as a required positional constructor parameter,
breaking any existing call site that doesn't pass it. Give it the
same false default the native model and every other bridge use.
@islameldesoky95
islameldesoky95 marked this pull request as ready for review August 6, 2026 08:50
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Propagate isExempt through ServiceConsent bridge models (TS/iOS/Android)

✨ Enhancement 🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Expose isExempt in iOS/Android ServiceConsent serialization to the JS bridge.
• Add isExempt to the TS ServiceConsent model, defaulting to false.
• Update platform mocks and JS/iOS tests to include isExempt expectations.
Diagram

graph TD
  A{{"Native UsercentricsServiceConsent"}} --> B["Android: toWritableMap()"] --> D["Bridge payload"]
  A --> C["iOS: toDictionary()"] --> D
  D --> E["TS ServiceConsent model"] --> F["JS API consumers"]
  E --> G["Mocks / tests"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make `isExempt` optional/nullable in the TS model
  • ➕ Avoids implying a default value if some native versions don’t provide it
  • ➕ Keeps model changes additive without any behavioral assumption
  • ➖ Downstream consumers must handle undefined everywhere
  • ➖ Diverges from native behavior where the field is effectively boolean with a default
2. Switch to an object-parameter constructor for ServiceConsent
  • ➕ Eliminates breaking changes when adding fields in the future
  • ➕ Improves call-site readability vs long positional argument lists
  • ➖ Larger API refactor and likely breaking for existing TypeScript call sites
  • ➖ Not necessary if the model is primarily instantiated from native payloads

Recommendation: Current approach is appropriate for a bridge model: serialize isExempt on both platforms and default it to false in the TS constructor to prevent a breaking signature change. Consider an object-parameter constructor only if ServiceConsent is commonly constructed directly in TypeScript and expected to evolve frequently.

Files changed (8) +28 / -12

Enhancement (3) +6 / -2
UsercentricsServiceConsentExtensions.ktSerialize 'isExempt' in Android ServiceConsent bridge map +1/-0

Serialize 'isExempt' in Android ServiceConsent bridge map

• Adds 'putBoolean("isExempt", isExempt)' when converting 'UsercentricsServiceConsent' to a 'WritableMap'. This exposes the field to the React Native JS layer.

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

UsercentricsServiceConsents+Dict.swiftSerialize 'isExempt' in iOS ServiceConsent dictionary +2/-1

Serialize 'isExempt' in iOS ServiceConsent dictionary

• Adds '"isExempt": self.isExempt' to the dictionary produced by 'UsercentricsServiceConsent.toDictionary()'. Keeps the iOS bridge payload aligned with Android/TS.

ios/Extensions/UsercentricsServiceConsents+Dict.swift

UsercentricsServiceConsent.tsxAdd 'isExempt' to TS ServiceConsent model with default 'false' +3/-1

Add 'isExempt' to TS ServiceConsent model with default 'false'

• Adds an 'isExempt: boolean' property to the TypeScript 'UsercentricsServiceConsent' model. Extends the constructor signature with 'isExempt' defaulting to 'false' to avoid breaking existing call sites.

src/models/UsercentricsServiceConsent.tsx

Tests (5) +22 / -10
GetConsentsMock.ktAdd 'isExempt' to Android GetConsents mock and expected map +3/-1

Add 'isExempt' to Android GetConsents mock and expected map

• Extends the mocked 'UsercentricsServiceConsent' instance with 'isExempt = false'. Updates the expected serialized map to include the 'isExempt' key.

android/src/androidTest/java/com/usercentrics/reactnative/mock/GetConsentsMock.kt

SaveDecisionsForTCFMock.ktAdd 'isExempt' to Android TCF decision mock fixtures +3/-1

Add 'isExempt' to Android TCF decision mock fixtures

• Adds 'isExempt = false' to the 'UsercentricsServiceConsent' mock. Updates the expected serialized result to assert 'isExempt' is present.

android/src/androidTest/java/com/usercentrics/reactnative/mock/SaveDecisionsForTCFMock.kt

UsercentricsIsReady+Mock.swiftUpdate iOS sample test mock to pass 'isExempt' +2/-1

Update iOS sample test mock to pass 'isExempt'

• Updates the 'UsercentricsServiceConsent.mock()' factory to include 'isExempt: false'. Prevents compilation/test failures after the native model gained the new property.

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

ReadyStatusDictTests.swiftUpdate iOS ready-status serialization tests for 'isExempt' +6/-3

Update iOS ready-status serialization tests for 'isExempt'

• Updates test consent construction to include 'isExempt: false' for explicit and implicit consents. Ensures the test suite remains compatible with the updated model/serialization.

sample/ios/sampleTests/ReadyStatusDictTests.swift

index.test.tsAdd 'isExempt' to JS test fixtures for service consents +8/-4

Add 'isExempt' to JS test fixtures for service consents

• Extends multiple consent fixture objects in the JS test suite to include 'isExempt: false'. Keeps snapshot/strict equality assertions aligned with the expanded bridge payload.

src/tests/index.test.ts

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Constructor default not applied 🐞 Bug ☼ Reliability
Description
UsercentricsServiceConsent.isExempt is typed as a required boolean, but the default value is only
provided in the class constructor, which is not used for objects returned directly from the native
module. If the JS layer is updated without the corresponding native update (e.g., OTA) or any native
path omits isExempt, callers can receive undefined while TypeScript claims it’s always a
boolean.
Code

src/models/UsercentricsServiceConsent.tsx[R13-15]

+    isExempt: boolean

-    constructor(templateId: string, status: boolean, dataProcessor: string, version: string, type: UsercentricsConsentType, isEssential: boolean, history: UsercentricsConsentHistoryEntry[], category: string) {
+    constructor(templateId: string, status: boolean, dataProcessor: string, version: string, type: UsercentricsConsentType, isEssential: boolean, history: UsercentricsConsentHistoryEntry[], category: string, isExempt: boolean = false) {
Evidence
The model adds isExempt and a constructor default, but the public API returns native results
directly without constructing the class, so the default will not populate missing fields.

src/models/UsercentricsServiceConsent.tsx[3-25]
src/Usercentrics.tsx[63-66]
src/NativeUsercentrics.ts[33-35]

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

## Issue description
`UsercentricsServiceConsent.isExempt` is non-optional in TS, but consents are returned from `RNUsercentricsModule` as plain objects and are not constructed via `new UsercentricsServiceConsent(...)`. This means the constructor’s default (`isExempt = false`) does not run, and `isExempt` can be `undefined` if native does not send it.

## Issue Context
This becomes visible in version-mismatch scenarios (e.g., OTA JS update without native update) or any native implementation path that forgets to serialize the new field.

## Fix Focus Areas
- src/models/UsercentricsServiceConsent.tsx[13-25]
- src/Usercentrics.tsx[63-66]

### Suggested approach
- Add a small normalization helper in `src/Usercentrics.tsx` (or a shared mapper) that maps each returned consent to ensure `isExempt` is present: `isExempt: consent.isExempt ?? false`.
- Apply it to all methods returning `Array<UsercentricsServiceConsent>`.
- (Alternative) Mark `isExempt` as optional in the model (`isExempt?: boolean`) if you want the type to accurately reflect potentially-missing native fields.

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


To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sample/ios/sampleTests/ReadyStatusDictTests.swift`:
- Around line 17-18: Update the serialization tests around the ReadyStatus
fixtures to assert the serialized isExempt field, and set isExempt to true in
one fixture so non-default values are verified; apply the same assertion and
fixture adjustment to the additional indicated test cases.

In `@src/__tests__/index.test.ts`:
- Around line 152-153: Update the changed fixture literals in the test file,
including the entries around category and isExempt at all referenced locations,
to use the repository’s Prettier formatting: single-quoted TypeScript strings
and no semicolons. Preserve the fixture values and structure.

In `@src/models/UsercentricsServiceConsent.tsx`:
- Line 15: Apply the repository’s Prettier formatting to all changed TypeScript:
reformat the long constructor declaration in
src/models/UsercentricsServiceConsent.tsx:15, remove the semicolon at
src/models/UsercentricsServiceConsent.tsx:24, and convert the changed fixtures
to single quotes at src/__tests__/index.test.ts:152-153, 206-207, 275-276, and
585-586. Use no semicolons and preserve the existing JSX formatting conventions.
🪄 Autofix

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 Plus

Run ID: a6084472-36fc-4c28-b0a9-88c0ac0be2a3

📥 Commits

Reviewing files that changed from the base of the PR and between 3380b40 and d9e5a89.

📒 Files selected for processing (8)
  • android/src/androidTest/java/com/usercentrics/reactnative/mock/GetConsentsMock.kt
  • android/src/androidTest/java/com/usercentrics/reactnative/mock/SaveDecisionsForTCFMock.kt
  • android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsServiceConsentExtensions.kt
  • ios/Extensions/UsercentricsServiceConsents+Dict.swift
  • sample/ios/sampleTests/Mock/UsercentricsIsReady+Mock.swift
  • sample/ios/sampleTests/ReadyStatusDictTests.swift
  • src/__tests__/index.test.ts
  • src/models/UsercentricsServiceConsent.tsx

Comment thread sample/ios/sampleTests/ReadyStatusDictTests.swift
Comment thread src/__tests__/index.test.ts
Comment thread src/models/UsercentricsServiceConsent.tsx
Comment thread src/models/UsercentricsServiceConsent.tsx
@codeant-ai

codeant-ai Bot commented Aug 6, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR ffd4724 Aug 06, 2026 · 09:02 09:06

@codeant-ai

codeant-ai Bot commented Aug 6, 2026

Copy link
Copy Markdown

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

@codeant-ai codeant-ai Bot added the size:S This PR changes 10-29 lines, ignoring generated files label Aug 6, 2026
Comment thread src/__tests__/index.test.ts
@islameldesoky95
islameldesoky95 merged commit fe65f38 into master Aug 6, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants