-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(workspace): add CRUD operations for projects and resources (#744)
- Loading branch information
1 parent
8c7dad0
commit 3a71f44
Showing
10 changed files
with
406 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import API from '../../APICore.js'; | ||
import {PageModel} from '../BaseInterfaces.js'; | ||
import Resource from '../Resource.js'; | ||
import {ResourceModel, ResourceParams} from '../Resources/index.js'; | ||
import {ListProjectParams, ProjectModel, BaseProjectModel, ProjectResourceType} from './ProjectInterfaces.js'; | ||
|
||
export default class Project extends Resource { | ||
static baseUrl = `/rest/organizations/${API.orgPlaceholder}/projects`; | ||
|
||
/** | ||
* Returns a paginated list of projects. | ||
* | ||
* @param {ListProjectParams} params | ||
* @returns {Promise<PageModel<ProjectModel>>} A paginated list of projects | ||
*/ | ||
list(params?: ListProjectParams): Promise<PageModel<ProjectModel>> { | ||
return this.api.get<PageModel<ProjectModel>>(this.buildPath(Project.baseUrl, params)); | ||
} | ||
|
||
/** | ||
* Creates and returns a new project. | ||
* | ||
* @param {ProjectModel} project | ||
* @returns {Promise<ProjectModel>} The newly created project | ||
*/ | ||
create(project: BaseProjectModel): Promise<ProjectModel> { | ||
return this.api.post<ProjectModel>(this.buildPath(Project.baseUrl), project); | ||
} | ||
|
||
/** | ||
* Updates a project with the model sent and returns the updated project. | ||
* | ||
* @param {string} projectId | ||
* @param {ProjectModel} updateProjectModel | ||
* @returns {Promise<ProjectModel>} The updated project | ||
*/ | ||
update(projectId: string, updateProjectModel: ProjectModel): Promise<ProjectModel> { | ||
return this.api.put<ProjectModel>(this.buildPath(`${Project.baseUrl}/${projectId}`), updateProjectModel); | ||
} | ||
|
||
/** | ||
* Returns a project. | ||
* | ||
* @param {string} projectId | ||
* @returns {Promise<ProjectModel>} The project specified by the provided id | ||
*/ | ||
get(projectId: string): Promise<ProjectModel> { | ||
return this.api.get<ProjectModel>(this.buildPath(`${Project.baseUrl}/${projectId}`)); | ||
} | ||
|
||
/** | ||
* Deletes a project. | ||
* | ||
* @param {string} projectId | ||
*/ | ||
delete(projectId: string): Promise<void> { | ||
return this.api.delete(this.buildPath(`${Project.baseUrl}/${projectId}`)); | ||
} | ||
|
||
/** | ||
* Returns a paginated list of resources associated to a project. | ||
* | ||
* @param projectId | ||
* @param resourceType | ||
* @param {ResourceParams} params | ||
* @returns {Promise<PageModel<ResourceModel>>} A paginated list of resources associated to a project. | ||
*/ | ||
listResources( | ||
projectId: string, | ||
resourceType: ProjectResourceType, | ||
params?: ResourceParams, | ||
): Promise<PageModel<ResourceModel>> { | ||
return this.api.get<PageModel<ResourceModel>>( | ||
this.buildPath(`${Project.baseUrl}/${projectId}/resources/${resourceType}`, params), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import {Paginated} from '../BaseInterfaces.js'; | ||
import {SortingOrder} from '../Enums.js'; | ||
|
||
export enum ProjectSortBy { | ||
name = 'NAME', | ||
createdBy = 'CREATED_BY', | ||
createdDate = 'CREATED_DATE', | ||
updatedBy = 'UPDATED_BY', | ||
updatedDate = 'UPDATED_DATE', | ||
} | ||
|
||
export const projectResourceTypes = [ | ||
'CATALOG', | ||
'CASE_ASSIST', | ||
'CRAWLING_MODULE', | ||
'EXTENSION', | ||
'IN_PRODUCT_EXPERIENCE', | ||
'INSIGHT_PANEL', | ||
'ML_MODEL', | ||
'QUERY_PIPELINE', | ||
'SEARCH_HUB', | ||
'SEARCH_PAGE', | ||
'SECURITY_PROVIDER', | ||
'SOURCE', | ||
'UA_REPORT', | ||
]; | ||
|
||
export type ProjectResourceType = (typeof projectResourceTypes)[number]; | ||
|
||
export enum SolutionType { | ||
Commerce = 'COMMERCE', | ||
Other = 'OTHER', | ||
Service = 'SERVICE', | ||
Website = 'WEBSITE', | ||
Workplace = 'WORKPLACE', | ||
} | ||
|
||
export interface BaseProjectModel { | ||
/** | ||
* The name of the project. | ||
*/ | ||
name: string; | ||
/** | ||
* The description of the project. | ||
*/ | ||
description: string; | ||
/** | ||
* The solution type of the project. | ||
*/ | ||
solutionType: SolutionType; | ||
/** | ||
* The list of usernames that will be points of contact for the project. | ||
* | ||
* @example: ['[email protected]', '[email protected]'] | ||
*/ | ||
pointsOfContact?: string[]; | ||
/** | ||
* The resources associated to the project. | ||
* | ||
* @example: {'SOURCE': ['sourceId1', 'sourceId2']} | ||
*/ | ||
resources?: Record<ProjectResourceType, string[]>; | ||
} | ||
|
||
export interface ProjectModel extends BaseProjectModel { | ||
/** | ||
* The unique identitifier of the project. | ||
*/ | ||
id: string; | ||
/** | ||
* The email of the user that created the project. | ||
* | ||
* @example: '[email protected]' | ||
*/ | ||
createdBy: string; | ||
/** | ||
* The date of the project's creation. | ||
* Note: ISO-8601 format | ||
* | ||
* @example: '2023-06-21T14:59:26.850Z' | ||
*/ | ||
createdDate: string; | ||
/** | ||
* The email of the user that last updated the project. | ||
* | ||
* @example: '[email protected]' | ||
*/ | ||
updatedBy: string; | ||
/** | ||
* The date of the project's last update. | ||
* Note: ISO-8601 format | ||
* | ||
* @example: '2023-06-21T14:59:26.850Z' | ||
*/ | ||
updatedDate: string; | ||
} | ||
|
||
export interface ListProjectParams extends Paginated { | ||
/** | ||
* The query filter to match. | ||
* This allows you to search according to the project name. | ||
* | ||
* By default, results are not required to match a specific query filter. | ||
*/ | ||
filter?: string; | ||
/** | ||
* The sorting criteria to apply on the results. | ||
* | ||
*/ | ||
sortBy?: ProjectSortBy; | ||
/** | ||
* The sorting order to apply on the results. | ||
* | ||
* @example: 'ASC' | ||
*/ | ||
order?: SortingOrder; | ||
/** | ||
* Whether to include resources when returning results. | ||
*/ | ||
includeResources?: boolean; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './Project.js'; | ||
export * from './ProjectInterfaces.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import API from '../../../APICore.js'; | ||
import Project from '../Project.js'; | ||
import {BaseProjectModel, ProjectModel, SolutionType} from '../ProjectInterfaces.js'; | ||
|
||
jest.mock('../../../APICore.js'); | ||
|
||
const APIMock: jest.Mock<API> = API as any; | ||
|
||
describe('Project', () => { | ||
let project: Project; | ||
const api = new APIMock() as jest.Mocked<API>; | ||
const serverlessApi = new APIMock() as jest.Mocked<API>; | ||
const mockProjectId = 'randomProjectId'; | ||
const mockRandomResourceType = 'CATALOG'; | ||
|
||
const mockNewProject: BaseProjectModel = { | ||
name: 'Pokemon Project', | ||
description: 'Project about pokemons', | ||
solutionType: SolutionType.Commerce, | ||
}; | ||
|
||
const mockProject: ProjectModel = { | ||
id: mockProjectId, | ||
name: 'Pokemon Project', | ||
description: 'Project about pokemons', | ||
solutionType: SolutionType.Commerce, | ||
createdBy: '[email protected]', | ||
updatedBy: '[email protected]', | ||
createdDate: '2023-07-19T02:37:23.399Z', | ||
updatedDate: '2023-07-22T21:52:22.588Z', | ||
}; | ||
|
||
beforeEach(() => { | ||
project = new Project(api, serverlessApi); | ||
|
||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe('list', () => { | ||
it('should make a GET call to the correct Project url', () => { | ||
project.list(); | ||
expect(api.get).toHaveBeenCalledTimes(1); | ||
expect(api.get).toHaveBeenCalledWith(Project.baseUrl); | ||
}); | ||
|
||
it('should use the passed parameters as its query paramaters', () => { | ||
project.list({page: 1, perPage: 50}); | ||
expect(api.get).toHaveBeenCalledTimes(1); | ||
expect(api.get).toHaveBeenCalledWith(`${Project.baseUrl}?page=1&perPage=50`); | ||
}); | ||
}); | ||
|
||
describe('create', () => { | ||
it('should make a POST call to the correct Project url', () => { | ||
project.create(mockNewProject); | ||
expect(api.post).toHaveBeenCalledTimes(1); | ||
expect(api.post).toHaveBeenCalledWith(Project.baseUrl, { | ||
name: 'Pokemon Project', | ||
description: 'Project about pokemons', | ||
solutionType: SolutionType.Commerce, | ||
}); | ||
}); | ||
}); | ||
|
||
describe('update', () => { | ||
it('should make a PUT call to the correct Project url', () => { | ||
project.update(mockProjectId, mockProject); | ||
expect(api.put).toHaveBeenCalledTimes(1); | ||
expect(api.put).toHaveBeenCalledWith(`${Project.baseUrl}/randomProjectId`, { | ||
id: mockProjectId, | ||
name: 'Pokemon Project', | ||
description: 'Project about pokemons', | ||
solutionType: SolutionType.Commerce, | ||
createdBy: '[email protected]', | ||
updatedBy: '[email protected]', | ||
createdDate: '2023-07-19T02:37:23.399Z', | ||
updatedDate: '2023-07-22T21:52:22.588Z', | ||
}); | ||
}); | ||
}); | ||
|
||
describe('get', () => { | ||
it('should make a GET call to the correct Project URL', () => { | ||
project.get(mockProjectId); | ||
expect(api.get).toHaveBeenCalledTimes(1); | ||
expect(api.get).toHaveBeenCalledWith(`${Project.baseUrl}/randomProjectId`); | ||
}); | ||
}); | ||
|
||
describe('delete', () => { | ||
it('should make a DELETE call to the correct Project URL', () => { | ||
project.delete(mockProjectId); | ||
expect(api.delete).toHaveBeenCalledTimes(1); | ||
expect(api.delete).toHaveBeenCalledWith(`${Project.baseUrl}/randomProjectId`); | ||
}); | ||
}); | ||
|
||
describe('listResources', () => { | ||
it('should make a GET call to the correct Project URL', () => { | ||
project.listResources(mockProjectId, mockRandomResourceType); | ||
expect(api.get).toHaveBeenCalledTimes(1); | ||
expect(api.get).toHaveBeenCalledWith( | ||
`${Project.baseUrl}/${mockProjectId}/resources/${mockRandomResourceType}`, | ||
); | ||
}); | ||
|
||
it('should use the passed parameters as its query paramaters', () => { | ||
project.listResources(mockProjectId, mockRandomResourceType, {page: 1, perPage: 50}); | ||
expect(api.get).toHaveBeenCalledTimes(1); | ||
expect(api.get).toHaveBeenCalledWith( | ||
`${Project.baseUrl}/${mockProjectId}/resources/${mockRandomResourceType}?page=1&perPage=50`, | ||
); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import API from '../../APICore.js'; | ||
import {PageModel} from '../BaseInterfaces.js'; | ||
import {ProjectResourceType} from '../Projects/ProjectInterfaces.js'; | ||
import Resource from '../Resource.js'; | ||
import {ResourceParams, ResourceModel} from './ResourcesInterfaces.js'; | ||
|
||
export default class Resources extends Resource { | ||
static baseUrl = `/rest/organizations/${API.orgPlaceholder}/resources`; | ||
|
||
/** | ||
* Returns a paginated list of resources. | ||
* | ||
* @param resourceType | ||
* @param {ListProjectParams} params | ||
* @returns {Promise<PageModel<ResourceModel>>} A paginated list of resources. | ||
*/ | ||
list(resourceType: ProjectResourceType, params?: ResourceParams): Promise<PageModel<ResourceModel>> { | ||
return this.api.get<PageModel<ResourceModel>>(this.buildPath(`${Resources.baseUrl}/${resourceType}`, params)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import {Paginated} from '../BaseInterfaces.js'; | ||
|
||
export interface ResourceModel { | ||
/** | ||
* The unique identifier of a resource within a project | ||
*/ | ||
id: string; | ||
/** | ||
* The name of the resouce | ||
*/ | ||
name: string; | ||
/** | ||
* The type of the resource | ||
*/ | ||
type?: string; | ||
/** | ||
* The version of the resource | ||
*/ | ||
version?: string; | ||
} | ||
|
||
export interface ResourceParams extends Paginated { | ||
/** | ||
* Term to filter resources by id or name | ||
*/ | ||
filter?: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './Resources.js'; | ||
export * from './ResourcesInterfaces.js'; |
Oops, something went wrong.