function getAmountsTestVariant()

in support-frontend/assets/helpers/abTests/abtest.ts [224:396]


function getAmountsTestVariant(
	country: IsoCountry,
	countryGroupId: CountryGroupId,
	settings: Settings,
	path: string = window.location.pathname,
	mvt: number = getMvtId(),
	acquisitionDataTests: AcquisitionABTest[] = getTestFromAcquisitionData() ??
		[],
): GetAmountsTestVariantResult {
	const { amounts } = settings;

	if (!amounts) {
		return {
			selectedAmountsVariant: getFallbackAmounts(countryGroupId),
		};
	}

	const buildParticipation = (
		test: AmountsTest,
		testName: string,
		variantName: string,
	): Participations | undefined => {
		// Check if we actually want to track this test
		const pathMatches = targetPageMatches(
			path,
			'/??/checkout|one-time-checkout|contribute|thankyou(/.*)?$',
		);

		if (pathMatches && test.variants.length > 1 && test.isLive) {
			return {
				[testName]: variantName,
			};
		}

		return;
	};

	const contribOnlyAmounts = amounts.find((t) => {
		return (
			t.isLive &&
			t.testName === contributionsOnlyAmountsTestName &&
			t.targeting.targetingType === 'Country' &&
			t.targeting.countries.includes(country)
		);
	});
	if (contribOnlyAmounts?.variants[0]) {
		const amountsParticipation = buildParticipation(
			contribOnlyAmounts,
			contributionsOnlyAmountsTestName,
			contribOnlyAmounts.variants[0].variantName,
		);
		return {
			selectedAmountsVariant: {
				...contribOnlyAmounts.variants[0],
				testName: contributionsOnlyAmountsTestName,
			},
			amountsParticipation,
		};
	}

	// Is an amounts test defined in the url?
	const urlTest = getAmountsTestFromURL(acquisitionDataTests);
	if (urlTest) {
		// Attempt to find urlTest in the configured amounts tests
		const candidate = amounts.find((t) => {
			if (t.isLive) {
				return t.liveTestName === urlTest.name;
			} else {
				return t.testName === urlTest.name;
			}
		});
		if (candidate) {
			const variants = candidate.variants;
			if (variants.length) {
				const variant =
					variants.find((variant) => variant.variantName === urlTest.variant) ??
					variants[0];

				if (variant) {
					const amountsParticipation = buildParticipation(
						candidate,
						urlTest.name,
						variant.variantName,
					);
					return {
						selectedAmountsVariant: {
							...variant,
							testName: urlTest.name,
						},
						amountsParticipation,
					};
				}
			}
		}
	}

	// No url test was found, use targeting
	let targetedTest: AmountsTest | undefined;

	// First try country-targeted tests
	const source = getSourceFromAcquisitionData() ?? '';
	const enableCountryTargetedTests = !['APPLE_NEWS', 'GOOGLE_AMP'].includes(
		source,
	);
	if (enableCountryTargetedTests) {
		const countryTargetedTests = amounts
			.filter(
				(t) =>
					t.isLive &&
					t.targeting.targetingType === 'Country' &&
					t.targeting.countries.includes(country),
			)
			.sort((a, b) => a.order - b.order);

		if (countryTargetedTests[0]) {
			targetedTest = countryTargetedTests[0];
		}
	}

	// Then try region-targeted tests
	if (!targetedTest) {
		targetedTest = amounts.find(
			(t) =>
				t.targeting.targetingType === 'Region' &&
				t.targeting.region === countryGroupId,
		);
	}

	if (!targetedTest) {
		return {
			selectedAmountsVariant: getFallbackAmounts(countryGroupId),
		};
	}

	const { testName, liveTestName, seed, variants, isLive } = targetedTest;

	const selectVariant = (
		isLive: boolean,
		variants: AmountsVariant[],
	): AmountsVariant | undefined => {
		if (isLive && variants.length > 1) {
			const assignmentIndex = randomNumber(mvt, seed) % variants.length;

			return variants[assignmentIndex];
		}
		// For regional AmountsTests, if the test is not live then we use the control

		return variants[0];
	};

	const currentTestName = isLive && liveTestName ? liveTestName : testName;
	const variant = selectVariant(isLive, variants);

	const amountsParticipation = buildParticipation(
		targetedTest,
		currentTestName,
		variant?.variantName ?? '',
	);

	if (!variant) {
		return {
			selectedAmountsVariant: getFallbackAmounts(countryGroupId),
		};
	}

	return {
		selectedAmountsVariant: {
			...variant,
			testName: currentTestName,
		},
		amountsParticipation,
	};
}