2021-08-12 15:04:37 +02:00
|
|
|
import supertest from 'supertest';
|
|
|
|
import createStores from '../../../test/fixtures/store';
|
|
|
|
import getApp from '../../app';
|
|
|
|
import { createTestConfig } from '../../../test/config/test-config';
|
2021-12-09 21:50:06 +01:00
|
|
|
import { clientMetricsSchema } from '../../services/client-metrics/schema';
|
2021-08-12 15:04:37 +02:00
|
|
|
import { createServices } from '../../services';
|
2022-06-30 12:27:12 +02:00
|
|
|
import { IUnleashOptions, IUnleashStores } from '../../types';
|
2017-06-28 10:20:22 +02:00
|
|
|
|
2022-01-06 10:31:00 +01:00
|
|
|
async function getSetup(opts?: IUnleashOptions) {
|
2021-08-12 15:04:37 +02:00
|
|
|
const stores = createStores();
|
2021-04-22 10:07:10 +02:00
|
|
|
|
2021-10-08 10:09:22 +02:00
|
|
|
const config = createTestConfig(opts);
|
2020-12-17 19:22:30 +01:00
|
|
|
const services = createServices(stores, config);
|
2022-01-06 10:31:00 +01:00
|
|
|
const app = await getApp(config, stores, services);
|
2017-06-28 10:20:22 +02:00
|
|
|
|
|
|
|
return {
|
|
|
|
request: supertest(app),
|
|
|
|
stores,
|
2021-05-28 11:10:24 +02:00
|
|
|
destroy: () => {
|
|
|
|
services.versionService.destroy();
|
2021-12-09 21:25:06 +01:00
|
|
|
services.clientInstanceService.destroy();
|
2021-05-28 11:10:24 +02:00
|
|
|
services.apiTokenService.destroy();
|
|
|
|
},
|
2017-06-28 10:20:22 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
let request;
|
2021-09-13 10:23:57 +02:00
|
|
|
let stores: IUnleashStores;
|
2021-05-28 11:10:24 +02:00
|
|
|
let destroy;
|
|
|
|
|
2022-01-06 10:31:00 +01:00
|
|
|
beforeEach(async () => {
|
|
|
|
const setup = await getSetup();
|
2021-05-28 11:10:24 +02:00
|
|
|
request = setup.request;
|
|
|
|
stores = setup.stores;
|
|
|
|
destroy = setup.destroy;
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
destroy();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should validate client metrics', () => {
|
2017-06-28 10:20:22 +02:00
|
|
|
return request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({ random: 'blush' })
|
|
|
|
.expect(400);
|
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should accept empty client metrics', () => {
|
2017-06-28 10:20:22 +02:00
|
|
|
return request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({
|
|
|
|
appName: 'demo',
|
|
|
|
instanceId: '1',
|
|
|
|
bucket: {
|
|
|
|
start: Date.now(),
|
|
|
|
stop: Date.now(),
|
|
|
|
toggles: {},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.expect(202);
|
|
|
|
});
|
2017-08-04 11:24:58 +02:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should accept client metrics with yes/no', () => {
|
2017-08-04 11:24:58 +02:00
|
|
|
return request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({
|
|
|
|
appName: 'demo',
|
|
|
|
instanceId: '1',
|
|
|
|
bucket: {
|
|
|
|
start: Date.now(),
|
|
|
|
stop: Date.now(),
|
|
|
|
toggles: {
|
|
|
|
toggleA: {
|
|
|
|
yes: 200,
|
|
|
|
no: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.expect(202);
|
|
|
|
});
|
|
|
|
|
2021-10-08 10:09:22 +02:00
|
|
|
test('should accept client metrics with yes/no with metricsV2', async () => {
|
2022-08-26 08:22:42 +02:00
|
|
|
const testRunner = await getSetup();
|
2021-10-08 10:09:22 +02:00
|
|
|
await testRunner.request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({
|
|
|
|
appName: 'demo',
|
|
|
|
instanceId: '1',
|
|
|
|
bucket: {
|
|
|
|
start: Date.now(),
|
|
|
|
stop: Date.now(),
|
|
|
|
toggles: {
|
|
|
|
toggleA: {
|
|
|
|
yes: 200,
|
|
|
|
no: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.expect(202);
|
|
|
|
|
|
|
|
testRunner.destroy();
|
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should accept client metrics with variants', () => {
|
2019-01-25 13:05:25 +01:00
|
|
|
return request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({
|
|
|
|
appName: 'demo',
|
|
|
|
instanceId: '1',
|
|
|
|
bucket: {
|
|
|
|
start: Date.now(),
|
|
|
|
stop: Date.now(),
|
|
|
|
toggles: {
|
|
|
|
toggleA: {
|
|
|
|
yes: 200,
|
|
|
|
no: 0,
|
|
|
|
variants: {
|
|
|
|
variant1: 1,
|
|
|
|
variant2: 2,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.expect(202);
|
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should accept client metrics without yes/no', () => {
|
2017-08-04 11:24:58 +02:00
|
|
|
return request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({
|
|
|
|
appName: 'demo',
|
|
|
|
instanceId: '1',
|
|
|
|
bucket: {
|
|
|
|
start: Date.now(),
|
|
|
|
stop: Date.now(),
|
|
|
|
toggles: {
|
|
|
|
toggleA: {
|
|
|
|
blue: 200,
|
|
|
|
green: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
2019-01-25 13:05:25 +01:00
|
|
|
.expect(202);
|
2017-08-04 11:24:58 +02:00
|
|
|
});
|
2019-05-06 10:50:50 +02:00
|
|
|
|
2021-09-15 20:28:10 +02:00
|
|
|
test('schema allow empty strings', () => {
|
2019-05-06 10:50:50 +02:00
|
|
|
const data = {
|
|
|
|
appName: 'java-test',
|
|
|
|
instanceId: 'instance y',
|
|
|
|
bucket: {
|
|
|
|
toggles: { Demo2: { yes: '', no: '', variants: {} } },
|
|
|
|
start: '2019-05-06T08:30:40.514Z',
|
|
|
|
stop: '2019-05-06T09:30:50.515Z',
|
|
|
|
},
|
|
|
|
};
|
2020-01-02 19:23:52 +01:00
|
|
|
const { error, value } = clientMetricsSchema.validate(data);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error).toBeFalsy();
|
|
|
|
expect(value.bucket.toggles.Demo2.yes).toBe(0);
|
|
|
|
expect(value.bucket.toggles.Demo2.no).toBe(0);
|
2019-05-06 10:50:50 +02:00
|
|
|
});
|
|
|
|
|
2021-07-07 10:46:50 +02:00
|
|
|
test('schema allow yes=<string nbr>', () => {
|
2019-05-06 10:50:50 +02:00
|
|
|
const data = {
|
|
|
|
appName: 'java-test',
|
|
|
|
instanceId: 'instance y',
|
|
|
|
bucket: {
|
|
|
|
toggles: { Demo2: { yes: '12', no: 256, variants: {} } },
|
|
|
|
start: '2019-05-06T08:30:40.514Z',
|
|
|
|
stop: '2019-05-06T09:30:50.515Z',
|
|
|
|
},
|
|
|
|
};
|
2020-01-02 19:23:52 +01:00
|
|
|
const { error, value } = clientMetricsSchema.validate(data);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error).toBeFalsy();
|
|
|
|
expect(value.bucket.toggles.Demo2.yes).toBe(12);
|
|
|
|
expect(value.bucket.toggles.Demo2.no).toBe(256);
|
2019-05-06 10:50:50 +02:00
|
|
|
});
|
2020-12-22 10:49:17 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should set lastSeen on toggle', async () => {
|
|
|
|
expect.assertions(1);
|
2021-09-13 10:23:57 +02:00
|
|
|
stores.featureToggleStore.create('default', {
|
2021-07-07 10:46:50 +02:00
|
|
|
name: 'toggleLastSeen',
|
|
|
|
});
|
2020-12-22 10:49:17 +01:00
|
|
|
await request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({
|
|
|
|
appName: 'demo',
|
|
|
|
bucket: {
|
|
|
|
start: Date.now(),
|
|
|
|
stop: Date.now(),
|
|
|
|
toggles: {
|
|
|
|
toggleLastSeen: {
|
|
|
|
yes: 200,
|
|
|
|
no: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.expect(202);
|
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const toggle = await stores.featureToggleStore.get('toggleLastSeen');
|
2020-12-22 10:49:17 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(toggle.lastSeenAt).toBeTruthy();
|
2020-12-22 10:49:17 +01:00
|
|
|
});
|
2022-06-30 12:27:12 +02:00
|
|
|
|
|
|
|
test('should return a 400 when required fields are missing', async () => {
|
|
|
|
stores.featureToggleStore.create('default', {
|
|
|
|
name: 'toggleLastSeen',
|
|
|
|
});
|
|
|
|
await request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({
|
|
|
|
appName: 'demo',
|
|
|
|
bucket: {
|
|
|
|
start: Date.now(),
|
|
|
|
toggles: {
|
|
|
|
toggleLastSeen: {
|
|
|
|
yes: 200,
|
|
|
|
no: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.expect(400);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should return a 200 if required fields are there', async () => {
|
|
|
|
stores.featureToggleStore.create('default', {
|
|
|
|
name: 'toggleLastSeen',
|
|
|
|
});
|
|
|
|
await request
|
|
|
|
.post('/api/client/metrics')
|
|
|
|
.send({
|
|
|
|
appName: 'demo',
|
|
|
|
someParam: 'some-value',
|
|
|
|
somOtherParam: 'some--other-value',
|
|
|
|
bucket: {
|
|
|
|
start: Date.now(),
|
|
|
|
stop: Date.now(),
|
|
|
|
toggles: {
|
|
|
|
toggleLastSeen: {
|
|
|
|
yes: 200,
|
|
|
|
no: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.expect(202);
|
|
|
|
});
|