1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-08-13 13:48:59 +02:00

feat: add warnings to the api response

This commit is contained in:
Thomas Heartman 2024-04-05 10:11:41 +02:00
parent 0fb3f9460d
commit 6363a3265f
No known key found for this signature in database
GPG Key ID: BD1F880DAED1EE78
5 changed files with 71 additions and 11 deletions

View File

@ -76,3 +76,30 @@ test('returns the input context exactly as it came in, even if invalid values ha
expect(body.input.context).toMatchObject(inputContext);
});
test('adds all removed top-level context properties to the list of warnings', async () => {
const invalidData = {
invalid1: {},
invalid2: {},
};
const inputContext = {
...invalidData,
appName: 'test',
};
const { body } = await app.request
.post('/api/admin/playground/advanced')
.send({
context: inputContext,
environments: ['production'],
projects: '*',
})
.expect(200);
const warned = body.warnings.invalidContextProperties;
const invalidKeys = Object.keys(invalidData);
expect(warned).toEqual(expect.arrayContaining(invalidKeys));
expect(invalidKeys).toEqual(expect.arrayContaining(warned));
});

View File

@ -103,7 +103,10 @@ export class PlaygroundService {
context: SdkContextSchema,
limit: number,
userId: number,
): Promise<AdvancedPlaygroundFeatureEvaluationResult[]> {
): Promise<{
result: AdvancedPlaygroundFeatureEvaluationResult[];
invalidContextProperties: string[];
}> {
const segments = await this.segmentReadModel.getActive();
let filteredProjects: typeof projects = projects;
@ -126,7 +129,8 @@ export class PlaygroundService {
),
);
const { context: cleanedContext } = cleanContext(context);
const { context: cleanedContext, removedProperties } =
cleanContext(context);
const contexts = generateObjectCombinations(cleanedContext);
validateQueryComplexity(
@ -152,7 +156,7 @@ export class PlaygroundService {
);
const items = results.flat();
const itemsByName = groupBy(items, (item) => item.name);
return Object.values(itemsByName).map((entries) => {
const result = Object.values(itemsByName).map((entries) => {
const groupedEnvironments = groupBy(
entries,
(entry) => entry.environment,
@ -163,6 +167,11 @@ export class PlaygroundService {
environments: groupedEnvironments,
};
});
return {
result,
invalidContextProperties: removedProperties,
};
}
private async evaluate({

View File

@ -40,6 +40,7 @@ const addStrategyEditLink = (
export const advancedPlaygroundViewModel = (
input: AdvancedPlaygroundRequestSchema,
playgroundResult: AdvancedPlaygroundFeatureEvaluationResult[],
invalidContextProperties: string[],
): AdvancedPlaygroundResponseSchema => {
const features = playgroundResult.map(({ environments, ...rest }) => {
const transformedEnvironments = Object.entries(environments).map(
@ -79,6 +80,10 @@ export const advancedPlaygroundViewModel = (
};
});
if (invalidContextProperties.length > 0) {
return { features, input, warnings: { invalidContextProperties } };
}
return { features, input };
};

View File

@ -125,16 +125,21 @@ export default class PlaygroundController extends Controller {
? Number.parseInt(payload?.value)
: 15000;
const result = await this.playgroundService.evaluateAdvancedQuery(
req.body.projects || '*',
req.body.environments,
req.body.context,
limit,
extractUserIdFromUser(user),
);
const { result, invalidContextProperties } =
await this.playgroundService.evaluateAdvancedQuery(
req.body.projects || '*',
req.body.environments,
req.body.context,
limit,
extractUserIdFromUser(user),
);
const response: AdvancedPlaygroundResponseSchema =
advancedPlaygroundViewModel(req.body, result);
advancedPlaygroundViewModel(
req.body,
result,
invalidContextProperties,
);
res.json(response);
}

View File

@ -30,6 +30,20 @@ export const advancedPlaygroundResponseSchema = {
$ref: advancedPlaygroundFeatureSchema.$id,
},
},
warnings: {
type: 'object',
description: 'Warnings that occurred during evaluation.',
properties: {
invalidContextProperties: {
type: 'array',
description:
'A list of top-level context properties that were provided as input that are not valid due to being the wrong type.',
items: {
type: 'string',
},
},
},
},
},
components: {
schemas: {