Skip to content

feat: filter, sort type, challenge-track and challenge-type delete api #559

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ workflows:
filters:
branches:
only:
- develop
- feature/PLAT-2032
- dev

# Production builds are exectuted only on tagged commits to the
# master branch.
Expand Down
8 changes: 8 additions & 0 deletions app-constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ const validChallengeParams = {
StartDate: 'startDate',
ProjectId: 'projectId',
Name: 'name',
Type: 'type',
NumOfSubmissions: 'numOfSubmissions',
NumOfRegistrants: 'numOfRegistrants',
Status: 'status',
TypeId: 'typeId',
Prizes: 'overview.totalPrizes'
}
Expand All @@ -64,6 +68,10 @@ const Topics = {
ChallengeDeleted: 'challenge.notification.delete',
ChallengeTypeCreated: 'test.new.bus.events', // 'challenge.action.type.created',
ChallengeTypeUpdated: 'test.new.bus.events', // 'challenge.action.type.updated',
ChallengeTypeDeleted: 'test.new.bus.events', // 'challenge.action.type.deleted',
ChallengeTrackCreated: 'test.new.bus.events', // 'challenge.action.track.created',
ChallengeTrackUpdated: 'test.new.bus.events', // 'challenge.action.track.updated',
ChallengeTrackDeleted: 'test.new.bus.events', // 'challenge.action.track.deleted',
ChallengePhaseCreated: 'test.new.bus.events', // 'challenge.action.phase.created',
ChallengePhaseUpdated: 'test.new.bus.events', // 'challenge.action.phase.updated',
ChallengePhaseDeleted: 'test.new.bus.events', // 'challenge.action.phase.deleted',
Expand Down
85 changes: 84 additions & 1 deletion docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,9 @@ paths:
projectId,
name,
typeId,
numOfRegistrants,
numOfSubmissions,
status,
overview.totalPrizes,
]
- name: sortOrder
Expand Down Expand Up @@ -908,6 +911,46 @@ paths:
description: Internal Server error
schema:
$ref: "#/definitions/ErrorModel"
delete:
tags:
- ChallengeTypes
description: Delete the challenge type with specified id.
security:
- bearer: []
produces:
- application/json
parameters:
- name: challengeTypeId
in: path
required: true
type: string
format: UUID
description: The id of challengeType to be deleted
responses:
"200":
description: Deleted - The request was successful and the resource is returned.
schema:
$ref: "#/definitions/ChallengeType"
"400":
description: Bad request. Request parameters were invalid.
schema:
$ref: "#/definitions/ErrorModel"
"401":
description: Unauthorized. Fail to authenticate the requester.
schema:
$ref: "#/definitions/ErrorModel"
"403":
description: Forbidden. The requester does not have the correct permission to delete the challenge type.
schema:
$ref: "#/definitions/ErrorModel"
"404":
description: Not Found. Challenge type not found
schema:
$ref: "#/definitions/ErrorModel"
"500":
description: Internal Server Error
schema:
$ref: "#/definitions/ErrorModel"
/challenge-tracks:
get:
tags:
Expand Down Expand Up @@ -1143,6 +1186,46 @@ paths:
description: Internal Server Error
schema:
$ref: "#/definitions/ErrorModel"
delete:
tags:
- ChallengeTracks
description: Delete the challenge track with specified id.
security:
- bearer: []
produces:
- application/json
parameters:
- name: challengeTrackId
in: path
required: true
type: string
format: UUID
description: The id of challengeTrack to be deleted.
responses:
"200":
description: Deleted - The request was successful and the resource is returned.
schema:
$ref: "#/definitions/ChallengeTrack"
"400":
description: Bad request. Request parameters were invalid.
schema:
$ref: "#/definitions/ErrorModel"
"401":
description: Unauthorized. Fail to authenticate the requester.
schema:
$ref: "#/definitions/ErrorModel"
"403":
description: Forbidden. The requester does not have the correct permission to delete the challenge track.
schema:
$ref: "#/definitions/ErrorModel"
"404":
description: Not Found. Challenge track not found
schema:
$ref: "#/definitions/ErrorModel"
"500":
description: Internal Server Error
schema:
$ref: "#/definitions/ErrorModel"
/challenge-phases:
get:
tags:
Expand Down Expand Up @@ -2927,7 +3010,7 @@ definitions:
type: boolean
selfServiceCopilot:
type: string
cancelReason:
cancelReason:
type: string
billing:
type: object
Expand Down
13 changes: 12 additions & 1 deletion src/controllers/ChallengeTrackController.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,21 @@ async function partiallyUpdateChallengeTrack (req, res) {
res.send(result)
}

/**
* Delete challenge track
* @param {Object} req the request
* @param {Object} res the response
*/
async function deleteChallengeTrack (req, res) {
const result = await service.deleteChallengeTrack(req.params.challengeTrackId)
res.send(result)
}

module.exports = {
searchChallengeTracks,
createChallengeTrack,
getChallengeTrack,
fullyUpdateChallengeTrack,
partiallyUpdateChallengeTrack
partiallyUpdateChallengeTrack,
deleteChallengeTrack
}
13 changes: 12 additions & 1 deletion src/controllers/ChallengeTypeController.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,21 @@ async function partiallyUpdateChallengeType (req, res) {
res.send(result)
}

/**
* Delete challenge type
* @param {Object} req the request
* @param {Object} res the response
*/
async function deleteChallengeType (req, res) {
const result = await service.deleteChallengeType(req.params.challengeTypeId)
res.send(result)
}

module.exports = {
searchChallengeTypes,
createChallengeType,
getChallengeType,
fullyUpdateChallengeType,
partiallyUpdateChallengeType
partiallyUpdateChallengeType,
deleteChallengeType
}
18 changes: 18 additions & 0 deletions src/init-es.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ const initES = async () => {
},
normalizer: 'custom_sort_normalizer'
},
status: {
type: 'keyword',
fields: {
text: {
type: 'text'
}
},
normalizer: 'custom_sort_normalizer'
},
type: {
type: 'keyword',
fields: {
text: {
type: 'text'
}
},
normalizer: 'custom_sort_normalizer'
},
prizeSets: {
properties: {
type: { type: 'text' },
Expand Down
14 changes: 14 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ module.exports = {
auth: 'jwt',
access: [constants.UserRoles.Admin, constants.UserRoles.Copilot, constants.UserRoles.Manager],
scopes: [UPDATE, ALL]
},
delete: {
controller: 'ChallengeTypeController',
method: 'deleteChallengeType',
auth: 'jwt',
access: [constants.UserRoles.Admin, constants.UserRoles.Copilot, constants.UserRoles.Manager],
scopes: [DELETE, ALL]
}
},
'/challenge-tracks': {
Expand Down Expand Up @@ -146,6 +153,13 @@ module.exports = {
auth: 'jwt',
access: [constants.UserRoles.Admin, constants.UserRoles.Copilot, constants.UserRoles.Manager],
scopes: [UPDATE, ALL]
},
delete: {
controller: 'ChallengeTrackController',
method: 'deleteChallengeTrack',
auth: 'jwt',
access: [constants.UserRoles.Admin, constants.UserRoles.Copilot, constants.UserRoles.Manager],
scopes: [DELETE, ALL]
}
},
'/challenge-timelines': {
Expand Down
2 changes: 1 addition & 1 deletion src/services/ChallengeService.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ async function searchChallenges (currentUser, criteria) {
if (criteria.types) {
for (const t of criteria.types) {
const typeSearchRes = await ChallengeTypeService.searchChallengeTypes({ abbreviation: t })
if (typeSearchRes.total > 0) {
if (typeSearchRes.total > 0 || criteria.types.length === 1) {
includedTypeIds.push(_.get(typeSearchRes, 'result[0].id'))
}
}
Expand Down
20 changes: 19 additions & 1 deletion src/services/ChallengeTrackService.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,30 @@ partiallyUpdateChallengeTrack.schema = {
}).required()
}

/**
* Delete challenge track.
* @param {String} id the challenge track id
* @return {Object} the deleted challenge track
*/
async function deleteChallengeTrack (id) {
const record = await helper.getById('ChallengeTrack', id)
await record.delete()
// post bus event
await helper.postBusEvent(constants.Topics.ChallengeTrackDeleted, record)
return record
}

deleteChallengeTrack.schema = {
id: Joi.id()
}

module.exports = {
searchChallengeTracks,
createChallengeTrack,
getChallengeTrack,
fullyUpdateChallengeTrack,
partiallyUpdateChallengeTrack
partiallyUpdateChallengeTrack,
deleteChallengeTrack
}

// logger.buildService(module.exports)
20 changes: 19 additions & 1 deletion src/services/ChallengeTypeService.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,30 @@ partiallyUpdateChallengeType.schema = {
}).required()
}

/**
* Delete challenge type.
* @param {String} id the challenge type id
* @returns {Object} the deleted challenge type
*/
async function deleteChallengeType (id) {
const ret = await helper.getById('ChallengeType', id)
await ret.delete()
// post bus event
await helper.postBusEvent(constants.Topics.ChallengeTypeDeleted, ret)
return ret
}

deleteChallengeType.schema = {
id: Joi.id()
}

module.exports = {
searchChallengeTypes,
createChallengeType,
getChallengeType,
fullyUpdateChallengeType,
partiallyUpdateChallengeType
partiallyUpdateChallengeType,
deleteChallengeType
}

// logger.buildService(module.exports)
42 changes: 42 additions & 0 deletions test/e2e/challenge.type.api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -665,4 +665,46 @@ describe('challenge type API E2E tests', () => {
should.equal(response.body.message, '"legacyId" must be a number')
})
})

describe('remove challenge type API tests', () => {
it('remove challenge type - forbidden', async () => {
const response = await chai.request(app)
.delete(`${basePath}/${id}`)
.set('Authorization', `Bearer ${config.USER_TOKEN}`)
should.equal(response.status, 403)
should.equal(response.body.message, 'You are not allowed to perform this action!')
})

it('remove challenge type successfully', async () => {
const response = await chai.request(app)
.delete(`${basePath}/${id}`)
.set('Authorization', `Bearer ${config.ADMIN_TOKEN}`)
should.equal(response.status, 200)
should.equal(response.body.id, id)
})

it('remove challenge type - not found 1', async () => {
const response = await chai.request(app)
.delete(`${basePath}/${id}`)
.set('Authorization', `Bearer ${config.ADMIN_TOKEN}`)
should.equal(response.status, 404)
should.equal(response.body.message, `ChallengeType with id: ${id} doesn't exist`)
})

it('remove challenge type - not found 2', async () => {
const response = await chai.request(app)
.delete(`${basePath}/${notFoundId}`)
.set('Authorization', `Bearer ${config.ADMIN_TOKEN}`)
should.equal(response.status, 404)
should.equal(response.body.message, `ChallengeType with id: ${notFoundId} doesn't exist`)
})

it('remove challenge type - invalid id', async () => {
const response = await chai.request(app)
.delete(`${basePath}/invalid`)
.set('Authorization', `Bearer ${config.ADMIN_TOKEN}`)
should.equal(response.status, 400)
should.equal(response.body.message, '"challengeTypeId" must be a valid GUID')
})
})
})
Loading