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:
parent
c48f3ad4de
commit
d94dd31677
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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';
|
||||
|
@ -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",
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user