mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-17 01:17:29 +02:00
fix: return 400 when enabling env of archived toggle (#6049)
Creates a new ArchivedFeatureError. Throw this error when trying to toggle a feature environment for an archived feature. Closes https://github.com/orgs/Unleash/projects/8/views/1?pane=issue&itemId=51242922 Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
parent
a1fa5a4212
commit
4a2d1b0364
13
src/lib/error/archivedfeature-error.ts
Normal file
13
src/lib/error/archivedfeature-error.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { UnleashError } from './unleash-error';
|
||||||
|
|
||||||
|
class ArchivedFeatureError extends UnleashError {
|
||||||
|
statusCode = 400;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
message: string = 'Cannot perform this operation on archived features',
|
||||||
|
) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ArchivedFeatureError;
|
||||||
|
module.exports = ArchivedFeatureError;
|
@ -104,6 +104,7 @@ import { IDependentFeaturesReadModel } from '../dependent-features/dependent-fea
|
|||||||
import EventService from '../events/event-service';
|
import EventService from '../events/event-service';
|
||||||
import { DependentFeaturesService } from '../dependent-features/dependent-features-service';
|
import { DependentFeaturesService } from '../dependent-features/dependent-features-service';
|
||||||
import { FeatureToggleInsert } from './feature-toggle-store';
|
import { FeatureToggleInsert } from './feature-toggle-store';
|
||||||
|
import ArchivedFeatureError from '../../error/archivedfeature-error';
|
||||||
|
|
||||||
interface IFeatureContext {
|
interface IFeatureContext {
|
||||||
featureName: string;
|
featureName: string;
|
||||||
@ -259,6 +260,17 @@ class FeatureToggleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async validateFeatureIsNotArchived(
|
||||||
|
featureName: string,
|
||||||
|
project: string,
|
||||||
|
): Promise<void> {
|
||||||
|
const toggle = await this.featureToggleStore.get(featureName);
|
||||||
|
|
||||||
|
if (toggle.archived || Boolean(toggle.archivedAt)) {
|
||||||
|
throw new ArchivedFeatureError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async validateNoChildren(featureName: string): Promise<void> {
|
async validateNoChildren(featureName: string): Promise<void> {
|
||||||
const children = await this.dependentFeaturesReadModel.getChildren([
|
const children = await this.dependentFeaturesReadModel.getChildren([
|
||||||
featureName,
|
featureName,
|
||||||
@ -1748,6 +1760,8 @@ class FeatureToggleService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.validateFeatureIsNotArchived(featureName, project);
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
const strategies = await this.getStrategiesForEnvironment(
|
const strategies = await this.getStrategiesForEnvironment(
|
||||||
project,
|
project,
|
||||||
|
@ -1707,6 +1707,50 @@ test('Disabling environment creates a FEATURE_ENVIRONMENT_DISABLED event', async
|
|||||||
expect(ourFeatureEvent).toBeTruthy();
|
expect(ourFeatureEvent).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Returns 400 when toggling environment of archived feature', async () => {
|
||||||
|
const environment = 'environment_test_archived';
|
||||||
|
const featureName = 'test_archived_feature';
|
||||||
|
|
||||||
|
// Create environment
|
||||||
|
await db.stores.environmentStore.create({
|
||||||
|
name: environment,
|
||||||
|
type: 'test',
|
||||||
|
});
|
||||||
|
// Connect environment to project
|
||||||
|
await app.request
|
||||||
|
.post('/api/admin/projects/default/environments')
|
||||||
|
.send({ environment })
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
// Create feature
|
||||||
|
await app.request
|
||||||
|
.post('/api/admin/projects/default/features')
|
||||||
|
.send({
|
||||||
|
name: featureName,
|
||||||
|
})
|
||||||
|
.set('Content-Type', 'application/json')
|
||||||
|
.expect(201);
|
||||||
|
// Archive feature
|
||||||
|
await app.request
|
||||||
|
.delete(`/api/admin/projects/default/features/${featureName}`)
|
||||||
|
.set('Content-Type', 'application/json')
|
||||||
|
.expect(202);
|
||||||
|
|
||||||
|
await app.request
|
||||||
|
.post(
|
||||||
|
`/api/admin/projects/default/features/${featureName}/environments/${environment}/strategies`,
|
||||||
|
)
|
||||||
|
.send({ name: 'default', constraints: [] })
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
await app.request
|
||||||
|
.post(
|
||||||
|
`/api/admin/projects/default/features/${featureName}/environments/${environment}/on`,
|
||||||
|
)
|
||||||
|
.set('Content-Type', 'application/json')
|
||||||
|
.expect(400);
|
||||||
|
});
|
||||||
|
|
||||||
test('Can delete strategy from feature toggle', async () => {
|
test('Can delete strategy from feature toggle', async () => {
|
||||||
const envName = 'del-strategy';
|
const envName = 'del-strategy';
|
||||||
const featureName = 'feature.strategy.toggle.delete.strategy';
|
const featureName = 'feature.strategy.toggle.delete.strategy';
|
||||||
|
Loading…
Reference in New Issue
Block a user