Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.

Commit 77f8361

Browse files
committed
Add tests
1 parent 88ce785 commit 77f8361

File tree

7 files changed

+162
-21
lines changed

7 files changed

+162
-21
lines changed

@types/index.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
function warn(...args: any): void;
22
export function verifyInit(): boolean;
3-
export function init(partnerId: string): void;
4-
export function track(conversionId: string): void;
3+
export function init(partnerId: string, subDomain?: string, disabled?: boolean): void;
4+
export function track(conversionId?: string, partnerId?: string, subDomain?: string): void;
55

66
export default LinkedInTag;

__tests__/index/classimport.test.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {LinkedInTag} from '../../src/index.js';
2+
const tag = new LinkedInTag()
3+
4+
describe('Happy path', () => {
5+
const partnerId = '0987654321';
6+
const conversionId = '123456789';
7+
const subDomain = 'dc';
8+
9+
beforeAll(() => {
10+
tag.init(partnerId, subDomain, false);
11+
});
12+
13+
document.body.innerHTML = '<script src="index.js" />';
14+
15+
it('init() should be properly initialized', () => {
16+
expect(tag.disabled).toEqual(false);
17+
expect(tag.initialized).toEqual(true);
18+
expect(tag.partnerId).toEqual(partnerId);
19+
});
20+
21+
it('init() should insert the LinkedIn insight.min.js script', () => {
22+
// Extract all script src strings from the DOM
23+
let scripts = [];
24+
const scriptElms = document.getElementsByTagName('script');
25+
Array.prototype.slice.call(scriptElms).forEach((elm) => { scripts.push(elm.src); });
26+
27+
// Assert if it correctly inserted the LinkedIn script
28+
expect(scripts).toEqual(
29+
expect.arrayContaining(['https://snap.licdn.com/li.lms-analytics/insight.min.js'])
30+
);
31+
});
32+
33+
it('track() should create an image with proper src', () => {
34+
const elm = tag.track(conversionId);
35+
36+
expect(elm.src).toEqual(expect.stringContaining(partnerId));
37+
expect(elm.src).toEqual(expect.stringContaining(subDomain));
38+
expect(elm.src).toEqual(expect.stringContaining(conversionId));
39+
});
40+
});

__tests__/index/defaults.test.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import LinkedInTag from '../../src/index.js';
2+
3+
beforeAll(() => {
4+
jest.mock('browser-or-node', () => ({ isBrowser: true }));
5+
});
6+
7+
describe('Check for proper defaults', () => {
8+
const partnerId = '1234';
9+
beforeAll(() => {
10+
LinkedInTag.init(partnerId);
11+
});
12+
13+
document.body.innerHTML = '<script src="" />'
14+
15+
it('init() should not be initialized', () => {
16+
expect(LinkedInTag.initialized).toEqual(true);
17+
expect(LinkedInTag.disabled).toEqual(false);
18+
});
19+
20+
it('track() should create an image with proper src', () => {
21+
const elm = LinkedInTag.track();
22+
23+
expect(elm.src).toEqual(expect.stringContaining(partnerId));
24+
expect(elm.src).toEqual(expect.stringContaining('dc'));
25+
});
26+
});

__tests__/index/disabled.test.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import LinkedInTag from '../../src/index.js';
2+
3+
describe('Disabled', () => {
4+
beforeAll(() => {
5+
LinkedInTag.init('1234', null, true);
6+
});
7+
8+
document.body.innerHTML = '<script src="" />';
9+
10+
it('init() should be properly initialized', () => {
11+
expect(LinkedInTag.initialized).toEqual(false);
12+
expect(LinkedInTag.disabled).toEqual(true);
13+
});
14+
15+
it('init() should not insert the LinkedIn insight.min.js script', () => {
16+
// Extract all script src strings from the DOM
17+
let scripts = [];
18+
const scriptElms = document.getElementsByTagName('script');
19+
Array.prototype.slice.call(scriptElms).forEach((elm) => { scripts.push(elm.src); });
20+
21+
// Assert if it correctly skipped the insertion
22+
expect(scripts).not.toEqual(
23+
expect.arrayContaining(['https://snap.licdn.com/li.lms-analytics/insight.min.js'])
24+
);
25+
});
26+
27+
it('track() should not do anything', () => {
28+
const elm = LinkedInTag.track();
29+
expect(elm).toBeUndefined();
30+
});
31+
});

__tests__/index/happypath.test.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import LinkedInTag from '../../src/index.js';
2+
3+
describe('Happy path', () => {
4+
const partnerId = '0987654321';
5+
const conversionId = '123456789';
6+
const subDomain = 'dc';
7+
8+
beforeAll(() => {
9+
LinkedInTag.init(partnerId, subDomain, false);
10+
});
11+
12+
document.body.innerHTML = '<script src="index.js" />';
13+
14+
it('init() should be properly initialized', () => {
15+
expect(LinkedInTag.disabled).toEqual(false);
16+
expect(LinkedInTag.initialized).toEqual(true);
17+
expect(LinkedInTag.partnerId).toEqual(partnerId);
18+
});
19+
20+
it('init() should insert the LinkedIn insight.min.js script', () => {
21+
// Extract all script src strings from the DOM
22+
let scripts = [];
23+
const scriptElms = document.getElementsByTagName('script');
24+
Array.prototype.slice.call(scriptElms).forEach((elm) => { scripts.push(elm.src); });
25+
26+
// Assert if it correctly inserted the LinkedIn script
27+
expect(scripts).toEqual(
28+
expect.arrayContaining(['https://snap.licdn.com/li.lms-analytics/insight.min.js'])
29+
);
30+
});
31+
32+
it('track() should create an image with proper src', () => {
33+
const elm = LinkedInTag.track(conversionId);
34+
35+
expect(elm.src).toEqual(expect.stringContaining(partnerId));
36+
expect(elm.src).toEqual(expect.stringContaining(subDomain));
37+
expect(elm.src).toEqual(expect.stringContaining(conversionId));
38+
});
39+
});

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"scripts": {
2727
"bundle": "npm run lint && export NODE_ENV=production && webpack --config webpack.config.dist.js",
2828
"lint": "eslint src/",
29-
"clean": "rm -rf node_modules"
29+
"clean": "rm -rf node_modules",
30+
"test": "jest"
3031
},
3132
"types": "./@types/index.d.ts",
3233
"dependencies": {
@@ -39,6 +40,7 @@
3940
"babel-loader": "^8.2.1",
4041
"eslint": "^7.14.0",
4142
"eslint-plugin-import": "^2.20.0",
43+
"jest": "^26.6.3",
4244
"webpack": "^5.6.0",
4345
"webpack-cli": "^4.2.0"
4446
}

src/index.js

+21-18
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import { isBrowser } from 'browser-or-node';
77
* @author Jelle Klaver
88
*/
99

10-
class LinkedInTag {
10+
export class LinkedInTag {
1111
constructor() {
1212
this.initialized = false;
13-
this.disabled = false;
13+
this.disabled = !isBrowser;
1414
this.partnerId = '';
1515
this.subDomain = 'dc';
1616
}
@@ -45,18 +45,19 @@ class LinkedInTag {
4545
* It is stated like '_linkedin_partner_id = "123456";' on the second row
4646
* of the code they provide. The "123456" is your partnerId.
4747
*
48-
* @param {string} partnerId - The partner id received from LinkedIn.
49-
* @param {string} subDomain - The the subDomain to use. Default 'dc'
48+
* @param {string} partnerId - Partner id received from LinkedIn.
49+
* @param {string} [subDomain='dc'] - Sub domain to use. Default 'dc'
50+
* @param {boolean} [disabled=!isBrowser] - Disable all tracking, e.g. for SSR or when the user disallows tracking
5051
*
5152
* @return void
5253
*/
53-
init(partnerId, subDomain, disabled = !isBrowser) {
54-
this.disabled = disabled;
55-
this.partnerId = String(partnerId);
54+
init(partnerId, subDomain, disabled) {
55+
this.partnerId = partnerId;
56+
this.subDomain = subDomain || this.subDomain;
57+
if(disabled != null) this.disabled = disabled;
5658

57-
if (disabled) return;
58-
if (!this.partnerId) this.warn('Partner id is empty.');
59-
if (subDomain) this.subDomain = subDomain;
59+
if (this.disabled) return;
60+
if (!this.partnerId) this.warn('Partner id is required.');
6061

6162
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
6263
window._linkedin_data_partner_ids.push(partnerId);
@@ -78,31 +79,33 @@ class LinkedInTag {
7879
* an event-specific pixel. The src url they provide holds a query variable
7980
* 'conversionId=123456'. This 123456 is your conversion id.
8081
*
81-
* @param {string?} conversionId - The conversion ID received from LinkedIn
82-
* @param {string?} partnerId - Override the partnerId for this specific tracking operation
83-
* @param {string?} subDomain - Override the subDomain for this specific tracking operation
82+
* @param {string} [conversionId] - The conversion ID received from LinkedIn
83+
* @param {string} [partnerId] - Override the partnerId for this specific tracking operation
84+
* @param {string} [subDomain] - Override the subDomain for this specific tracking operation
8485
*
85-
* @return void
86+
* @return [element]
8687
*/
8788
track(conversionId, partnerId, subDomain) {
88-
if (!this.verifyInit() || this.disabled) return this.warn('Called `track` before calling `init`.');
89+
if (this.disabled) return;
90+
if (!this.verifyInit()) return this.warn('You must call `init` before calling `track`.');
8991

9092
partnerId = partnerId || this.partnerId || window._linkedin_data_partner_ids[0];
91-
if (!partnerId) return this.warn('Partner id is empty.');
92-
9393
subDomain = subDomain || this.subDomain;
9494

9595
let url = `https://${subDomain}.ads.linkedin.com/collect/?pid=${partnerId}&fmt=gif`;
9696
if(conversionId) {
9797
url = `${url}&conversionId=${conversionId}`;
9898
}
9999

100-
// It creates an element without actually posting it to the page. The call is already made to the linkedin servers and will be registered
100+
// It creates an element without actually adding it to the page DOM.
101+
// The call is already made to the LinkedIn servers and will be registered.
101102
const element = document.createElement('img');
102103
element.alt = '';
103104
element.height = 1;
104105
element.width = 1;
105106
element.src = url;
107+
108+
return element;
106109
}
107110
}
108111

0 commit comments

Comments
 (0)