2021-08-12 15:04:37 +02:00
|
|
|
import { ValidationError } from 'joi';
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
import getLogger from '../../test/fixtures/no-logger';
|
2023-11-29 11:44:56 +01:00
|
|
|
import TagTypeService from '../features/tag-type/tag-type-service';
|
2021-08-12 15:04:37 +02:00
|
|
|
import {
|
2021-01-19 10:42:45 +01:00
|
|
|
ADDON_CONFIG_CREATED,
|
|
|
|
ADDON_CONFIG_DELETED,
|
2021-08-12 15:04:37 +02:00
|
|
|
ADDON_CONFIG_UPDATED,
|
|
|
|
FEATURE_CREATED,
|
|
|
|
} from '../types/events';
|
|
|
|
import createStores from '../../test/fixtures/store';
|
2021-02-04 11:02:58 +01:00
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
import AddonService from './addon-service';
|
|
|
|
import { IAddonDto } from '../types/stores/addon-store';
|
|
|
|
import SimpleAddon from './addon-service-test-simple-addon';
|
2022-07-12 14:13:25 +02:00
|
|
|
import { IAddonProviders } from '../addons';
|
2023-09-27 15:23:05 +02:00
|
|
|
import EventService from './event-service';
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const MASKED_VALUE = '*****';
|
2021-05-28 11:10:24 +02:00
|
|
|
|
2022-07-12 14:13:25 +02:00
|
|
|
let addonProvider: IAddonProviders;
|
2021-01-19 10:42:45 +01:00
|
|
|
|
|
|
|
function getSetup() {
|
2021-08-12 15:04:37 +02:00
|
|
|
const stores = createStores();
|
2023-09-27 15:23:05 +02:00
|
|
|
const eventService = new EventService(stores, { getLogger });
|
|
|
|
const tagTypeService = new TagTypeService(
|
|
|
|
stores,
|
|
|
|
{ getLogger },
|
|
|
|
eventService,
|
|
|
|
);
|
2021-08-12 15:04:37 +02:00
|
|
|
|
2022-07-12 14:13:25 +02:00
|
|
|
addonProvider = { simple: new SimpleAddon() };
|
2021-01-19 10:42:45 +01:00
|
|
|
return {
|
2021-04-27 09:16:44 +02:00
|
|
|
addonService: new AddonService(
|
|
|
|
stores,
|
2021-08-12 15:04:37 +02:00
|
|
|
{
|
|
|
|
getLogger,
|
|
|
|
// @ts-ignore
|
|
|
|
server: { unleashUrl: 'http://test' },
|
|
|
|
},
|
2021-04-27 09:16:44 +02:00
|
|
|
tagTypeService,
|
2023-09-27 15:23:05 +02:00
|
|
|
eventService,
|
2021-08-12 15:04:37 +02:00
|
|
|
addonProvider,
|
2021-04-27 09:16:44 +02:00
|
|
|
),
|
2023-09-27 15:23:05 +02:00
|
|
|
eventService,
|
2021-01-19 10:42:45 +01:00
|
|
|
stores,
|
|
|
|
tagTypeService,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should load addon configurations', async () => {
|
2021-01-19 10:42:45 +01:00
|
|
|
const { addonService } = getSetup();
|
|
|
|
|
|
|
|
const configs = await addonService.getAddons();
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(configs.length).toBe(0);
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should load provider definitions', async () => {
|
2021-01-19 10:42:45 +01:00
|
|
|
const { addonService } = getSetup();
|
|
|
|
|
2022-07-12 14:13:25 +02:00
|
|
|
const providerDefinitions = addonService.getProviderDefinitions();
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const simple = providerDefinitions.find((p) => p.name === 'simple');
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(providerDefinitions.length).toBe(1);
|
|
|
|
expect(simple.name).toBe('simple');
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should not allow addon-config for unknown provider', async () => {
|
2021-01-19 10:42:45 +01:00
|
|
|
const { addonService } = getSetup();
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
await expect(async () => {
|
2021-08-12 15:04:37 +02:00
|
|
|
await addonService.createAddon(
|
|
|
|
{
|
|
|
|
provider: 'unknown',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {},
|
|
|
|
events: [],
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
'test',
|
|
|
|
);
|
OpenAPI: addon operations (#3421)
This PR updates the OpenAPI schemas for all the operations tagged with
"addons". In doing so, I also uncovered a few bugs and inconsistencies.
These have also been fixed.
## Changes
I've added inline comments to the changed files to call out anything
that I think is worth clarifying specifically. As an overall
description, this PR does the following:
Splits `addon-schema` into `addon-schema` and
`addon-create-update-schema`. The former is used when describing addons
that exist within Unleash and contain IDs and `created_at` timestamps.
The latter is used when creating or updating addons.
Adds examples and descriptions to all relevant schemas (and their
dependencies).
Updates addons operations descriptions and response codes (including the
recently introduced 413 and 415).
Fixes a bug where the server would crash if it didn't recognize the
addon provider (test added).
Fixes a bug where updating an addon wouldn't return anything, even if
the API said that it would. (test added)
Resolves some inconsistencies in handling of addon description. (tests
added)
### Addon descriptions
when creating addons, descriptions are optional. The original
`addonSchema` said they could be `null | string | undefined`. This
caused some inconsistencies in return values. Sometimes they were
returned, other times not. I've made it so that `descriptions` are now
always returned from the API. If it's not defined or if it's set to
`null`, the API will return `description: null`.
### `IAddonDto`
`IAddonDto`, the type we used internally to model the incoming addons
(for create and update) says that `description` is required. This hasn't
been true at least since we introduced OpenAPI schemas. As such, the
update and insert methods that the service uses were incompatible with
the **actual** data that we require.
I've changed the type to reflect reality for now. Assuming the tests
pass, this **should** all be good, but I'd like the reviewer(s) to give
this a think too.
---------
Co-authored-by: Christopher Kolstad <chriswk@getunleash.ai>
2023-04-18 12:50:34 +02:00
|
|
|
}).rejects.toThrow(ValidationError);
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should trigger simple-addon eventHandler', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2021-01-19 10:42:45 +01:00
|
|
|
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost/wh',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-01-19 10:42:45 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
|
|
|
|
|
|
|
// Feature toggle was created
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2021-01-19 10:42:45 +01:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
data: {
|
|
|
|
name: 'some-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
2021-08-12 15:04:37 +02:00
|
|
|
// @ts-ignore
|
2021-01-19 10:42:45 +01:00
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(events.length).toBe(1);
|
|
|
|
expect(events[0].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[0].event.data.name).toBe('some-toggle');
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
|
|
|
|
2022-07-12 14:13:25 +02:00
|
|
|
test('should not trigger event handler if project of event is different from addon', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2022-07-12 14:13:25 +02:00
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
projects: ['someproject'],
|
|
|
|
description: '',
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost:wh',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: 'someotherproject',
|
|
|
|
data: {
|
|
|
|
name: 'some-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
|
|
|
// @ts-expect-error
|
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
|
|
|
expect(events.length).toBe(0);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should trigger event handler if project for event is one of the desired projects for addon', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2022-07-12 14:13:25 +02:00
|
|
|
const desiredProject = 'desired';
|
|
|
|
const otherProject = 'other';
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
projects: [desiredProject],
|
|
|
|
description: '',
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost:wh',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProject,
|
|
|
|
data: {
|
|
|
|
name: 'some-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: otherProject,
|
|
|
|
data: {
|
|
|
|
name: 'other-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
|
|
|
// @ts-expect-error
|
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
|
|
|
expect(events.length).toBe(1);
|
|
|
|
expect(events[0].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[0].event.data.name).toBe('some-toggle');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should trigger events for multiple projects if addon is setup to filter multiple projects', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2022-07-12 14:13:25 +02:00
|
|
|
const desiredProjects = ['desired', 'desired2'];
|
|
|
|
const otherProject = 'other';
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
projects: desiredProjects,
|
|
|
|
description: '',
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost:wh',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProjects[0],
|
|
|
|
data: {
|
|
|
|
name: 'some-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: otherProject,
|
|
|
|
data: {
|
|
|
|
name: 'other-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProjects[1],
|
|
|
|
data: {
|
|
|
|
name: 'third-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
|
|
|
// @ts-expect-error
|
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
|
|
|
expect(events.length).toBe(2);
|
|
|
|
expect(events[0].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[0].event.data.name).toBe('some-toggle');
|
|
|
|
expect(events[1].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[1].event.data.name).toBe('third-toggle');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should filter events on environment if addon is setup to filter for it', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2022-07-12 14:13:25 +02:00
|
|
|
const desiredEnvironment = 'desired';
|
|
|
|
const otherEnvironment = 'other';
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
projects: [],
|
|
|
|
environments: [desiredEnvironment],
|
|
|
|
description: '',
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost:wh',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredEnvironment,
|
|
|
|
environment: desiredEnvironment,
|
|
|
|
data: {
|
|
|
|
name: 'some-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
environment: otherEnvironment,
|
|
|
|
data: {
|
|
|
|
name: 'other-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
|
|
|
// @ts-expect-error
|
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
|
|
|
expect(events.length).toBe(1);
|
|
|
|
expect(events[0].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[0].event.data.name).toBe('some-toggle');
|
|
|
|
});
|
|
|
|
|
2023-09-13 09:22:18 +02:00
|
|
|
test('should not filter out global events (no specific environment) even if addon is setup to filter for environments', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2023-09-13 09:22:18 +02:00
|
|
|
const filteredEnvironment = 'filtered';
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
projects: [],
|
|
|
|
environments: [filteredEnvironment],
|
|
|
|
description: '',
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost:wh',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const globalEventWithNoEnvironment = {
|
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: 'some-project',
|
|
|
|
data: {
|
|
|
|
name: 'some-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent(globalEventWithNoEnvironment);
|
2023-09-13 09:22:18 +02:00
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
|
|
|
// @ts-expect-error
|
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
|
|
|
expect(events.length).toBe(1);
|
|
|
|
expect(events[0].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[0].event.data.name).toBe('some-toggle');
|
|
|
|
});
|
|
|
|
|
2023-09-14 09:19:38 +02:00
|
|
|
test('should not filter out global events (no specific project) even if addon is setup to filter for projects', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2023-09-14 09:19:38 +02:00
|
|
|
const filteredProject = 'filtered';
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
projects: [filteredProject],
|
|
|
|
environments: [],
|
|
|
|
description: '',
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost:wh',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const globalEventWithNoProject = {
|
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
data: {
|
|
|
|
name: 'some-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent(globalEventWithNoProject);
|
2023-09-14 09:19:38 +02:00
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
|
|
|
// @ts-expect-error
|
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
|
|
|
expect(events.length).toBe(1);
|
|
|
|
expect(events[0].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[0].event.data.name).toBe('some-toggle');
|
|
|
|
});
|
|
|
|
|
2022-07-12 15:50:22 +02:00
|
|
|
test('should support wildcard option for filtering addons', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2022-07-12 15:50:22 +02:00
|
|
|
const desiredProjects = ['desired', 'desired2'];
|
|
|
|
const otherProject = 'other';
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
projects: ['*'],
|
|
|
|
description: '',
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost:wh',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 15:50:22 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProjects[0],
|
|
|
|
data: {
|
|
|
|
name: 'some-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 15:50:22 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: otherProject,
|
|
|
|
data: {
|
|
|
|
name: 'other-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 15:50:22 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProjects[1],
|
|
|
|
data: {
|
|
|
|
name: 'third-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
|
|
|
// @ts-expect-error
|
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
|
|
|
expect(events).toHaveLength(3);
|
|
|
|
expect(events[0].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[0].event.data.name).toBe('some-toggle');
|
|
|
|
expect(events[1].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[1].event.data.name).toBe('other-toggle');
|
|
|
|
expect(events[2].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[2].event.data.name).toBe('third-toggle');
|
|
|
|
});
|
|
|
|
|
2022-07-12 14:13:25 +02:00
|
|
|
test('Should support filtering by both project and environment', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2022-07-12 14:13:25 +02:00
|
|
|
const desiredProjects = ['desired1', 'desired2', 'desired3'];
|
|
|
|
const desiredEnvironments = ['env1', 'env2', 'env3'];
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
projects: desiredProjects,
|
|
|
|
environments: desiredEnvironments,
|
|
|
|
description: '',
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost:wh',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const expectedFeatureNames = [
|
|
|
|
'desired-toggle1',
|
|
|
|
'desired-toggle2',
|
|
|
|
'desired-toggle3',
|
|
|
|
];
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProjects[0],
|
|
|
|
environment: desiredEnvironments[0],
|
|
|
|
data: {
|
|
|
|
name: expectedFeatureNames[0],
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProjects[0],
|
|
|
|
environment: 'wrongenvironment',
|
|
|
|
data: {
|
|
|
|
name: 'other-toggle',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProjects[2],
|
|
|
|
environment: desiredEnvironments[1],
|
|
|
|
data: {
|
|
|
|
name: expectedFeatureNames[1],
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: desiredProjects[2],
|
|
|
|
environment: desiredEnvironments[2],
|
|
|
|
data: {
|
|
|
|
name: expectedFeatureNames[2],
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
2023-09-27 15:23:05 +02:00
|
|
|
await eventService.storeEvent({
|
2022-07-12 14:13:25 +02:00
|
|
|
type: FEATURE_CREATED,
|
|
|
|
createdBy: 'some@user.com',
|
|
|
|
project: 'wrongproject',
|
|
|
|
environment: desiredEnvironments[0],
|
|
|
|
data: {
|
|
|
|
name: 'not-expected',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
const simpleProvider = addonService.addonProviders.simple;
|
|
|
|
// @ts-expect-error
|
|
|
|
const events = simpleProvider.getEvents();
|
|
|
|
|
|
|
|
expect(events.length).toBe(3);
|
|
|
|
expect(events[0].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[0].event.data.name).toBe(expectedFeatureNames[0]);
|
|
|
|
expect(events[1].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[1].event.data.name).toBe(expectedFeatureNames[1]);
|
|
|
|
expect(events[2].event.type).toBe(FEATURE_CREATED);
|
|
|
|
expect(events[2].event.data.name).toBe(expectedFeatureNames[2]);
|
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should create simple-addon config', async () => {
|
2021-01-19 10:42:45 +01:00
|
|
|
const { addonService } = getSetup();
|
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const config: IAddonDto = {
|
2021-01-19 10:42:45 +01:00
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost/wh',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-01-19 10:42:45 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
|
|
|
const addons = await addonService.getAddons();
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(addons.length).toBe(1);
|
|
|
|
expect(addons[0].provider).toBe('simple');
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should create tag type for simple-addon', async () => {
|
2021-01-19 10:42:45 +01:00
|
|
|
const { addonService, tagTypeService } = getSetup();
|
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const config: IAddonDto = {
|
2021-01-19 10:42:45 +01:00
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost/wh',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-01-19 10:42:45 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
|
|
|
const tagType = await tagTypeService.getTagType('me');
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(tagType.name).toBe('me');
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should store ADDON_CONFIG_CREATE event', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2021-01-19 10:42:45 +01:00
|
|
|
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost/wh',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-01-19 10:42:45 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
await addonService.createAddon(config, 'me@mail.com');
|
|
|
|
|
2023-09-27 15:23:05 +02:00
|
|
|
const { events } = await eventService.getEvents();
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(events.length).toBe(2); // Also tag-types where created
|
|
|
|
expect(events[1].type).toBe(ADDON_CONFIG_CREATED);
|
|
|
|
expect(events[1].data.provider).toBe('simple');
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should store ADDON_CONFIG_UPDATE event', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const config: IAddonDto = {
|
|
|
|
description: '',
|
2021-01-19 10:42:45 +01:00
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost/wh',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
};
|
|
|
|
|
|
|
|
const addonConfig = await addonService.createAddon(config, 'me@mail.com');
|
|
|
|
|
|
|
|
const updated = { ...addonConfig, description: 'test' };
|
|
|
|
await addonService.updateAddon(addonConfig.id, updated, 'me@mail.com');
|
|
|
|
|
2023-09-27 15:23:05 +02:00
|
|
|
const { events } = await eventService.getEvents();
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(events.length).toBe(3);
|
|
|
|
expect(events[2].type).toBe(ADDON_CONFIG_UPDATED);
|
|
|
|
expect(events[2].data.provider).toBe('simple');
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should store ADDON_CONFIG_REMOVE event', async () => {
|
2023-09-27 15:23:05 +02:00
|
|
|
const { addonService, eventService } = getSetup();
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const config: IAddonDto = {
|
2021-01-19 10:42:45 +01:00
|
|
|
provider: 'simple',
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-01-19 10:42:45 +01:00
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost/wh',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
};
|
|
|
|
|
|
|
|
const addonConfig = await addonService.createAddon(config, 'me@mail.com');
|
|
|
|
|
|
|
|
await addonService.removeAddon(addonConfig.id, 'me@mail.com');
|
|
|
|
|
2023-09-27 15:23:05 +02:00
|
|
|
const { events } = await eventService.getEvents();
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(events.length).toBe(3);
|
|
|
|
expect(events[2].type).toBe(ADDON_CONFIG_DELETED);
|
2023-09-29 17:11:59 +02:00
|
|
|
expect(events[2].preData.id).toBe(addonConfig.id);
|
2021-01-19 10:42:45 +01:00
|
|
|
});
|
2021-02-04 11:02:58 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should hide sensitive fields when fetching', async () => {
|
2021-02-04 11:02:58 +01:00
|
|
|
const { addonService } = getSetup();
|
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const config: IAddonDto = {
|
2021-02-04 11:02:58 +01:00
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-02-04 11:02:58 +01:00
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost/wh',
|
|
|
|
var: 'some-value',
|
|
|
|
sensitiveParam: 'should be hidden when fetching',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
|
|
|
};
|
|
|
|
|
|
|
|
const createdConfig = await addonService.createAddon(config, 'me@mail.com');
|
|
|
|
const addons = await addonService.getAddons();
|
|
|
|
const addonRetrieved = await addonService.getAddon(createdConfig.id);
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(addons.length).toBe(1);
|
2021-08-12 15:04:37 +02:00
|
|
|
// @ts-ignore
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(addons[0].parameters.sensitiveParam).toBe(MASKED_VALUE);
|
2021-08-12 15:04:37 +02:00
|
|
|
// @ts-ignore
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(addonRetrieved.parameters.sensitiveParam).toBe(MASKED_VALUE);
|
2021-02-04 11:02:58 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should not overwrite masked values when updating', async () => {
|
2021-02-04 11:02:58 +01:00
|
|
|
const { addonService, stores } = getSetup();
|
|
|
|
|
2021-08-12 15:04:37 +02:00
|
|
|
const config: IAddonDto = {
|
2021-02-04 11:02:58 +01:00
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: 'http://localhost/wh',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-02-04 11:02:58 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const addonConfig = await addonService.createAddon(config, 'me@mail.com');
|
|
|
|
|
|
|
|
const updated = {
|
|
|
|
...addonConfig,
|
|
|
|
parameters: { url: MASKED_VALUE, var: 'some-new-value' },
|
|
|
|
description: 'test',
|
|
|
|
};
|
|
|
|
await addonService.updateAddon(addonConfig.id, updated, 'me@mail.com');
|
|
|
|
|
|
|
|
const updatedConfig = await stores.addonStore.get(addonConfig.id);
|
2021-08-12 15:04:37 +02:00
|
|
|
// @ts-ignore
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(updatedConfig.parameters.url).toBe('http://localhost/wh');
|
2021-08-12 15:04:37 +02:00
|
|
|
// @ts-ignore
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(updatedConfig.parameters.var).toBe('some-new-value');
|
2021-02-04 11:02:58 +01:00
|
|
|
});
|
2021-02-05 14:07:46 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should reject addon config with missing required parameter when creating', async () => {
|
2021-02-05 14:07:46 +01:00
|
|
|
const { addonService } = getSetup();
|
|
|
|
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-02-05 14:07:46 +01:00
|
|
|
};
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
await expect(async () =>
|
|
|
|
addonService.createAddon(config, 'me@mail.com'),
|
|
|
|
).rejects.toThrow(ValidationError);
|
2021-02-05 14:07:46 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should reject updating addon config with missing required parameter', async () => {
|
2021-02-05 14:07:46 +01:00
|
|
|
const { addonService } = getSetup();
|
|
|
|
|
|
|
|
const addonConfig = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: 'https://some.site/api',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-02-05 14:07:46 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const config = await addonService.createAddon(addonConfig, 'me@mail.com');
|
|
|
|
const updated = {
|
|
|
|
...config,
|
|
|
|
parameters: { var: 'some-new-value' },
|
|
|
|
description: 'test',
|
|
|
|
};
|
2021-05-28 11:10:24 +02:00
|
|
|
await expect(async () =>
|
|
|
|
addonService.updateAddon(config.id, updated, 'me@mail.com'),
|
|
|
|
).rejects.toThrow(ValidationError);
|
2021-02-05 14:07:46 +01:00
|
|
|
});
|
2021-02-05 14:07:46 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('Should reject addon config if a required parameter is just the empty string', async () => {
|
2021-02-05 14:07:46 +01:00
|
|
|
const { addonService } = getSetup();
|
|
|
|
|
|
|
|
const config = {
|
|
|
|
provider: 'simple',
|
|
|
|
enabled: true,
|
|
|
|
parameters: {
|
|
|
|
url: '',
|
|
|
|
var: 'some-value',
|
|
|
|
},
|
|
|
|
events: [FEATURE_CREATED],
|
2021-08-12 15:04:37 +02:00
|
|
|
description: '',
|
2021-02-05 14:07:46 +01:00
|
|
|
};
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
await expect(async () =>
|
|
|
|
addonService.createAddon(config, 'me@mail.com'),
|
|
|
|
).rejects.toThrow(ValidationError);
|
2021-02-05 14:07:46 +01:00
|
|
|
});
|