Skip to content

Commit 29ff442

Browse files
DimaIntentIQdmytro-poeyvazahmadzadaEyvaz Ahmadzadapatmmccann
authored
IntentIq ID Module: AB group updates, bug fixes (prebid#14136)
* 0.33 version * AGT-705: AB group by TC (prebid#49) * AGT-705: AB group by TC * Remove extra param in utils method * AGT-705: abTestUuid and abPercentage by user * AGT-705: Fix tests, refactoring * AGT-705: Changes after review * text changes --------- Co-authored-by: DimaIntentIQ <dmytro.piskun@intentiq.com> * partner callback encrypted string (prebid#47) Co-authored-by: Eyvaz Ahmadzada <eyvazahmadzada@gmail.com> Co-authored-by: DimaIntentIQ <139111483+DimaIntentIQ@users.noreply.github.com> * Change communication way between modules. (prebid#50) * Change communication way between modules. * Log error refactoring * fix waiting for CH in tests * move action file to action/save folder * fix "success" process in getting Partner data from global object * Share abGroup between modules thru a global object instead of using function in both ones * fix failed test in CI/CD * group related updates * add new parameters related to group * Analytical adapter config updates, GAM fixes --------- Co-authored-by: dmytro-po <dmytro.po@intentiq.com> Co-authored-by: Eyvaz <62054743+eyvazahmadzada@users.noreply.github.com> Co-authored-by: Eyvaz Ahmadzada <eyvazahmadzada@gmail.com> Co-authored-by: Patrick McCann <patmmccann@gmail.com> Co-authored-by: JulianRSL <88969792+JulianRSL@users.noreply.github.com>
1 parent 941bbd9 commit 29ff442

File tree

9 files changed

+926
-613
lines changed

9 files changed

+926
-613
lines changed
Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
export const FIRST_PARTY_KEY = '_iiq_fdata';
1+
export const FIRST_PARTY_KEY = "_iiq_fdata";
22

3-
export const SUPPORTED_TYPES = ['html5', 'cookie']
3+
export const SUPPORTED_TYPES = ["html5", "cookie"];
44

5-
export const WITH_IIQ = 'A';
6-
export const WITHOUT_IIQ = 'B';
7-
export const NOT_YET_DEFINED = 'U';
8-
export const BLACK_LIST = 'L';
9-
export const CLIENT_HINTS_KEY = '_iiq_ch';
10-
export const EMPTY = 'EMPTY';
11-
export const GVLID = '1323';
12-
export const VERSION = 0.32;
13-
export const PREBID = 'pbjs';
5+
export const WITH_IIQ = "A";
6+
export const WITHOUT_IIQ = "B";
7+
export const DEFAULT_PERCENTAGE = 95;
8+
export const BLACK_LIST = "L";
9+
export const CLIENT_HINTS_KEY = "_iiq_ch";
10+
export const EMPTY = "EMPTY";
11+
export const GVLID = "1323";
12+
export const VERSION = 0.33;
13+
export const PREBID = "pbjs";
1414
export const HOURS_24 = 86400000;
1515

16-
export const INVALID_ID = 'INVALID_ID';
16+
export const INVALID_ID = "INVALID_ID";
1717

1818
export const SYNC_REFRESH_MILL = 3600000;
1919
export const META_DATA_CONSTANT = 256;
@@ -25,10 +25,24 @@ export const MAX_REQUEST_LENGTH = {
2525
opera: 2097152,
2626
edge: 2048,
2727
firefox: 65536,
28-
ie: 2048
28+
ie: 2048,
2929
};
3030

3131
export const CH_KEYS = [
32-
'brands', 'mobile', 'platform', 'bitness', 'wow64', 'architecture',
33-
'model', 'platformVersion', 'fullVersionList'
32+
"brands",
33+
"mobile",
34+
"platform",
35+
"bitness",
36+
"wow64",
37+
"architecture",
38+
"model",
39+
"platformVersion",
40+
"fullVersionList",
3441
];
42+
43+
export const AB_CONFIG_SOURCE = {
44+
PERCENTAGE: "percentage",
45+
GROUP: "group",
46+
IIQ_SERVER: "IIQServer",
47+
DISABLED: "disabled",
48+
};
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import {
2+
WITH_IIQ,
3+
WITHOUT_IIQ,
4+
DEFAULT_PERCENTAGE,
5+
AB_CONFIG_SOURCE,
6+
} from "../intentIqConstants/intentIqConstants.js";
7+
8+
/**
9+
* Fix percentage if provided some incorrect data
10+
* clampPct(150) => 100
11+
* clampPct(-5) => 0
12+
* clampPct('abc') => DEFAULT_PERCENTAGE
13+
*/
14+
function clampPct(val) {
15+
const n = Number(val);
16+
if (!Number.isFinite(n)) return DEFAULT_PERCENTAGE; // fallback = 95
17+
return Math.max(0, Math.min(100, n));
18+
}
19+
20+
/**
21+
* Randomly assigns a user to group A or B based on the given percentage.
22+
* Generates a random number (1–100) and compares it with the percentage.
23+
*
24+
* @param {number} pct The percentage threshold (0–100).
25+
* @returns {string} Returns WITH_IIQ for Group A or WITHOUT_IIQ for Group B.
26+
*/
27+
function pickABByPercentage(pct) {
28+
const percentageToUse =
29+
typeof pct === "number" ? pct : DEFAULT_PERCENTAGE;
30+
const percentage = clampPct(percentageToUse);
31+
const roll = Math.floor(Math.random() * 100) + 1;
32+
return roll <= percentage ? WITH_IIQ : WITHOUT_IIQ; // A : B
33+
}
34+
35+
function configurationSourceGroupInitialization(group) {
36+
return typeof group === 'string' && group.toUpperCase() === WITHOUT_IIQ ? WITHOUT_IIQ : WITH_IIQ;
37+
}
38+
39+
/**
40+
* Determines the runtime A/B testing group without saving it to Local Storage.
41+
* 1. If terminationCause (tc) exists:
42+
* - tc = 41 → Group B (WITHOUT_IIQ)
43+
* - any other value → Group A (WITH_IIQ)
44+
* 2. Otherwise, assigns the group randomly based on DEFAULT_PERCENTAGE (default 95% for A, 5% for B).
45+
*
46+
* @param {number} [tc] The termination cause value returned by the server.
47+
* @param {number} [abPercentage] A/B percentage provided by partner.
48+
* @returns {string} The determined group: WITH_IIQ (A) or WITHOUT_IIQ (B).
49+
*/
50+
51+
function IIQServerConfigurationSource(tc, abPercentage) {
52+
if (typeof tc === "number" && Number.isFinite(tc)) {
53+
return tc === 41 ? WITHOUT_IIQ : WITH_IIQ;
54+
}
55+
56+
return pickABByPercentage(abPercentage);
57+
}
58+
59+
export function defineABTestingGroup(configObject, tc) {
60+
switch (configObject.ABTestingConfigurationSource) {
61+
case AB_CONFIG_SOURCE.GROUP:
62+
return configurationSourceGroupInitialization(
63+
configObject.group
64+
);
65+
case AB_CONFIG_SOURCE.PERCENTAGE:
66+
return pickABByPercentage(configObject.abPercentage);
67+
default: {
68+
if (!configObject.ABTestingConfigurationSource) {
69+
configObject.ABTestingConfigurationSource = AB_CONFIG_SOURCE.IIQ_SERVER;
70+
}
71+
return IIQServerConfigurationSource(tc, configObject.abPercentage);
72+
}
73+
}
74+
}

libraries/intentIqUtils/gamPredictionReport.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export function gamPredictionReport (gamObjectReference, sendData) {
5555
dataToSend.originalCurrency = bid.originalCurrency;
5656
dataToSend.status = bid.status;
5757
dataToSend.prebidAuctionId = element.args?.auctionId;
58+
if (!dataToSend.bidderCode) dataToSend.bidderCode = 'GAM';
5859
};
5960
if (dataToSend.bidderCode) {
6061
const relevantBid = element.args?.bidsReceived.find(
@@ -86,12 +87,12 @@ export function gamPredictionReport (gamObjectReference, sendData) {
8687
gamObjectReference.pubads().addEventListener('slotRenderEnded', (event) => {
8788
if (event.isEmpty) return;
8889
const data = extractWinData(event);
89-
if (data?.cpm) {
90+
if (data) {
9091
sendData(data);
9192
}
9293
});
9394
});
9495
} catch (error) {
95-
this.logger.error('Failed to subscribe to GAM: ' + error);
96+
logError('Failed to subscribe to GAM: ' + error);
9697
}
9798
};

0 commit comments

Comments
 (0)