mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-20 00:08:02 +01:00
This PR updates the feature type service by adding a new `updateLifetime` method. This method handles the connection between the API (#4256) and the store (#4252). I've also added some new e2e tests to ensure that the API behaves as expected.
This commit is contained in:
parent
276261c913
commit
b990c6dfe0
@ -69,12 +69,12 @@ class FeatureTypeStore implements IFeatureTypeStore {
|
||||
}
|
||||
|
||||
async updateLifetime(
|
||||
name: string,
|
||||
id: string,
|
||||
newLifetimeDays: number | null,
|
||||
): Promise<IFeatureType | undefined> {
|
||||
const [updatedType] = await this.db(TABLE)
|
||||
.update({ lifetime_days: newLifetimeDays })
|
||||
.where({ name })
|
||||
.where({ id })
|
||||
.returning(['*']);
|
||||
|
||||
if (updatedType) {
|
||||
|
@ -13,13 +13,13 @@ import { createResponseSchema } from '../../openapi/util/create-response-schema'
|
||||
import Controller from '../controller';
|
||||
import {
|
||||
createRequestSchema,
|
||||
featureTypeSchema,
|
||||
FeatureTypeSchema,
|
||||
getStandardResponses,
|
||||
UpdateFeatureTypeLifetimeSchema,
|
||||
} from '../../openapi';
|
||||
import { IAuthRequest } from '../unleash-types';
|
||||
import { IFlagResolver } from '../../types';
|
||||
import NotImplementedError from '../../error/not-implemented-error';
|
||||
|
||||
const version = 1;
|
||||
|
||||
@ -114,8 +114,16 @@ When a feature toggle type's expected lifetime is changed, this will also cause
|
||||
res: Response<FeatureTypeSchema>,
|
||||
): Promise<void> {
|
||||
if (this.flagResolver.isEnabled('configurableFeatureTypeLifetimes')) {
|
||||
throw new NotImplementedError(
|
||||
"This operation isn't implemented yet",
|
||||
const result = await this.featureTypeService.updateLifetime(
|
||||
req.params.id.toLowerCase(),
|
||||
req.body.lifetimeDays,
|
||||
);
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
featureTypeSchema.$id,
|
||||
result,
|
||||
);
|
||||
} else {
|
||||
res.status(409).end();
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
IFeatureType,
|
||||
IFeatureTypeStore,
|
||||
} from '../types/stores/feature-type-store';
|
||||
import NotFoundError from '../error/notfound-error';
|
||||
|
||||
export default class FeatureTypeService {
|
||||
private featureTypeStore: IFeatureTypeStore;
|
||||
@ -22,6 +23,29 @@ export default class FeatureTypeService {
|
||||
async getAll(): Promise<IFeatureType[]> {
|
||||
return this.featureTypeStore.getAll();
|
||||
}
|
||||
|
||||
async updateLifetime(
|
||||
id: string,
|
||||
newLifetimeDays: number | null,
|
||||
): Promise<IFeatureType> {
|
||||
// because our OpenAPI library does type coercion, any `null` values you
|
||||
// pass in get converted to `0`.
|
||||
const translatedLifetime =
|
||||
newLifetimeDays === 0 ? null : newLifetimeDays;
|
||||
|
||||
const result = await this.featureTypeStore.updateLifetime(
|
||||
id,
|
||||
translatedLifetime,
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
throw new NotFoundError(
|
||||
`The feature type you tried to update ("${id}") does not exist.`,
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FeatureTypeService;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import dbInit from '../../helpers/database-init';
|
||||
import getLogger from '../../../fixtures/no-logger';
|
||||
import { setupApp } from '../../helpers/test-helper';
|
||||
import { setupAppWithCustomConfig } from '../../helpers/test-helper';
|
||||
import { validateSchema } from '../../../../lib/openapi/validate';
|
||||
import { featureTypesSchema } from '../../../../lib/openapi/spec/feature-types-schema';
|
||||
|
||||
@ -9,7 +9,14 @@ let db;
|
||||
|
||||
beforeAll(async () => {
|
||||
db = await dbInit('feature_type_api_serial', getLogger);
|
||||
app = await setupApp(db.stores);
|
||||
app = await setupAppWithCustomConfig(db.stores, {
|
||||
experimental: {
|
||||
flags: {
|
||||
configurableFeatureTypeLifetimes: true,
|
||||
strictSchemaValidation: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@ -32,3 +39,44 @@ test('Should get all defined feature types', async () => {
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('updating lifetimes', () => {
|
||||
test.each([null, 5])(
|
||||
'it updates to the lifetime correctly: `%s`',
|
||||
async (lifetimeDays) => {
|
||||
const { body } = await app.request
|
||||
.put(`/api/admin/feature-types/release/lifetime`)
|
||||
.send({ lifetimeDays })
|
||||
.expect(200);
|
||||
|
||||
expect(body.lifetimeDays).toEqual(lifetimeDays);
|
||||
},
|
||||
);
|
||||
test("if the feature type doesn't exist, you get a 404", async () => {
|
||||
await app.request
|
||||
.put(`/api/admin/feature-types/bogus-feature-type/lifetime`)
|
||||
.send({ lifetimeDays: 45 })
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
test('Setting lifetime to `null` is the same as setting it to `0`', async () => {
|
||||
const setLifetime = async (lifetimeDays) => {
|
||||
const { body } = await app.request
|
||||
.put('/api/admin/feature-types/release/lifetime')
|
||||
.send({ lifetimeDays })
|
||||
.expect(200);
|
||||
return body;
|
||||
};
|
||||
|
||||
expect(await setLifetime(0)).toMatchObject(await setLifetime(null));
|
||||
});
|
||||
test('the :id parameter is not case sensitive', async () => {
|
||||
const lifetimeDays = 45;
|
||||
const { body } = await app.request
|
||||
.put(`/api/admin/feature-types/kIlL-SwItCh/lifetime`)
|
||||
.send({ lifetimeDays })
|
||||
.expect(200);
|
||||
|
||||
expect(body.lifetimeDays).toEqual(lifetimeDays);
|
||||
});
|
||||
});
|
||||
|
@ -46,15 +46,13 @@ describe('update lifetimes', () => {
|
||||
|
||||
for (const type of featureTypes) {
|
||||
const updated = await featureTypeStore.updateLifetime(
|
||||
type.name,
|
||||
type.id,
|
||||
newLifetime,
|
||||
);
|
||||
|
||||
expect(updated?.lifetimeDays).toBe(newLifetime);
|
||||
|
||||
expect(updated).toMatchObject(
|
||||
await featureTypeStore.getByName(type.name),
|
||||
);
|
||||
expect(updated).toMatchObject(await featureTypeStore.get(type.id));
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user