From 7e938a21b4fefe1a06579d054afef6dea20122b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20G=C3=B3is?= Date: Wed, 4 May 2022 07:45:29 +0100 Subject: [PATCH] feat: show archived toggles on a project level (#1555) * feat: show archived toggles on a project level * refactor: split behaviour in 2 separate routes and methods for clarity * add e2e test --- src/lib/routes/admin-api/archive.ts | 27 +++++++++++ src/lib/services/feature-toggle-service.ts | 7 +++ src/test/e2e/api/admin/archive.test.ts | 52 ++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/src/lib/routes/admin-api/archive.ts b/src/lib/routes/admin-api/archive.ts index 056bb18d4e..01c0a230d6 100644 --- a/src/lib/routes/admin-api/archive.ts +++ b/src/lib/routes/admin-api/archive.ts @@ -42,6 +42,20 @@ export default class ArchiveController extends Controller { ], }); + this.route({ + method: 'get', + path: '/features/:projectId', + acceptAnyContentType: true, + handler: this.getArchivedFeaturesByProjectId, + middleware: [ + openApiService.validPath({ + tags: ['admin'], + responses: { 200: featuresResponse }, + deprecated: true, + }), + ], + }); + this.delete('/:featureName', this.deleteFeature, DELETE_FEATURE); this.post( '/revive/:featureName', @@ -60,6 +74,19 @@ export default class ArchiveController extends Controller { res.json({ version: 2, features }); } + async getArchivedFeaturesByProjectId( + req: Request<{ projectId: string }, any, any, any>, + res: Response, + ): Promise { + const { projectId } = req.params; + const features = + await this.featureService.getMetadataForAllFeaturesByProjectId( + true, + projectId, + ); + res.json({ version: 2, features }); + } + async deleteFeature( req: IAuthRequest, res: Response, diff --git a/src/lib/services/feature-toggle-service.ts b/src/lib/services/feature-toggle-service.ts index 7bd7ed0233..d8fe322f1f 100644 --- a/src/lib/services/feature-toggle-service.ts +++ b/src/lib/services/feature-toggle-service.ts @@ -997,6 +997,13 @@ class FeatureToggleService { return this.featureToggleStore.getAll({ archived }); } + async getMetadataForAllFeaturesByProjectId( + archived: boolean, + project: string, + ): Promise { + return this.featureToggleStore.getAll({ archived, project }); + } + async getProjectId(name: string): Promise { return this.featureToggleStore.getProjectId(name); } diff --git a/src/test/e2e/api/admin/archive.test.ts b/src/test/e2e/api/admin/archive.test.ts index 4c94cdb733..80f20a8504 100644 --- a/src/test/e2e/api/admin/archive.test.ts +++ b/src/test/e2e/api/admin/archive.test.ts @@ -68,6 +68,58 @@ test('Should get archived toggles via admin', async () => { }); }); +test('Should get archived toggles via project', async () => { + await db.stores.featureToggleStore.deleteAll(); + + await db.stores.projectStore.create({ + id: 'proj-1', + name: 'proj-1', + description: '', + }); + await db.stores.projectStore.create({ + id: 'proj-2', + name: 'proj-2', + description: '', + }); + + await db.stores.featureToggleStore.create('proj-1', { + name: 'feat-proj-1', + archived: true, + }); + await db.stores.featureToggleStore.create('proj-2', { + name: 'feat-proj-2', + archived: true, + }); + await db.stores.featureToggleStore.create('proj-2', { + name: 'feat-proj-2-2', + archived: true, + }); + + await app.request + .get('/api/admin/archive/features/proj-1') + .expect(200) + .expect('Content-Type', /json/) + .expect((res) => { + expect(res.body.features).toHaveLength(1); + }); + + await app.request + .get('/api/admin/archive/features/proj-2') + .expect(200) + .expect('Content-Type', /json/) + .expect((res) => { + expect(res.body.features).toHaveLength(2); + }); + + await app.request + .get('/api/admin/archive/features') + .expect(200) + .expect('Content-Type', /json/) + .expect((res) => { + expect(res.body.features).toHaveLength(3); + }); +}); + test('Should be able to revive toggle', async () => { await app.request.post('/api/admin/projects/default/features').send({ name: 'archived.revival',