1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-15 01:16:22 +02:00

feat: refactor archive (#3330)

This commit is contained in:
Jaanus Sellin 2023-03-16 10:26:02 +02:00 committed by GitHub
parent c48f3ad4de
commit d94dd31677
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 57 deletions

View File

@ -53,6 +53,9 @@ export default class ProjectArchiveController extends Controller {
openApiService.validPath({
tags: ['Archive'],
operationId: 'deleteFeatures',
description:
'This endpoint deletes the specified features, that are in archive.',
summary: 'Deletes a list of features',
requestBody: createRequestSchema('batchFeaturesSchema'),
responses: { 200: emptyResponse },
}),
@ -69,11 +72,32 @@ export default class ProjectArchiveController extends Controller {
openApiService.validPath({
tags: ['Archive'],
operationId: 'reviveFeatures',
description:
'This endpoint revives the specified features.',
summary: 'Revives a list of features',
requestBody: createRequestSchema('batchFeaturesSchema'),
responses: { 200: emptyResponse },
}),
],
});
this.route({
method: 'post',
path: PATH,
handler: this.archiveFeatures,
permission: DELETE_FEATURE,
middleware: [
openApiService.validPath({
tags: ['Features'],
operationId: 'archiveFeatures',
description:
'This endpoint archives the specified features.',
summary: 'Archives a list of features',
requestBody: createRequestSchema('batchFeaturesSchema'),
responses: { 202: emptyResponse },
}),
],
});
}
async deleteFeatures(
@ -103,6 +127,22 @@ export default class ProjectArchiveController extends Controller {
await this.featureService.reviveFeatures(features, projectId, user);
res.status(200).end();
}
async archiveFeatures(
req: IAuthRequest<IProjectParam, void, BatchFeaturesSchema>,
res: Response,
): Promise<void> {
if (!this.flagResolver.isEnabled('bulkOperations')) {
throw new NotFoundError('Bulk operations are not enabled');
}
const { features } = req.body;
const { projectId } = req.params;
const userName = extractUsername(req);
await this.featureService.archiveToggles(features, userName, projectId);
res.status(202).end();
}
}
module.exports = ProjectArchiveController;

View File

@ -20,7 +20,6 @@ import { extractUsername } from '../../../util';
import { IAuthRequest } from '../../unleash-types';
import {
AdminFeaturesQuerySchema,
BatchFeaturesSchema,
CreateFeatureSchema,
CreateFeatureStrategySchema,
createRequestSchema,
@ -72,7 +71,6 @@ export interface IFeatureProjectUserParams extends ProjectParam {
}
const PATH = '/:projectId/features';
const PATH_ARCHIVE = '/:projectId/archive';
const PATH_STALE = '/:projectId/stale';
const PATH_FEATURE = `${PATH}/:featureName`;
const PATH_FEATURE_CLONE = `${PATH_FEATURE}/clone`;
@ -398,23 +396,6 @@ export default class ProjectFeaturesController extends Controller {
],
});
this.route({
method: 'post',
path: PATH_ARCHIVE,
handler: this.archiveFeatures,
permission: DELETE_FEATURE,
middleware: [
openApiService.validPath({
tags: ['Features'],
operationId: 'archiveFeatures',
description:
'This endpoint archives the specified features.',
summary: 'Archives a list of features',
requestBody: createRequestSchema('batchFeaturesSchema'),
responses: { 202: emptyResponse },
}),
],
});
this.route({
method: 'post',
path: PATH_STALE,
@ -609,22 +590,6 @@ export default class ProjectFeaturesController extends Controller {
res.status(202).send();
}
async archiveFeatures(
req: IAuthRequest<{ projectId: string }, void, BatchFeaturesSchema>,
res: Response,
): Promise<void> {
if (!this.flagResolver.isEnabled('bulkOperations')) {
throw new NotFoundError('Bulk operations are not enabled');
}
const { features } = req.body;
const { projectId } = req.params;
const userName = extractUsername(req);
await this.featureService.archiveToggles(features, userName, projectId);
res.status(202).end();
}
async staleFeatures(
req: IAuthRequest<{ projectId: string }, void, BatchStaleSchema>,
res: Response,

View File

@ -6,6 +6,15 @@ import { DEFAULT_PROJECT } from '../../../../lib/types';
let app;
let db;
const createFeatureToggle = (
featureName: string,
project = DEFAULT_PROJECT,
) => {
return app.request.post(`/api/admin/projects/${project}/features`).send({
name: featureName,
});
};
beforeAll(async () => {
db = await dbInit('archive_serial', getLogger);
app = await setupAppWithCustomConfig(db.stores, {
@ -253,3 +262,28 @@ test('can bulk revive features', async () => {
.expect(200);
}
});
test('Should be able to bulk archive features', async () => {
const featureName1 = 'archivedFeature1';
const featureName2 = 'archivedFeature2';
await createFeatureToggle(featureName1);
await createFeatureToggle(featureName2);
await app.request
.post(`/api/admin/projects/${DEFAULT_PROJECT}/archive`)
.send({
features: [featureName1, featureName2],
})
.expect(202);
const { body } = await app.request
.get(`/api/admin/archive/features/${DEFAULT_PROJECT}`)
.expect(200);
const archivedFeatures = body.features.filter(
(feature) =>
feature.name === featureName1 || feature.name === featureName2,
);
expect(archivedFeatures).toHaveLength(2);
});

View File

@ -2824,28 +2824,6 @@ test('Can query for two tags at the same time. Tags are ORed together', async ()
});
});
test('Should be able to bulk archive features', async () => {
const featureName1 = 'archivedFeature1';
const featureName2 = 'archivedFeature2';
await createFeatureToggle(featureName1);
await createFeatureToggle(featureName2);
await app.request
.post(`/api/admin/projects/${DEFAULT_PROJECT}/archive`)
.send({
features: [featureName1, featureName2],
})
.expect(202);
const { body } = await app.request
.get(`/api/admin/archive/features/${DEFAULT_PROJECT}`)
.expect(200);
expect(body).toMatchObject({
features: [{}, { name: featureName1 }, { name: featureName2 }],
});
});
test('Should batch stale features', async () => {
const staledFeatureName1 = 'staledFeature1';
const staledFeatureName2 = 'staledFeature2';

View File

@ -6082,6 +6082,7 @@ If the provided project does not exist, the list of events will be empty.",
},
"/api/admin/projects/{projectId}/archive/delete": {
"post": {
"description": "This endpoint deletes the specified features, that are in archive.",
"operationId": "deleteFeatures",
"parameters": [
{
@ -6109,6 +6110,7 @@ If the provided project does not exist, the list of events will be empty.",
"description": "This response has no body.",
},
},
"summary": "Deletes a list of features",
"tags": [
"Archive",
],
@ -6116,6 +6118,7 @@ If the provided project does not exist, the list of events will be empty.",
},
"/api/admin/projects/{projectId}/archive/revive": {
"post": {
"description": "This endpoint revives the specified features.",
"operationId": "reviveFeatures",
"parameters": [
{
@ -6143,6 +6146,7 @@ If the provided project does not exist, the list of events will be empty.",
"description": "This response has no body.",
},
},
"summary": "Revives a list of features",
"tags": [
"Archive",
],