mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: exclude archived projects from insights and project stats (#7843)
This commit is contained in:
		
							parent
							
								
									0934c6ccd8
								
							
						
					
					
						commit
						fcf1329816
					
				| @ -1,9 +1,9 @@ | ||||
| import type { IEnvironmentStore } from '../../../lib/features/project-environments/environment-store-type'; | ||||
| import type { IEnvironmentStore } from '../project-environments/environment-store-type'; | ||||
| 
 | ||||
| import dbInit, { type ITestDb } from '../helpers/database-init'; | ||||
| import getLogger from '../../fixtures/no-logger'; | ||||
| import type { IProjectStore, IUnleashStores } from '../../../lib/types'; | ||||
| import type { IProjectInsert } from '../../../lib/features/project/project-store-type'; | ||||
| import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init'; | ||||
| import getLogger from '../../../test/fixtures/no-logger'; | ||||
| import type { IProjectStore, IUnleashStores } from '../../types'; | ||||
| import type { IProjectInsert } from './project-store-type'; | ||||
| 
 | ||||
| let stores: IUnleashStores; | ||||
| let db: ITestDb; | ||||
| @ -11,7 +11,9 @@ let projectStore: IProjectStore; | ||||
| let environmentStore: IEnvironmentStore; | ||||
| 
 | ||||
| beforeAll(async () => { | ||||
|     db = await dbInit('project_store_serial', getLogger); | ||||
|     db = await dbInit('project_store_serial', getLogger, { | ||||
|         experimental: { flags: { archiveProjects: true } }, | ||||
|     }); | ||||
|     stores = db.stores; | ||||
|     projectStore = stores.projectStore; | ||||
|     environmentStore = stores.environmentStore; | ||||
| @ -21,6 +23,25 @@ afterAll(async () => { | ||||
|     await db.destroy(); | ||||
| }); | ||||
| 
 | ||||
| test('should exclude archived projects', async () => { | ||||
|     const project = { | ||||
|         id: 'archive-me', | ||||
|         name: 'archive-me', | ||||
|         description: 'Blah', | ||||
|         mode: 'open' as const, | ||||
|     }; | ||||
|     await projectStore.create(project); | ||||
|     await projectStore.archive(project.id); | ||||
| 
 | ||||
|     const allProjects = await projectStore.getAll(); | ||||
|     const count = await projectStore.count(); | ||||
|     const modeCounts = await projectStore.getProjectModeCounts(); | ||||
| 
 | ||||
|     expect(allProjects).toMatchObject([{ id: 'default' }]); | ||||
|     expect(count).toBe(1); | ||||
|     expect(modeCounts).toMatchObject([{ mode: 'open', count: 1 }]); | ||||
| }); | ||||
| 
 | ||||
| test('should have default project', async () => { | ||||
|     const project = await projectStore.get('default'); | ||||
|     expect(project).toBeDefined(); | ||||
| @ -131,8 +131,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); | ||||
|             projects = projects.where(`${TABLE}.archived_at`, null); | ||||
|         } | ||||
| 
 | ||||
|         if (query) { | ||||
| @ -221,12 +222,18 @@ class ProjectStore implements IProjectStore { | ||||
|     } | ||||
| 
 | ||||
|     async getAll(query: IProjectQuery = {}): Promise<IProject[]> { | ||||
|         const rows = await this.db | ||||
|         let projects = this.db | ||||
|             .select(COLUMNS) | ||||
|             .from(TABLE) | ||||
|             .where(query) | ||||
|             .orderBy('name', 'asc'); | ||||
| 
 | ||||
|         if (this.flagResolver.isEnabled('archiveProjects')) { | ||||
|             projects = projects.where(`${TABLE}.archived_at`, null); | ||||
|         } | ||||
| 
 | ||||
|         const rows = await projects; | ||||
| 
 | ||||
|         return rows.map(this.mapRow); | ||||
|     } | ||||
| 
 | ||||
| @ -706,14 +713,17 @@ class ProjectStore implements IProjectStore { | ||||
|     } | ||||
| 
 | ||||
|     async count(): Promise<number> { | ||||
|         return this.db | ||||
|             .from(TABLE) | ||||
|             .count('*') | ||||
|             .then((res) => Number(res[0].count)); | ||||
|         let count = this.db.from(TABLE).count('*'); | ||||
| 
 | ||||
|         if (this.flagResolver.isEnabled('archiveProjects')) { | ||||
|             count = count.where(`${TABLE}.archived_at`, null); | ||||
|         } | ||||
| 
 | ||||
|         return count.then((res) => Number(res[0].count)); | ||||
|     } | ||||
| 
 | ||||
|     async getProjectModeCounts(): Promise<ProjectModeCount[]> { | ||||
|         const result: ProjectModeCount[] = await this.db | ||||
|         let query = this.db | ||||
|             .select( | ||||
|                 this.db.raw( | ||||
|                     `COALESCE(${SETTINGS_TABLE}.project_mode, 'open') as mode`, | ||||
| @ -729,11 +739,18 @@ class ProjectStore implements IProjectStore { | ||||
|             .groupBy( | ||||
|                 this.db.raw(`COALESCE(${SETTINGS_TABLE}.project_mode, 'open')`), | ||||
|             ); | ||||
| 
 | ||||
|         if (this.flagResolver.isEnabled('archiveProjects')) { | ||||
|             query = query.where(`${TABLE}.archived_at`, null); | ||||
|         } | ||||
| 
 | ||||
|         const result: ProjectModeCount[] = await query; | ||||
| 
 | ||||
|         return result.map(this.mapProjectModeCount); | ||||
|     } | ||||
| 
 | ||||
|     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | ||||
|     mapProjectModeCount(row): ProjectModeCount { | ||||
|     private mapProjectModeCount(row): ProjectModeCount { | ||||
|         return { | ||||
|             mode: row.mode, | ||||
|             count: Number(row.count), | ||||
| @ -741,7 +758,7 @@ class ProjectStore implements IProjectStore { | ||||
|     } | ||||
| 
 | ||||
|     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | ||||
|     mapLinkRow(row): IEnvironmentProjectLink { | ||||
|     private mapLinkRow(row): IEnvironmentProjectLink { | ||||
|         return { | ||||
|             environmentName: row.environment_name, | ||||
|             projectId: row.project_id, | ||||
| @ -749,7 +766,7 @@ class ProjectStore implements IProjectStore { | ||||
|     } | ||||
| 
 | ||||
|     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | ||||
|     mapRow(row): IProject { | ||||
|     private mapRow(row): IProject { | ||||
|         if (!row) { | ||||
|             throw new NotFoundError('No project found'); | ||||
|         } | ||||
| @ -772,7 +789,7 @@ class ProjectStore implements IProjectStore { | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     mapProjectEnvironmentRow(row: { | ||||
|     private mapProjectEnvironmentRow(row: { | ||||
|         environment_name: string; | ||||
|         default_strategy: CreateFeatureStrategySchema; | ||||
|     }): ProjectEnvironment { | ||||
| @ -785,7 +802,7 @@ class ProjectStore implements IProjectStore { | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     getAggregatedApplicationsData(rows): IProjectApplication[] { | ||||
|     private getAggregatedApplicationsData(rows): IProjectApplication[] { | ||||
|         const entriesMap = new Map<string, IProjectApplication>(); | ||||
| 
 | ||||
|         rows.forEach((row) => { | ||||
|  | ||||
							
								
								
									
										7
									
								
								src/test/fixtures/fake-project-store.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								src/test/fixtures/fake-project-store.ts
									
									
									
									
										vendored
									
									
								
							| @ -50,7 +50,7 @@ export default class FakeProjectStore implements IProjectStore { | ||||
| 
 | ||||
|     async getProjectsWithCounts(): Promise<IProjectWithCount[]> { | ||||
|         return this.projects | ||||
|             .filter((project) => project.archivedAt !== null) | ||||
|             .filter((project) => project.archivedAt === null) | ||||
|             .map((project) => { | ||||
|                 return { | ||||
|                     ...project, | ||||
| @ -105,7 +105,8 @@ export default class FakeProjectStore implements IProjectStore { | ||||
|     destroy(): void {} | ||||
| 
 | ||||
|     async count(): Promise<number> { | ||||
|         return this.projects.length; | ||||
|         return this.projects.filter((project) => project.archivedAt === null) | ||||
|             .length; | ||||
|     } | ||||
| 
 | ||||
|     async get(key: string): Promise<IProject> { | ||||
| @ -117,7 +118,7 @@ export default class FakeProjectStore implements IProjectStore { | ||||
|     } | ||||
| 
 | ||||
|     async getAll(): Promise<IProject[]> { | ||||
|         return this.projects; | ||||
|         return this.projects.filter((project) => project.archivedAt === null); | ||||
|     } | ||||
| 
 | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user