mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
chore!: remove deprecated POST events search endpoint (#10030)
https://linear.app/unleash/issue/2-3368/remove-post-apiadmineventssearch-deprecated-in-610 Removes POST `/api/admin/events/search` which was deprecated in v6.1. Also cleans up related code.
This commit is contained in:
parent
45434109a9
commit
290ef6ca40
@ -2,17 +2,21 @@ import dbInit, {
|
||||
type ITestDb,
|
||||
} from '../../../test/e2e/helpers/database-init.js';
|
||||
import {
|
||||
createUserWithRootRole,
|
||||
type IUnleashTest,
|
||||
setupAppWithCustomConfig,
|
||||
setupAppWithAuth,
|
||||
} from '../../../test/e2e/helpers/test-helper.js';
|
||||
import getLogger from '../../../test/fixtures/no-logger.js';
|
||||
import { RoleName } from '../../types/index.js';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
|
||||
const adminEmail = 'admin-user@getunleash.io';
|
||||
|
||||
beforeAll(async () => {
|
||||
db = await dbInit('tag_types_api_serial', getLogger);
|
||||
app = await setupAppWithCustomConfig(
|
||||
app = await setupAppWithAuth(
|
||||
db.stores,
|
||||
{
|
||||
experimental: {
|
||||
@ -23,6 +27,17 @@ beforeAll(async () => {
|
||||
},
|
||||
db.rawDatabase,
|
||||
);
|
||||
|
||||
await createUserWithRootRole({
|
||||
app,
|
||||
stores: db.stores,
|
||||
email: adminEmail,
|
||||
roleName: RoleName.ADMIN,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await app.login({ email: adminEmail });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
|
@ -18,8 +18,6 @@ import {
|
||||
type FeatureEventsSchema,
|
||||
} from '../../../lib/openapi/spec/feature-events-schema.js';
|
||||
import { getStandardResponses } from '../../../lib/openapi/util/standard-responses.js';
|
||||
import { createRequestSchema } from '../../openapi/util/create-request-schema.js';
|
||||
import type { DeprecatedSearchEventsSchema } from '../../openapi/spec/deprecated-search-events-schema.js';
|
||||
import type { IFlagResolver } from '../../types/experimental.js';
|
||||
import type { IAuthRequest } from '../unleash-types.js';
|
||||
import {
|
||||
@ -100,27 +98,6 @@ export default class EventController extends Controller {
|
||||
],
|
||||
});
|
||||
|
||||
this.route({
|
||||
method: 'post',
|
||||
path: '/events/search',
|
||||
handler: this.deprecatedSearchEvents,
|
||||
permission: NONE,
|
||||
middleware: [
|
||||
openApiService.validPath({
|
||||
operationId: 'deprecatedSearchEvents',
|
||||
tags: ['Events'],
|
||||
deprecated: true,
|
||||
summary: 'Search for events (deprecated)',
|
||||
description:
|
||||
'Allows searching for events matching the search criteria in the request body',
|
||||
requestBody: createRequestSchema(
|
||||
'deprecatedSearchEventsSchema',
|
||||
),
|
||||
responses: { 200: createResponseSchema('eventsSchema') },
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
this.route({
|
||||
method: 'get',
|
||||
path: '/event-creators',
|
||||
@ -201,28 +178,6 @@ export default class EventController extends Controller {
|
||||
);
|
||||
}
|
||||
|
||||
async deprecatedSearchEvents(
|
||||
req: Request<unknown, unknown, DeprecatedSearchEventsSchema>,
|
||||
res: Response<EventsSchema>,
|
||||
): Promise<void> {
|
||||
const eventList = await this.eventService.deprecatedSearchEvents(
|
||||
req.body,
|
||||
);
|
||||
|
||||
const response = {
|
||||
version,
|
||||
events: serializeDates(this.maybeAnonymiseEvents(eventList.events)),
|
||||
totalEvents: eventList.totalEvents,
|
||||
};
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
featureEventsSchema.$id,
|
||||
response,
|
||||
);
|
||||
}
|
||||
|
||||
async getEventCreators(
|
||||
req: IAuthRequest,
|
||||
res: Response<ProjectFlagCreatorsSchema>,
|
||||
|
@ -6,66 +6,26 @@ import {
|
||||
type IUnleashStores,
|
||||
RoleName,
|
||||
} from '../../../../lib/types/index.js';
|
||||
import type {
|
||||
AccessService,
|
||||
EventService,
|
||||
} from '../../../../lib/services/index.js';
|
||||
import type { EventService } from '../../../../lib/services/index.js';
|
||||
import getLogger from '../../../fixtures/no-logger.js';
|
||||
import {
|
||||
createUserWithRootRole,
|
||||
type IUnleashTest,
|
||||
setupAppWithAuth,
|
||||
} from '../../helpers/test-helper.js';
|
||||
import { createEventsService } from '../../../../lib/features/index.js';
|
||||
import { createTestConfig } from '../../../config/test-config.js';
|
||||
import type { IRole } from '../../../../lib/types/stores/access-store.js';
|
||||
import { FEATURE_CREATED, USER_CREATED } from '../../../../lib/events/index.js';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
let eventService: EventService;
|
||||
const TEST_USER_ID = -9999;
|
||||
const regularUserName = 'import-user';
|
||||
const adminUserName = 'admin-user';
|
||||
const regularEmail = 'import-user@getunleash.io';
|
||||
const adminEmail = 'admin-user@getunleash.io';
|
||||
|
||||
const config: IUnleashConfig = createTestConfig();
|
||||
let adminRole: IRole;
|
||||
let stores: IUnleashStores;
|
||||
let accessService: AccessService;
|
||||
|
||||
const loginRegularUser = () =>
|
||||
app.request
|
||||
.post(`/auth/demo/login`)
|
||||
.send({
|
||||
email: `${regularUserName}@getunleash.io`,
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
const loginAdminUser = () =>
|
||||
app.request
|
||||
.post(`/auth/demo/login`)
|
||||
.send({
|
||||
email: `${adminUserName}@getunleash.io`,
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
const createUserEditorAccess = async (name, email) => {
|
||||
const { userStore } = stores;
|
||||
const user = await userStore.insert({
|
||||
name,
|
||||
email,
|
||||
});
|
||||
return user;
|
||||
};
|
||||
|
||||
const createUserAdminAccess = async (name, email) => {
|
||||
const { userStore } = stores;
|
||||
const user = await userStore.insert({
|
||||
name,
|
||||
email,
|
||||
});
|
||||
await accessService.addUserToRole(user.id, adminRole.id, 'default');
|
||||
return user;
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
db = await dbInit('event_search', getLogger);
|
||||
@ -84,19 +44,18 @@ beforeAll(async () => {
|
||||
|
||||
eventService = createEventsService(db.rawDatabase, config);
|
||||
|
||||
accessService = app.services.accessService;
|
||||
await createUserWithRootRole({
|
||||
app,
|
||||
stores,
|
||||
email: regularEmail,
|
||||
});
|
||||
|
||||
const roles = await accessService.getRootRoles();
|
||||
adminRole = roles.find((role) => role.name === RoleName.ADMIN)!;
|
||||
|
||||
await createUserEditorAccess(
|
||||
regularUserName,
|
||||
`${regularUserName}@getunleash.io`,
|
||||
);
|
||||
await createUserAdminAccess(
|
||||
adminUserName,
|
||||
`${adminUserName}@getunleash.io`,
|
||||
);
|
||||
await createUserWithRootRole({
|
||||
app,
|
||||
stores,
|
||||
email: adminEmail,
|
||||
roleName: RoleName.ADMIN,
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@ -105,7 +64,7 @@ afterAll(async () => {
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await loginAdminUser();
|
||||
await app.login({ email: adminEmail });
|
||||
await db.stores.featureToggleStore.deleteAll();
|
||||
await db.stores.segmentStore.deleteAll();
|
||||
await db.stores.eventStore.deleteAll();
|
||||
@ -522,7 +481,7 @@ test('should filter events by project using IS_ANY_OF', async () => {
|
||||
});
|
||||
|
||||
test('should not show user creation events for non-admins', async () => {
|
||||
await loginRegularUser();
|
||||
await app.login({ email: regularEmail });
|
||||
await eventService.storeEvent({
|
||||
type: USER_CREATED,
|
||||
createdBy: 'test-user',
|
||||
|
@ -90,75 +90,6 @@ test('Can filter by project', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('can search for events', async () => {
|
||||
const events: IBaseEvent[] = [
|
||||
{
|
||||
type: FEATURE_CREATED,
|
||||
project: randomId(),
|
||||
data: { id: randomId() },
|
||||
tags: [],
|
||||
createdBy: randomId(),
|
||||
createdByUserId: TEST_USER_ID,
|
||||
ip: '127.0.0.1',
|
||||
},
|
||||
{
|
||||
type: FEATURE_CREATED,
|
||||
project: randomId(),
|
||||
data: { id: randomId() },
|
||||
preData: { id: randomId() },
|
||||
tags: [{ type: 'simple', value: randomId() }],
|
||||
createdBy: randomId(),
|
||||
createdByUserId: TEST_USER_ID,
|
||||
ip: '127.0.0.1',
|
||||
},
|
||||
];
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
test('event creators - if system user, return system name, else should return name from database if user exists, else from events table', async () => {
|
||||
const user = await db.stores.userStore.insert({ name: 'database-user' });
|
||||
const events: IBaseEvent[] = [
|
||||
|
@ -1,18 +1,22 @@
|
||||
import dbInit, { type ITestDb } from '../../helpers/database-init.js';
|
||||
import getLogger from '../../../fixtures/no-logger.js';
|
||||
import {
|
||||
createUserWithRootRole,
|
||||
type IUnleashTest,
|
||||
setupAppWithCustomConfig,
|
||||
setupAppWithAuth,
|
||||
} from '../../helpers/test-helper.js';
|
||||
import { validateSchema } from '../../../../lib/openapi/validate.js';
|
||||
import { featureTypesSchema } from '../../../../lib/openapi/spec/feature-types-schema.js';
|
||||
import { RoleName } from '../../../../lib/types/index.js';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
|
||||
const adminEmail = 'admin-user@getunleash.io';
|
||||
|
||||
beforeAll(async () => {
|
||||
db = await dbInit('feature_type_api_serial', getLogger);
|
||||
app = await setupAppWithCustomConfig(
|
||||
app = await setupAppWithAuth(
|
||||
db.stores,
|
||||
{
|
||||
experimental: {
|
||||
@ -23,6 +27,17 @@ beforeAll(async () => {
|
||||
},
|
||||
db.rawDatabase,
|
||||
);
|
||||
|
||||
await createUserWithRootRole({
|
||||
app,
|
||||
stores: db.stores,
|
||||
email: adminEmail,
|
||||
roleName: RoleName.ADMIN,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await app.login({ email: adminEmail });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
|
@ -24,9 +24,23 @@ import type { Knex } from 'knex';
|
||||
import type TestAgent from 'supertest/lib/agent.d.ts';
|
||||
import type Test from 'supertest/lib/test.d.ts';
|
||||
import type { Server } from 'node:http';
|
||||
import { initialServiceSetup } from '../../../lib/server-impl.js';
|
||||
import {
|
||||
initialServiceSetup,
|
||||
type IUser,
|
||||
type RoleName,
|
||||
} from '../../../lib/server-impl.js';
|
||||
import type { EventSearchQueryParameters } from '../../../lib/openapi/spec/event-search-query-parameters.js';
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
type DemoLoginArgs = {
|
||||
email: string;
|
||||
};
|
||||
|
||||
type SimpleLoginArgs = {
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
export interface IUnleashTest extends IUnleashHttpAPI {
|
||||
request: TestAgent<Test>;
|
||||
destroy: () => Promise<void>;
|
||||
@ -115,7 +129,10 @@ export interface IUnleashHttpAPI {
|
||||
expectedResponseCode?: number,
|
||||
): supertest.Test;
|
||||
|
||||
getRecordedEvents(): supertest.Test;
|
||||
getRecordedEvents(
|
||||
queryParams?: EventSearchQueryParameters,
|
||||
expectedResponseCode?: number,
|
||||
): supertest.Test;
|
||||
|
||||
createSegment(postData: object, expectStatusCode?: number): supertest.Test;
|
||||
deleteSegment(
|
||||
@ -127,6 +144,8 @@ export interface IUnleashHttpAPI {
|
||||
postData: object,
|
||||
expectStatusCode?: number,
|
||||
): supertest.Test;
|
||||
|
||||
login(args: DemoLoginArgs | SimpleLoginArgs): supertest.Test;
|
||||
}
|
||||
|
||||
function httpApis(
|
||||
@ -318,15 +337,32 @@ function httpApis(
|
||||
.expect(expectStatusCode);
|
||||
},
|
||||
getRecordedEvents(
|
||||
project: string | null = null,
|
||||
queryParams: EventSearchQueryParameters = {},
|
||||
expectedResponseCode: number = 200,
|
||||
): supertest.Test {
|
||||
const query = new URLSearchParams(queryParams as any).toString();
|
||||
return request
|
||||
.post('/api/admin/events/search')
|
||||
.send({ project, query: '', limit: 50, offset: 0 })
|
||||
.set('Content-Type', 'application/json')
|
||||
.get(`/api/admin/search/events${query ? `?${query}` : ''}`)
|
||||
.expect(expectedResponseCode);
|
||||
},
|
||||
login(args: DemoLoginArgs | SimpleLoginArgs): supertest.Test {
|
||||
if ('email' in args) {
|
||||
const { email } = args;
|
||||
return request
|
||||
.post(`${base}/auth/demo/login`)
|
||||
.send({ email })
|
||||
.expect(200);
|
||||
}
|
||||
|
||||
const { username, password } = args;
|
||||
return request
|
||||
.post(`${base}/auth/simple/login`)
|
||||
.send({
|
||||
username,
|
||||
password,
|
||||
} as SimpleLoginArgs)
|
||||
.expect(200);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -509,3 +545,39 @@ export const insertFeatureEnvironmentsLastSeen = async (
|
||||
|
||||
return date;
|
||||
};
|
||||
|
||||
export const createUserWithRootRole = async ({
|
||||
app,
|
||||
stores,
|
||||
email,
|
||||
name = email,
|
||||
roleName,
|
||||
}: {
|
||||
app: IUnleashTest;
|
||||
stores: IUnleashStores;
|
||||
name?: string;
|
||||
email: string;
|
||||
roleName?: RoleName;
|
||||
}): Promise<IUser> => {
|
||||
const createdUser = await stores.userStore.insert({
|
||||
name,
|
||||
email,
|
||||
});
|
||||
|
||||
if (roleName) {
|
||||
const roles = await app.services.accessService.getRootRoles();
|
||||
const role = roles.find((role) => role.name === roleName);
|
||||
|
||||
if (!role) {
|
||||
throw new Error(`Role ${roleName} not found`);
|
||||
}
|
||||
|
||||
await app.services.accessService.addUserToRole(
|
||||
createdUser.id,
|
||||
role.id,
|
||||
'default',
|
||||
);
|
||||
}
|
||||
|
||||
return createdUser;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user