unleash-server
Version:
Unleash is an enterprise ready feature toggles service. It provides different strategies for handling feature toggles.
169 lines • 6.32 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const supertest_1 = __importDefault(require("supertest"));
const store_1 = __importDefault(require("../../../test/fixtures/store"));
const no_logger_1 = __importDefault(require("../../../test/fixtures/no-logger"));
const app_1 = __importDefault(require("../../app"));
const services_1 = require("../../services");
const feature_1 = __importDefault(require("./feature"));
const test_config_1 = require("../../../test/config/test-config");
const date_fns_1 = require("date-fns");
const client_spec_service_1 = require("../../services/client-spec-service");
async function getSetup() {
const base = `/random${Math.round(Math.random() * 1000)}`;
const stores = (0, store_1.default)();
const config = (0, test_config_1.createTestConfig)({
server: { baseUriPath: base },
});
const services = (0, services_1.createServices)(stores, config);
const app = await (0, app_1.default)(config, stores, services);
return {
base,
featureToggleStore: stores.featureToggleStore,
featureToggleClientStore: stores.featureToggleClientStore,
request: (0, supertest_1.default)(app),
destroy: () => {
services.versionService.destroy();
services.clientInstanceService.destroy();
services.apiTokenService.destroy();
},
};
}
const callGetAll = async (controller) => {
await controller.getAll(
// @ts-expect-error
{ query: {}, header: () => undefined }, { json: () => { } });
};
let base;
let request;
let destroy;
let featureToggleClientStore;
beforeEach(async () => {
const setup = await getSetup();
base = setup.base;
request = setup.request;
featureToggleClientStore = setup.featureToggleClientStore;
destroy = setup.destroy;
});
afterEach(() => {
destroy();
});
test('should get empty getFeatures via client', () => {
expect.assertions(1);
return request
.get(`${base}/api/client/features`)
.expect('Content-Type', /json/)
.expect(200)
.expect((res) => {
expect(res.body.features.length === 0).toBe(true);
});
});
test('if caching is enabled should memoize', async () => {
const getClientFeatures = jest.fn().mockReturnValue([]);
const getActive = jest.fn().mockReturnValue([]);
const respondWithValidation = jest.fn().mockReturnValue({});
const validPath = jest.fn().mockReturnValue(jest.fn());
const clientSpecService = new client_spec_service_1.ClientSpecService({ getLogger: no_logger_1.default });
const openApiService = { respondWithValidation, validPath };
const featureToggleServiceV2 = { getClientFeatures };
const segmentService = { getActive };
const controller = new feature_1.default({
clientSpecService,
// @ts-expect-error
openApiService,
// @ts-expect-error
featureToggleServiceV2,
// @ts-expect-error
segmentService,
}, {
getLogger: no_logger_1.default,
clientFeatureCaching: {
enabled: true,
maxAge: (0, date_fns_1.secondsToMilliseconds)(10),
},
});
await callGetAll(controller);
await callGetAll(controller);
expect(getClientFeatures).toHaveBeenCalledTimes(1);
});
test('if caching is not enabled all calls goes to service', async () => {
const getClientFeatures = jest.fn().mockReturnValue([]);
const getActive = jest.fn().mockReturnValue([]);
const respondWithValidation = jest.fn().mockReturnValue({});
const validPath = jest.fn().mockReturnValue(jest.fn());
const clientSpecService = new client_spec_service_1.ClientSpecService({ getLogger: no_logger_1.default });
const featureToggleServiceV2 = { getClientFeatures };
const segmentService = { getActive };
const openApiService = { respondWithValidation, validPath };
const controller = new feature_1.default({
clientSpecService,
// @ts-expect-error
openApiService,
// @ts-expect-error
featureToggleServiceV2,
// @ts-expect-error
segmentService,
}, {
getLogger: no_logger_1.default,
clientFeatureCaching: {
enabled: false,
maxAge: (0, date_fns_1.secondsToMilliseconds)(10),
},
});
await callGetAll(controller);
await callGetAll(controller);
expect(getClientFeatures).toHaveBeenCalledTimes(2);
});
test('fetch single feature', async () => {
expect.assertions(1);
await featureToggleClientStore.createFeature({
name: 'test_',
strategies: [{ name: 'default' }],
});
return request
.get(`${base}/api/client/features/test_`)
.expect('Content-Type', /json/)
.expect(200)
.expect((res) => {
expect(res.body.name === 'test_').toBe(true);
});
});
test('support name prefix', async () => {
expect.assertions(2);
await featureToggleClientStore.createFeature({ name: 'a_test1' });
await featureToggleClientStore.createFeature({ name: 'a_test2' });
await featureToggleClientStore.createFeature({ name: 'b_test1' });
await featureToggleClientStore.createFeature({ name: 'b_test2' });
const namePrefix = 'b_';
return request
.get(`${base}/api/client/features?namePrefix=${namePrefix}`)
.expect('Content-Type', /json/)
.expect(200)
.expect((res) => {
expect(res.body.features.length).toBe(2);
expect(res.body.features[1].name).toBe('b_test2');
});
});
test('support filtering on project', async () => {
expect.assertions(2);
await featureToggleClientStore.createFeature({
name: 'a_test1',
project: 'projecta',
});
await featureToggleClientStore.createFeature({
name: 'b_test2',
project: 'projectb',
});
return request
.get(`${base}/api/client/features?project=projecta`)
.expect('Content-Type', /json/)
.expect(200)
.expect((res) => {
expect(res.body.features).toHaveLength(1);
expect(res.body.features[0].name).toBe('a_test1');
});
});
//# sourceMappingURL=feature.test.js.map