Skip to content

Commit

Permalink
Analytics algo d (#589)
Browse files Browse the repository at this point in the history
  • Loading branch information
strausr authored Jan 17, 2024
1 parent a3bd5aa commit c3bc4ff
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 52 deletions.
10 changes: 5 additions & 5 deletions __TESTS_BUNDLE_SIZE__/bundleSizeTestCases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import importFromPackage from "./utils/stringGenerators/importFromPackage";
const bundleSizeTestCases:ITestCase[] = [
{
name: 'Tests CloudinaryImage with Resize',
sizeLimitInKB: 27,
sizeLimitInKB: 28,
importsArray: [
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
importFromDist('instance/Cloudinary', 'Cloudinary'),
Expand All @@ -24,7 +24,7 @@ const bundleSizeTestCases:ITestCase[] = [
},
{
name: 'Tests CloudinaryImage with Resize and Adjust',
sizeLimitInKB: 31,
sizeLimitInKB: 32,
importsArray: [
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
importFromDist('instance/Cloudinary', 'Cloudinary'),
Expand All @@ -34,7 +34,7 @@ const bundleSizeTestCases:ITestCase[] = [
},
{
name: 'Tests CloudinaryImage with Resize, Adjust and Border',
sizeLimitInKB: 33,
sizeLimitInKB: 34,
importsArray: [
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
importFromDist('instance/Cloudinary', 'Cloudinary'),
Expand All @@ -45,7 +45,7 @@ const bundleSizeTestCases:ITestCase[] = [
},
{
name: 'Tests CloudinaryImage image with Resize, adjust and delivery',
sizeLimitInKB: 33,
sizeLimitInKB: 34,
importsArray: [
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
importFromDist('instance/Cloudinary', 'Cloudinary'),
Expand All @@ -56,7 +56,7 @@ const bundleSizeTestCases:ITestCase[] = [
},
{
name: 'Tests Overlay imports',
sizeLimitInKB: 30,
sizeLimitInKB: 31,
importsArray: [
importFromDist('assets/CloudinaryImage', 'CloudinaryImage'),
importFromDist('actions/overlay', 'Overlay'),
Expand Down
32 changes: 16 additions & 16 deletions __TESTS__/unit/analytics/analytics.browser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ describe('Add analytics to a URL from the browser', () => {
}
});

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

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

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

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

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


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

// BATAAB{NODE_VERSION}0
// BATAAB{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
// expect BATAABAA0
expect(url).toContain('sample.webm?_a=BATAABAA0'); // we shouldn't have a query param at all
// DATAABAAZ{NODE_VERSION}0
// DATAABAAZ{AA}0 -> we expect nodeVersion to be 0.0.0 in browser (Since it's missing)
// expect DATAABAAZAA0
expect(url).toContain('sample.webm?_a=DATAABAAZAA0'); // we shouldn't have a query param at all
});
});
36 changes: 31 additions & 5 deletions __TESTS__/unit/analytics/analytics.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('Add analytics to a regular URL', () => {
techVersion: '12.0.0',
accessibility: true
}
})).toContain('?_a=BAZAlhAMD');
})).toContain('?_a=DAZAlhAMZAAD');
});

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

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

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

it('Test product letter', () => {
Expand All @@ -103,7 +103,33 @@ describe('Add analytics to a regular URL', () => {
techVersion: '12.0.0',
product: 'B'
}
})).toContain('?_a=BBZAlhAM0');
})).toContain('?_a=DBZAlhAMZAA0');
});

it('Test OS type letter', () => {
const cldImage = createNewImageWithAnalytics('sample');
expect(cldImage.toURL({
trackedAnalytics: {
sdkCode: 'Z',
sdkSemver: '1.24.0',
techVersion: '12.0.0',
product: 'B',
osType: 'A'
}
})).toContain('?_a=DBZAlhAMAAA0');
});

it('Test OS version letters', () => {
const cldImage = createNewImageWithAnalytics('sample');
expect(cldImage.toURL({
trackedAnalytics: {
sdkCode: 'Z',
sdkSemver: '1.24.0',
techVersion: '12.0.0',
product: 'B',
osVersion: '16.3'
}
})).toContain('?_a=DBZAlhAMZQD0');
});

it('Can be turned off', () => {
Expand Down
4 changes: 2 additions & 2 deletions __TESTS__/unit/url/url.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ describe('Tests for URL configuration', () => {
sdkSemver: '1.0.0'
};
const url = image.toURL({trackedAnalytics: analyticsOptions});
expect(url).toEqual(`https://res.cloudinary.com/demo/image/upload/sample?_i=abcde&_a=BATAABAQ0`);
expect(url).toEqual(`https://res.cloudinary.com/demo/image/upload/sample?_i=abcde&_a=DATAABAQZAA0`);
});

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

});
21 changes: 21 additions & 0 deletions src/sdkAnalytics/encodeOSVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {base64Map} from "./base64Map.js";

/**
* @private
* @description Encodes a semVer-like version string for OS
* @param {string} semVer Input is x.y
* @return {string} A string built from 2 characters of the base64 table that encode the semVer
*/
export function encodeOSVersion(semVer: string):string {
const [major, minor] = semVer.split('.');

//convert to binary
const binaryMajorVersion = parseInt(major).toString(2);
const binaryMinorVersion = parseInt(minor).toString(2);

//pad to 6
const paddedMajor = binaryMajorVersion.padStart(6, '0');
const paddedMinor = binaryMinorVersion.padStart(6, '0');

return base64Map[paddedMajor]+base64Map[paddedMinor];
}
11 changes: 4 additions & 7 deletions src/sdkAnalytics/encodeVersion.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {base64Map} from "./base64Map.js";
import {stringPad} from "./stringPad.js";
import {reverseVersion} from "./reverseVersion.js";
import {padVersion} from "./padVersion.js";

/**
* @private
Expand All @@ -14,20 +15,16 @@ export function encodeVersion(semVer: string):string {
// support x.y or x.y.z by using 'parts' as a variable
const parts = semVer.split('.').length;
const paddedStringLength = parts * 6; // we pad to either 12 or 18 characters

// reverse (but don't mirror) the version. 1.5.15 -> 15.5.1
const reversedSemver = reverseVersion(semVer);
// Pad to two spaces, 15.5.1 -> 15.05.01
const paddedReversedSemver = reverseVersion(semVer);

const paddedSemver = padVersion(reversedSemver);
// turn 15.05.01 to a string '150501' then to a number 150501
const num = parseInt(paddedReversedSemver.split('.').join(''));

const num = parseInt(paddedSemver.split('.').join(''));
// Represent as binary, add left padding to 12 or 18 characters.
// 150,501 -> 100100101111100101

let paddedBinary = num.toString(2);
paddedBinary = stringPad(paddedBinary, paddedStringLength, '0');

// Stop in case an invalid version number was provided
// paddedBinary must be built from sections of 6 bits
if (paddedBinary.length % 6 !== 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/sdkAnalytics/getAnalyticsOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export function getAnalyticsOptions(options: ITrackedPropertiesThroughAnalytics)
sdkCode: options.sdkCode,
product: options.product,
feature: '0',
osType: options.osType,
osVersion: options.osVersion,
};

if (options.accessibility) {
Expand Down
10 changes: 7 additions & 3 deletions src/sdkAnalytics/getSDKAnalyticsSignature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {encodeVersion} from "./encodeVersion.js";
import {getAnalyticsOptions} from "./getAnalyticsOptions.js";
import {ITrackedPropertiesThroughAnalytics} from "./interfaces/ITrackedPropertiesThroughAnalytics.js";
import {packageVersion} from "../internal/utils/packageVersion.js";
import {encodeOSVersion} from "./encodeOSVersion.js";

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

const featureCode = analyticsOptions.feature;
const SDKCode = analyticsOptions.sdkCode;
const product = analyticsOptions.product;
const algoVersion = 'B'; // The algo version is determined here, it should not be an argument
const {product, osType } = analyticsOptions;
const algoVersion = 'D'; // The algo version is determined here, it should not be an argument


return `${algoVersion}${product}${SDKCode}${encodedSDKVersion}${encodedTechVersion}${featureCode}`;
return `${algoVersion}${product}${SDKCode}${encodedSDKVersion}${encodedTechVersion}${osType}${encodedOSVersion}${featureCode}`;
} catch (e) {
// Either SDK or Node versions were unparsable
return 'E';
Expand Down
2 changes: 2 additions & 0 deletions src/sdkAnalytics/interfaces/IAnalyticsOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ export interface IAnalyticsOptions {
sdkCode: string,
feature: string,
product: string,
osType: string,
osVersion: string,
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export interface ITrackedPropertiesThroughAnalytics {
techVersion: string; // Node Version or 1.0.0 by default
sdkCode: string; // Constant for Base?
product?: string; // Product code, 'A' for classic, 'B' for integrations
osType?: string; // OS code, 'A' for android, 'B' for iOS, defaults to 'Z'
osVersion?: string; // OS version,
accessibility?: boolean; // Was accessibility used
lazyload?: boolean; // Was lazy-load used
responsive?: boolean; // Was responsive used
Expand Down
25 changes: 25 additions & 0 deletions src/sdkAnalytics/padVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {stringPad} from "./stringPad.js";

/**
* @private
* @description Pads each segment with '0' so they have length of 2
* @param {string} semVer Input can be either x.y.z or x.y
* @return {string} in the form of xx.yy.zz (
*/
export function padVersion(semVer: string): string {
if (semVer.split('.').length < 2) {
throw new Error('invalid semVer, must have at least two segments');
}

// Split by '.', reverse, create new array with padded values and concat it together
return semVer.split('.').map((segment) => {
// try to cast to number
const asNumber = +segment;

if (isNaN(asNumber) || asNumber < 0) {
throw 'Invalid version number provided';
}

return stringPad(segment, 2, '0');
}).join('.');
}
16 changes: 2 additions & 14 deletions src/sdkAnalytics/reverseVersion.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import {stringPad} from "./stringPad.js";

/**
* @private
* @description Reverses the version positions, x.y.z turns to z.y.x
* Pads each segment with '0' so they have length of 2
* Example: 1.2.3 -> 03.02.01
* @param {string} semVer Input can be either x.y.z or x.y
* @return {string} in the form of zz.yy.xx (
Expand All @@ -12,16 +10,6 @@ export function reverseVersion(semVer: string): string {
if (semVer.split('.').length < 2) {
throw new Error('invalid semVer, must have at least two segments');
}

// Split by '.', reverse, create new array with padded values and concat it together
return semVer.split('.').reverse().map((segment) => {
// try to cast to number
const asNumber = +segment;

if (isNaN(asNumber) || asNumber < 0) {
throw 'Invalid version number provided';
}

return stringPad(segment, 2, '0');
}).join('.');
// Split by '.', reverse, create new array
return semVer.split('.').reverse().join('.');
}

0 comments on commit c3bc4ff

Please sign in to comment.