Skip to content
Merged
27 changes: 24 additions & 3 deletions test/src/config/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,33 @@ declare global {
let userApi = null;

window.mParticle._isTestEnv = true;
type MParticleSDK = { _forwardingStatsTimer?: number | null };


beforeEach(function() {
const mpInstance = window.mParticle.getInstance();
const store = mpInstance?._Store;
const sessionTimer = store?.globalTimer;

if (typeof sessionTimer === 'number') {
clearTimeout(sessionTimer);
store.globalTimer = 0;
}

const mParticleSDK = (window as Window & { mParticle?: MParticleSDK }).mParticle;
const forwardingStatsTimer = mParticleSDK?._forwardingStatsTimer;

if (typeof forwardingStatsTimer === 'number') {
clearInterval(forwardingStatsTimer);
mParticleSDK._forwardingStatsTimer = 0;
}

// mocha can't clean up after itself, so this lets
// tests mock the current user and restores in between runs.
if (!userApi) {
userApi = window.mParticle.getInstance().Identity.getCurrentUser;
userApi = mpInstance.Identity.getCurrentUser;
} else {
window.mParticle.getInstance().Identity.getCurrentUser = userApi;
mpInstance.Identity.getCurrentUser = userApi;
}

window.mParticle.config = {
Expand All @@ -28,9 +47,11 @@ beforeEach(function() {
isDevelopmentMode: false,
flags: {
eventBatchingIntervalMillis: 0,
astBackgroundEvents: 'False',
offlineStorage: '0',
}
};

// This is to tell the resetPersistence method that we are in a test environment
// It should probably be refactored to be included as an argument
window.mParticle._resetForTests(MPConfig);
Expand Down
52 changes: 51 additions & 1 deletion test/src/config/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
das,
} from './constants';
import fetchMock from 'fetch-mock/esm/client';
import sinon from 'sinon';
import { expect } from 'chai';

var pluses = /\+/g,
decoded = function decoded(s) {
Expand Down Expand Up @@ -624,7 +626,50 @@ var pluses = /\+/g,
return window.mParticle.Identity.getCurrentUser()?.getMPID() === _mpid;
},
hasIdentityCallInflightReturned = () => !mParticle.getInstance()?._Store?.identityCallInFlight,
hasConfigurationReturned = () => !!mParticle.getInstance()?._Store?.configurationLoaded;
hasConfigurationReturned = () => !!mParticle.getInstance()?._Store?.configurationLoaded,
setupLoggerSpy = () => {
const loggerSpy = {
verbose: sinon.spy(),
warning: sinon.spy(),
error: sinon.spy(),
};
window.mParticle.config.logger = loggerSpy;
window.mParticle.config.logLevel = 'verbose';
return loggerSpy;
},
hasIdentityResponseParsed = (loggerSpy) => {
return () => loggerSpy?.verbose?.getCalls()?.some(call =>
call.args[0] === 'Successfully parsed Identity Response'
);
},
getBeaconBatch = async function(beaconSpy, callIndex = 0) {
const beaconCall = beaconSpy.getCall(callIndex);
expect(beaconCall, 'Expected beacon call to exist').to.exist;

const blob = beaconCall.args[1];
expect(blob).to.be.instanceof(Blob);

const reader = new FileReader();
const blobContent = await new Promise((resolve) => {
reader.onload = () => resolve(reader.result);
reader.readAsText(blob);
});

return JSON.parse(blobContent);
},
setupFakeTimers = function(now) {
return sinon.useFakeTimers({
now: now || Date.now(),
shouldAdvanceTime: true
});
},
triggerVisibilityHidden = function() {
Object.defineProperty(document, 'visibilityState', {
configurable: true,
get: () => 'hidden'
});
document.dispatchEvent(new Event('visibilitychange'));
};

var TestsCore = {
findCookie: findCookie,
Expand All @@ -651,8 +696,13 @@ var TestsCore = {
waitForCondition: waitForCondition,
fetchMockSuccess: fetchMockSuccess,
hasIdentifyReturned: hasIdentifyReturned,
getBeaconBatch: getBeaconBatch,
setupFakeTimers: setupFakeTimers,
triggerVisibilityHidden: triggerVisibilityHidden,
hasIdentityCallInflightReturned,
hasConfigurationReturned,
setupLoggerSpy,
hasIdentityResponseParsed,
};

export default TestsCore;
96 changes: 35 additions & 61 deletions test/src/tests-apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ const mParticle = window.mParticle;

describe('Api Client', () => {
beforeEach(() => {
mParticle.init(apiKey, mParticle.config);
});

afterEach(() => {
mParticle._resetForTests(MPConfig);
mParticle.init(apiKey, mParticle.config);
});

it('should update queued events with latest user info', done => {
it('should update queued events with latest user info', () => {
const event = {
messageType: Types.MessageType.PageEvent,
name: 'foo page',
Expand All @@ -30,89 +27,66 @@ describe('Api Client', () => {
customFlags: { 'foo-flag': 'foo-flag-val' },
};

expect(mParticle.getInstance()._Store).to.be.ok;
let sdkEvent1 = mParticle
.getInstance()
._ServerModel.createEventObject(event);
const mpInstance = mParticle.getInstance();
expect(mpInstance._Store).to.be.ok;

const sdkEvent1 = mpInstance._ServerModel.createEventObject(event);
const sdkEvent2 = mpInstance._ServerModel.createEventObject(event);

expect(sdkEvent1).to.be.ok;
expect(sdkEvent1.MPID).equal(null);
expect(sdkEvent1.UserAttributes).equal(null);
expect(sdkEvent1.UserIdentities).equal(null);
expect(sdkEvent1.ConsentState).equal(null);

let sdkEvent2 = mParticle
.getInstance()
._ServerModel.createEventObject(event);

expect(sdkEvent2).to.be.ok;
expect(sdkEvent2.MPID).equal(null);
expect(sdkEvent2.UserAttributes).equal(null);
expect(sdkEvent2.UserIdentities).equal(null);
expect(sdkEvent2.ConsentState).equal(null);

const consentState = mParticle
.getInstance()
.Consent.createConsentState();
const consentState = mpInstance.Consent.createConsentState();
consentState.addGDPRConsentState(
'foo',
mParticle
.getInstance()
.Consent.createGDPRConsent(
true,
10,
'foo document',
'foo location',
'foo hardware id'
)
mpInstance.Consent.createGDPRConsent(
true,
10,
'foo document',
'foo location',
'foo hardware id'
)
);

mParticle.getInstance().Identity.getCurrentUser = () => {
return {
getUserIdentities: () => {
return {
userIdentities: {
customerid: '1234567',
email: 'foo-email',
other: 'foo-other',
other2: 'foo-other2',
other3: 'foo-other3',
other4: 'foo-other4',
},
};
},
getAllUserAttributes: () => {
return {
'foo-user-attr': 'foo-attr-value',
'foo-user-attr-list': ['item1', 'item2'],
};
const mockUser = {
getUserIdentities: () => ({
userIdentities: {
customerid: '1234567',
email: 'foo-email',
other: 'foo-other',
other2: 'foo-other2',
other3: 'foo-other3',
other4: 'foo-other4',
},
getMPID: () => {
return '98765';
},
getConsentState: () => {
return consentState;
},
} as IMParticleUser;
};
}),
getAllUserAttributes: () => ({
'foo-user-attr': 'foo-attr-value',
'foo-user-attr-list': ['item1', 'item2'],
}),
getMPID: () => '98765',
getConsentState: () => consentState,
} as IMParticleUser;

mParticle
.getInstance()
._APIClient.appendUserInfoToEvents(
mParticle.Identity.getCurrentUser(),
[sdkEvent1, sdkEvent2]
);

mpInstance._APIClient.appendUserInfoToEvents(mockUser, [sdkEvent1, sdkEvent2]);

expect(sdkEvent1.UserIdentities.length).to.equal(6);
expect(Object.keys(sdkEvent2.UserAttributes).length).to.equal(2);
expect(Object.keys(sdkEvent1.UserAttributes).length).to.equal(2);
expect(sdkEvent1.MPID).to.equal('98765');
expect(sdkEvent1.ConsentState).to.not.equal(null);

expect(sdkEvent2.UserIdentities.length).to.equal(6);
expect(Object.keys(sdkEvent2.UserAttributes).length).to.equal(2);
expect(sdkEvent2.MPID).to.equal('98765');
expect(sdkEvent2.ConsentState).to.not.equal(null);

done();
});
});
50 changes: 22 additions & 28 deletions test/src/tests-audience-manager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sinon from 'sinon';
import fetchMock from 'fetch-mock/esm/client';
import { expect } from 'chai';
import { urls, apiKey, testMPID } from './config/constants';
import { urls, apiKey, testMPID, MPConfig } from './config/constants';
import Constants from '../../src/constants';
import { IMParticleInstanceManager, SDKLoggerApi } from '../../src/sdkRuntimeModels';
import AudienceManager, {
Expand All @@ -21,21 +21,11 @@ declare global {
const userAudienceUrl = `https://${Constants.DefaultBaseUrls.userAudienceUrl}${apiKey}/audience`;

describe('AudienceManager', () => {
before(function() {
fetchMock.restore();
sinon.restore();
});

beforeEach(function() {
fetchMock.restore();

beforeEach(() => {
window.mParticle._resetForTests(MPConfig);
fetchMockSuccess(urls.identify, {
mpid: testMPID, is_logged_in: false
});

window.mParticle.config.flags = {
eventBatchingIntervalMillis: 1000,
};
});

afterEach(() => {
Expand All @@ -59,12 +49,16 @@ describe('AudienceManager', () => {
});

describe('#sendGetUserAudienceRequest', () => {
const newLogger = new Logger(window.mParticle.config);
const audienceManager = new AudienceManager(
Constants.DefaultBaseUrls.userAudienceUrl,
apiKey,
newLogger
);
let newLogger: SDKLoggerApi;
let audienceManager: AudienceManager;
beforeEach(() => {
newLogger = new Logger(window.mParticle.config);
audienceManager = new AudienceManager(
Constants.DefaultBaseUrls.userAudienceUrl,
apiKey,
newLogger
);
});

const audienceMembershipServerResponse: IAudienceMembershipsServerResponse = {
ct: 1710441407914,
Expand Down Expand Up @@ -135,15 +129,15 @@ describe('AudienceManager', () => {
};

const expectedAudienceMembership2: IAudienceMemberships = {
currentAudienceMemberships: [
{
audience_id: 9876,
},
{
audience_id: 5432,
},
]
};
currentAudienceMemberships: [
{
audience_id: 9876,
},
{
audience_id: 5432,
},
]
};

fetchMock.get(newMPIDAudienceEndpoint, {
status: 200,
Expand Down
Loading
Loading