-
-
Notifications
You must be signed in to change notification settings - Fork 737
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: handle objects in top-level context in playground (#6773)
Don't include invalid context properties in the contexts that we evaluate. This PR removes any non-`properties` fields that have a non-string value. This prevents the front end from crashing when trying to render an object. Expect follow-up PRs to include more warnings/diagnostics we can show to the end user to inform them of what fields have been removed and why.
- Loading branch information
1 parent
770155d
commit ac6c05d
Showing
4 changed files
with
132 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { cleanContext } from './clean-context'; | ||
|
||
test('strips invalid context properties from the context', async () => { | ||
const invalidJsonTypes = { | ||
object: {}, | ||
array: [], | ||
true: true, | ||
false: false, | ||
number: 123, | ||
null: null, | ||
}; | ||
|
||
const validValues = { | ||
appName: 'test', | ||
}; | ||
|
||
const inputContext = { | ||
...invalidJsonTypes, | ||
...validValues, | ||
}; | ||
|
||
const cleanedContext = cleanContext(inputContext); | ||
|
||
expect(cleanedContext).toStrictEqual(validValues); | ||
}); | ||
|
||
test("doesn't add non-existing properties", async () => { | ||
const input = { | ||
appName: 'test', | ||
}; | ||
|
||
const output = cleanContext(input); | ||
|
||
expect(output).toStrictEqual(input); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import type { SdkContextSchema } from '../../openapi'; | ||
|
||
export const cleanContext = (context: SdkContextSchema): SdkContextSchema => { | ||
const { appName, ...otherContextFields } = context; | ||
|
||
const cleanedContextFields = Object.fromEntries( | ||
Object.entries(otherContextFields).filter( | ||
([key, value]) => key === 'properties' || typeof value === 'string', | ||
), | ||
); | ||
|
||
return { | ||
...cleanedContextFields, | ||
appName, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init'; | ||
import { | ||
type IUnleashTest, | ||
setupApp, | ||
} from '../../../test/e2e/helpers/test-helper'; | ||
import type { IUnleashStores } from '../../types'; | ||
import getLogger from '../../../test/fixtures/no-logger'; | ||
|
||
let stores: IUnleashStores; | ||
let db: ITestDb; | ||
let app: IUnleashTest; | ||
|
||
const flag = { | ||
name: 'test-flag', | ||
enabled: true, | ||
strategies: [{ name: 'default' }], | ||
createdByUserId: 9999, | ||
}; | ||
|
||
beforeAll(async () => { | ||
db = await dbInit('playground_api', getLogger); | ||
stores = db.stores; | ||
|
||
await stores.featureToggleStore.create('default', flag); | ||
|
||
app = await setupApp(stores); | ||
}); | ||
|
||
afterAll(async () => { | ||
await db.destroy(); | ||
}); | ||
|
||
test('strips invalid context properties from input before using it', async () => { | ||
const validData = { | ||
appName: 'test', | ||
}; | ||
|
||
const inputContext = { | ||
invalid: {}, | ||
...validData, | ||
}; | ||
|
||
const { body } = await app.request | ||
.post('/api/admin/playground/advanced') | ||
.send({ | ||
context: inputContext, | ||
environments: ['production'], | ||
projects: '*', | ||
}) | ||
.expect(200); | ||
|
||
const evaluatedContext = | ||
body.features[0].environments.production[0].context; | ||
|
||
expect(evaluatedContext).toStrictEqual(validData); | ||
}); | ||
|
||
test('returns the input context exactly as it came in, even if invalid values have been removed for the evaluation', async () => { | ||
const invalidData = { | ||
invalid: {}, | ||
}; | ||
|
||
const inputContext = { | ||
...invalidData, | ||
appName: 'test', | ||
}; | ||
|
||
const { body } = await app.request | ||
.post('/api/admin/playground/advanced') | ||
.send({ | ||
context: inputContext, | ||
environments: ['production'], | ||
projects: '*', | ||
}) | ||
.expect(200); | ||
|
||
expect(body.input.context).toMatchObject(inputContext); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters