-
Notifications
You must be signed in to change notification settings - Fork 16
feat(MSDK-3781): Add notifySubscriptionLapsed to React Native bridge #244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -272,4 +272,13 @@ final class FakeUsercentricsManager: UsercentricsManager { | |
| } | ||
| onSuccess() | ||
| } | ||
|
|
||
| var notifySubscriptionLapsedError: Error? | ||
| func notifySubscriptionLapsed(onSuccess: @escaping (() -> Void), onError: @escaping ((Error) -> Void)) { | ||
| if let notifySubscriptionLapsedError = notifySubscriptionLapsedError { | ||
| onError(notifySubscriptionLapsedError) | ||
| return | ||
| } | ||
| onSuccess() | ||
| } | ||
|
Comment on lines
+276
to
+283
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [NITPICK] Mock implementation for notifySubscriptionLapsed is correct. Consider adding a unit test that exercises the error path by setting notifySubscriptionLapsedError to a known Error so coverage includes both success and failure flows for iOS sample tests. final class FakeUsercentricsManager: UsercentricsManager {
// ...existing fakes...
var notifySubscriptionLapsedError: Error?
func notifySubscriptionLapsed(onSuccess: @escaping (() -> Void), onError: @escaping ((Error) -> Void)) {
if let notifySubscriptionLapsedError = notifySubscriptionLapsedError {
onError(notifySubscriptionLapsedError)
return
}
onSuccess()
}
}
final class UsercentricsManagerTests: XCTestCase {
func testNotifySubscriptionLapsed_error_isPropagated() {
let fakeManager = FakeUsercentricsManager()
let expectedError = NSError(domain: "test", code: 1)
fakeManager.notifySubscriptionLapsedError = expectedError
let expectation = expectation(description: "notifySubscriptionLapsed error path")
fakeManager.notifySubscriptionLapsed {
XCTFail("Expected error, got success")
} onError: { error in
XCTAssertEqual(error as NSError, expectedError)
expectation.fulfill()
}
wait(for: [expectation], timeout: 1)
}
} |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,7 @@ export interface Spec extends TurboModule { | |
| // Consent or Pay | ||
| notifyLoginSuccess(): Promise<void>; | ||
| notifySubscribeSuccess(): Promise<void>; | ||
| notifySubscriptionLapsed(): Promise<void>; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [VALIDATION] You added notifySubscriptionLapsed() to the exported TurboModule Spec. Ensure both the JS-side typings (this file) and the fabric/native spec (src/fabric/NativeUsercentricsModule.ts) remain in sync with any generated/native-facing specs; run a full TypeScript build and the native codegen to validate there are no type/signature mismatches that could cause runtime failures on either platform. |
||
|
|
||
| // Data Retrieval | ||
| getConsents(): Promise<Array<UsercentricsServiceConsent>>; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -65,6 +65,7 @@ jest.mock("react-native", () => { | |
| reset: jest.fn(), | ||
| getDpsMetadata: jest.fn(), | ||
| clearUserSession: jest.fn(), | ||
| notifySubscriptionLapsed: jest.fn(), | ||
| addListener: jest.fn(), | ||
| removeListeners: jest.fn() | ||
| }; | ||
|
|
@@ -618,4 +619,25 @@ describe('Test Usercentrics Module', () => { | |
| expect(e).toBe("Failed"); | ||
| } | ||
| }) | ||
|
|
||
| test('testNotifySubscriptionLapsed', async () => { | ||
| RNUsercentricsModule.notifySubscriptionLapsed.mockImplementationOnce( | ||
| (): Promise<any> => Promise.resolve() | ||
| ) | ||
|
|
||
| await Usercentrics.notifySubscriptionLapsed(); | ||
| expect(RNUsercentricsModule.notifySubscriptionLapsed).toHaveBeenCalled(); | ||
| }) | ||
|
|
||
| test('testNotifySubscriptionLapsedWithError', async () => { | ||
| RNUsercentricsModule.notifySubscriptionLapsed.mockImplementationOnce( | ||
| (): Promise<any> => Promise.reject("Failed") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Assert the rejected promise with an If Proposed fix- RNUsercentricsModule.notifySubscriptionLapsed.mockImplementationOnce(
- (): Promise<any> => Promise.reject("Failed")
- )
-
- try {
- await Usercentrics.notifySubscriptionLapsed();
- } catch (e) {
- expect(e).toBe("Failed");
- }
+ const error = new Error('Failed')
+ RNUsercentricsModule.notifySubscriptionLapsed.mockRejectedValueOnce(error)
+
+ await expect(Usercentrics.notifySubscriptionLapsed()).rejects.toBe(error)🤖 Prompt for AI Agents |
||
| ) | ||
|
|
||
| try { | ||
| await Usercentrics.notifySubscriptionLapsed(); | ||
| } catch (e) { | ||
| expect(e).toBe("Failed"); | ||
| } | ||
| }) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ export interface Spec extends TurboModule { | |
| // Consent or Pay | ||
| notifyLoginSuccess(): Promise<void>; | ||
| notifySubscribeSuccess(): Promise<void>; | ||
| notifySubscriptionLapsed(): Promise<void>; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [REFACTORING] You added notifySubscriptionLapsed to the fabric TurboModule spec — ensure the TypeScript signature and ordering match any generated native specs and the JS spec (src/NativeUsercentrics.ts). After adding TurboModule methods, run your codegen (and the project's prepare scripts) to update JNI / ObjC generated files so new method bindings exist on both platforms. // src/fabric/NativeUsercentricsModule.ts
export interface Spec extends TurboModule {
// Configuration
configure(options: Object): void;
isReady(): Promise<Object>;
// UI Methods
showFirstLayer(options?: Object): Promise<Object>;
showSecondLayer(options?: Object): Promise<Object>;
// Session Management
restoreUserSession(controllerId: string): Promise<Object>;
getControllerId(): Promise<string>;
clearUserSession(): Promise<Object>;
// Consent or Pay (keep ordering in sync with src/NativeUsercentrics.ts
// and native specs / codegen outputs)
notifyLoginSuccess(): Promise<void>;
notifySubscribeSuccess(): Promise<void>;
notifySubscriptionLapsed(): Promise<void>;
// Data Retrieval
getConsents(): Promise<Array<Object>>;
getCMPData(): Promise<Object>;
getAdditionalConsentModeData(): Promise<Object>;
getTCFData(): Promise<Object>;
getUserSessionData(): Promise<string>;
getUSPData(): Promise<Object>;
getGPPData(): Promise<Object>;
getGPPString(): Promise<string | null>;
getABTestingVariant(): Promise<string>;
getDpsMetadata(templateId: string): Promise<Object | null>;
// Configuration Setters
setCMPId(id: number): void;
setABTestingVariant(variant: string): void;
setGPPConsent(sectionName: string, fieldName: string, value: Object): void;
changeLanguage(language: string): Promise<void>;
// Consent Actions
acceptAll(consentType: number): Promise<Array<Object>>;
acceptAllForTCF(fromLayer: number, consentType: number): Promise<Array<Object>>;
denyAll(consentType: number): Promise<Array<Object>>;
denyAllForTCF(
fromLayer: number,
consentType: number,
unsavedPurposeLIDecisions: Array<Object>,
unsavedVendorLIDecisions: Array<Object>,
): Promise<Array<Object>>;
saveDecisions(decisions: Array<Object>, consentType: number): Promise<Array<Object>>;
saveDecisionsForTCF(
tcfDecisions: Object,
fromLayer: number,
saveDecisions: Array<Object>,
): Promise<Array<Object>>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('RNUsercentricsModule'); |
||
|
|
||
| // Data Retrieval | ||
| getConsents(): Promise<Array<Object>>; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[REFACTORING] You added notifySubscriptionLapsed to the protocol and implementation which is correct. Double-check that the underlying UsercentricsCore.shared.notifySubscriptionLapsed is available in the pinned native SDK version; if it was introduced in a new native SDK release, ensure the iOS dependency/podspec is updated accordingly and that CI runs pod install with the updated native SDK.