unleash-server
Version:
Unleash is an enterprise ready feature flag service. It provides different strategies for handling feature flags.
267 lines • 10.2 kB
JavaScript
import { createTestConfig } from '../../../test/config/test-config.js';
import { BadDataError } from '../../error/index.js';
import { RoleName, TEST_AUDIT_USER, } from '../../types/index.js';
import { createFakeProjectService } from './createProjectService.js';
import { vi } from 'vitest';
describe('enterprise extension: enable change requests', () => {
const createService = (mode = 'enterprise') => {
const config = createTestConfig();
config.isEnterprise = mode === 'enterprise';
const alwaysOnFlagResolver = {
isEnabled() {
return true;
},
};
config.flagResolver = alwaysOnFlagResolver;
const { projectService, accessService, environmentStore, eventService, projectStore, } = createFakeProjectService(config);
accessService.createRole({
name: RoleName.OWNER,
description: 'Project owner',
createdByUserId: -1,
}, TEST_AUDIT_USER);
return {
service: projectService,
environmentStore,
eventService,
projectStore,
};
};
test('it calls the change request enablement function on enterprise after creating the project', async () => {
expect.assertions(1);
const { service, projectStore } = createService();
const projectId = 'fake-project-id';
await service.createProject({
id: projectId,
name: 'fake-project-name',
changeRequestEnvironments: [],
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER, async () => {
const project = await projectStore.get(projectId);
expect(project).toBeTruthy();
return [];
});
});
test("it does not call the change request enablement function if we're not enterprise", async () => {
const { service } = createService('oss');
const fn = vi.fn();
const projectId = 'fake-project-id';
await service.createProject({
id: projectId,
name: 'fake-project-name',
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER, fn);
expect(fn).not.toHaveBeenCalled();
});
test('the emitted event contains an empty list of changeRequestEnvironments if the input had none', async () => {
expect.assertions(1);
const { service, eventService } = createService();
const projectId = 'fake-project-id';
await service.createProject({
id: projectId,
name: 'fake-project-name',
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER);
const { events } = await eventService.getEvents();
expect(events).toMatchObject([
{
type: 'project-created',
data: { changeRequestEnvironments: [] },
},
]);
});
test('the emitted event contains no changeRequestEnvironments if we are not on enterprise', async () => {
const { service, eventService } = createService('oss');
const projectId = 'fake-project-id';
await service.createProject({
id: projectId,
name: 'fake-project-name',
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER, async () => []);
const { events } = await eventService.getEvents();
expect(events[0].data.changeRequestEnvironments).toBeUndefined();
});
test('the emitted event contains the list of change request envs returned from the extension function, *not* what was passed in', async () => {
const { service, environmentStore, eventService } = createService();
await environmentStore.create({
name: 'dev',
type: 'production',
enabled: true,
protected: false,
sortOrder: 0,
});
const crEnvs = [{ name: 'prod', requiredApprovals: 10 }];
const projectId = 'fake-project-id';
await service.createProject({
id: projectId,
name: 'fake-project-name',
changeRequestEnvironments: [
{ name: 'dev', requiredApprovals: 1 },
],
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER, async () => crEnvs);
const { events } = await eventService.getEvents();
expect(events).toMatchObject([
{
type: 'project-created',
data: {
changeRequestEnvironments: [
{ name: 'prod', requiredApprovals: 10 },
],
},
},
]);
});
test('prefer env approval settings over explicit user approvals', async () => {
const { service, environmentStore, eventService } = createService();
await environmentStore.create({
name: 'dev',
type: 'production',
enabled: true,
protected: false,
sortOrder: 0,
});
await environmentStore.create({
name: 'stage',
type: 'production',
enabled: true,
protected: false,
sortOrder: 0,
requiredApprovals: 2,
});
await environmentStore.create({
name: 'prod',
type: 'production',
enabled: true,
protected: false,
sortOrder: 0,
requiredApprovals: 3,
});
const projectId = 'fake-project-id';
await service.createProject({
id: projectId,
name: 'fake-project-name',
environments: ['prod', 'stage'], // stage selected but no approvals set by user
changeRequestEnvironments: [
{ name: 'dev', requiredApprovals: 1 },
{ name: 'prod', requiredApprovals: 10 }, // ignored in favor of env config
],
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER, async (envs) => envs);
const { events } = await eventService.getEvents();
expect(events).toMatchObject([
{
type: 'project-created',
data: {
changeRequestEnvironments: [
{ name: 'dev', requiredApprovals: 1 },
{ name: 'stage', requiredApprovals: 2 },
{ name: 'prod', requiredApprovals: 3 },
],
},
},
]);
});
test('the create project function returns the list of change request envs returned from the extension function, *not* what was passed in', async () => {
const { service, environmentStore } = createService();
await environmentStore.create({
name: 'dev',
type: 'production',
enabled: true,
protected: false,
sortOrder: 0,
});
const crEnvs = [{ name: 'prod', requiredApprovals: 10 }];
const projectId = 'fake-project-id';
const result = await service.createProject({
id: projectId,
name: 'fake-project-name',
changeRequestEnvironments: [
{ name: 'dev', requiredApprovals: 1 },
],
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER, async () => crEnvs);
expect(result.changeRequestEnvironments).toStrictEqual(crEnvs);
});
test('the create project function defaults to returning an empty list if the input had no cr envs', async () => {
const { service } = createService();
const projectId = 'fake-project-id';
const result = await service.createProject({
id: projectId,
name: 'fake-project-name',
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER, async () => []);
expect(result.changeRequestEnvironments).toStrictEqual([]);
});
test('the create project function does not return a list of change request envs if we are not on enterprise', async () => {
const { service } = createService('oss');
const crEnvs = [{ name: 'prod', requiredApprovals: 10 }];
const projectId = 'fake-project-id';
const result = await service.createProject({
id: projectId,
name: 'fake-project-name',
changeRequestEnvironments: [
{ name: 'dev', requiredApprovals: 1 },
],
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER, async () => crEnvs);
expect('changeRequestEnvironments' in result).toBeFalsy();
});
test("it throws an error if you provide it with environments that don't exist", async () => {
const { service } = createService();
const projectId = 'fake-project-id';
await expect(service.createProject({
id: projectId,
name: 'fake-project-name',
changeRequestEnvironments: [
{ name: 'dev', requiredApprovals: 1 },
],
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER)).rejects.toThrow(BadDataError);
});
test("it does not throw if an error if you provide it with environments that don't exist but aren't on enterprise", async () => {
const { service } = createService('oss');
const projectId = 'fake-project-id';
await expect(service.createProject({
id: projectId,
name: 'fake-project-name',
changeRequestEnvironments: [
{ name: 'dev', requiredApprovals: 1 },
],
}, {
id: 5,
permissions: [],
isAPI: false,
}, TEST_AUDIT_USER)).resolves.toBeTruthy();
});
});
//# sourceMappingURL=project-service.test.js.map