Skip to content

Commit 56f155a

Browse files
Feature/add analytics to cld base (#351)
Add analytics support.
1 parent fb3b4fe commit 56f155a

38 files changed

+554
-41
lines changed

__TESTS__/TestUtils/createCloudinaryFile.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import {CloudinaryFile} from "../../src";
66
*
77
*/
88
function createNewFile(publicID?: string, cloudConfig?: ICloudConfig, urlConfig?:IURLConfig): CloudinaryFile {
9-
return new CloudinaryFile(publicID, Object.assign({
10-
cloudName: 'demo'
11-
}, cloudConfig), urlConfig);
9+
const newCloudConfig = { cloudName: 'demo', ...cloudConfig};
10+
const newUrlConfig = { analytics: false, ...urlConfig};
11+
12+
return new CloudinaryFile(publicID, newCloudConfig, newUrlConfig);
1213
}
1314

1415
export {createNewFile};

__TESTS__/TestUtils/createCloudinaryImage.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import IURLConfig from "../../src/config/interfaces/Config/IURLConfig";
66
*
77
*/
88
function createNewImage(publicID?: string, cloudConfig?: ICloudConfig, urlConfig?:IURLConfig): CloudinaryImage {
9-
return new CloudinaryImage(publicID, Object.assign({
10-
cloudName: 'demo'
11-
}, cloudConfig), urlConfig);
9+
const newCloudConfig = { cloudName: 'demo', ...cloudConfig};
10+
const newUrlConfig = { analytics: false, ...urlConfig};
11+
12+
return new CloudinaryImage(publicID, newCloudConfig, newUrlConfig);
1213
}
1314

1415
export {createNewImage};
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import {CloudinaryVideo} from "../../src/assets/CloudinaryVideo";
2+
import ICloudConfig from "../../src/config/interfaces/Config/ICloudConfig";
3+
import IURLConfig from "../../src/config/interfaces/Config/IURLConfig";
24

35
/**
46
*
57
*/
6-
function createNewVideo(publicID = 'sample'): CloudinaryVideo {
7-
return new CloudinaryVideo(publicID, {
8-
cloudName: 'demo'
9-
});
8+
function createNewVideo(publicID = 'sample', cloudConfig?: ICloudConfig, urlConfig?:IURLConfig): CloudinaryVideo {
9+
const newCloudConfig = { cloudName: 'demo', ...cloudConfig};
10+
const newUrlConfig = { analytics: false, ...urlConfig};
11+
12+
return new CloudinaryVideo(publicID, newCloudConfig, newUrlConfig);
1013
}
1114

1215
export {createNewVideo};

__TESTS__/unit/Instance/Cloudinary.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ describe('Tests for Cloudinary instance', () => {
77
const cloudinary = new Cloudinary(new CloudinaryConfig({
88
cloud: {
99
cloudName:'demoInInstance'
10+
},
11+
url: {
12+
analytics: false
1013
}
1114
}));
1215
const tImage = cloudinary.image('sample');
@@ -23,6 +26,9 @@ describe('Tests for Cloudinary instance', () => {
2326
cloudinary.setConfig(new CloudinaryConfig({
2427
cloud: {
2528
cloudName:'demoInInstance'
29+
},
30+
url: {
31+
analytics: false
2632
}
2733
}));
2834

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
5+
6+
7+
import {createNewImageWithAnalytics} from "./testUtils/createNewImageWithAnalytics";
8+
9+
10+
describe('Add analytics to a URL from the browser', () => {
11+
it('Uses default techVersion 0.0.0 when in browser', () => {
12+
const cldImage = createNewImageWithAnalytics('sample');
13+
14+
// ATAAB{NODE_VERSION}0
15+
// ATAAB{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
16+
// expect ATAABAA0
17+
expect(cldImage.toURL({
18+
trackedAnalytics: {
19+
sdkSemver: '1.0.0'
20+
}
21+
})).toContain('ATAABAA0'); // we shouldn't have a query param at all
22+
});
23+
});
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/**
2+
* @jest-environment node
3+
*/
4+
5+
6+
import pkg from '../../../src/package.json';
7+
import {createNewImageWithAnalytics} from "./testUtils/createNewImageWithAnalytics";
8+
9+
describe('Add analytics to a regular URL', () => {
10+
it('Works with default values', () => {
11+
const cldImage = createNewImageWithAnalytics('sample');
12+
13+
// Generate a URL without any special configuration
14+
const sigFromDefaultValues = cldImage.toURL().split('?')[1];
15+
// Generate a URL with provided sdkSemver and techVersion, but we're using the values that should be given by default
16+
const sigFromExplicitPackageVersion = cldImage.toURL({
17+
trackedAnalytics: {
18+
sdkSemver: pkg.version.split('-')[0], // remove -beta, -alpha or other tagged versions from the version string
19+
techVersion: process.versions.node
20+
}
21+
}).split('?')[1];
22+
23+
// AT AAB WE 0
24+
expect(sigFromDefaultValues).not.toBeUndefined();
25+
expect(sigFromDefaultValues).toBe(sigFromExplicitPackageVersion);
26+
});
27+
28+
29+
it('Can overwrite default values', () => {
30+
const cldImage = createNewImageWithAnalytics('sample');
31+
// AZ -> Algo A, SDK Code is Z
32+
// Alh -> 1.24.0 from package.json
33+
// AM -> 12.0.0 Underlying tech
34+
// D -> Accessibility
35+
expect(cldImage.toURL({
36+
trackedAnalytics: {
37+
sdkCode: 'Z', // arbitrary, just show we can overwrite it
38+
sdkSemver: '1.24.0', // If not specified, this is taken from package.json
39+
techVersion: '12.0.0',
40+
accessibility: true
41+
}
42+
})).toContain('?_a=AZAlhAMD');
43+
});
44+
45+
it('Test lazyload feature value', () => {
46+
const cldImage = createNewImageWithAnalytics('sample');
47+
// AZ -> Algo A, SDK Code is Z
48+
// Alh -> 1.24.0 from package.json
49+
// AM -> 12.0.0 Underlying tech
50+
// C -> lazyload
51+
expect(cldImage.toURL({
52+
trackedAnalytics: {
53+
sdkCode: 'Z',
54+
sdkSemver: '1.24.0',
55+
techVersion: '12.0.0',
56+
lazyload: true
57+
}
58+
})).toContain('?_a=AZAlhAMC');
59+
});
60+
61+
it('Test responsive feature value', () => {
62+
const cldImage = createNewImageWithAnalytics('sample');
63+
// AZ -> Algo A, SDK Code is Z
64+
// Alh -> 1.24.0 from package.json
65+
// AM -> 12.0.0 Underlying tech
66+
// A -> responsive
67+
expect(cldImage.toURL({
68+
trackedAnalytics: {
69+
sdkCode: 'Z',
70+
sdkSemver: '1.24.0',
71+
techVersion: '12.0.0',
72+
responsive: true
73+
}
74+
})).toContain('?_a=AZAlhAMA');
75+
});
76+
77+
it('Test placeholder feature value', () => {
78+
const cldImage = createNewImageWithAnalytics('sample');
79+
// AZ -> Algo A, SDK Code is Z
80+
// Alh -> 1.24.0 from package.json
81+
// AM -> 12.0.0 Underlying tech
82+
// B -> placeholder
83+
expect(cldImage.toURL({
84+
trackedAnalytics: {
85+
sdkCode: 'Z',
86+
sdkSemver: '1.24.0',
87+
techVersion: '12.0.0',
88+
placeholder: true
89+
}
90+
})).toContain('?_a=AZAlhAMB');
91+
});
92+
93+
it('Can be turned off', () => {
94+
const cldImage = createNewImageWithAnalytics('sample', {}, {
95+
analytics: false
96+
});
97+
98+
expect(cldImage.toURL({
99+
trackedAnalytics: {
100+
sdkCode: 'M',
101+
sdkSemver: '1.24.0', // If not specified, this is taken from package.json
102+
techVersion: '12.0.0'
103+
}
104+
})).not.toContain('?'); // we shouldn't have a query param at all
105+
});
106+
107+
108+
it('Expect to error for very large versions', () => {
109+
const cldImage = createNewImageWithAnalytics('sample');
110+
111+
expect(cldImage.toURL({
112+
trackedAnalytics: {
113+
sdkSemver: '50.50.50' // If not specified, this is taken from package.json
114+
}
115+
})).toContain('?_a=E');
116+
});
117+
118+
it('Expect to error for invalid versions', () => {
119+
const cldImage = createNewImageWithAnalytics('sample');
120+
// All these cases should error the analytics function
121+
['abc', '1', 'foo.bar', '-55'].forEach((version) => {
122+
// Try catch to provide a a meaningful error message
123+
// This will fail the test and print what case failed exactly
124+
try {
125+
expect(cldImage.toURL({
126+
trackedAnalytics: {
127+
sdkSemver: version // If not specified, this is taken from package.json
128+
}
129+
})).toContain('?_a=E');
130+
} catch (e) {
131+
e.message = `Error for {{${version}}} ${e.message}`;
132+
throw e;
133+
}
134+
});
135+
});
136+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import ICloudConfig from "../../../../src/config/interfaces/Config/ICloudConfig";
2+
import IURLConfig from "../../../../src/config/interfaces/Config/IURLConfig";
3+
import {CloudinaryImage} from "../../../../src";
4+
import {createNewImage} from "../../../TestUtils/createCloudinaryImage";
5+
6+
/**
7+
* Create a new CloudinaryImage with analytics turned on by default
8+
*/
9+
export function createNewImageWithAnalytics(publicID: string, cloudConfig?: ICloudConfig, urlConfig?: IURLConfig): CloudinaryImage {
10+
return createNewImage(publicID, {cloudName: 'demo'}, {analytics: true, ...urlConfig});
11+
}

__TESTS__/unit/asset/CloudinaryFile.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {CloudinaryFile} from "../../../src/assets/CloudinaryFile";
33
describe('Tests for CloudinaryFile', () => {
44
let cloudinaryFile: CloudinaryFile = null;
55
beforeEach(() => {
6-
cloudinaryFile = new CloudinaryFile('sample', {cloudName:'demo'});
6+
cloudinaryFile = new CloudinaryFile('sample', {cloudName:'demo'}, {analytics:false});
77
});
88

99
it('Instantiates a cloudinaryFile', () => {

__TESTS__/unit/scripts/createEntryPoints.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe('Tests for createEntryPoints', () => {
1414
});
1515

1616
it ('Creates the main entrypoint to the project', () => {
17-
createEntryPoints.createMainEntryPoint();
17+
createEntryPoints.copyPackageJson();
1818
const mainPackageJson = JSON.parse(fs.readFileSync('./dist/package.json', 'utf-8'));
1919

2020
// Expect the right main entrypoint

__TESTS__/unit/url/url.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ describe('Tests for URL configuration', () => {
8585
});
8686

8787
it('Should support an external signature', () => {
88-
const image = new CloudinaryImage('sample', {cloudName: 'demo'}, {});
88+
const image = createNewImage('sample');
8989
const signature = "some-signature";
9090

9191
image.setSignature(signature);

0 commit comments

Comments
 (0)