diff --git a/src/lib/openapi/spec/playground-feature-schema.test.ts b/src/lib/openapi/spec/playground-feature-schema.test.ts index 1db02069cf..0d01284b8f 100644 --- a/src/lib/openapi/spec/playground-feature-schema.test.ts +++ b/src/lib/openapi/spec/playground-feature-schema.test.ts @@ -1,4 +1,5 @@ import fc, { Arbitrary } from 'fast-check'; +import { WeightType } from '../../../lib/types/model'; import { urlFriendlyString } from '../../../test/arbitraries.test'; import { validateSchema } from '../validate'; import { @@ -12,28 +13,42 @@ export const generate = (): Arbitrary => isEnabled: fc.constant(isEnabled), projectId: urlFriendlyString(), name: urlFriendlyString(), - variant: fc.record( - { - name: urlFriendlyString(), - enabled: fc.constant(isEnabled), - payload: fc.oneof( - fc.record({ - type: fc.constant('json' as 'json'), - value: fc.json(), - }), - fc.record({ - type: fc.constant('csv' as 'csv'), - value: fc - .array(fc.lorem()) - .map((words) => words.join(',')), - }), - fc.record({ - type: fc.constant('string' as 'string'), - value: fc.string(), - }), - ), - }, - { requiredKeys: ['name', 'enabled'] }, + variants: fc.uniqueArray( + fc.record( + { + name: urlFriendlyString(), + enabled: fc.constant(isEnabled), + payload: fc.oneof( + fc.record({ + type: fc.constant('json' as 'json'), + value: fc.json(), + }), + fc.record({ + type: fc.constant('csv' as 'csv'), + value: fc + .array(fc.lorem()) + .map((words) => words.join(',')), + }), + fc.record({ + type: fc.constant('string' as 'string'), + value: fc.string(), + }), + ), + weight: fc.nat({ max: 1000 }), + weightType: fc.constant(WeightType.VARIABLE), + stickiness: fc.constant('default'), + }, + { + requiredKeys: [ + 'name', + 'enabled', + 'weight', + 'stickiness', + 'weightType', + ], + }, + ), + { selector: (variant) => variant.name }, ), }), ); diff --git a/src/lib/openapi/spec/playground-feature-schema.ts b/src/lib/openapi/spec/playground-feature-schema.ts index 5eee0afc20..ebeb7190ba 100644 --- a/src/lib/openapi/spec/playground-feature-schema.ts +++ b/src/lib/openapi/spec/playground-feature-schema.ts @@ -1,4 +1,6 @@ import { FromSchema } from 'json-schema-to-ts'; +import { overrideSchema } from './override-schema'; +import { variantSchema } from './variant-schema'; export const playgroundFeatureSchema = { $id: '#/components/schemas/playgroundFeatureSchema', @@ -6,36 +8,28 @@ export const playgroundFeatureSchema = { 'A simplified feature toggle model intended for the Unleash playground.', type: 'object', additionalProperties: false, - required: ['name', 'projectId', 'isEnabled', 'variant'], + required: ['name', 'projectId', 'isEnabled', 'variants'], properties: { name: { type: 'string', examples: ['my-feature'] }, projectId: { type: 'string', examples: ['my-project'] }, isEnabled: { type: 'boolean', examples: [true] }, - variant: { - type: 'object', - additionalProperties: false, - required: ['name', 'enabled'], - properties: { - name: { type: 'string' }, - enabled: { type: 'boolean' }, - payload: { - type: 'object', - additionalProperties: false, - required: ['type', 'value'], - properties: { - type: { - type: 'string', - enum: ['json', 'csv', 'string'], + variants: { + type: 'array', + items: { + allOf: [ + { $ref: variantSchema.$id }, + { + type: 'object', + required: ['enabled'], + properties: { + enabled: { type: 'boolean', examples: [true] }, }, - value: { type: 'string' }, }, - }, + ], }, - nullable: true, - examples: ['green'], }, }, - components: { schemas: {} }, + components: { schemas: { variantSchema, overrideSchema } }, } as const; export type PlaygroundFeatureSchema = FromSchema< diff --git a/src/lib/openapi/spec/playground-response-schema.test.ts b/src/lib/openapi/spec/playground-response-schema.test.ts index e70f8ff168..09cca87e2a 100644 --- a/src/lib/openapi/spec/playground-response-schema.test.ts +++ b/src/lib/openapi/spec/playground-response-schema.test.ts @@ -5,12 +5,14 @@ import { } from '../../../lib/openapi/spec/playground-response-schema'; import { validateSchema } from '../validate'; import { generate as generateInput } from './playground-request-schema.test'; -import { generate as generateToggles } from './playground-feature-schema.test'; +import { generate as generateFeature } from './playground-feature-schema.test'; const generate = (): Arbitrary => fc.record({ input: generateInput(), - features: fc.array(generateToggles()), + features: fc.uniqueArray(generateFeature(), { + selector: (feature) => feature.name, + }), }); test('playgroundResponseSchema', () => diff --git a/src/lib/openapi/spec/playground-response-schema.ts b/src/lib/openapi/spec/playground-response-schema.ts index be47d2a0e7..b48c625c21 100644 --- a/src/lib/openapi/spec/playground-response-schema.ts +++ b/src/lib/openapi/spec/playground-response-schema.ts @@ -3,6 +3,8 @@ import { sdkContextSchema } from './sdk-context-schema'; import { playgroundRequestSchema } from './playground-request-schema'; import { playgroundFeatureSchema } from './playground-feature-schema'; import { featureVariantsSchema } from './feature-variants-schema'; +import { variantSchema } from './variant-schema'; +import { overrideSchema } from './override-schema'; export const playgroundResponseSchema = { $id: '#/components/schemas/playgroundResponseSchema', @@ -17,21 +19,7 @@ export const playgroundResponseSchema = { features: { type: 'array', items: { - allOf: [ - { $ref: playgroundFeatureSchema.$id }, - { - type: 'object', - required: ['variants'], - properties: { - variants: { - type: 'array', - items: { - $ref: featureVariantsSchema.$id, - }, - }, - }, - }, - ], + $ref: playgroundFeatureSchema.$id, }, }, }, @@ -41,6 +29,8 @@ export const playgroundResponseSchema = { playgroundFeatureSchema, playgroundRequestSchema, sdkContextSchema, + variantSchema, + overrideSchema, }, }, } as const; diff --git a/src/lib/openapi/spec/variant-schema.ts b/src/lib/openapi/spec/variant-schema.ts index 65e6880033..c2a7480e27 100644 --- a/src/lib/openapi/spec/variant-schema.ts +++ b/src/lib/openapi/spec/variant-schema.ts @@ -4,7 +4,6 @@ import { overrideSchema } from './override-schema'; export const variantSchema = { $id: '#/components/schemas/variantSchema', type: 'object', - additionalProperties: false, required: ['name', 'weight', 'weightType', 'stickiness'], properties: { name: {