Skip to content

Commit

Permalink
feat: fetch anonymous id by cookie name provided in load option (#1625)
Browse files Browse the repository at this point in the history
* feat: fetch anonymous id by cookie name provided in load option

* test: unit test modified

* chore: removed unnecessary type casting

* chore: added more test cases

---------

Co-authored-by: George Bardis <[email protected]>
  • Loading branch information
MoumitaM and bardisg authored Feb 26, 2024
1 parent a4c4fc0 commit d8ccb10
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/analytics-js-common/src/types/LoadOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export type LoadOptions = {
transportMode?: EventsTransportMode; // Unused for now. This will deprecate the useBeacon and beaconQueueOptions
consentManagement?: ConsentManagementOptions;
sameDomainCookiesOnly?: boolean;
externalAnonymousIdCookieName?: string;
};

export type ConsentOptions = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,70 @@ describe('User session manager', () => {
expect(state.session.anonymousId.value).toBe(customData.rl_anonymous_id);
expect(state.session.authToken.value).toBe(DEFAULT_USER_SESSION_VALUES.authToken);
});
it('should set anonymousId from external name if externalAnonymousIdCookieName load option is provided', () => {
const customData = {
rl_anonymous_id: 'dummy-anonymousId',
};
setDataInCookieStorage(customData);
state.loadOptions.value.externalAnonymousIdCookieName = 'anonId';
state.storage.entries.value = entriesWithOnlyCookieStorage;
const spy = jest.spyOn(userSessionManager, 'getExternalAnonymousIdByCookieName');
userSessionManager.syncStorageDataToState();
expect(spy).toHaveBeenCalledWith('anonId');
});
it('should set anonymousId with existing logic if external name is not string', () => {
const customData = {
rl_anonymous_id: 'dummy-anonymousId',
};
setDataInCookieStorage(customData);
state.loadOptions.value.externalAnonymousIdCookieName = 12345;
state.storage.entries.value = entriesWithOnlyCookieStorage;
const spy = jest.spyOn(userSessionManager, 'getExternalAnonymousIdByCookieName');

userSessionManager.syncStorageDataToState();

expect(spy).not.toHaveBeenCalled();
expect(state.session.anonymousId.value).toBe('dummy-anonymousId');
});
it('should set anonymousId with existing logic if external name is null', () => {
const customData = {
rl_anonymous_id: 'dummy-anonymousId',
};
setDataInCookieStorage(customData);
state.loadOptions.value.externalAnonymousIdCookieName = null;
state.storage.entries.value = entriesWithOnlyCookieStorage;
const spy = jest.spyOn(userSessionManager, 'getExternalAnonymousIdByCookieName');

userSessionManager.syncStorageDataToState();

expect(spy).not.toHaveBeenCalled();
expect(state.session.anonymousId.value).toBe('dummy-anonymousId');
});
it('should set anonymousId with existing logic if external name is undefined', () => {
const customData = {
rl_anonymous_id: 'dummy-anonymousId',
};
setDataInCookieStorage(customData);
state.loadOptions.value.externalAnonymousIdCookieName = undefined;
state.storage.entries.value = entriesWithOnlyCookieStorage;
const spy = jest.spyOn(userSessionManager, 'getExternalAnonymousIdByCookieName');

userSessionManager.syncStorageDataToState();

expect(spy).not.toHaveBeenCalled();
expect(state.session.anonymousId.value).toBe('dummy-anonymousId');
});
it('should set anonymousId with existing logic if anonymousId fetch by the external name is null', () => {
const customData = {
rl_anonymous_id: 'dummy-anonymousId',
};
setDataInCookieStorage(customData);
state.loadOptions.value.externalAnonymousIdCookieName = 'anonId';
state.storage.entries.value = entriesWithOnlyCookieStorage;
userSessionManager.getExternalAnonymousIdByCookieName = jest.fn(() => null);
userSessionManager.syncStorageDataToState();
expect(state.session.anonymousId.value).toBe('dummy-anonymousId');
});
});

describe('init', () => {
Expand Down Expand Up @@ -1305,4 +1369,18 @@ describe('User session manager', () => {
expect(state.session.sessionInfo.value).toEqual(sessionInfoBeforeReset);
});
});

describe('getExternalAnonymousIdByCookieName', () => {
it('Should return null if the cookie value does not exists', () => {
const externalAnonymousId =
userSessionManager.getExternalAnonymousIdByCookieName('anonId_cookie');
expect(externalAnonymousId).toEqual(null);
});
it('Should return the cookie value if exists', () => {
document.cookie = 'anonId_cookie=sampleAnonymousId12345';
const externalAnonymousId =
userSessionManager.getExternalAnonymousIdByCookieName('anonId_cookie');
expect(externalAnonymousId).toEqual('sampleAnonymousId12345');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
mergeDeepRight,
} from '@rudderstack/analytics-js-common/utilities/object';
import {
isDefinedAndNotNull,
isDefinedNotNullAndNotEmptyString,
isNullOrUndefined,
isString,
Expand Down Expand Up @@ -93,7 +94,15 @@ class UserSessionManager implements IUserSessionManager {
this.setUserTraits(this.getUserTraits());
this.setGroupId(this.getGroupId());
this.setGroupTraits(this.getGroupTraits());
this.setAnonymousId(this.getAnonymousId(state.loadOptions.value.anonymousIdOptions));
const { externalAnonymousIdCookieName, anonymousIdOptions } = state.loadOptions.value;
let externalAnonymousId;
if (
isDefinedAndNotNull(externalAnonymousIdCookieName) &&
typeof externalAnonymousIdCookieName === 'string'
) {
externalAnonymousId = this.getExternalAnonymousIdByCookieName(externalAnonymousIdCookieName);
}
this.setAnonymousId(externalAnonymousId ?? this.getAnonymousId(anonymousIdOptions));
this.setAuthToken(this.getAuthToken());
this.setInitialReferrerInfo();
this.configureSessionTracking();
Expand Down Expand Up @@ -352,6 +361,14 @@ class UserSessionManager implements IUserSessionManager {
return null;
}

getExternalAnonymousIdByCookieName(key: string) {
const storageEngine = getStorageEngine(COOKIE_STORAGE);
if (storageEngine?.isEnabled) {
return storageEngine.getItem(key) ?? null;
}
return null;
}

/**
* Fetches User Id
* @returns
Expand Down

0 comments on commit d8ccb10

Please sign in to comment.