mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: add projects api for oss as well
This commit is contained in:
		
							parent
							
								
									737e00e1e2
								
							
						
					
					
						commit
						54a99460ce
					
				| @ -6,6 +6,7 @@ import { IProject } from '../types/model'; | |||||||
| import { | import { | ||||||
|     IProjectHealthUpdate, |     IProjectHealthUpdate, | ||||||
|     IProjectInsert, |     IProjectInsert, | ||||||
|  |     IProjectQuery, | ||||||
|     IProjectStore, |     IProjectStore, | ||||||
| } from '../types/stores/project-store'; | } from '../types/stores/project-store'; | ||||||
| import { DEFAULT_ENV } from '../util/constants'; | import { DEFAULT_ENV } from '../util/constants'; | ||||||
| @ -43,10 +44,11 @@ class ProjectStore implements IProjectStore { | |||||||
|         return present; |         return present; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getAll(): Promise<IProject[]> { |     async getAll(query: IProjectQuery = {}): Promise<IProject[]> { | ||||||
|         const rows = await this.db |         const rows = await this.db | ||||||
|             .select(COLUMNS) |             .select(COLUMNS) | ||||||
|             .from(TABLE) |             .from(TABLE) | ||||||
|  |             .where(query) | ||||||
|             .orderBy('name', 'asc'); |             .orderBy('name', 'asc'); | ||||||
| 
 | 
 | ||||||
|         return rows.map(this.mapRow); |         return rows.map(this.mapRow); | ||||||
|  | |||||||
| @ -1,15 +1,28 @@ | |||||||
|  | import { Request, Response } from 'express'; | ||||||
| import Controller from '../../controller'; | import Controller from '../../controller'; | ||||||
| import { IUnleashConfig } from '../../../types/option'; | import { IUnleashConfig } from '../../../types/option'; | ||||||
| import { IUnleashServices } from '../../../types/services'; | import { IUnleashServices } from '../../../types/services'; | ||||||
| import ProjectFeaturesController from './features'; | import ProjectFeaturesController from './features'; | ||||||
| import EnvironmentsController from './environments'; | import EnvironmentsController from './environments'; | ||||||
| import ProjectHealthReport from './health-report'; | import ProjectHealthReport from './health-report'; | ||||||
|  | import ProjectService from '../../../services/project-service'; | ||||||
| 
 | 
 | ||||||
| export default class ProjectApi extends Controller { | export default class ProjectApi extends Controller { | ||||||
|  |     private projectService: ProjectService; | ||||||
|  | 
 | ||||||
|     constructor(config: IUnleashConfig, services: IUnleashServices) { |     constructor(config: IUnleashConfig, services: IUnleashServices) { | ||||||
|         super(config); |         super(config); | ||||||
|  |         this.projectService = services.projectService; | ||||||
|  |         this.get('/', this.getProjects); | ||||||
|         this.use('/', new ProjectFeaturesController(config, services).router); |         this.use('/', new ProjectFeaturesController(config, services).router); | ||||||
|         this.use('/', new EnvironmentsController(config, services).router); |         this.use('/', new EnvironmentsController(config, services).router); | ||||||
|         this.use('/', new ProjectHealthReport(config, services).router); |         this.use('/', new ProjectHealthReport(config, services).router); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     async getProjects(req: Request, res: Response): Promise<void> { | ||||||
|  |         const projects = await this.projectService.getProjects({ | ||||||
|  |             id: 'default', | ||||||
|  |         }); | ||||||
|  |         res.json({ version: 1, projects }).end(); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ import { IEnvironmentStore } from '../types/stores/environment-store'; | |||||||
| import { IFeatureTypeStore } from '../types/stores/feature-type-store'; | import { IFeatureTypeStore } from '../types/stores/feature-type-store'; | ||||||
| import { IFeatureToggleStore } from '../types/stores/feature-toggle-store'; | import { IFeatureToggleStore } from '../types/stores/feature-toggle-store'; | ||||||
| import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store'; | import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store'; | ||||||
| import { IProjectStore } from '../types/stores/project-store'; | import { IProjectQuery, IProjectStore } from '../types/stores/project-store'; | ||||||
| import { IRole } from '../types/stores/access-store'; | import { IRole } from '../types/stores/access-store'; | ||||||
| import { IEventStore } from '../types/stores/event-store'; | import { IEventStore } from '../types/stores/event-store'; | ||||||
| import FeatureToggleServiceV2 from './feature-toggle-service-v2'; | import FeatureToggleServiceV2 from './feature-toggle-service-v2'; | ||||||
| @ -91,8 +91,8 @@ export default class ProjectService { | |||||||
|         this.logger = config.getLogger('services/project-service.js'); |         this.logger = config.getLogger('services/project-service.js'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getProjects(): Promise<IProjectWithCount[]> { |     async getProjects(query?: IProjectQuery): Promise<IProjectWithCount[]> { | ||||||
|         const projects = await this.store.getAll(); |         const projects = await this.store.getAll(query); | ||||||
|         const projectsWithCount = await Promise.all( |         const projectsWithCount = await Promise.all( | ||||||
|             projects.map(async (p) => { |             projects.map(async (p) => { | ||||||
|                 let featureCount = 0; |                 let featureCount = 0; | ||||||
|  | |||||||
| @ -17,6 +17,10 @@ export interface IProjectHealthUpdate { | |||||||
|     health: number; |     health: number; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export interface IProjectQuery { | ||||||
|  |     id?: string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export interface IProjectStore extends Store<IProject, string> { | export interface IProjectStore extends Store<IProject, string> { | ||||||
|     hasProject(id: string): Promise<boolean>; |     hasProject(id: string): Promise<boolean>; | ||||||
|     updateHealth(healthUpdate: IProjectHealthUpdate): Promise<void>; |     updateHealth(healthUpdate: IProjectHealthUpdate): Promise<void>; | ||||||
| @ -28,4 +32,5 @@ export interface IProjectStore extends Store<IProject, string> { | |||||||
|     getEnvironmentsForProject(id: string): Promise<string[]>; |     getEnvironmentsForProject(id: string): Promise<string[]>; | ||||||
|     getMembers(projectId: string): Promise<number>; |     getMembers(projectId: string): Promise<number>; | ||||||
|     count(): Promise<number>; |     count(): Promise<number>; | ||||||
|  |     getAll(query?: IProjectQuery): Promise<IProject[]>; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								src/test/e2e/api/admin/project/projects.e2e.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/test/e2e/api/admin/project/projects.e2e.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | import dbInit from '../../../helpers/database-init'; | ||||||
|  | import { setupApp } from '../../../helpers/test-helper'; | ||||||
|  | import getLogger from '../../../../fixtures/no-logger'; | ||||||
|  | import ProjectStore from '../../../../../lib/db/project-store'; | ||||||
|  | 
 | ||||||
|  | let app; | ||||||
|  | let db; | ||||||
|  | 
 | ||||||
|  | let projectStore: ProjectStore; | ||||||
|  | 
 | ||||||
|  | beforeAll(async () => { | ||||||
|  |     db = await dbInit('projects_api_serial', getLogger); | ||||||
|  |     app = await setupApp(db.stores); | ||||||
|  |     projectStore = db.stores.projectStore; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | afterAll(async () => { | ||||||
|  |     await app.destroy(); | ||||||
|  |     await db.destroy(); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('Should ONLY return default project', async () => { | ||||||
|  |     projectStore.create({ id: 'test2', name: 'test', description: '' }); | ||||||
|  | 
 | ||||||
|  |     const { body } = await app.request | ||||||
|  |         .get('/api/admin/projects') | ||||||
|  |         .expect(200) | ||||||
|  |         .expect('Content-Type', /json/); | ||||||
|  | 
 | ||||||
|  |     expect(body.projects).toHaveLength(1); | ||||||
|  |     expect(body.projects[0].id).toBe('default'); | ||||||
|  | }); | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user