mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-06 00:07:44 +01:00
87d9497be9
https://linear.app/unleash/issue/2-1403/consider-refactoring-the-way-tags-are-fetched-for-the-events This adds 2 methods to `EventService`: - `storeEvent`; - `storeEvents`; This allows us to run event-specific logic inside these methods. In the case of this PR, this means fetching the feature tags in case the event contains a `featureName` and there are no tags specified in the event. This prevents us from having to remember to fetch the tags in order to store feature-related events except for very specific cases, like the deletion of a feature - You can't fetch tags for a feature that no longer exists, so in that case we need to pre-fetch the tags before deleting the feature. This also allows us to do any event-specific post-processing to the event before reaching the DB layer. In general I think it's also nicer that we reference the event service instead of the event store directly. There's a lot of changes and a lot of files touched, but most of it is boilerplate to inject the `eventService` where needed instead of using the `eventStore` directly. Hopefully this will be a better approach than https://github.com/Unleash/unleash/pull/4729 --------- Co-authored-by: Gastón Fournier <gaston@getunleash.io>
142 lines
4.0 KiB
TypeScript
142 lines
4.0 KiB
TypeScript
import {
|
|
IUnleashTest,
|
|
setupAppWithCustomConfig,
|
|
} from '../../helpers/test-helper';
|
|
import dbInit, { ITestDb } from '../../helpers/database-init';
|
|
import getLogger from '../../../fixtures/no-logger';
|
|
import { FEATURE_CREATED, IBaseEvent } from '../../../../lib/types/events';
|
|
import { randomId } from '../../../../lib/util/random-id';
|
|
import { EventService } from '../../../../lib/services';
|
|
|
|
let app: IUnleashTest;
|
|
let db: ITestDb;
|
|
let eventService: EventService;
|
|
|
|
beforeAll(async () => {
|
|
db = await dbInit('event_api_serial', getLogger);
|
|
app = await setupAppWithCustomConfig(db.stores, {
|
|
experimental: {
|
|
flags: {
|
|
strictSchemaValidation: true,
|
|
},
|
|
},
|
|
});
|
|
eventService = new EventService(db.stores, { getLogger });
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await db.stores.eventStore.deleteAll();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await app.destroy();
|
|
await db.destroy();
|
|
});
|
|
|
|
test('returns events', async () => {
|
|
expect.assertions(0);
|
|
return app.request
|
|
.get('/api/admin/events')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200);
|
|
});
|
|
|
|
test('returns events given a name', async () => {
|
|
expect.assertions(0);
|
|
return app.request
|
|
.get('/api/admin/events/myname')
|
|
.expect('Content-Type', /json/)
|
|
.expect(200);
|
|
});
|
|
|
|
test('Can filter by project', async () => {
|
|
await eventService.storeEvent({
|
|
type: FEATURE_CREATED,
|
|
project: 'something-else',
|
|
data: { id: 'some-other-feature' },
|
|
tags: [],
|
|
createdBy: 'test-user',
|
|
environment: 'test',
|
|
});
|
|
await eventService.storeEvent({
|
|
type: FEATURE_CREATED,
|
|
project: 'default',
|
|
data: { id: 'feature' },
|
|
tags: [],
|
|
createdBy: 'test-user',
|
|
environment: 'test',
|
|
});
|
|
await app.request
|
|
.get('/api/admin/events?project=default')
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body.events).toHaveLength(1);
|
|
expect(res.body.events[0].data.id).toEqual('feature');
|
|
});
|
|
});
|
|
|
|
test('can search for events', async () => {
|
|
const events: IBaseEvent[] = [
|
|
{
|
|
type: FEATURE_CREATED,
|
|
project: randomId(),
|
|
data: { id: randomId() },
|
|
tags: [],
|
|
createdBy: randomId(),
|
|
},
|
|
{
|
|
type: FEATURE_CREATED,
|
|
project: randomId(),
|
|
data: { id: randomId() },
|
|
preData: { id: randomId() },
|
|
tags: [{ type: 'simple', value: randomId() }],
|
|
createdBy: randomId(),
|
|
},
|
|
];
|
|
|
|
await Promise.all(
|
|
events.map((event) => {
|
|
return eventService.storeEvent(event);
|
|
}),
|
|
);
|
|
|
|
await app.request
|
|
.post('/api/admin/events/search')
|
|
.send({})
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body.events).toHaveLength(2);
|
|
});
|
|
await app.request
|
|
.post('/api/admin/events/search')
|
|
.send({ limit: 1, offset: 1 })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body.events).toHaveLength(1);
|
|
});
|
|
await app.request
|
|
.post('/api/admin/events/search')
|
|
.send({ query: events[1].data.id })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body.events).toHaveLength(1);
|
|
expect(res.body.events[0].data.id).toEqual(events[1].data.id);
|
|
});
|
|
await app.request
|
|
.post('/api/admin/events/search')
|
|
.send({ query: events[1].preData.id })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body.events).toHaveLength(1);
|
|
expect(res.body.events[0].preData.id).toEqual(events[1].preData.id);
|
|
});
|
|
await app.request
|
|
.post('/api/admin/events/search')
|
|
.send({ query: events[1].tags![0].value })
|
|
.expect(200)
|
|
.expect((res) => {
|
|
expect(res.body.events).toHaveLength(1);
|
|
expect(res.body.events[0].data.id).toEqual(events[1].data.id);
|
|
});
|
|
});
|