1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

fix: disable projects (#1085)

This commit is contained in:
Fredrik Strand Oseberg 2021-11-04 21:09:52 +01:00 committed by GitHub
parent ce16c5a77b
commit ec60f4485c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 7 deletions

View File

@ -0,0 +1,23 @@
class MinimumOneEnvironmentError extends Error {
constructor(message: string) {
super();
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = message;
}
toJSON(): object {
return {
isJoi: true,
name: this.constructor.name,
details: [
{
message: this.message,
},
],
};
}
}
export default MinimumOneEnvironmentError;
module.exports = MinimumOneEnvironmentError;

View File

@ -54,6 +54,8 @@ export const handleErrors: (
return res.status(400).json(error).end();
case 'IncompatibleProjectError':
return res.status(403).json(error).end();
case 'MinimumOneEnvironmentError':
return res.status(400).json(error).end();
default:
logger.error('Server failed executing request', error);
return res.status(500).end();

View File

@ -9,6 +9,8 @@ import NotFoundError from '../error/notfound-error';
import { IEnvironmentStore } from '../types/stores/environment-store';
import { IFeatureStrategiesStore } from '../types/stores/feature-strategies-store';
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
import { IProjectStore } from 'lib/types/stores/project-store';
import MinimumOneEnvironmentError from '../error/minimum-one-environment-error';
export default class EnvironmentService {
private logger: Logger;
@ -17,6 +19,8 @@ export default class EnvironmentService {
private featureStrategiesStore: IFeatureStrategiesStore;
private projectStore: IProjectStore;
private featureEnvironmentStore: IFeatureEnvironmentStore;
constructor(
@ -24,11 +28,13 @@ export default class EnvironmentService {
environmentStore,
featureStrategiesStore,
featureEnvironmentStore,
projectStore,
}: Pick<
IUnleashStores,
| 'environmentStore'
| 'featureStrategiesStore'
| 'featureEnvironmentStore'
| 'projectStore'
>,
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
) {
@ -36,6 +42,7 @@ export default class EnvironmentService {
this.environmentStore = environmentStore;
this.featureStrategiesStore = featureStrategiesStore;
this.featureEnvironmentStore = featureEnvironmentStore;
this.projectStore = projectStore;
}
async getAll(): Promise<IEnvironment[]> {
@ -91,13 +98,23 @@ export default class EnvironmentService {
environment: string,
projectId: string,
): Promise<void> {
await this.featureEnvironmentStore.disconnectFeatures(
environment,
const projectEnvs = await this.projectStore.getEnvironmentsForProject(
projectId,
);
await this.featureEnvironmentStore.disconnectProject(
environment,
projectId,
if (projectEnvs.length > 1) {
await this.featureEnvironmentStore.disconnectFeatures(
environment,
projectId,
);
await this.featureEnvironmentStore.disconnectProject(
environment,
projectId,
);
return;
}
throw new MinimumOneEnvironmentError(
'You must always have one active environment',
);
}
}

View File

@ -85,3 +85,20 @@ test('Should remove environment from project', async () => {
expect(envs).toHaveLength(1);
});
test('Should not remove environment from project if project only has one environment enabled', async () => {
await app.request
.delete(`/api/admin/projects/default/environments/default`)
.expect(400)
.expect((r) => {
expect(r.body.details[0].message).toBe(
'You must always have one active environment',
);
});
const envs = await db.stores.projectStore.getEnvironmentsForProject(
'default',
);
expect(envs).toHaveLength(1);
});

View File

@ -53,7 +53,12 @@ test('returns feature toggle for default env', async () => {
});
test('returns feature toggle for default env even if it is removed from project', async () => {
await app.services.environmentService.removeEnvironmentFromProject(
await db.stores.featureEnvironmentStore.disconnectFeatures(
'default',
'default',
);
await db.stores.featureEnvironmentStore.disconnectProject(
'default',
'default',
);

View File

@ -109,10 +109,11 @@ test('Adding same environment twice should throw a NameExistsError', async () =>
name: 'uniqueness-test',
type: 'production',
});
await service.addEnvironmentToProject('uniqueness-test', 'default');
await service.removeEnvironmentFromProject('test-connection', 'default');
await service.removeEnvironmentFromProject('removal-test', 'default');
await service.addEnvironmentToProject('uniqueness-test', 'default');
return expect(async () =>
service.addEnvironmentToProject('uniqueness-test', 'default'),
).rejects.toThrow(