diff --git a/src/core/classes/Iterable.test.ts b/src/core/classes/Iterable.test.ts index 7774b5bba..bfe4c26f6 100644 --- a/src/core/classes/Iterable.test.ts +++ b/src/core/classes/Iterable.test.ts @@ -74,6 +74,58 @@ describe('Iterable', () => { }); }); + describe('logout', () => { + it('should call setEmail with null', () => { + // GIVEN no parameters + // WHEN Iterable.logout is called + const setEmailSpy = jest.spyOn(Iterable, 'setEmail'); + Iterable.logout(); + // THEN Iterable.setEmail is called with null + expect(setEmailSpy).toBeCalledWith(null); + setEmailSpy.mockRestore(); + }); + + it('should call setUserId with null', () => { + // GIVEN no parameters + // WHEN Iterable.logout is called + const setUserIdSpy = jest.spyOn(Iterable, 'setUserId'); + Iterable.logout(); + // THEN Iterable.setUserId is called with null + expect(setUserIdSpy).toBeCalledWith(null); + setUserIdSpy.mockRestore(); + }); + + it('should clear email and userId', async () => { + // GIVEN a user is logged in + + // This is just for testing purposed. + // Usually you'd either call `setEmail` or `setUserId`, but not both. + Iterable.setEmail('user@example.com'); + Iterable.setUserId('user123'); + // WHEN Iterable.logout is called + Iterable.logout(); + // THEN email and userId are set to null + const email = await Iterable.getEmail(); + const userId = await Iterable.getUserId(); + expect(email).toBeNull(); + expect(userId).toBeNull(); + }); + + it('should call setEmail and setUserId with null', () => { + // GIVEN no parameters + const setEmailSpy = jest.spyOn(Iterable, 'setEmail'); + const setUserIdSpy = jest.spyOn(Iterable, 'setUserId'); + // WHEN Iterable.logout is called + Iterable.logout(); + // THEN both methods are called with null + expect(setEmailSpy).toBeCalledWith(null); + expect(setUserIdSpy).toBeCalledWith(null); + // Clean up + setEmailSpy.mockRestore(); + setUserIdSpy.mockRestore(); + }); + }); + describe('disableDeviceForCurrentUser', () => { it('should disable the device for the current user', () => { // GIVEN no parameters diff --git a/src/core/classes/Iterable.ts b/src/core/classes/Iterable.ts index 4c64cb7da..2a23693e2 100644 --- a/src/core/classes/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -890,6 +890,34 @@ export class Iterable { }); } + /** + * Logs out the current user from the Iterable SDK. + * + * This method will remove all event listeners for the Iterable SDK and set the email and user ID to null. + * + * @example + * ```typescript + * Iterable.logout(); + * ``` + */ + static logout() { + Iterable.removeAllEventListeners(); + Iterable.setEmail(null); + Iterable.setUserId(null); + } + + /** + * Removes all event listeners for the Iterable SDK. + */ + private static removeAllEventListeners() { + RNEventEmitter.removeAllListeners(IterableEventName.handleUrlCalled); + RNEventEmitter.removeAllListeners(IterableEventName.handleInAppCalled); + RNEventEmitter.removeAllListeners(IterableEventName.handleCustomActionCalled); + RNEventEmitter.removeAllListeners(IterableEventName.handleAuthCalled); + RNEventEmitter.removeAllListeners(IterableEventName.handleAuthSuccessCalled); + RNEventEmitter.removeAllListeners(IterableEventName.handleAuthFailureCalled); + } + /** * Sets up event handlers for various Iterable events. * @@ -912,12 +940,7 @@ export class Iterable { */ private static setupEventHandlers() { // Remove all listeners to avoid duplicate listeners - RNEventEmitter.removeAllListeners(IterableEventName.handleUrlCalled); - RNEventEmitter.removeAllListeners(IterableEventName.handleInAppCalled); - RNEventEmitter.removeAllListeners( - IterableEventName.handleCustomActionCalled - ); - RNEventEmitter.removeAllListeners(IterableEventName.handleAuthCalled); + Iterable.removeAllEventListeners(); if (Iterable.savedConfig.urlHandler) { RNEventEmitter.addListener(IterableEventName.handleUrlCalled, (dict) => {