Skip to content

Commit 570984c

Browse files
committed
combine test code for obsfucated and unobfuscated
1 parent fb7c554 commit 570984c

File tree

2 files changed

+102
-79
lines changed

2 files changed

+102
-79
lines changed

src/client/eppo-client.spec.ts

Lines changed: 40 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -317,43 +317,59 @@ describe('EppoClient E2E test', () => {
317317
});
318318
});
319319

320-
describe('UFC Shared Test Cases', () => {
320+
describe.each(['Not Obfuscated', 'Obfuscated'])('UFC Shared Test Cases %s', (obfuscationType) => {
321321
const testCases = testCasesByFileName<IAssignmentTestCase>(ASSIGNMENT_TEST_DATA_DIR);
322+
const isObfuscated = obfuscationType === 'Obfuscated';
322323

323-
describe('Not obfuscated', () => {
324-
beforeAll(async () => {
325-
global.fetch = jest.fn(() => {
326-
return Promise.resolve({
327-
ok: true,
328-
status: 200,
329-
json: () => Promise.resolve(readMockUFCResponse(MOCK_UFC_RESPONSE_FILE)),
330-
});
331-
}) as jest.Mock;
324+
beforeAll(async () => {
325+
global.fetch = jest.fn(() => {
326+
return Promise.resolve({
327+
ok: true,
328+
status: 200,
329+
json: () =>
330+
Promise.resolve(
331+
readMockUFCResponse(
332+
isObfuscated ? OBFUSCATED_MOCK_UFC_RESPONSE_FILE : MOCK_UFC_RESPONSE_FILE,
333+
),
334+
),
335+
});
336+
}) as jest.Mock;
332337

333-
await initConfiguration(storage);
334-
});
338+
await initConfiguration(storage);
339+
});
335340

336-
afterAll(() => {
337-
jest.restoreAllMocks();
338-
});
341+
afterAll(() => {
342+
jest.restoreAllMocks();
343+
});
344+
345+
describe.each(['Scalar', 'With Details'])('%s', (assignmentType) => {
346+
const assignmentWithDetails = assignmentType === 'With Details';
339347

340348
it.each(Object.keys(testCases))('test variation assignment splits - %s', async (fileName) => {
341349
const { flag, variationType, defaultValue, subjects } = testCases[fileName];
342-
const client = new EppoClient({ flagConfigurationStore: storage });
350+
const client = new EppoClient({ flagConfigurationStore: storage, isObfuscated });
343351
client.setIsGracefulFailureMode(false);
344352

345353
let assignments: {
346354
subject: SubjectTestCase;
347355
assignment: string | boolean | number | null | object;
348356
}[] = [];
349357

350-
const typeAssignmentFunctions = {
351-
[VariationType.BOOLEAN]: client.getBooleanAssignment.bind(client),
352-
[VariationType.NUMERIC]: client.getNumericAssignment.bind(client),
353-
[VariationType.INTEGER]: client.getIntegerAssignment.bind(client),
354-
[VariationType.STRING]: client.getStringAssignment.bind(client),
355-
[VariationType.JSON]: client.getJSONAssignment.bind(client),
356-
};
358+
const typeAssignmentFunctions = assignmentWithDetails
359+
? {
360+
[VariationType.BOOLEAN]: client.getBooleanAssignmentDetails.bind(client),
361+
[VariationType.NUMERIC]: client.getNumericAssignmentDetails.bind(client),
362+
[VariationType.INTEGER]: client.getIntegerAssignmentDetails.bind(client),
363+
[VariationType.STRING]: client.getStringAssignmentDetails.bind(client),
364+
[VariationType.JSON]: client.getJSONAssignmentDetails.bind(client),
365+
}
366+
: {
367+
[VariationType.BOOLEAN]: client.getBooleanAssignment.bind(client),
368+
[VariationType.NUMERIC]: client.getNumericAssignment.bind(client),
369+
[VariationType.INTEGER]: client.getIntegerAssignment.bind(client),
370+
[VariationType.STRING]: client.getStringAssignment.bind(client),
371+
[VariationType.JSON]: client.getJSONAssignment.bind(client),
372+
};
357373

358374
const assignmentFn = typeAssignmentFunctions[variationType] as (
359375
flagKey: string,
@@ -370,56 +386,7 @@ describe('EppoClient E2E test', () => {
370386
assignmentFn,
371387
);
372388

373-
validateTestAssignments(assignments, flag);
374-
});
375-
});
376-
377-
describe('Obfuscated', () => {
378-
beforeAll(async () => {
379-
global.fetch = jest.fn(() => {
380-
return Promise.resolve({
381-
ok: true,
382-
status: 200,
383-
json: () => Promise.resolve(readMockUFCResponse(OBFUSCATED_MOCK_UFC_RESPONSE_FILE)),
384-
});
385-
}) as jest.Mock;
386-
387-
await initConfiguration(storage);
388-
});
389-
390-
afterAll(() => {
391-
jest.restoreAllMocks();
392-
});
393-
394-
it.each(Object.keys(testCases))('test variation assignment splits - %s', async (fileName) => {
395-
const { flag, variationType, defaultValue, subjects } = testCases[fileName];
396-
const client = new EppoClient({ flagConfigurationStore: storage, isObfuscated: true });
397-
client.setIsGracefulFailureMode(false);
398-
399-
const typeAssignmentFunctions = {
400-
[VariationType.BOOLEAN]: client.getBooleanAssignment.bind(client),
401-
[VariationType.NUMERIC]: client.getNumericAssignment.bind(client),
402-
[VariationType.INTEGER]: client.getIntegerAssignment.bind(client),
403-
[VariationType.STRING]: client.getStringAssignment.bind(client),
404-
[VariationType.JSON]: client.getJSONAssignment.bind(client),
405-
};
406-
407-
const assignmentFn = typeAssignmentFunctions[variationType] as (
408-
flagKey: string,
409-
subjectKey: string,
410-
subjectAttributes: Record<string, AttributeType>,
411-
defaultValue: boolean | string | number | object,
412-
) => never;
413-
if (!assignmentFn) {
414-
throw new Error(`Unknown variation type: ${variationType}`);
415-
}
416-
417-
const assignments = getTestAssignments(
418-
{ flag, variationType, defaultValue, subjects },
419-
assignmentFn,
420-
);
421-
422-
validateTestAssignments(assignments, flag);
389+
validateTestAssignments(assignments, flag, assignmentWithDetails);
423390
});
424391
});
425392
});

test/testHelpers.ts

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as fs from 'fs';
22

33
import { isEqual } from 'lodash';
44

5-
import { AttributeType, ContextAttributes, IAssignmentDetails, VariationType } from '../src';
5+
import { AttributeType, ContextAttributes, IAssignmentDetails, Variation, VariationType } from '../src';
66
import { IFlagEvaluationDetails } from '../src/flag-evaluation-details-builder';
77
import { IBanditParametersResponse, IUniversalFlagConfigResponse } from '../src/http-client';
88

@@ -87,7 +87,16 @@ export function getTestAssignments(
8787
subjectAttributes: Record<string, AttributeType>,
8888
defaultValue: string | number | boolean | object,
8989
) => never,
90-
): { subject: SubjectTestCase; assignment: string | boolean | number | null | object }[] {
90+
): {
91+
subject: SubjectTestCase;
92+
assignment:
93+
| string
94+
| boolean
95+
| number
96+
| null
97+
| object
98+
| IAssignmentDetails<typeof testCase.defaultValue>;
99+
}[] {
91100
const assignments: {
92101
subject: SubjectTestCase;
93102
assignment: string | boolean | number | null | object;
@@ -130,22 +139,69 @@ export function getTestAssignmentDetails(
130139
export function validateTestAssignments(
131140
assignments: {
132141
subject: SubjectTestCase;
133-
assignment: string | boolean | number | object | null;
142+
assignment:
143+
| string
144+
| boolean
145+
| number
146+
| object
147+
| null
148+
| IAssignmentDetails<string | boolean | number | object>;
134149
}[],
135150
flag: string,
151+
withDetails: boolean,
136152
) {
137153
for (const { subject, assignment } of assignments) {
138-
if (!isEqual(assignment, subject.assignment)) {
154+
let assignedVariation = assignment;
155+
let assignmentDetails: IFlagEvaluationDetails | null = null;
156+
if (
157+
withDetails === true &&
158+
typeof assignment === 'object' &&
159+
assignment !== null &&
160+
'variation' in assignment
161+
) {
162+
assignedVariation = assignment.variation;
163+
assignmentDetails = assignment.evaluationDetails;
164+
}
165+
166+
if (!isEqual(assignedVariation, subject.assignment)) {
139167
// More friendly error message
140168
console.error(
141169
`subject ${subject.subjectKey} was assigned ${JSON.stringify(
142-
assignment,
170+
assignedVariation,
143171
undefined,
144172
2,
145173
)} when expected ${JSON.stringify(subject.assignment, undefined, 2)} for flag ${flag}`,
146174
);
147175
}
148176

149-
expect(assignment).toEqual(subject.assignment);
177+
expect(assignedVariation).toEqual(subject.assignment);
178+
179+
if (withDetails && assignmentDetails) {
180+
expect(assignmentDetails.environmentName).toBe(subject.evaluationDetails.environmentName);
181+
expect(assignmentDetails.flagEvaluationCode).toBe(
182+
subject.evaluationDetails.flagEvaluationCode,
183+
);
184+
expect(assignmentDetails.flagEvaluationDescription).toBe(
185+
subject.evaluationDetails.flagEvaluationDescription,
186+
);
187+
expect(assignmentDetails.variationKey).toBe(subject.evaluationDetails.variationKey);
188+
// Use toString() to handle comparing JSON
189+
expect(assignmentDetails.variationValue?.toString()).toBe(
190+
subject.evaluationDetails.variationValue?.toString(),
191+
);
192+
// TODO: below needs to be fixed
193+
//expect(assignmentDetails.configFetchedAt).toBe(subject.evaluationDetails.configFetchedAt);
194+
//expect(assignmentDetails.configPublishedAt).toBe(subject.evaluationDetails.configPublishedAt);
195+
expect(assignmentDetails.matchedRule).toEqual(subject.evaluationDetails.matchedRule);
196+
expect(assignmentDetails.matchedAllocation).toEqual(
197+
subject.evaluationDetails.matchedAllocation,
198+
);
199+
expect(assignmentDetails.unmatchedAllocations).toEqual(
200+
subject.evaluationDetails.unmatchedAllocations,
201+
);
202+
expect(assignmentDetails.unevaluatedAllocations).toEqual(
203+
subject.evaluationDetails.unevaluatedAllocations,
204+
);
205+
}
150206
}
151207
}

0 commit comments

Comments
 (0)