diff --git a/openapi3.yaml b/openapi3.yaml index 1b5009a..4797fce 100644 --- a/openapi3.yaml +++ b/openapi3.yaml @@ -6,7 +6,7 @@ info: paths: /jobs: get: - operationId: findJobs + operationId: getJobs parameters: - $ref: '#/components/parameters/resourceId' - $ref: '#/components/parameters/version' @@ -20,7 +20,7 @@ paths: - $ref: '#/components/parameters/internalId' - $ref: '#/components/parameters/domain' - $ref: '#/components/parameters/shouldReturnAvailableActions' - summary: find jobs by criteria + summary: Get jobs by criteria tags: - jobs responses: @@ -34,7 +34,7 @@ paths: $ref: '#/components/schemas/jobResponse' post: operationId: createJob - summary: Creates a new job + summary: Create a new job tags: - jobs requestBody: @@ -73,7 +73,7 @@ paths: /jobs/find: post: operationId: findJobsByCriteria - summary: gets jobs by criteria + summary: Find jobs by criteria tags: - jobs requestBody: @@ -99,7 +99,7 @@ paths: - $ref: '#/components/parameters/shouldReturnTasks' - $ref: '#/components/parameters/shouldReturnAvailableActions' operationId: getJob - summary: Get job by id + summary: Get job by ID tags: - jobs responses: @@ -117,7 +117,7 @@ paths: $ref: '#/components/schemas/errorMessage' put: operationId: updateJob - summary: Updates a job + summary: Update a job tags: - jobs requestBody: @@ -179,7 +179,7 @@ paths: parameters: - $ref: '#/components/parameters/parameters' summary: >- - find jobs by job's parameters, temporary only 1 level nested object is + Find jobs by job's parameters, temporary only 1 level nested object is supported. tags: - jobs @@ -197,7 +197,7 @@ paths: - $ref: '#/components/parameters/jobId' post: operationId: isJobResettable - summary: checks if job is resettable + summary: Check if job is resettable tags: - jobs responses: @@ -212,7 +212,7 @@ paths: - $ref: '#/components/parameters/jobId' post: operationId: resetJob - summary: reset a resettable job + summary: Reset a resettable job tags: - jobs requestBody: @@ -250,7 +250,7 @@ paths: operationId: getTasks tags: - tasks - summary: Get all the tasks of a job + summary: Get all tasks of a job responses: '200': description: Array of tasks @@ -332,7 +332,7 @@ paths: - tasks put: operationId: updateTask - summary: Update task by task Id + summary: Update task by task ID requestBody: required: true content: @@ -408,7 +408,7 @@ paths: /tasks/find: post: operationId: findTasks - summary: return list of matching tasks + summary: Find matching tasks tags: - tasks requestBody: @@ -443,7 +443,7 @@ paths: post: operationId: startPendingTask summary: >- - retrive the highest priority pending task and update its status to + Retrieve the highest priority pending task and update its status to In-Progress responses: '200': @@ -463,7 +463,7 @@ paths: /tasks/findInactive: post: operationId: findInactiveTasks - summary: retrive list of inactive task ids + summary: Retrieve a list of inactive task ids requestBody: required: true content: @@ -488,7 +488,7 @@ paths: /tasks/releaseInactive: post: operationId: releaseInactiveTasks - summary: release inactive tasks and return the ids of the released tasks + summary: Release inactive tasks and return the ids of the released tasks requestBody: required: true content: @@ -510,7 +510,7 @@ paths: post: operationId: updateExpiredStatus summary: >- - update status of open jobs and tasks to "Expired" if their expiration + Update status of open jobs and tasks to "Expired" if their expiration date has passed responses: '200': @@ -528,7 +528,7 @@ paths: - $ref: '#/components/parameters/jobId' post: operationId: abortTasksAndJob - summary: updates job and pending tasks statuses to "Aborted" + summary: Update job and pending tasks statuses to "Aborted" responses: '200': description: aborted pending tasks @@ -745,6 +745,9 @@ components: shouldReturnAvailableActions: type: boolean default: false + shouldExcludeParameters: + type: boolean + default: false findTaskRequest: type: object description: task find model diff --git a/src/DAL/repositories/jobRepository.ts b/src/DAL/repositories/jobRepository.ts index e982159..3dcc2ba 100644 --- a/src/DAL/repositories/jobRepository.ts +++ b/src/DAL/repositories/jobRepository.ts @@ -97,10 +97,19 @@ export class JobRepository extends GeneralRepository { delete filter[key]; } } + const queryBuilder = this.createQueryBuilder('job'); + + if (req.shouldExcludeParameters === true) { + queryBuilder.select(excludeColumns(JobEntity, ['parameters', 'tasks']).map((c) => `job.${c}`)); + } else { + queryBuilder.select('job'); + } + + queryBuilder.where(filter); + if (req.shouldReturnTasks !== false) { - filter.relations = ['tasks']; + queryBuilder.leftJoinAndSelect('job.tasks', 'tasks'); } - const queryBuilder = this.createQueryBuilder('job').select().where(filter); if ((req.types?.length ?? 0) > 0) { queryBuilder.andWhere('job.type IN (:...types)', { types: req.types }); } diff --git a/src/common/dataModels/jobs.ts b/src/common/dataModels/jobs.ts index 0defc44..411fdb9 100644 --- a/src/common/dataModels/jobs.ts +++ b/src/common/dataModels/jobs.ts @@ -34,6 +34,7 @@ export interface IFindJobsByCriteriaBody { types?: string[]; shouldReturnTasks?: boolean; shouldReturnAvailableActions?: boolean; + shouldExcludeParameters?: boolean; productType?: string; fromDate?: string; tillDate?: string; diff --git a/tests/integration/jobs/jobs.spec.ts b/tests/integration/jobs/jobs.spec.ts index 54b9479..3206105 100644 --- a/tests/integration/jobs/jobs.spec.ts +++ b/tests/integration/jobs/jobs.spec.ts @@ -16,6 +16,7 @@ import { import { getApp } from '../../../src/app'; import { FindJobsResponse, IAvailableActions, IGetJobResponse } from '../../../src/common/dataModels/jobs'; import { ResponseCodes } from '../../../src/common/constants'; +import { excludeColumns } from '../../../src/common/utils'; import { TaskRepository } from '../../../src/DAL/repositories/taskRepository'; import { TaskEntity } from '../../../src/DAL/entity/task'; import { JobManager } from '../../../src/jobs/models/jobManager'; @@ -23,6 +24,7 @@ import { JobsRequestSender, SearchJobsParams } from './helpers/jobsRequestSender let jobRepositoryMocks: RepositoryMocks; let taskRepositoryMocks: RepositoryMocks; + function createJobDataForFind(): unknown { const taskModel = { jobId: 'jobId', @@ -256,6 +258,7 @@ function createJobDataForAvailableActionsWithAbortableJob(): unknown { }; return jobModel; } + function jobModelToEntity(jobModel: unknown): JobEntity { const model = jobModel as { created: string; @@ -668,6 +671,32 @@ describe('job', function () { expect(response).toSatisfyApiSpec(); }); + it('should exclude parameters when shouldExcludeParameters=true', async () => { + const jobEntity = jobModelToEntity(createJobDataForFind()); + + jobRepositoryMocks.queryBuilder.getMany.mockResolvedValue([jobEntity]); + + await requestSender.findJobs({ + shouldExcludeParameters: true, + }); + + expect(jobRepositoryMocks.queryBuilder.select).toHaveBeenCalledWith( + expect.arrayContaining(excludeColumns(JobEntity, ['parameters', 'tasks']).map((c) => `job.${c}`)) + ); + }); + + it('should include parameters when shouldExcludeParameters=false', async () => { + const jobEntity = jobModelToEntity(createJobDataForFind()); + + jobRepositoryMocks.queryBuilder.getMany.mockResolvedValue([jobEntity]); + + await requestSender.findJobs({ + shouldExcludeParameters: false, + }); + + expect(jobRepositoryMocks.queryBuilder.select).toHaveBeenCalledWith('job'); + }); + it('should not find matched jobs and return status 200 with an empty array', async function () { const filter = { isCleaned: true,