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 dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init'; | ||||||
| import getLogger from '../../fixtures/no-logger'; | import getLogger from '../../../test/fixtures/no-logger'; | ||||||
| import type { IProjectStore, IUnleashStores } from '../../../lib/types'; | import type { IProjectStore, IUnleashStores } from '../../types'; | ||||||
| import type { IProjectInsert } from '../../../lib/features/project/project-store-type'; | import type { IProjectInsert } from './project-store-type'; | ||||||
| 
 | 
 | ||||||
| let stores: IUnleashStores; | let stores: IUnleashStores; | ||||||
| let db: ITestDb; | let db: ITestDb; | ||||||
| @ -11,7 +11,9 @@ let projectStore: IProjectStore; | |||||||
| let environmentStore: IEnvironmentStore; | let environmentStore: IEnvironmentStore; | ||||||
| 
 | 
 | ||||||
| beforeAll(async () => { | beforeAll(async () => { | ||||||
|     db = await dbInit('project_store_serial', getLogger); |     db = await dbInit('project_store_serial', getLogger, { | ||||||
|  |         experimental: { flags: { archiveProjects: true } }, | ||||||
|  |     }); | ||||||
|     stores = db.stores; |     stores = db.stores; | ||||||
|     projectStore = stores.projectStore; |     projectStore = stores.projectStore; | ||||||
|     environmentStore = stores.environmentStore; |     environmentStore = stores.environmentStore; | ||||||
| @ -21,6 +23,25 @@ afterAll(async () => { | |||||||
|     await db.destroy(); |     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 () => { | test('should have default project', async () => { | ||||||
|     const project = await projectStore.get('default'); |     const project = await projectStore.get('default'); | ||||||
|     expect(project).toBeDefined(); |     expect(project).toBeDefined(); | ||||||
| @ -131,8 +131,9 @@ class ProjectStore implements IProjectStore { | |||||||
|             ) |             ) | ||||||
|             .leftJoin('project_stats', 'project_stats.project', 'projects.id') |             .leftJoin('project_stats', 'project_stats.project', 'projects.id') | ||||||
|             .orderBy('projects.name', 'asc'); |             .orderBy('projects.name', 'asc'); | ||||||
|  | 
 | ||||||
|         if (this.flagResolver.isEnabled('archiveProjects')) { |         if (this.flagResolver.isEnabled('archiveProjects')) { | ||||||
|             projects = projects.where('projects.archived_at', null); |             projects = projects.where(`${TABLE}.archived_at`, null); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (query) { |         if (query) { | ||||||
| @ -221,12 +222,18 @@ class ProjectStore implements IProjectStore { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getAll(query: IProjectQuery = {}): Promise<IProject[]> { |     async getAll(query: IProjectQuery = {}): Promise<IProject[]> { | ||||||
|         const rows = await this.db |         let projects = this.db | ||||||
|             .select(COLUMNS) |             .select(COLUMNS) | ||||||
|             .from(TABLE) |             .from(TABLE) | ||||||
|             .where(query) |             .where(query) | ||||||
|             .orderBy('name', 'asc'); |             .orderBy('name', 'asc'); | ||||||
| 
 | 
 | ||||||
|  |         if (this.flagResolver.isEnabled('archiveProjects')) { | ||||||
|  |             projects = projects.where(`${TABLE}.archived_at`, null); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const rows = await projects; | ||||||
|  | 
 | ||||||
|         return rows.map(this.mapRow); |         return rows.map(this.mapRow); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -706,14 +713,17 @@ class ProjectStore implements IProjectStore { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async count(): Promise<number> { |     async count(): Promise<number> { | ||||||
|         return this.db |         let count = this.db.from(TABLE).count('*'); | ||||||
|             .from(TABLE) | 
 | ||||||
|             .count('*') |         if (this.flagResolver.isEnabled('archiveProjects')) { | ||||||
|             .then((res) => Number(res[0].count)); |             count = count.where(`${TABLE}.archived_at`, null); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return count.then((res) => Number(res[0].count)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getProjectModeCounts(): Promise<ProjectModeCount[]> { |     async getProjectModeCounts(): Promise<ProjectModeCount[]> { | ||||||
|         const result: ProjectModeCount[] = await this.db |         let query = this.db | ||||||
|             .select( |             .select( | ||||||
|                 this.db.raw( |                 this.db.raw( | ||||||
|                     `COALESCE(${SETTINGS_TABLE}.project_mode, 'open') as mode`, |                     `COALESCE(${SETTINGS_TABLE}.project_mode, 'open') as mode`, | ||||||
| @ -729,11 +739,18 @@ class ProjectStore implements IProjectStore { | |||||||
|             .groupBy( |             .groupBy( | ||||||
|                 this.db.raw(`COALESCE(${SETTINGS_TABLE}.project_mode, 'open')`), |                 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); |         return result.map(this.mapProjectModeCount); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 |     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | ||||||
|     mapProjectModeCount(row): ProjectModeCount { |     private mapProjectModeCount(row): ProjectModeCount { | ||||||
|         return { |         return { | ||||||
|             mode: row.mode, |             mode: row.mode, | ||||||
|             count: Number(row.count), |             count: Number(row.count), | ||||||
| @ -741,7 +758,7 @@ class ProjectStore implements IProjectStore { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 |     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | ||||||
|     mapLinkRow(row): IEnvironmentProjectLink { |     private mapLinkRow(row): IEnvironmentProjectLink { | ||||||
|         return { |         return { | ||||||
|             environmentName: row.environment_name, |             environmentName: row.environment_name, | ||||||
|             projectId: row.project_id, |             projectId: row.project_id, | ||||||
| @ -749,7 +766,7 @@ class ProjectStore implements IProjectStore { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 |     // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 | ||||||
|     mapRow(row): IProject { |     private mapRow(row): IProject { | ||||||
|         if (!row) { |         if (!row) { | ||||||
|             throw new NotFoundError('No project found'); |             throw new NotFoundError('No project found'); | ||||||
|         } |         } | ||||||
| @ -772,7 +789,7 @@ class ProjectStore implements IProjectStore { | |||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     mapProjectEnvironmentRow(row: { |     private mapProjectEnvironmentRow(row: { | ||||||
|         environment_name: string; |         environment_name: string; | ||||||
|         default_strategy: CreateFeatureStrategySchema; |         default_strategy: CreateFeatureStrategySchema; | ||||||
|     }): ProjectEnvironment { |     }): ProjectEnvironment { | ||||||
| @ -785,7 +802,7 @@ class ProjectStore implements IProjectStore { | |||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     getAggregatedApplicationsData(rows): IProjectApplication[] { |     private getAggregatedApplicationsData(rows): IProjectApplication[] { | ||||||
|         const entriesMap = new Map<string, IProjectApplication>(); |         const entriesMap = new Map<string, IProjectApplication>(); | ||||||
| 
 | 
 | ||||||
|         rows.forEach((row) => { |         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[]> { |     async getProjectsWithCounts(): Promise<IProjectWithCount[]> { | ||||||
|         return this.projects |         return this.projects | ||||||
|             .filter((project) => project.archivedAt !== null) |             .filter((project) => project.archivedAt === null) | ||||||
|             .map((project) => { |             .map((project) => { | ||||||
|                 return { |                 return { | ||||||
|                     ...project, |                     ...project, | ||||||
| @ -105,7 +105,8 @@ export default class FakeProjectStore implements IProjectStore { | |||||||
|     destroy(): void {} |     destroy(): void {} | ||||||
| 
 | 
 | ||||||
|     async count(): Promise<number> { |     async count(): Promise<number> { | ||||||
|         return this.projects.length; |         return this.projects.filter((project) => project.archivedAt === null) | ||||||
|  |             .length; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async get(key: string): Promise<IProject> { |     async get(key: string): Promise<IProject> { | ||||||
| @ -117,7 +118,7 @@ export default class FakeProjectStore implements IProjectStore { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getAll(): Promise<IProject[]> { |     async getAll(): Promise<IProject[]> { | ||||||
|         return this.projects; |         return this.projects.filter((project) => project.archivedAt === null); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user