mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-11 00:08:30 +01:00
feat: check if child and parent are in the same project (#5093)
This commit is contained in:
parent
7195a63e56
commit
56892c54d9
@ -96,9 +96,10 @@ export class DependentFeaturesService {
|
||||
);
|
||||
}
|
||||
|
||||
const [children, parentExists] = await Promise.all([
|
||||
const [children, parentExists, sameProject] = await Promise.all([
|
||||
this.dependentFeaturesReadModel.getChildren([child]),
|
||||
this.featuresReadModel.featureExists(parent),
|
||||
this.featuresReadModel.featuresInTheSameProject(child, parent),
|
||||
]);
|
||||
|
||||
if (children.length > 0) {
|
||||
@ -113,6 +114,12 @@ export class DependentFeaturesService {
|
||||
);
|
||||
}
|
||||
|
||||
if (!sameProject) {
|
||||
throw new InvalidOperationError(
|
||||
'Parent and child features should be in the same project',
|
||||
);
|
||||
}
|
||||
|
||||
const featureDependency: FeatureDependency =
|
||||
enabled === false
|
||||
? {
|
||||
|
@ -11,7 +11,9 @@ import {
|
||||
FEATURE_DEPENDENCY_ADDED,
|
||||
FEATURE_DEPENDENCY_REMOVED,
|
||||
IEventStore,
|
||||
IUser,
|
||||
} from '../../types';
|
||||
import { ProjectService } from '../../services';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
@ -34,6 +36,15 @@ beforeAll(async () => {
|
||||
eventStore = db.stores.eventStore;
|
||||
});
|
||||
|
||||
const createProject = async (name: string) => {
|
||||
await db.stores.projectStore.create({
|
||||
name: name,
|
||||
description: '',
|
||||
id: name,
|
||||
mode: 'open' as const,
|
||||
});
|
||||
};
|
||||
|
||||
const getRecordedEventTypesForDependencies = async () =>
|
||||
(await eventStore.getEvents())
|
||||
.map((event) => event.type)
|
||||
@ -207,3 +218,19 @@ test('should not allow to add dependency to self', async () => {
|
||||
403,
|
||||
);
|
||||
});
|
||||
|
||||
test('should not allow to add dependency to feature from another project', async () => {
|
||||
const child = uuidv4();
|
||||
const parent = uuidv4();
|
||||
await app.createFeature(parent);
|
||||
await createProject('another-project');
|
||||
await app.createFeature(child, 'another-project');
|
||||
|
||||
await addFeatureDependency(
|
||||
child,
|
||||
{
|
||||
feature: parent,
|
||||
},
|
||||
403,
|
||||
);
|
||||
});
|
||||
|
@ -4,4 +4,11 @@ export class FakeFeaturesReadModel implements IFeaturesReadModel {
|
||||
featureExists(): Promise<boolean> {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
featuresInTheSameProject(
|
||||
featureA: string,
|
||||
featureB: string,
|
||||
): Promise<boolean> {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
|
@ -16,4 +16,14 @@ export class FeaturesReadModel implements IFeaturesReadModel {
|
||||
|
||||
return rows.length > 0;
|
||||
}
|
||||
|
||||
async featuresInTheSameProject(
|
||||
featureA: string,
|
||||
featureB: string,
|
||||
): Promise<boolean> {
|
||||
const rows = await this.db('features')
|
||||
.countDistinct('project as count')
|
||||
.whereIn('name', [featureA, featureB]);
|
||||
return Number(rows[0].count) === 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
export interface IFeaturesReadModel {
|
||||
featureExists(parent: string): Promise<boolean>;
|
||||
featuresInTheSameProject(
|
||||
featureA: string,
|
||||
featureB: string,
|
||||
): Promise<boolean>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user