1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-01 01:18:10 +02:00
unleash.unleash/src/lib/db/segment-store.test.ts
Thomas Heartman dc1aaf6d99
chore: only return change request data if the unleash instance is an enterprise instance (#5331)
Otherwise, we might accidentally display CR data to open source users.
But more importantly, it might keep them from being able to delete a
segment that's in use by a CR in their database that they can't touch.

So by checking that they're on an enterprise instance, we avoid this
potential blocker.

I've added the `includeChangeRequestUsageData` parameter as a boolean
now, but I'm open to other suggestions.
2023-11-22 12:15:29 +00:00

220 lines
6.6 KiB
TypeScript

import { ISegmentStore } from '../types/stores/segment-store';
import dbInit from '../../test/e2e/helpers/database-init';
import getLogger from '../../test/fixtures/no-logger';
import NotFoundError from '../error/notfound-error';
let stores;
let db;
let segmentStore: ISegmentStore;
beforeAll(async () => {
db = await dbInit('segment_store_serial', getLogger, {
experimental: {
flags: {
detectSegmentUsageInChangeRequests: true,
},
},
});
stores = db.stores;
segmentStore = stores.segmentStore;
});
afterAll(async () => {
await db.destroy();
});
describe('unexpected input handling for get segment', () => {
test("gives a NotFoundError with the ID of the segment if it doesn't exist", async () => {
const id = 123;
try {
await segmentStore.get(id);
} catch (e) {
expect(e instanceof NotFoundError).toBeTruthy();
expect(e.message).toEqual(expect.stringMatching(id.toString()));
}
});
});
describe('usage counting', () => {
let user;
beforeAll(async () => {
user = await db.stores.userStore.insert({
username: 'test',
});
});
afterEach(async () => {
await db.stores.featureToggleStore.deleteAll();
await db.stores.segmentStore.deleteAll();
await db.rawDatabase.table('change_requests').delete();
});
test('segment usage in active CRs is counted iff we ask for it', async () => {
const CR_ID = 54321;
const flag1 = await db.stores.featureToggleStore.create('default', {
name: 'test',
});
const flag2 = await db.stores.featureToggleStore.create('default', {
name: 'test2',
});
const segment = await segmentStore.create(
{
name: 'cr-segment',
constraints: [],
createdAt: new Date(),
},
user,
);
await db.rawDatabase.table('change_requests').insert({
id: CR_ID,
environment: 'default',
state: 'In Review',
project: 'default',
created_by: user.id,
created_at: '2023-01-01 00:00:00',
min_approvals: 1,
title: 'My change request',
});
await db.rawDatabase.table('change_request_events').insert({
feature: flag1.name,
action: 'addStrategy',
payload: {
name: 'flexibleRollout',
title: '',
disabled: false,
segments: [segment.id],
variants: [],
parameters: {
groupId: flag1.name,
rollout: '100',
stickiness: 'default',
},
constraints: [],
},
created_at: '2023-01-01 00:01:00',
change_request_id: CR_ID,
created_by: user.id,
});
await db.rawDatabase.table('change_request_events').insert({
feature: flag2.name,
action: 'updateStrategy',
payload: {
strategyId: 'not-a-real-strategy-id',
name: 'flexibleRollout',
title: '',
disabled: false,
segments: [segment.id],
variants: [],
parameters: {
groupId: flag2.name,
rollout: '100',
stickiness: 'default',
},
constraints: [],
},
created_at: '2023-01-01 00:01:00',
change_request_id: CR_ID,
created_by: user.id,
});
const [enterpriseData] = await segmentStore.getAll(true);
expect(enterpriseData.usedInFeatures).toBe(2);
expect(enterpriseData.usedInProjects).toBe(1);
const [ossData] = await segmentStore.getAll(false);
expect(ossData.usedInFeatures).toBe(0);
expect(ossData.usedInProjects).toBe(0);
});
test('Segment usage is only counted once per feature', async () => {
// if the segment is used on a feature, but there is also a
// change request updateStrategy event for the same feature, the
// feature should only be counted once
const CR_ID = 54321;
const flag = await db.stores.featureToggleStore.create('default', {
name: 'test',
});
const segment1 = await segmentStore.create(
{
name: 'cr-segment',
constraints: [],
createdAt: new Date(),
},
user,
);
const segment2 = await segmentStore.create(
{
name: 'cr-segment-2',
constraints: [],
createdAt: new Date(),
},
user,
);
const strategy =
await stores.featureStrategiesStore.createStrategyFeatureEnv({
featureName: flag.name,
projectId: 'default',
environment: 'default',
strategyName: 'flexibleRollout',
segments: [segment1.id],
parameters: {
groupId: flag.name,
rollout: '100',
stickiness: 'default',
},
});
await db.rawDatabase.table('change_requests').insert({
id: CR_ID,
environment: 'default',
state: 'In Review',
project: 'default',
created_by: user.id,
created_at: '2023-01-01 00:00:00',
min_approvals: 1,
title: 'My change request',
});
await db.rawDatabase.table('change_request_events').insert({
feature: flag.name,
action: 'updateStrategy',
payload: {
strategyId: strategy.id,
name: 'flexibleRollout',
title: '',
disabled: false,
segments: [segment1.id, segment2.id],
variants: [],
parameters: {
groupId: flag.name,
rollout: '100',
stickiness: 'default',
},
constraints: [],
},
created_at: '2023-01-01 00:01:00',
change_request_id: CR_ID,
created_by: user.id,
});
const storedSegments = await segmentStore.getAll(true);
expect(storedSegments).toMatchObject([
{ usedInFeatures: 1, usedInProjects: 1 },
{ usedInFeatures: 1, usedInProjects: 1 },
]);
});
});