mirror of
https://github.com/Unleash/unleash.git
synced 2024-11-01 19:07:38 +01:00
5b66346e56
## What Previously when importing strategies we've used the same data type we've used for creating strategies (the minimal, a name, an optional description, optional parameters and an optional editable column). This meant that exporting strategies and then importing them would reactivate deprecated strategies. This PR changes to allow the import to preserve all the data coming in the export file. ## Tests Added four new tests, two new unit tests using our fake stores and two new e2e tests. Interestingly the ones in the fake store ran green before this change as well, probably because we just insert the parsed json object in the fake store, whereas the real store actually converts the object from camelCasing to the postgresql snake_casing standard. ## Discussion points: ### Mismatch between fake and real stores This is inevitable since storing things in javascript arrays vs saving in a real database will have some differences, but this again shows the value of our e2e tests. ### Invariants Should we see if we can add some invariants to our import/export so that we can write some proptests for it? One candidate is commutativity of import/export. On a fresh database importing and then exporting should yield the same file that was imported provided all flags are turned on. Candidate for Q1 improvement of import/export.
128 lines
3.5 KiB
TypeScript
128 lines
3.5 KiB
TypeScript
import {
|
|
IEditableStrategy,
|
|
IMinimalStrategy,
|
|
IStrategy,
|
|
IStrategyImport,
|
|
IStrategyStore,
|
|
} from '../../lib/types/stores/strategy-store';
|
|
import NotFoundError from '../../lib/error/notfound-error';
|
|
|
|
export default class FakeStrategiesStore implements IStrategyStore {
|
|
count(): Promise<number> {
|
|
return Promise.resolve(0);
|
|
}
|
|
|
|
defaultStrategy: IStrategy = {
|
|
name: 'default',
|
|
description: 'default strategy',
|
|
displayName: 'Default',
|
|
editable: false,
|
|
parameters: [],
|
|
deprecated: false,
|
|
};
|
|
|
|
strategies: IStrategy[] = [this.defaultStrategy];
|
|
|
|
async createStrategy(update: IMinimalStrategy): Promise<void> {
|
|
let params;
|
|
if (
|
|
typeof update.parameters === 'string' ||
|
|
typeof update.parameters === 'number'
|
|
) {
|
|
if (update.parameters === '') {
|
|
params = {};
|
|
} else {
|
|
params = JSON.parse(update.parameters);
|
|
}
|
|
} else {
|
|
params = update.parameters;
|
|
}
|
|
this.strategies.push({
|
|
editable: true,
|
|
deprecated: false,
|
|
description: '',
|
|
displayName: update.name,
|
|
...update,
|
|
parameters: params,
|
|
});
|
|
}
|
|
|
|
async delete(key: string): Promise<void> {
|
|
this.strategies.splice(
|
|
this.strategies.findIndex((k) => k.name === key),
|
|
1,
|
|
);
|
|
}
|
|
|
|
async deleteAll(): Promise<void> {
|
|
this.strategies = [this.defaultStrategy];
|
|
}
|
|
|
|
async deleteStrategy({ name }: Pick<IStrategy, 'name'>): Promise<void> {
|
|
return this.delete(name);
|
|
}
|
|
|
|
async deprecateStrategy({ name }: Pick<IStrategy, 'name'>): Promise<void> {
|
|
const strategy = await this.get(name);
|
|
strategy.deprecated = true;
|
|
}
|
|
|
|
destroy(): void {}
|
|
|
|
async exists(key: string): Promise<boolean> {
|
|
return this.strategies.some((s) => s.name === key && !s.deprecated);
|
|
}
|
|
|
|
async get(key: string): Promise<IStrategy> {
|
|
const strat = this.strategies.find((s) => s.name === key);
|
|
if (strat) {
|
|
return strat;
|
|
}
|
|
throw new NotFoundError(`Could not find strategy with name: ${key}`);
|
|
}
|
|
|
|
async getAll(): Promise<IStrategy[]> {
|
|
return this.strategies.filter((s) => !s.deprecated);
|
|
}
|
|
|
|
async getEditableStrategies(): Promise<IEditableStrategy[]> {
|
|
return this.strategies
|
|
.filter((s) => s.editable)
|
|
.map((s) => {
|
|
if (!s.parameters) {
|
|
// eslint-disable-next-line no-param-reassign
|
|
s.parameters = [];
|
|
}
|
|
return s;
|
|
});
|
|
}
|
|
|
|
async getStrategy(name: string): Promise<IStrategy> {
|
|
const strat = this.get(name);
|
|
if (strat) {
|
|
return strat;
|
|
}
|
|
throw new NotFoundError(`Could not find strategy with name: ${name}`);
|
|
}
|
|
|
|
async importStrategy(data: IStrategyImport): Promise<void> {
|
|
return this.createStrategy(data);
|
|
}
|
|
|
|
async reactivateStrategy({ name }: Pick<IStrategy, 'name'>): Promise<void> {
|
|
const strategy = await this.get(name);
|
|
strategy.deprecated = false;
|
|
await this.delete(name);
|
|
this.strategies.push(strategy);
|
|
}
|
|
|
|
async updateStrategy(update: IMinimalStrategy): Promise<void> {
|
|
await this.delete(update.name);
|
|
return this.createStrategy(update);
|
|
}
|
|
|
|
async dropCustomStrategies(): Promise<void> {
|
|
return this.deleteAll();
|
|
}
|
|
}
|