Skip to content

Commit c3bc4ff

Browse files
authored
Analytics algo d (#589)
1 parent a3bd5aa commit c3bc4ff

12 files changed

+119
-52
lines changed

__TESTS_BUNDLE_SIZE__/bundleSizeTestCases.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import importFromPackage from "./utils/stringGenerators/importFromPackage";
1515
const bundleSizeTestCases:ITestCase[] = [
1616
{
1717
name: 'Tests CloudinaryImage with Resize',
18-
sizeLimitInKB: 27,
18+
sizeLimitInKB: 28,
1919
importsArray: [
2020
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
2121
importFromDist('instance/Cloudinary', 'Cloudinary'),
@@ -24,7 +24,7 @@ const bundleSizeTestCases:ITestCase[] = [
2424
},
2525
{
2626
name: 'Tests CloudinaryImage with Resize and Adjust',
27-
sizeLimitInKB: 31,
27+
sizeLimitInKB: 32,
2828
importsArray: [
2929
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
3030
importFromDist('instance/Cloudinary', 'Cloudinary'),
@@ -34,7 +34,7 @@ const bundleSizeTestCases:ITestCase[] = [
3434
},
3535
{
3636
name: 'Tests CloudinaryImage with Resize, Adjust and Border',
37-
sizeLimitInKB: 33,
37+
sizeLimitInKB: 34,
3838
importsArray: [
3939
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
4040
importFromDist('instance/Cloudinary', 'Cloudinary'),
@@ -45,7 +45,7 @@ const bundleSizeTestCases:ITestCase[] = [
4545
},
4646
{
4747
name: 'Tests CloudinaryImage image with Resize, adjust and delivery',
48-
sizeLimitInKB: 33,
48+
sizeLimitInKB: 34,
4949
importsArray: [
5050
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
5151
importFromDist('instance/Cloudinary', 'Cloudinary'),
@@ -56,7 +56,7 @@ const bundleSizeTestCases:ITestCase[] = [
5656
},
5757
{
5858
name: 'Tests Overlay imports',
59-
sizeLimitInKB: 30,
59+
sizeLimitInKB: 31,
6060
importsArray: [
6161
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
6262
importFromDist('actions/overlay', 'Overlay'),

__TESTS__/unit/analytics/analytics.browser.test.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ describe('Add analytics to a URL from the browser', () => {
1414
}
1515
});
1616

17-
// BATAAB{NODE_VERSION}0
18-
// BATAAB{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
19-
// expect BATAABAA0
20-
expect(url).toContain('sample?_a=BATAABAA0'); // we shouldn't have a query param at all
17+
// DATAABAAZ{NODE_VERSION}0
18+
// DATAABAAZ{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
19+
// expect DATAABAAZAA0
20+
expect(url).toContain('sample?_a=DATAABAAZAA0'); // we shouldn't have a query param at all
2121
});
2222

2323
it('Uses default techVersion 0.0.0 when in browser for image with file extension', () => {
@@ -28,10 +28,10 @@ describe('Add analytics to a URL from the browser', () => {
2828
}
2929
});
3030

31-
// BATAAB{NODE_VERSION}0
32-
// BATAAB{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
33-
// expect BATAABAA0
34-
expect(url).toContain('sample.jpg?_a=BATAABAA0'); // we shouldn't have a query param at all
31+
// DATAABAAZ{NODE_VERSION}0
32+
// DATAABAAZ{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
33+
// expect DATAABAAZAA0
34+
expect(url).toContain('sample.jpg?_a=DATAABAAZAA0'); // we shouldn't have a query param at all
3535
});
3636

3737
it('Uses default techVersion 0.0.0 when in browser for video', () => {
@@ -42,10 +42,10 @@ describe('Add analytics to a URL from the browser', () => {
4242
}
4343
});
4444

45-
// BATAAB{NODE_VERSION}0
46-
// BATAAB{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
47-
// expect BATAABAA0
48-
expect(url).toContain('sample?_a=BATAABAA0'); // we shouldn't have a query param at all
45+
// DATAABAAZ{NODE_VERSION}0
46+
// DATAABAAZ{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
47+
// expect DATAABAAZAA0
48+
expect(url).toContain('sample?_a=DATAABAAZAA0'); // we shouldn't have a query param at all
4949
});
5050

5151

@@ -57,9 +57,9 @@ describe('Add analytics to a URL from the browser', () => {
5757
}
5858
});
5959

60-
// BATAAB{NODE_VERSION}0
61-
// BATAAB{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
62-
// expect BATAABAA0
63-
expect(url).toContain('sample.webm?_a=BATAABAA0'); // we shouldn't have a query param at all
60+
// DATAABAAZ{NODE_VERSION}0
61+
// DATAABAAZ{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
62+
// expect DATAABAAZAA0
63+
expect(url).toContain('sample.webm?_a=DATAABAAZAA0'); // we shouldn't have a query param at all
6464
});
6565
});

__TESTS__/unit/analytics/analytics.node.test.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ describe('Add analytics to a regular URL', () => {
4343
techVersion: '12.0.0',
4444
accessibility: true
4545
}
46-
})).toContain('?_a=BAZAlhAMD');
46+
})).toContain('?_a=DAZAlhAMZAAD');
4747
});
4848

4949
it('Test lazyload feature value', () => {
@@ -59,7 +59,7 @@ describe('Add analytics to a regular URL', () => {
5959
techVersion: '12.0.0',
6060
lazyload: true
6161
}
62-
})).toContain('?_a=BAZAlhAMC');
62+
})).toContain('?_a=DAZAlhAMZAAC');
6363
});
6464

6565
it('Test responsive feature value', () => {
@@ -75,7 +75,7 @@ describe('Add analytics to a regular URL', () => {
7575
techVersion: '12.0.0',
7676
responsive: true
7777
}
78-
})).toContain('?_a=BAZAlhAMA');
78+
})).toContain('?_a=DAZAlhAMZAAA');
7979
});
8080

8181
it('Test placeholder feature value', () => {
@@ -91,7 +91,7 @@ describe('Add analytics to a regular URL', () => {
9191
techVersion: '12.0.0',
9292
placeholder: true
9393
}
94-
})).toContain('?_a=BAZAlhAMB');
94+
})).toContain('?_a=DAZAlhAMZAAB');
9595
});
9696

9797
it('Test product letter', () => {
@@ -103,7 +103,33 @@ describe('Add analytics to a regular URL', () => {
103103
techVersion: '12.0.0',
104104
product: 'B'
105105
}
106-
})).toContain('?_a=BBZAlhAM0');
106+
})).toContain('?_a=DBZAlhAMZAA0');
107+
});
108+
109+
it('Test OS type letter', () => {
110+
const cldImage = createNewImageWithAnalytics('sample');
111+
expect(cldImage.toURL({
112+
trackedAnalytics: {
113+
sdkCode: 'Z',
114+
sdkSemver: '1.24.0',
115+
techVersion: '12.0.0',
116+
product: 'B',
117+
osType: 'A'
118+
}
119+
})).toContain('?_a=DBZAlhAMAAA0');
120+
});
121+
122+
it('Test OS version letters', () => {
123+
const cldImage = createNewImageWithAnalytics('sample');
124+
expect(cldImage.toURL({
125+
trackedAnalytics: {
126+
sdkCode: 'Z',
127+
sdkSemver: '1.24.0',
128+
techVersion: '12.0.0',
129+
product: 'B',
130+
osVersion: '16.3'
131+
}
132+
})).toContain('?_a=DBZAlhAMZQD0');
107133
});
108134

109135
it('Can be turned off', () => {

__TESTS__/unit/url/url.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ describe('Tests for URL configuration', () => {
115115
sdkSemver: '1.0.0'
116116
};
117117
const url = image.toURL({trackedAnalytics: analyticsOptions});
118-
expect(url).toEqual(`https://res.cloudinary.com/demo/image/upload/sample?_i=abcde&_a=BATAABAQ0`);
118+
expect(url).toEqual(`https://res.cloudinary.com/demo/image/upload/sample?_i=abcde&_a=DATAABAQZAA0`);
119119
});
120120

121121
it('Should include query params with analytics when passed as a string', function () {
@@ -126,7 +126,7 @@ describe('Tests for URL configuration', () => {
126126
sdkSemver: '1.0.0'
127127
};
128128
const url = image.toURL({trackedAnalytics: analyticsOptions});
129-
expect(url).toEqual(`https://res.cloudinary.com/demo/image/upload/sample?_i=abcde&_z=1234&_t=false&_a=BATAABAQ0`);
129+
expect(url).toEqual(`https://res.cloudinary.com/demo/image/upload/sample?_i=abcde&_z=1234&_t=false&_a=DATAABAQZAA0`);
130130
});
131131

132132
});

src/sdkAnalytics/encodeOSVersion.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {base64Map} from "./base64Map.js";
2+
3+
/**
4+
* @private
5+
* @description Encodes a semVer-like version string for OS
6+
* @param {string} semVer Input is x.y
7+
* @return {string} A string built from 2 characters of the base64 table that encode the semVer
8+
*/
9+
export function encodeOSVersion(semVer: string):string {
10+
const [major, minor] = semVer.split('.');
11+
12+
//convert to binary
13+
const binaryMajorVersion = parseInt(major).toString(2);
14+
const binaryMinorVersion = parseInt(minor).toString(2);
15+
16+
//pad to 6
17+
const paddedMajor = binaryMajorVersion.padStart(6, '0');
18+
const paddedMinor = binaryMinorVersion.padStart(6, '0');
19+
20+
return base64Map[paddedMajor]+base64Map[paddedMinor];
21+
}

src/sdkAnalytics/encodeVersion.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {base64Map} from "./base64Map.js";
22
import {stringPad} from "./stringPad.js";
33
import {reverseVersion} from "./reverseVersion.js";
4+
import {padVersion} from "./padVersion.js";
45

56
/**
67
* @private
@@ -14,20 +15,16 @@ export function encodeVersion(semVer: string):string {
1415
// support x.y or x.y.z by using 'parts' as a variable
1516
const parts = semVer.split('.').length;
1617
const paddedStringLength = parts * 6; // we pad to either 12 or 18 characters
17-
1818
// reverse (but don't mirror) the version. 1.5.15 -> 15.5.1
19+
const reversedSemver = reverseVersion(semVer);
1920
// Pad to two spaces, 15.5.1 -> 15.05.01
20-
const paddedReversedSemver = reverseVersion(semVer);
21-
21+
const paddedSemver = padVersion(reversedSemver);
2222
// turn 15.05.01 to a string '150501' then to a number 150501
23-
const num = parseInt(paddedReversedSemver.split('.').join(''));
24-
23+
const num = parseInt(paddedSemver.split('.').join(''));
2524
// Represent as binary, add left padding to 12 or 18 characters.
2625
// 150,501 -> 100100101111100101
27-
2826
let paddedBinary = num.toString(2);
2927
paddedBinary = stringPad(paddedBinary, paddedStringLength, '0');
30-
3128
// Stop in case an invalid version number was provided
3229
// paddedBinary must be built from sections of 6 bits
3330
if (paddedBinary.length % 6 !== 0) {

src/sdkAnalytics/getAnalyticsOptions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export function getAnalyticsOptions(options: ITrackedPropertiesThroughAnalytics)
1414
sdkCode: options.sdkCode,
1515
product: options.product,
1616
feature: '0',
17+
osType: options.osType,
18+
osVersion: options.osVersion,
1719
};
1820

1921
if (options.accessibility) {

src/sdkAnalytics/getSDKAnalyticsSignature.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {encodeVersion} from "./encodeVersion.js";
22
import {getAnalyticsOptions} from "./getAnalyticsOptions.js";
33
import {ITrackedPropertiesThroughAnalytics} from "./interfaces/ITrackedPropertiesThroughAnalytics.js";
44
import {packageVersion} from "../internal/utils/packageVersion.js";
5+
import {encodeOSVersion} from "./encodeOSVersion.js";
56

67
/**
78
* @private
@@ -31,6 +32,8 @@ function ensureShapeOfTrackedProperties(trackedAnalytics?: Partial<ITrackedPrope
3132
sdkCode: 'T', // Base code
3233
sdkSemver : packageVersion.split('-')[0], // remove -beta, -alpha or other tagged versions from the version string
3334
product: 'A',
35+
osType: 'Z',
36+
osVersion: '0.0',
3437
responsive: false,
3538
placeholder: false,
3639
lazyload: false,
@@ -69,14 +72,15 @@ export function getSDKAnalyticsSignature(_trackedAnalytics?: Partial<ITrackedPro
6972
const twoPartVersion = removePatchFromSemver(analyticsOptions.techVersion);
7073
const encodedSDKVersion = encodeVersion(analyticsOptions.sdkSemver);
7174
const encodedTechVersion = encodeVersion(twoPartVersion);
75+
const encodedOSVersion = encodeOSVersion(analyticsOptions.osVersion);
7276

7377
const featureCode = analyticsOptions.feature;
7478
const SDKCode = analyticsOptions.sdkCode;
75-
const product = analyticsOptions.product;
76-
const algoVersion = 'B'; // The algo version is determined here, it should not be an argument
79+
const {product, osType } = analyticsOptions;
80+
const algoVersion = 'D'; // The algo version is determined here, it should not be an argument
7781

7882

79-
return `${algoVersion}${product}${SDKCode}${encodedSDKVersion}${encodedTechVersion}${featureCode}`;
83+
return `${algoVersion}${product}${SDKCode}${encodedSDKVersion}${encodedTechVersion}${osType}${encodedOSVersion}${featureCode}`;
8084
} catch (e) {
8185
// Either SDK or Node versions were unparsable
8286
return 'E';

src/sdkAnalytics/interfaces/IAnalyticsOptions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ export interface IAnalyticsOptions {
77
sdkCode: string,
88
feature: string,
99
product: string,
10+
osType: string,
11+
osVersion: string,
1012
}

src/sdkAnalytics/interfaces/ITrackedPropertiesThroughAnalytics.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export interface ITrackedPropertiesThroughAnalytics {
99
techVersion: string; // Node Version or 1.0.0 by default
1010
sdkCode: string; // Constant for Base?
1111
product?: string; // Product code, 'A' for classic, 'B' for integrations
12+
osType?: string; // OS code, 'A' for android, 'B' for iOS, defaults to 'Z'
13+
osVersion?: string; // OS version,
1214
accessibility?: boolean; // Was accessibility used
1315
lazyload?: boolean; // Was lazy-load used
1416
responsive?: boolean; // Was responsive used

0 commit comments

Comments
 (0)