1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

fix: respect environment if set on context (#2206)

When using the frontend api (embedded proxy) we should allow the use to self-define the environment on the proxy.
This commit is contained in:
Fredrik Strand Oseberg 2022-10-19 12:29:00 +02:00 committed by GitHub
parent f1c678e5c4
commit b0626d46bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 7 deletions

View File

@ -1,6 +1,6 @@
// Copy of https://github.com/Unleash/unleash-proxy/blob/main/src/test/create-context.test.ts.
import { createContext } from './create-context';
import { createContext, enrichContextWithIp } from './create-context';
test('should remove undefined properties', () => {
const context = createContext({
@ -55,13 +55,50 @@ test('will not blow up if properties is an array', () => {
properties: ['some'],
});
// console.log(context);
expect(context.userId).toBe('123');
expect(context).not.toHaveProperty('tenantId');
expect(context).not.toHaveProperty('region');
});
test('will respect environment set in context', () => {
const context = createContext({
userId: '123',
tenantId: 'some-tenant',
environment: 'development',
region: 'eu',
properties: ['some'],
});
expect(context.environment).toBe('development');
});
test('will not set environment to be development if not set in context', () => {
const context = createContext({
userId: '123',
tenantId: 'some-tenant',
region: 'eu',
properties: ['some'],
});
expect(context.environment).toBe(undefined);
});
test('will enrich context with ip', () => {
const query = {};
const ip = '192.168.10.0';
const result = enrichContextWithIp(query, ip);
expect(result.remoteAddress).toBe(ip);
});
test('will not change environment when enriching', () => {
const query = { environment: 'production' };
const ip = '192.168.10.0';
const result = enrichContextWithIp(query, ip);
expect(result.environment).toBe('production');
});
test.skip('will not blow up if userId is an array', () => {
const context = createContext({
userId: ['123'],

View File

@ -32,3 +32,9 @@ export function createContext(value: any): Context {
return cleanContext;
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const enrichContextWithIp = (query: any, ip: string): Context => {
query.remoteAddress = query.remoteAddress || ip;
return createContext(query);
};

View File

@ -9,7 +9,7 @@ import {
ProxyFeaturesSchema,
} from '../../openapi/spec/proxy-features-schema';
import { Context } from 'unleash-client';
import { createContext } from '../../proxy/create-context';
import { enrichContextWithIp } from '../../proxy/create-context';
import { ProxyMetricsSchema } from '../../openapi/spec/proxy-metrics-schema';
import { ProxyClientSchema } from '../../openapi/spec/proxy-client-schema';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
@ -168,8 +168,6 @@ export default class ProxyController extends Controller {
private static createContext(req: ApiUserRequest): Context {
const { query } = req;
query.remoteAddress = query.remoteAddress || req.ip;
query.environment = req.user.environment;
return createContext(query);
return enrichContextWithIp(query, req.ip);
}
}

View File

@ -538,6 +538,47 @@ test('should filter features by constraints', async () => {
.expect((res) => expect(res.body.toggles).toHaveLength(0));
});
test('should be able to set environment as a context variable', async () => {
const frontendToken = await createApiToken(ApiTokenType.FRONTEND);
const featureName = 'featureWithEnvironmentConstraint';
await createFeatureToggle({
name: featureName,
enabled: true,
strategies: [
{
name: 'default',
constraints: [
{
contextName: 'environment',
operator: 'IN',
values: ['staging'],
},
],
parameters: {},
},
],
});
await app.request
.get('/api/frontend?environment=staging')
.set('Authorization', frontendToken.secret)
.expect('Content-Type', /json/)
.expect(200)
.expect((res) => {
expect(res.body.toggles).toHaveLength(1);
expect(res.body.toggles[0].name).toBe(featureName);
});
await app.request
.get('/api/frontend')
.set('Authorization', frontendToken.secret)
.expect('Content-Type', /json/)
.expect(200)
.expect((res) => {
expect(res.body.toggles).toHaveLength(0);
});
});
test('should filter features by project', async () => {
const projectA = 'projectA';
const projectB = 'projectB';