From 8666955eaba12769e34d10594230a183717b7648 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Mon, 20 Nov 2023 12:22:24 +0100 Subject: [PATCH] feat: fix impl --- ...e-request-segment-usage-read-model.test.ts | 31 ++++++++------- ...change-request-segment-usage-read-model.ts | 2 +- ...change-request-segment-usage-read-model.ts | 20 +++++++++- ...change-request-segment-usage-read-model.ts | 38 +++++++++++++++++-- 4 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/lib/features/change-request-segment-usage-service/change-request-segment-usage-read-model.test.ts b/src/lib/features/change-request-segment-usage-service/change-request-segment-usage-read-model.test.ts index bd6076a71f..acd2b6233d 100644 --- a/src/lib/features/change-request-segment-usage-service/change-request-segment-usage-read-model.test.ts +++ b/src/lib/features/change-request-segment-usage-service/change-request-segment-usage-read-model.test.ts @@ -113,7 +113,7 @@ describe.each([ ])('Should handle %s changes correctly', (_, addOrUpdateStrategy) => { test.each([ ['Draft', true], - ['In Review', true], + ['In review', true], ['Scheduled', true], ['Approved', true], ['Rejected', false], @@ -137,7 +137,7 @@ describe.each([ describe('addStrategy events should show up in used strategies correctly', () => { test.each([ ['Draft', true], - ['In Review', true], + ['In review', true], ['Scheduled', true], ['Approved', true], ['Rejected', false], @@ -152,18 +152,21 @@ describe('addStrategy events should show up in used strategies correctly', () => await addStrategyToCr(segmentId, FLAG_NAME); - const result = await readModel.isSegmentUsedInActiveChangeRequests( - segmentId, - ); + const result = + await readModel.getStrategiesUsedInActiveChangeRequests( + segmentId, + ); if (shouldShow) { - expect(result).toBe({ - projectId: 'default', - strategyName: 'flexibleRollout', - environment: 'default', - featureName: FLAG_NAME, - }); + expect(result).toStrictEqual([ + { + projectId: 'default', + strategyName: 'flexibleRollout', + environment: 'default', + featureName: FLAG_NAME, + }, + ]); } else { - expect(result).toBe([]); + expect(result).toStrictEqual([]); } }, ); @@ -172,7 +175,7 @@ describe('addStrategy events should show up in used strategies correctly', () => describe('updateStrategy events should show up in used strategies correctly', () => { test.each([ ['Draft', true], - ['In Review', true], + ['In review', true], ['Scheduled', true], ['Approved', true], ['Rejected', false], @@ -204,7 +207,7 @@ describe('updateStrategy events should show up in used strategies correctly', () }, ]); } else { - expect(result).toBe([]); + expect(result).toStrictEqual([]); } }, ); diff --git a/src/lib/features/change-request-segment-usage-service/change-request-segment-usage-read-model.ts b/src/lib/features/change-request-segment-usage-service/change-request-segment-usage-read-model.ts index 3c184bc8f8..4b2928c7b3 100644 --- a/src/lib/features/change-request-segment-usage-service/change-request-segment-usage-read-model.ts +++ b/src/lib/features/change-request-segment-usage-service/change-request-segment-usage-read-model.ts @@ -7,7 +7,7 @@ type NewStrategy = { type ExistingStrategy = NewStrategy & { id?: string }; -type ChangeRequestStrategy = NewStrategy | ExistingStrategy; +export type ChangeRequestStrategy = NewStrategy | ExistingStrategy; export interface IChangeRequestSegmentUsageReadModel { isSegmentUsedInActiveChangeRequests(segmentId: number): Promise; diff --git a/src/lib/features/change-request-segment-usage-service/fake-change-request-segment-usage-read-model.ts b/src/lib/features/change-request-segment-usage-service/fake-change-request-segment-usage-read-model.ts index d5cb25554a..a5e0573b45 100644 --- a/src/lib/features/change-request-segment-usage-service/fake-change-request-segment-usage-read-model.ts +++ b/src/lib/features/change-request-segment-usage-service/fake-change-request-segment-usage-read-model.ts @@ -1,16 +1,32 @@ -import { IChangeRequestSegmentUsageReadModel } from './change-request-segment-usage-read-model'; +import { + ChangeRequestStrategy, + IChangeRequestSegmentUsageReadModel, +} from './change-request-segment-usage-read-model'; export class FakeChangeRequestSegmentUsageReadModel implements IChangeRequestSegmentUsageReadModel { private isSegmentUsedInActiveChangeRequestsValue: boolean; + strategiesUsedInActiveChangeRequests: ChangeRequestStrategy[]; - constructor(isSegmentUsedInActiveChangeRequests = false) { + constructor( + isSegmentUsedInActiveChangeRequests = false, + strategiesUsedInActiveChangeRequests = [], + ) { this.isSegmentUsedInActiveChangeRequestsValue = isSegmentUsedInActiveChangeRequests; + + this.strategiesUsedInActiveChangeRequests = + strategiesUsedInActiveChangeRequests; } public async isSegmentUsedInActiveChangeRequests(): Promise { return this.isSegmentUsedInActiveChangeRequestsValue; } + + public async getStrategiesUsedInActiveChangeRequests(): Promise< + ChangeRequestStrategy[] + > { + return this.strategiesUsedInActiveChangeRequests; + } } diff --git a/src/lib/features/change-request-segment-usage-service/sql-change-request-segment-usage-read-model.ts b/src/lib/features/change-request-segment-usage-service/sql-change-request-segment-usage-read-model.ts index 47dbf632ae..f33f5606cc 100644 --- a/src/lib/features/change-request-segment-usage-service/sql-change-request-segment-usage-read-model.ts +++ b/src/lib/features/change-request-segment-usage-service/sql-change-request-segment-usage-read-model.ts @@ -1,5 +1,8 @@ import { Db } from '../../db/db'; -import { IChangeRequestSegmentUsageReadModel } from './change-request-segment-usage-read-model'; +import { + ChangeRequestStrategy, + IChangeRequestSegmentUsageReadModel, +} from './change-request-segment-usage-read-model'; export class ChangeRequestSegmentUsageReadModel implements IChangeRequestSegmentUsageReadModel @@ -9,7 +12,6 @@ export class ChangeRequestSegmentUsageReadModel constructor(db: Db) { this.db = db; } - public async isSegmentUsedInActiveChangeRequests( segmentId: number, ): Promise { @@ -17,7 +19,7 @@ export class ChangeRequestSegmentUsageReadModel `SELECT events.* FROM change_request_events events JOIN change_requests cr ON events.change_request_id = cr.id - WHERE cr.state IN ('Draft', 'In Review', 'Scheduled', 'Approved') + WHERE cr.state IN ('Draft', 'In review', 'Scheduled', 'Approved') AND events.action IN ('updateStrategy', 'addStrategy');`, ); @@ -27,4 +29,34 @@ export class ChangeRequestSegmentUsageReadModel return isUsed; } + + mapRow = (row): ChangeRequestStrategy => { + const { payload, project, environment, feature } = row; + return { + projectId: project, + featureName: feature, + environment: environment, + strategyName: payload.name, + ...(payload.id ? { id: payload.id } : {}), + }; + }; + + public async getStrategiesUsedInActiveChangeRequests( + segmentId: number, + ): Promise { + const query = this.db.raw( + `SELECT events.*, cr.project, cr.environment + FROM change_request_events events + JOIN change_requests cr ON events.change_request_id = cr.id + WHERE cr.state NOT IN ('Applied', 'Cancelled', 'Rejected') + AND events.action IN ('updateStrategy', 'addStrategy');`, + ); + + const queryResult = await query; + const strategies = queryResult.rows + .filter((row) => row.payload?.segments?.includes(segmentId)) + .map(this.mapRow); + + return strategies; + } }