From fd35f3cc94b4494978a3ec262ec485b46b4b2d04 Mon Sep 17 00:00:00 2001 From: islameldesoky1 Date: Wed, 29 Jul 2026 14:19:41 +0100 Subject: [PATCH 1/2] feat(MSDK-4514): Propagate isExempt to the ServiceConsent bridge model 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 --- .../usercentrics/reactnative/mock/GetConsentsMock.kt | 4 +++- .../reactnative/mock/SaveDecisionsForTCFMock.kt | 4 +++- .../UsercentricsServiceConsentExtensions.kt | 1 + .../UsercentricsServiceConsents+Dict.swift | 3 ++- .../sampleTests/Mock/UsercentricsIsReady+Mock.swift | 3 ++- sample/ios/sampleTests/ReadyStatusDictTests.swift | 9 ++++++--- src/__tests__/index.test.ts | 12 ++++++++---- src/models/UsercentricsServiceConsent.tsx | 4 +++- 8 files changed, 28 insertions(+), 12 deletions(-) diff --git a/android/src/androidTest/java/com/usercentrics/reactnative/mock/GetConsentsMock.kt b/android/src/androidTest/java/com/usercentrics/reactnative/mock/GetConsentsMock.kt index 36c024fa..a490e7de 100644 --- a/android/src/androidTest/java/com/usercentrics/reactnative/mock/GetConsentsMock.kt +++ b/android/src/androidTest/java/com/usercentrics/reactnative/mock/GetConsentsMock.kt @@ -23,6 +23,7 @@ internal class GetConsentsMock { ), isEssential = false, category = "marketing", + isExempt = false, ) ) @@ -41,7 +42,8 @@ internal class GetConsentsMock { "status" to false ) ), - "category" to "marketing" + "category" to "marketing", + "isExempt" to false ) ) } diff --git a/android/src/androidTest/java/com/usercentrics/reactnative/mock/SaveDecisionsForTCFMock.kt b/android/src/androidTest/java/com/usercentrics/reactnative/mock/SaveDecisionsForTCFMock.kt index e17c79ed..618da24e 100644 --- a/android/src/androidTest/java/com/usercentrics/reactnative/mock/SaveDecisionsForTCFMock.kt +++ b/android/src/androidTest/java/com/usercentrics/reactnative/mock/SaveDecisionsForTCFMock.kt @@ -29,6 +29,7 @@ internal class SaveDecisionsForTCFMock { ), isEssential = false, category = "marketing", + isExempt = false, ) ) @@ -86,7 +87,8 @@ internal class SaveDecisionsForTCFMock { "status" to false ) ), - "category" to "marketing" + "category" to "marketing", + "isExempt" to false ) ) } diff --git a/android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsServiceConsentExtensions.kt b/android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsServiceConsentExtensions.kt index 70eb6371..64269197 100644 --- a/android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsServiceConsentExtensions.kt +++ b/android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsServiceConsentExtensions.kt @@ -33,6 +33,7 @@ internal fun UsercentricsServiceConsent.toWritableMap(): WritableMap { putBoolean("isEssential", isEssential) putArray("history", history.toWritableArray()) putString("category", category) + putBoolean("isExempt", isExempt) } } diff --git a/ios/Extensions/UsercentricsServiceConsents+Dict.swift b/ios/Extensions/UsercentricsServiceConsents+Dict.swift index eb690468..9b77738f 100644 --- a/ios/Extensions/UsercentricsServiceConsents+Dict.swift +++ b/ios/Extensions/UsercentricsServiceConsents+Dict.swift @@ -16,7 +16,8 @@ public extension UsercentricsServiceConsent { "dataProcessor": self.dataProcessor, "isEssential": self.isEssential, "history": self.history.toDictionary(), - "category": self.category + "category": self.category, + "isExempt": self.isExempt ] if let type = self.type?.ordinal { diff --git a/sample/ios/sampleTests/Mock/UsercentricsIsReady+Mock.swift b/sample/ios/sampleTests/Mock/UsercentricsIsReady+Mock.swift index 5f693b9a..9449eab3 100644 --- a/sample/ios/sampleTests/Mock/UsercentricsIsReady+Mock.swift +++ b/sample/ios/sampleTests/Mock/UsercentricsIsReady+Mock.swift @@ -26,7 +26,8 @@ extension UsercentricsServiceConsent { dataProcessor: "BBBB", version: "1.2.3", isEssential: false, - category: "marketing") + category: "marketing", + isExempt: false) } } diff --git a/sample/ios/sampleTests/ReadyStatusDictTests.swift b/sample/ios/sampleTests/ReadyStatusDictTests.swift index de338d28..2f71c913 100644 --- a/sample/ios/sampleTests/ReadyStatusDictTests.swift +++ b/sample/ios/sampleTests/ReadyStatusDictTests.swift @@ -14,7 +14,8 @@ class ReadyStatusDictTests: XCTestCase { dataProcessor: "abc", version: "version", isEssential: true, - category: "marketing") + category: "marketing", + isExempt: false) let usercentricsReady = UsercentricsReadyStatus(shouldCollectConsent: false, consents: [consent], @@ -43,7 +44,8 @@ class ReadyStatusDictTests: XCTestCase { dataProcessor: "abc", version: "version", isEssential: false, - category: "marketing").toDictionary() + category: "marketing", + isExempt: false).toDictionary() XCTAssertEqual("abc", consent["templateId"] as! String) XCTAssertEqual(true, consent["status"] as! Bool) @@ -60,7 +62,8 @@ class ReadyStatusDictTests: XCTestCase { dataProcessor: "abc", version: "version", isEssential: false, - category: "marketing").toDictionary() + category: "marketing", + isExempt: false).toDictionary() XCTAssertEqual(1, consentImplicit["type"] as! Int) } diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 3c23bc39..1430de41 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -149,7 +149,8 @@ describe('Test Usercentrics Module', () => { timestampInMillis: 123.0, type: 0 }], - category: "essemtial" + category: "essemtial", + isExempt: false, } ], { @@ -202,7 +203,8 @@ describe('Test Usercentrics Module', () => { timestampInMillis: 123.0, type: 0 }], - category: "essemtial" + category: "essemtial", + isExempt: false, } ] ) @@ -270,7 +272,8 @@ describe('Test Usercentrics Module', () => { timestampInMillis: 123.0, type: 0 }], - category: "essemtial" + category: "essemtial", + isExempt: false, } ], { @@ -579,7 +582,8 @@ describe('Test Usercentrics Module', () => { timestampInMillis: 123.0, type: 0 }], - category: "essemtial" + category: "essemtial", + isExempt: false, } ], { diff --git a/src/models/UsercentricsServiceConsent.tsx b/src/models/UsercentricsServiceConsent.tsx index 9f29ffe5..c265300e 100644 --- a/src/models/UsercentricsServiceConsent.tsx +++ b/src/models/UsercentricsServiceConsent.tsx @@ -10,8 +10,9 @@ export class UsercentricsServiceConsent { isEssential: boolean history: UsercentricsConsentHistoryEntry[] category: string + 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) { this.templateId = templateId this.status = status this.dataProcessor = dataProcessor @@ -20,6 +21,7 @@ export class UsercentricsServiceConsent { this.isEssential = isEssential this.history = history this.category = category; + this.isExempt = isExempt; } } From d9e5a898e657bb901b0842cb99855e4e6e456fc2 Mon Sep 17 00:00:00 2001 From: islameldesoky1 Date: Wed, 5 Aug 2026 11:36:33 +0100 Subject: [PATCH 2/2] fix(MSDK-4514): default isExempt to false to avoid a breaking constructor 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. --- src/models/UsercentricsServiceConsent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/UsercentricsServiceConsent.tsx b/src/models/UsercentricsServiceConsent.tsx index c265300e..d63c50b5 100644 --- a/src/models/UsercentricsServiceConsent.tsx +++ b/src/models/UsercentricsServiceConsent.tsx @@ -12,7 +12,7 @@ export class UsercentricsServiceConsent { category: string isExempt: boolean - constructor(templateId: string, status: boolean, dataProcessor: string, version: string, type: UsercentricsConsentType, isEssential: boolean, history: UsercentricsConsentHistoryEntry[], category: string, isExempt: boolean) { + constructor(templateId: string, status: boolean, dataProcessor: string, version: string, type: UsercentricsConsentType, isEssential: boolean, history: UsercentricsConsentHistoryEntry[], category: string, isExempt: boolean = false) { this.templateId = templateId this.status = status this.dataProcessor = dataProcessor