mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	test: project insights service test (#6661)
This commit is contained in:
		
							parent
							
								
									f5a7cc9125
								
							
						
					
					
						commit
						86f229a69d
					
				| @ -323,10 +323,26 @@ export default class FakeFeatureToggleStore implements IFeatureToggleStore { | ||||
|         throw new Error('Method not implemented.'); | ||||
|     } | ||||
| 
 | ||||
|     getFeatureTypeCounts( | ||||
|     async getFeatureTypeCounts( | ||||
|         params: IFeatureProjectUserParams, | ||||
|     ): Promise<IFeatureTypeCount[]> { | ||||
|         throw new Error('Method not implemented.'); | ||||
|         const typeCounts = this.features.reduce( | ||||
|             (acc, feature) => { | ||||
|                 if (!feature.type) { | ||||
|                     return acc; | ||||
|                 } | ||||
| 
 | ||||
|                 if (!acc[feature.type]) { | ||||
|                     acc[feature.type] = { type: feature.type, count: 0 }; | ||||
|                 } | ||||
|                 acc[feature.type].count += 1; | ||||
| 
 | ||||
|                 return acc; | ||||
|             }, | ||||
|             {} as Record<string, IFeatureTypeCount>, | ||||
|         ); | ||||
| 
 | ||||
|         return Object.values(typeCounts); | ||||
|     } | ||||
| 
 | ||||
|     setCreatedByUserId(batchSize: number): Promise<number | undefined> { | ||||
|  | ||||
| @ -53,17 +53,14 @@ export const createProjectInsightsService = ( | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| export const createFakeProjectInsightsService = ( | ||||
|     config: IUnleashConfig, | ||||
| ): ProjectInsightsService => { | ||||
| export const createFakeProjectInsightsService = () => { | ||||
|     const projectStore = new FakeProjectStore(); | ||||
|     const featureToggleStore = new FakeFeatureToggleStore(); | ||||
|     const featureTypeStore = new FakeFeatureTypeStore(); | ||||
|     const projectStatsStore = new FakeProjectStatsStore(); | ||||
|     const featureStrategiesStore = new FakeFeatureStrategiesStore(); | ||||
|     const projectInsightsReadModel = new FakeProjectInsightsReadModel(); | ||||
| 
 | ||||
|     return new ProjectInsightsService( | ||||
|     const projectInsightsService = new ProjectInsightsService( | ||||
|         { | ||||
|             projectStore, | ||||
|             featureToggleStore, | ||||
| @ -73,4 +70,12 @@ export const createFakeProjectInsightsService = ( | ||||
|         }, | ||||
|         projectInsightsReadModel, | ||||
|     ); | ||||
| 
 | ||||
|     return { | ||||
|         projectInsightsService, | ||||
|         projectStatsStore, | ||||
|         featureToggleStore, | ||||
|         projectStore, | ||||
|         projectInsightsReadModel, | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| @ -8,12 +8,18 @@ const changeRequestCounts: ChangeRequestCounts = { | ||||
|     approved: 0, | ||||
|     applied: 0, | ||||
|     rejected: 0, | ||||
|     reviewRequired: 10, | ||||
|     reviewRequired: 0, | ||||
|     scheduled: 0, | ||||
| }; | ||||
| 
 | ||||
| export class FakeProjectInsightsReadModel implements IProjectInsightsReadModel { | ||||
|     private counts: Record<string, ChangeRequestCounts> = {}; | ||||
| 
 | ||||
|     async getChangeRequests(projectId: string): Promise<ChangeRequestCounts> { | ||||
|         return changeRequestCounts; | ||||
|         return this.counts[projectId] ?? changeRequestCounts; | ||||
|     } | ||||
| 
 | ||||
|     async setChangeRequests(projectId: string, counts: ChangeRequestCounts) { | ||||
|         this.counts[projectId] = counts; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,296 @@ | ||||
| import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init'; | ||||
| import getLogger from '../../../test/fixtures/no-logger'; | ||||
| import type FeatureToggleService from '../../../lib/features/feature-toggle/feature-toggle-service'; | ||||
| import type ProjectService from '../../../lib/features/project/project-service'; | ||||
| import { createTestConfig } from '../../../test/config/test-config'; | ||||
| import { | ||||
|     EventService, | ||||
|     type ProjectInsightsService, | ||||
| } from '../../../lib/services'; | ||||
| import { FeatureEnvironmentEvent } from '../../../lib/types/events'; | ||||
| import { subDays } from 'date-fns'; | ||||
| import { | ||||
|     createFeatureToggleService, | ||||
|     createProjectService, | ||||
| } from '../../../lib/features'; | ||||
| import type { IUnleashStores, IUser } from '../../../lib/types'; | ||||
| import type { User } from '../../../lib/server-impl'; | ||||
| import { createProjectInsightsService } from './createProjectInsightsService'; | ||||
| 
 | ||||
| let stores: IUnleashStores; | ||||
| let db: ITestDb; | ||||
| 
 | ||||
| let projectService: ProjectService; | ||||
| let projectInsightsService: ProjectInsightsService; | ||||
| let eventService: EventService; | ||||
| let featureToggleService: FeatureToggleService; | ||||
| let user: User; // many methods in this test use User instead of IUser
 | ||||
| let opsUser: IUser; | ||||
| 
 | ||||
| beforeAll(async () => { | ||||
|     db = await dbInit('project_service_serial', getLogger); | ||||
|     stores = db.stores; | ||||
|     // @ts-ignore return type IUser type missing generateImageUrl
 | ||||
|     user = await stores.userStore.insert({ | ||||
|         name: 'Some Name', | ||||
|         email: 'test@getunleash.io', | ||||
|     }); | ||||
|     opsUser = await stores.userStore.insert({ | ||||
|         name: 'Test user', | ||||
|         email: 'test@example.com', | ||||
|     }); | ||||
|     const config = createTestConfig({ | ||||
|         getLogger, | ||||
|     }); | ||||
|     eventService = new EventService(stores, config); | ||||
| 
 | ||||
|     featureToggleService = createFeatureToggleService(db.rawDatabase, config); | ||||
| 
 | ||||
|     projectService = createProjectService(db.rawDatabase, config); | ||||
| 
 | ||||
|     projectInsightsService = createProjectInsightsService( | ||||
|         db.rawDatabase, | ||||
|         config, | ||||
|     ); | ||||
| }); | ||||
| 
 | ||||
| afterAll(async () => { | ||||
|     await db.destroy(); | ||||
| }); | ||||
| 
 | ||||
| afterEach(async () => { | ||||
|     await stores.eventStore.deleteAll(); | ||||
| }); | ||||
| 
 | ||||
| const updateFeature = async (featureName: string, update: any) => { | ||||
|     return db.rawDatabase | ||||
|         .table('features') | ||||
|         .update(update) | ||||
|         .where({ name: featureName }); | ||||
| }; | ||||
| 
 | ||||
| test('should return average time to production per toggle', async () => { | ||||
|     const project = { | ||||
|         id: 'average-time-to-prod-per-toggle', | ||||
|         name: 'average-time-to-prod-per-toggle', | ||||
|         mode: 'open' as const, | ||||
|         defaultStickiness: 'clientId', | ||||
|     }; | ||||
| 
 | ||||
|     await projectService.createProject(project, user); | ||||
| 
 | ||||
|     const toggles = [ | ||||
|         { name: 'average-prod-time-pt', subdays: 7 }, | ||||
|         { name: 'average-prod-time-pt-2', subdays: 14 }, | ||||
|         { name: 'average-prod-time-pt-3', subdays: 40 }, | ||||
|         { name: 'average-prod-time-pt-4', subdays: 15 }, | ||||
|         { name: 'average-prod-time-pt-5', subdays: 2 }, | ||||
|     ]; | ||||
| 
 | ||||
|     const featureToggles = await Promise.all( | ||||
|         toggles.map((toggle) => { | ||||
|             return featureToggleService.createFeatureToggle( | ||||
|                 project.id, | ||||
|                 toggle, | ||||
|                 user.email, | ||||
|                 opsUser.id, | ||||
|             ); | ||||
|         }), | ||||
|     ); | ||||
| 
 | ||||
|     await Promise.all( | ||||
|         featureToggles.map((toggle) => { | ||||
|             return eventService.storeEvent( | ||||
|                 new FeatureEnvironmentEvent({ | ||||
|                     enabled: true, | ||||
|                     project: project.id, | ||||
|                     featureName: toggle.name, | ||||
|                     environment: 'default', | ||||
|                     createdBy: 'Fredrik', | ||||
|                     createdByUserId: opsUser.id, | ||||
|                 }), | ||||
|             ); | ||||
|         }), | ||||
|     ); | ||||
| 
 | ||||
|     await Promise.all( | ||||
|         toggles.map((toggle) => | ||||
|             updateFeature(toggle.name, { | ||||
|                 created_at: subDays(new Date(), toggle.subdays), | ||||
|             }), | ||||
|         ), | ||||
|     ); | ||||
| 
 | ||||
|     const result = await projectInsightsService.getDoraMetrics(project.id); | ||||
| 
 | ||||
|     expect(result.features).toHaveLength(5); | ||||
|     expect(result.features[0].timeToProduction).toBeTruthy(); | ||||
|     expect(result.projectAverage).toBeTruthy(); | ||||
| }); | ||||
| 
 | ||||
| test('should return average time to production per toggle for a specific project', async () => { | ||||
|     const project1 = { | ||||
|         id: 'average-time-to-prod-per-toggle-1', | ||||
|         name: 'Project 1', | ||||
|         mode: 'open' as const, | ||||
|         defaultStickiness: 'clientId', | ||||
|     }; | ||||
| 
 | ||||
|     const project2 = { | ||||
|         id: 'average-time-to-prod-per-toggle-2', | ||||
|         name: 'Project 2', | ||||
|         mode: 'open' as const, | ||||
|         defaultStickiness: 'clientId', | ||||
|     }; | ||||
| 
 | ||||
|     await projectService.createProject(project1, user); | ||||
|     await projectService.createProject(project2, user); | ||||
| 
 | ||||
|     const togglesProject1 = [ | ||||
|         { name: 'average-prod-time-pt-10', subdays: 7 }, | ||||
|         { name: 'average-prod-time-pt-11', subdays: 14 }, | ||||
|         { name: 'average-prod-time-pt-12', subdays: 40 }, | ||||
|     ]; | ||||
| 
 | ||||
|     const togglesProject2 = [ | ||||
|         { name: 'average-prod-time-pt-13', subdays: 15 }, | ||||
|         { name: 'average-prod-time-pt-14', subdays: 2 }, | ||||
|     ]; | ||||
| 
 | ||||
|     const featureTogglesProject1 = await Promise.all( | ||||
|         togglesProject1.map((toggle) => { | ||||
|             return featureToggleService.createFeatureToggle( | ||||
|                 project1.id, | ||||
|                 toggle, | ||||
|                 user.email, | ||||
|                 opsUser.id, | ||||
|             ); | ||||
|         }), | ||||
|     ); | ||||
| 
 | ||||
|     const featureTogglesProject2 = await Promise.all( | ||||
|         togglesProject2.map((toggle) => { | ||||
|             return featureToggleService.createFeatureToggle( | ||||
|                 project2.id, | ||||
|                 toggle, | ||||
|                 user.email, | ||||
|                 opsUser.id, | ||||
|             ); | ||||
|         }), | ||||
|     ); | ||||
| 
 | ||||
|     await Promise.all( | ||||
|         featureTogglesProject1.map((toggle) => { | ||||
|             return eventService.storeEvent( | ||||
|                 new FeatureEnvironmentEvent({ | ||||
|                     enabled: true, | ||||
|                     project: project1.id, | ||||
|                     featureName: toggle.name, | ||||
|                     environment: 'default', | ||||
|                     createdBy: 'Fredrik', | ||||
|                     createdByUserId: opsUser.id, | ||||
|                 }), | ||||
|             ); | ||||
|         }), | ||||
|     ); | ||||
| 
 | ||||
|     await Promise.all( | ||||
|         featureTogglesProject2.map((toggle) => { | ||||
|             return eventService.storeEvent( | ||||
|                 new FeatureEnvironmentEvent({ | ||||
|                     enabled: true, | ||||
|                     project: project2.id, | ||||
|                     featureName: toggle.name, | ||||
|                     environment: 'default', | ||||
|                     createdBy: 'Fredrik', | ||||
|                     createdByUserId: opsUser.id, | ||||
|                 }), | ||||
|             ); | ||||
|         }), | ||||
|     ); | ||||
| 
 | ||||
|     await Promise.all( | ||||
|         togglesProject1.map((toggle) => | ||||
|             updateFeature(toggle.name, { | ||||
|                 created_at: subDays(new Date(), toggle.subdays), | ||||
|             }), | ||||
|         ), | ||||
|     ); | ||||
| 
 | ||||
|     await Promise.all( | ||||
|         togglesProject2.map((toggle) => | ||||
|             updateFeature(toggle.name, { | ||||
|                 created_at: subDays(new Date(), toggle.subdays), | ||||
|             }), | ||||
|         ), | ||||
|     ); | ||||
| 
 | ||||
|     const resultProject1 = await projectInsightsService.getDoraMetrics( | ||||
|         project1.id, | ||||
|     ); | ||||
|     const resultProject2 = await projectInsightsService.getDoraMetrics( | ||||
|         project2.id, | ||||
|     ); | ||||
| 
 | ||||
|     expect(resultProject1.features).toHaveLength(3); | ||||
|     expect(resultProject2.features).toHaveLength(2); | ||||
| }); | ||||
| 
 | ||||
| test('should return average time to production per toggle and include archived toggles', async () => { | ||||
|     const project1 = { | ||||
|         id: 'average-time-to-prod-per-toggle-12', | ||||
|         name: 'Project 1', | ||||
|         mode: 'open' as const, | ||||
|         defaultStickiness: 'clientId', | ||||
|     }; | ||||
| 
 | ||||
|     await projectService.createProject(project1, user); | ||||
| 
 | ||||
|     const togglesProject1 = [ | ||||
|         { name: 'average-prod-time-pta-10', subdays: 7 }, | ||||
|         { name: 'average-prod-time-pta-11', subdays: 14 }, | ||||
|         { name: 'average-prod-time-pta-12', subdays: 40 }, | ||||
|     ]; | ||||
| 
 | ||||
|     const featureTogglesProject1 = await Promise.all( | ||||
|         togglesProject1.map((toggle) => { | ||||
|             return featureToggleService.createFeatureToggle( | ||||
|                 project1.id, | ||||
|                 toggle, | ||||
|                 user.email, | ||||
|                 opsUser.id, | ||||
|             ); | ||||
|         }), | ||||
|     ); | ||||
| 
 | ||||
|     await Promise.all( | ||||
|         featureTogglesProject1.map((toggle) => { | ||||
|             return eventService.storeEvent( | ||||
|                 new FeatureEnvironmentEvent({ | ||||
|                     enabled: true, | ||||
|                     project: project1.id, | ||||
|                     featureName: toggle.name, | ||||
|                     environment: 'default', | ||||
|                     createdBy: 'Fredrik', | ||||
|                     createdByUserId: opsUser.id, | ||||
|                 }), | ||||
|             ); | ||||
|         }), | ||||
|     ); | ||||
| 
 | ||||
|     await Promise.all( | ||||
|         togglesProject1.map((toggle) => | ||||
|             updateFeature(toggle.name, { | ||||
|                 created_at: subDays(new Date(), toggle.subdays), | ||||
|             }), | ||||
|         ), | ||||
|     ); | ||||
| 
 | ||||
|     await featureToggleService.archiveToggle('average-prod-time-pta-12', user); | ||||
| 
 | ||||
|     const resultProject1 = await projectInsightsService.getDoraMetrics( | ||||
|         project1.id, | ||||
|     ); | ||||
| 
 | ||||
|     expect(resultProject1.features).toHaveLength(3); | ||||
| }); | ||||
| @ -0,0 +1,70 @@ | ||||
| import { createFakeProjectInsightsService } from './createProjectInsightsService'; | ||||
| 
 | ||||
| test('Return basic insights', async () => { | ||||
|     const { | ||||
|         projectInsightsService, | ||||
|         projectStatsStore, | ||||
|         featureToggleStore, | ||||
|         projectStore, | ||||
|         projectInsightsReadModel, | ||||
|     } = createFakeProjectInsightsService(); | ||||
|     await featureToggleStore.create('default', { | ||||
|         name: 'irrelevant', | ||||
|         createdByUserId: 1, | ||||
|         type: 'release', | ||||
|     }); | ||||
|     await projectInsightsReadModel.setChangeRequests('default', { | ||||
|         total: 5, | ||||
|         approved: 1, | ||||
|         applied: 1, | ||||
|         rejected: 1, | ||||
|         reviewRequired: 1, | ||||
|         scheduled: 1, | ||||
|     }); | ||||
|     await projectStore.create({ | ||||
|         id: 'default', | ||||
|         name: 'irrelevant', | ||||
|     }); | ||||
|     await projectStatsStore.updateProjectStats('default', { | ||||
|         archivedCurrentWindow: 1, | ||||
|         archivedPastWindow: 1, | ||||
|         createdCurrentWindow: 1, | ||||
|         createdPastWindow: 1, | ||||
|         avgTimeToProdCurrentWindow: 1, | ||||
|         projectActivityCurrentWindow: 1, | ||||
|         projectActivityPastWindow: 1, | ||||
|         projectMembersAddedCurrentWindow: 1, | ||||
|     }); | ||||
| 
 | ||||
|     const insights = await projectInsightsService.getProjectInsights('default'); | ||||
| 
 | ||||
|     expect(insights).toEqual({ | ||||
|         stats: { | ||||
|             archivedCurrentWindow: 1, | ||||
|             archivedPastWindow: 1, | ||||
|             createdCurrentWindow: 1, | ||||
|             createdPastWindow: 1, | ||||
|             avgTimeToProdCurrentWindow: 1, | ||||
|             projectActivityCurrentWindow: 1, | ||||
|             projectActivityPastWindow: 1, | ||||
|             projectMembersAddedCurrentWindow: 1, | ||||
|         }, | ||||
|         featureTypeCounts: [{ type: 'release', count: 1 }], | ||||
|         health: { | ||||
|             activeCount: 0, | ||||
|             potentiallyStaleCount: 0, | ||||
|             staleCount: 0, | ||||
|             rating: 100, | ||||
|         }, | ||||
|         leadTime: { features: [], projectAverage: 0 }, | ||||
|         changeRequests: { | ||||
|             total: 5, | ||||
|             approved: 1, | ||||
|             applied: 1, | ||||
|             rejected: 1, | ||||
|             reviewRequired: 1, | ||||
|             scheduled: 1, | ||||
|         }, | ||||
|         members: { currentMembers: 0, change: 0 }, | ||||
|     }); | ||||
| }); | ||||
| @ -54,9 +54,7 @@ export class ProjectInsightsService { | ||||
|         this.projectInsightsReadModel = projectInsightsReadModel; | ||||
|     } | ||||
| 
 | ||||
|     private async getDoraMetrics( | ||||
|         projectId: string, | ||||
|     ): Promise<ProjectDoraMetricsSchema> { | ||||
|     async getDoraMetrics(projectId: string): Promise<ProjectDoraMetricsSchema> { | ||||
|         const activeFeatureToggles = ( | ||||
|             await this.featureToggleStore.getAll({ project: projectId }) | ||||
|         ).map((feature) => feature.name); | ||||
|  | ||||
| @ -118,6 +118,7 @@ export default class ProjectController extends Controller { | ||||
|             ], | ||||
|         }); | ||||
| 
 | ||||
|         /** @deprecated use project insights instead */ | ||||
|         this.route({ | ||||
|             method: 'get', | ||||
|             path: '/:projectId/dora', | ||||
| @ -245,6 +246,7 @@ export default class ProjectController extends Controller { | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** @deprecated use projectInsights instead */ | ||||
|     async getProjectDora( | ||||
|         req: IAuthRequest, | ||||
|         res: Response<ProjectDoraMetricsSchema>, | ||||
|  | ||||
| @ -1,31 +1,31 @@ | ||||
| import dbInit, { type ITestDb } from '../helpers/database-init'; | ||||
| import getLogger from '../../fixtures/no-logger'; | ||||
| import type FeatureToggleService from '../../../lib/features/feature-toggle/feature-toggle-service'; | ||||
| import type ProjectService from '../../../lib/features/project/project-service'; | ||||
| import type { AccessService } from '../../../lib/services/access-service'; | ||||
| import { MOVE_FEATURE_TOGGLE } from '../../../lib/types/permissions'; | ||||
| import { createTestConfig } from '../../config/test-config'; | ||||
| import { RoleName } from '../../../lib/types/model'; | ||||
| import { randomId } from '../../../lib/util/random-id'; | ||||
| import EnvironmentService from '../../../lib/features/project-environments/environment-service'; | ||||
| import IncompatibleProjectError from '../../../lib/error/incompatible-project-error'; | ||||
| import { EventService } from '../../../lib/services'; | ||||
| import { FeatureEnvironmentEvent } from '../../../lib/types/events'; | ||||
| import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init'; | ||||
| import getLogger from '../../../test/fixtures/no-logger'; | ||||
| import type FeatureToggleService from '../feature-toggle/feature-toggle-service'; | ||||
| import type ProjectService from './project-service'; | ||||
| import type { AccessService } from '../../services/access-service'; | ||||
| import { MOVE_FEATURE_TOGGLE } from '../../types/permissions'; | ||||
| import { createTestConfig } from '../../../test/config/test-config'; | ||||
| import { RoleName } from '../../types/model'; | ||||
| import { randomId } from '../../util/random-id'; | ||||
| import EnvironmentService from '../project-environments/environment-service'; | ||||
| import IncompatibleProjectError from '../../error/incompatible-project-error'; | ||||
| import { EventService } from '../../services'; | ||||
| import { FeatureEnvironmentEvent } from '../../types/events'; | ||||
| import { addDays, subDays } from 'date-fns'; | ||||
| import { | ||||
|     createAccessService, | ||||
|     createFeatureToggleService, | ||||
|     createProjectService, | ||||
| } from '../../../lib/features'; | ||||
| } from '../index'; | ||||
| import { | ||||
|     type IGroup, | ||||
|     type IUnleashStores, | ||||
|     type IUser, | ||||
|     SYSTEM_USER, | ||||
|     SYSTEM_USER_ID, | ||||
| } from '../../../lib/types'; | ||||
| import type { User } from '../../../lib/server-impl'; | ||||
| import { InvalidOperationError } from '../../../lib/error'; | ||||
| } from '../../types'; | ||||
| import type { User } from '../../server-impl'; | ||||
| import { InvalidOperationError } from '../../error'; | ||||
| 
 | ||||
| let stores: IUnleashStores; | ||||
| let db: ITestDb; | ||||
| @ -945,6 +945,7 @@ export default class ProjectService { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** @deprecated use projectInsightsService instead */ | ||||
|     async getDoraMetrics(projectId: string): Promise<ProjectDoraMetricsSchema> { | ||||
|         const activeFeatureToggles = ( | ||||
|             await this.featureToggleStore.getAll({ project: projectId }) | ||||
|  | ||||
| @ -270,7 +270,7 @@ export const createServices = ( | ||||
|         : createFakeProjectService(config); | ||||
|     const projectInsightsService = db | ||||
|         ? createProjectInsightsService(db, config) | ||||
|         : createFakeProjectInsightsService(config); | ||||
|         : createFakeProjectInsightsService().projectInsightsService; | ||||
| 
 | ||||
|     const projectHealthService = new ProjectHealthService( | ||||
|         stores, | ||||
|  | ||||
							
								
								
									
										21
									
								
								src/test/fixtures/fake-project-stats-store.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								src/test/fixtures/fake-project-stats-store.ts
									
									
									
									
										vendored
									
									
								
							| @ -3,25 +3,28 @@ import type { | ||||
|     ICreateEnabledDates, | ||||
|     IProjectStatsStore, | ||||
| } from '../../lib/types/stores/project-stats-store-type'; | ||||
| import type { DoraFeaturesSchema } from '../../lib/openapi'; | ||||
| /* eslint-disable @typescript-eslint/no-unused-vars */ | ||||
| 
 | ||||
| export default class FakeProjectStatsStore implements IProjectStatsStore { | ||||
|     updateProjectStats( | ||||
|     private stats: Record<string, IProjectStats> = {}; | ||||
| 
 | ||||
|     async updateProjectStats( | ||||
|         projectId: string, | ||||
|         status: IProjectStats, | ||||
|         stats: IProjectStats, | ||||
|     ): Promise<void> { | ||||
|         throw new Error('not implemented'); | ||||
|         this.stats[projectId] = stats; | ||||
|     } | ||||
| 
 | ||||
|     getProjectStats(projectId: string): Promise<IProjectStats> { | ||||
|         throw new Error('not implemented'); | ||||
|     async getProjectStats(projectId: string): Promise<IProjectStats> { | ||||
|         return this.stats[projectId]; | ||||
|     } | ||||
| 
 | ||||
|     getTimeToProdDates(): Promise<ICreateEnabledDates[]> { | ||||
|         throw new Error('not implemented'); | ||||
|     async getTimeToProdDates(): Promise<ICreateEnabledDates[]> { | ||||
|         return []; | ||||
|     } | ||||
| 
 | ||||
|     getTimeToProdDatesForFeatureToggles(): Promise<any> { | ||||
|         throw new Error('not implemented'); | ||||
|     async getTimeToProdDatesForFeatureToggles(): Promise<DoraFeaturesSchema[]> { | ||||
|         return []; | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										4
									
								
								src/test/fixtures/fake-project-store.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								src/test/fixtures/fake-project-store.ts
									
									
									
									
										vendored
									
									
								
							| @ -166,13 +166,13 @@ export default class FakeProjectStore implements IProjectStore { | ||||
|         throw new Error('Method not implemented.'); | ||||
|     } | ||||
| 
 | ||||
|     getMembersCountByProjectAfterDate( | ||||
|     async getMembersCountByProjectAfterDate( | ||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|         projectId: string, | ||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|         date: string, | ||||
|     ): Promise<number> { | ||||
|         throw new Error('Method not implemented'); | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     updateDefaultStrategy( | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user