Skip to content

Commit

Permalink
Merge branch 'develop' into feat.googleads.ecom.spec.support.v2
Browse files Browse the repository at this point in the history
  • Loading branch information
yashasvibajpai authored Feb 28, 2024
2 parents dcf2d81 + 080155a commit 79d6766
Show file tree
Hide file tree
Showing 30 changed files with 18,545 additions and 4 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ testBookSuites/
tsconfig.build.tsbuildinfo
nativeSdkLoader.js
nativeSdkLoader.ts
packages/analytics-js-integrations/src/integrations/Ninetailed/sample-app/
assets/
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CONTRIBUTING.md
examples/chrome-extension/**/rudderAnalytics.js
examples/chrome-extension/**/foreground.js
examples/**/index.html
packages/analytics-js-integrations/src/integrations/Ninetailed/sample-app/
**/public/index.html

/.nx/cache
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ import {
SpotifyPixelDirectoryName,
CommandBarDisplayName,
CommandBarDirectoryName,
NinetailedDisplayName,
NinetailedDirectoryName,
} from './destinationNames';

// The destination directory name is used as the destination SDK file name in CDN
Expand Down Expand Up @@ -235,6 +237,7 @@ const destDisplayNamesToFileNamesMap: Record<string, string> = {
[SprigDisplayName]: SprigDirectoryName,
[SpotifyPixelDisplayName]: SpotifyPixelDirectoryName,
[CommandBarDisplayName]: CommandBarDirectoryName,
[NinetailedDisplayName]: NinetailedDirectoryName,
};

export { destDisplayNamesToFileNamesMap };
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,7 @@ export {
DISPLAY_NAME as CommandBarDisplayName,
DIR_NAME as CommandBarDirectoryName,
} from './integrations/CommandBar/constants';
export {
DISPLAY_NAME as NinetailedDisplayName,
DIR_NAME as NinetailedDirectoryName,
} from './integrations/Ninetailed/constants';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const DIR_NAME = 'Ninetailed';
const NAME = 'NINETAILED';
const DISPLAY_NAME = 'Ninetailed';

const DISPLAY_NAME_TO_DIR_NAME_MAP = { [DISPLAY_NAME]: DIR_NAME };
const CNameMapping = {
[NAME]: NAME,
Ninetailed: NAME,
ninetailed: NAME,
NineTailed: NAME,
};

export { NAME, CNameMapping, DISPLAY_NAME_TO_DIR_NAME_MAP, DISPLAY_NAME, DIR_NAME };
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ const clientToServerNames = {
TIKTOK_ADS: 'TikTok Ads',
ACTIVE_CAMPAIGN: 'ActiveCampaign',
SPRIG: 'Sprig',
SPOTIFYPIXEL:'Spotify Pixel',
COMMANDBAR:'CommandBar',
SPOTIFYPIXEL: 'Spotify Pixel',
COMMANDBAR: 'CommandBar',
NINETAILED: 'Ninetailed',
};

export { clientToServerNames };
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const configToIntNames = {
SPRIG: 'Sprig',
SPOTIFYPIXEL: 'SpotifyPixel',
COMMANDBAR: 'CommandBar',
NINETAILED: 'Ninetailed',
};

export { configToIntNames };
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ import { CNameMapping as ActiveCampaign } from '../../constants/integrations/Act
import { CNameMapping as Sprig } from '../../constants/integrations/Sprig/constants';
import { CNameMapping as SpotifyPixel } from '../../constants/integrations/SpotifyPixel/constants';
import { CNameMapping as CommandBar } from '../../constants/integrations/CommandBar/constants';
import { CNameMapping as Ninetailed } from '../../constants/integrations/Ninetailed/constants';

// for sdk side native integration identification
// add a mapping from common names to index.js exported key names as identified by Rudder
const commonNames = {
Expand Down Expand Up @@ -113,6 +115,7 @@ const commonNames = {
...Lytics,
...Mixpanel,
...MoEngage,
...Ninetailed,
...Optimizely,
...Pendo,
...PinterestTag,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import Ninetailed from '../../../src/integrations/Ninetailed/browser';

const destinationInfo = {
areTransformationsConnected: false,
destinationId: 'sample-destination-id',
};

describe('Ninetailed Intialization', () => {
let nt;
beforeEach(() => {
nt = new Ninetailed({}, { loglevel: 'DEBUG' }, destinationInfo);
});
afterEach(() => {
jest.restoreAllMocks();
window.ninetailed = undefined;
});
describe(' Is Loaded test Cases', () => {
// when ninetailed is not loaded from webapp
test('isLoaded should return False', () => {
expect(nt.isLoaded()).toBe(false);
});
// when ninetailed is loaded from webapp
test('isLoaded should return True', () => {
// since init call does not have any body so we are intialising the ninetailed object
window.ninetailed = {};
expect(nt.isLoaded()).toBeTruthy();
});
});
describe(' Is Ready test Cases', () => {
// when ninetailed is not loaded from webapp
test('isReady should return False', () => {
expect(nt.isReady()).toBe(false);
});
// when ninetailed is loaded from webapp
test('isReady should return True', () => {
// since init call does not have any body so we are intialising the ninetailed object
window.ninetailed = {};
expect(nt.isReady()).toBeTruthy();
});
});
});
describe('Ninetailed Event APIs', () => {
beforeEach(() => {
window.ninetailed = {};
});
describe('Page', () => {
let nt;
beforeEach(() => {
nt = new Ninetailed({}, { loglevel: 'DEBUG' }, destinationInfo);
window.ninetailed.page = jest.fn();
});
afterAll(() => {
jest.restoreAllMocks();
});
test('send pageview with properties', () => {
const properties = {
category: 'test cat',
path: '/test',
url: 'http://localhost:8080',
referrer: '',
title: 'test page',
testDimension: 'abc',
isRudderEvents: true,
};

nt.page({
message: {
context: {},
properties,
},
});
expect(window.ninetailed.page.mock.calls[0][0]).toEqual(properties);
});
test('send pageview without properties', () => {
nt.page({
message: {
context: {},
},
});
expect(window.ninetailed.page.mock.calls[0][0]).toEqual(undefined);
});
});
describe('Track', () => {
let nt;
beforeEach(() => {
nt = new Ninetailed({}, { loglevel: 'DEBUG' }, destinationInfo);
window.ninetailed.track = jest.fn();
});
afterAll(() => {
jest.restoreAllMocks();
});
test('Testing Track Event with event', () => {
const properties = {
customProp: 'testProp',
checkout_id: 'what is checkout id here??',
event_id: 'purchaseId',
order_id: 'transactionId',
value: 35.0,
shipping: 4.0,
isRudderEvents: true,
};
nt.track({
message: {
context: {},
event: 'Custom',
properties,
},
});
expect(window.ninetailed.track.mock.calls[0][0]).toEqual('Custom');
expect(window.ninetailed.track.mock.calls[0][1]).toEqual(properties);
});
test('Testing Track Event without event', () => {
nt.track({
message: {
context: {},
properties: {},
},
});
expect(window.ninetailed.track).not.toHaveBeenCalledWith();
});
});
describe('Identify', () => {
let nt;
beforeEach(() => {
nt = new Ninetailed({}, { loglevel: 'DEBUG' }, destinationInfo);
window.ninetailed.identify = jest.fn();
});
afterAll(() => {
jest.restoreAllMocks();
});
test('Testing Identify Custom Events', () => {
const traits = {
email: '[email protected]',
isRudderEvents: true,
};
nt.identify({
message: {
userId: 'rudder01',
context: {
traits,
},
},
});
expect(window.ninetailed.identify.mock.calls[0][0]).toEqual('rudder01');
expect(window.ninetailed.identify.mock.calls[0][1]).toEqual(traits);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* eslint-disable no-underscore-dangle */
/* eslint-disable class-methods-use-this */
import {
NAME,
DISPLAY_NAME,
} from '@rudderstack/analytics-js-common/constants/integrations/Ninetailed/constants';
import Logger from '../../utils/logger';

const logger = new Logger(DISPLAY_NAME);
class Ninetailed {
constructor(config, analytics, destinationInfo) {
if (analytics.logLevel) {
logger.setLogLevel(analytics.logLevel);
}
this.analytics = analytics;
this.name = NAME;
({
shouldApplyDeviceModeTransformation: this.shouldApplyDeviceModeTransformation,
propagateEventsUntransformedOnError: this.propagateEventsUntransformedOnError,
destinationId: this.destinationId,
} = destinationInfo ?? {});
}

init() {
// We expect the customer to load the SDK through NPM package
// Docs: https://docs.ninetailed.io/for-developers/experience-sdk/getting-started
}

isLoaded() {
return !!window.ninetailed;
}

isReady() {
return this.isLoaded();
}

identify(rudderElement) {
const { message } = rudderElement;
const { userId, context } = message;
const userTraits = { ...context?.traits };
// for userId: until we don't pass the id to ninetailed, it will not make server identify call but is accepting the data
window.ninetailed.identify(userId, userTraits);
}
track(rudderElement) {
const { message } = rudderElement;
const { properties, event } = message;
if (!event) {
logger.error('Event name is required');
return;
}
window.ninetailed.track(event, properties);
}
page(rudderElement) {
const { message } = rudderElement;
const { properties } = message;
if (properties) {
properties.url = window.location.href;
window.ninetailed.page(properties);
return;
}
window.ninetailed.page();
}
}

export default Ninetailed;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Ninetailed } from './browser';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
Loading

0 comments on commit 79d6766

Please sign in to comment.