diff --git a/src/featureflag/featureflag.controller.spec.ts b/src/featureflag/featureflag.controller.spec.ts new file mode 100644 index 0000000..9dbbf1f --- /dev/null +++ b/src/featureflag/featureflag.controller.spec.ts @@ -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); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/featureflag/featureflag.controller.ts b/src/featureflag/featureflag.controller.ts new file mode 100644 index 0000000..fca0071 --- /dev/null +++ b/src/featureflag/featureflag.controller.ts @@ -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 ); + } +} diff --git a/src/featureflag/featureflag.service.spec.ts b/src/featureflag/featureflag.service.spec.ts new file mode 100644 index 0000000..d114fae --- /dev/null +++ b/src/featureflag/featureflag.service.spec.ts @@ -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); + sharedService = module.get(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}`); + + }); +}); diff --git a/src/featureflag/featureflag.service.ts b/src/featureflag/featureflag.service.ts new file mode 100644 index 0000000..bda57f9 --- /dev/null +++ b/src/featureflag/featureflag.service.ts @@ -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 { + 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 { + 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', + } + } + +}