TGD-30: FeatureFlags
This commit is contained in:
parent
dfd149103e
commit
0d26101948
4 changed files with 122 additions and 0 deletions
18
src/featureflag/featureflag.controller.spec.ts
Normal file
18
src/featureflag/featureflag.controller.spec.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { FeatureflagController } from './featureflag.controller';
|
||||
|
||||
describe('FeatureflagController', () => {
|
||||
let controller: FeatureflagController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [FeatureflagController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<FeatureflagController>(FeatureflagController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
18
src/featureflag/featureflag.controller.ts
Normal file
18
src/featureflag/featureflag.controller.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import {Body, Controller, Get, Param, Post} from '@nestjs/common';
|
||||
import {FeatureflagService} from "./featureflag.service";
|
||||
|
||||
@Controller('featureflag')
|
||||
export class FeatureflagController {
|
||||
constructor(private featureflagService: FeatureflagService) {
|
||||
}
|
||||
|
||||
@Get(':ffname')
|
||||
async getFeatureFlag(@Param() params: { ffname: string}) {
|
||||
return await this.featureflagService.getFeatureFlag(params.ffname);
|
||||
}
|
||||
|
||||
@Post(':ffname')
|
||||
async setFeatureFlag(@Param() params: { ffname: string}, @Body() ffState: { name: string, state: boolean }) {
|
||||
return await this.featureflagService.setFeatureFlag(params.ffname, ffState.state );
|
||||
}
|
||||
}
|
||||
51
src/featureflag/featureflag.service.spec.ts
Normal file
51
src/featureflag/featureflag.service.spec.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { FeatureflagService } from './featureflag.service';
|
||||
import {SharedService} from "../shared/shared.service";
|
||||
import {SharedServiceMock} from "../mocks/shared-service.mock";
|
||||
|
||||
|
||||
describe('FeatureflagService', () => {
|
||||
let service: FeatureflagService;
|
||||
let sharedService: SharedService;
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
FeatureflagService,
|
||||
{ provide: SharedService,useValue: SharedServiceMock },
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<FeatureflagService>(FeatureflagService);
|
||||
sharedService = module.get<SharedService>(SharedService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
it('should set feature flag state', async () => {
|
||||
const testFeatureName = 'TestFeatureFlag';
|
||||
const testFeatureState = true;
|
||||
const setConfigMock = jest
|
||||
.spyOn(sharedService,'setConfig')
|
||||
.mockImplementation((name: string, value: string) => Promise.resolve({ key: name, value: value}));
|
||||
await service.setFeatureFlag(testFeatureName, testFeatureState);
|
||||
expect(setConfigMock).toHaveBeenCalledWith(`featureflag/${testFeatureName}`, testFeatureState.toString());
|
||||
expect(setConfigMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return state of the feature flag', async () => {
|
||||
const testFeatureName = 'TestFeatureFlag';
|
||||
const testFeatureState = true;
|
||||
const getConfigMock = jest
|
||||
.spyOn(sharedService, 'getConfig')
|
||||
.mockImplementation((key: string) => Promise.resolve({ key:key, value: testFeatureState.toString() }));
|
||||
await service.getFeatureFlag(testFeatureName);
|
||||
|
||||
expect(getConfigMock).toHaveBeenCalledTimes(1);
|
||||
expect(getConfigMock).toHaveBeenCalledWith(`featureflag/${testFeatureName}`);
|
||||
|
||||
});
|
||||
});
|
||||
35
src/featureflag/featureflag.service.ts
Normal file
35
src/featureflag/featureflag.service.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import {Injectable, Logger} from '@nestjs/common';
|
||||
import {SharedService} from "../shared/shared.service";
|
||||
|
||||
export interface IFeatureFlagStatus {
|
||||
name: string;
|
||||
state: boolean;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class FeatureflagService {
|
||||
private logger = new Logger(FeatureflagService.name);
|
||||
constructor(private sharedService: SharedService ) {
|
||||
}
|
||||
|
||||
async getFeatureFlag(id: string): Promise<IFeatureFlagStatus> {
|
||||
this.logger.verbose(`Getting feature flag status for ${id}`);
|
||||
const state = await this.sharedService.getConfig(`featureflag/${id}`);
|
||||
return {
|
||||
name: id,
|
||||
state: state.value !== 'false',
|
||||
}
|
||||
}
|
||||
|
||||
async setFeatureFlag(id: string, status: boolean) : Promise<IFeatureFlagStatus> {
|
||||
this.logger.verbose(`Setting feature flag status for ${id} to ${status} `);
|
||||
const result = await this.sharedService.setConfig(`featureflag/${id}`, status.toString());
|
||||
console.log(result.value);
|
||||
console.log(!!result.value);
|
||||
return {
|
||||
name: id,
|
||||
state: result.value !== 'false',
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue