diff --git a/src/lib/features/project/project-service.e2e.test.ts b/src/lib/features/project/project-service.e2e.test.ts index 71dfe1219e..be318f0fe1 100644 --- a/src/lib/features/project/project-service.e2e.test.ts +++ b/src/lib/features/project/project-service.e2e.test.ts @@ -79,7 +79,10 @@ beforeAll(async () => { email: 'test@example.com', }); await stores.accessStore.addUserToRole(opsUser.id, 1, ''); - const config = createTestConfig({ getLogger }); + const config = createTestConfig({ + getLogger, + experimental: { flags: { archiveProjects: true } }, + }); eventService = new EventService(stores, config); accessService = createAccessService(db.rawDatabase, config); @@ -299,6 +302,10 @@ test('should archive project', async () => { type: 'project-archived', createdBy: TEST_AUDIT_USER.username, }); + + const projects = await projectService.getProjects(); + expect(projects.find((p) => p.id === project.id)).toBeUndefined(); + expect(projects.length).not.toBe(0); }); test('should not be able to archive project with flags', async () => { diff --git a/src/lib/features/project/project-store.ts b/src/lib/features/project/project-store.ts index feefb4c99d..127bd50a6b 100644 --- a/src/lib/features/project/project-store.ts +++ b/src/lib/features/project/project-store.ts @@ -140,6 +140,9 @@ class ProjectStore implements IProjectStore { ) .leftJoin('project_stats', 'project_stats.project', 'projects.id') .orderBy('projects.name', 'asc'); + if (this.flagResolver.isEnabled('archiveProjects')) { + projects = projects.where('projects.archived_at', null); + } if (query) { projects = projects.where(query); diff --git a/src/test/fixtures/fake-project-store.ts b/src/test/fixtures/fake-project-store.ts index deaa79e3bf..a12d70e328 100644 --- a/src/test/fixtures/fake-project-store.ts +++ b/src/test/fixtures/fake-project-store.ts @@ -19,8 +19,10 @@ import type { ProjectEnvironment, } from '../../lib/features/project/project-store-type'; +type ArchivableProject = IProject & { archivedAt: null | Date }; + export default class FakeProjectStore implements IProjectStore { - projects: IProject[] = []; + projects: ArchivableProject[] = []; projectEnvironment: Map> = new Map(); @@ -47,25 +49,28 @@ export default class FakeProjectStore implements IProjectStore { } async getProjectsWithCounts(): Promise { - return this.projects.map((project) => { - return { - ...project, - memberCount: 0, - featureCount: 0, - staleFeatureCount: 0, - potentiallyStaleFeatureCount: 0, - avgTimeToProduction: 0, - }; - }); + return this.projects + .filter((project) => project.archivedAt !== null) + .map((project) => { + return { + ...project, + memberCount: 0, + featureCount: 0, + staleFeatureCount: 0, + potentiallyStaleFeatureCount: 0, + avgTimeToProduction: 0, + }; + }); } private createInternal(project: IProjectInsert): IProject { - const newProj: IProject = { + const newProj: ArchivableProject = { ...project, health: 100, createdAt: new Date(), mode: 'open', defaultStickiness: 'default', + archivedAt: null, }; this.projects.push(newProj); return newProj; @@ -215,5 +220,11 @@ export default class FakeProjectStore implements IProjectStore { throw new Error('Method not implemented.'); } - async archive(id: string): Promise {} + async archive(id: string): Promise { + this.projects = this.projects.map((project) => + project.id === id + ? { ...project, archivedAt: new Date() } + : project, + ); + } }