Skip to content

Add support for challenge terms #5

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 2 commits into from
Mar 3, 2020
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,4 @@ npm run cov-e2e
- TBD

## Verification
Refer to the verification document `Verification.md`
Refer to the verification document `Verification.md`
213 changes: 59 additions & 154 deletions Verification.md

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions src/services/ProcessorService.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ update.schema = {
fileName: Joi.string().required(),
challengeId: Joi.string().uuid().required()
})).allow(null),
terms: Joi.array().items(Joi.object().keys({
id: Joi.number().strict(true).integer().positive().required(),
agreeabilityType: Joi.string().required(),
title: Joi.string(),
url: Joi.string().allow(''),
templateId: Joi.string()
})).allow(null),
groups: Joi.array().items(Joi.string()).allow(null), // group names
created: Joi.date(),
createdBy: Joi.string(), // user handle
Expand Down
34 changes: 32 additions & 2 deletions test/common/testData.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,28 @@ const challengeUpdatedMessage = {
created: '2019-02-03T00:00:00',
createdBy: 'admin',
updated: '2019-02-04T01:01:00',
updatedBy: 'user'
updatedBy: 'user',
terms: [
{
id: 21343,
agreeabilityType: 'DocuSignable',
title: 'Competition Non-Disclosure Agreement',
url: '',
templateId: '0c5b7081-1fff-4484-a20f-824c97a03b9b'
},
{
id: 20723,
agreeabilityType: 'Non-electronically-agreeable',
title: 'Subcontractor Services Agreement 2009-09-02',
url: 'http://www.topcoder.com/i/terms/Subcontractor+Services+Agreement+2009-09-02.pdf'
},
{
id: 20645,
agreeabilityType: 'Electronically-agreeable',
title: '2008 TCO Marathon Match Competition Official Rules',
url: 'http://topcoder.com/mm-terms'
}
]
}
}

Expand All @@ -98,7 +119,16 @@ const challengePartiallyUpdatedMessage = {
}],
groups: ['group4'],
updated: '2019-01-02T00:00:00',
updatedBy: 'user'
updatedBy: 'user',
terms: [
{
id: 21343,
agreeabilityType: 'DocuSignable',
title: 'Competition Non-Disclosure Agreement',
url: '',
templateId: '0c5b7081-1fff-4484-a20f-824c97a03b9b'
}
]
}
}

Expand Down
14 changes: 13 additions & 1 deletion test/common/testHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ const expect = require('chai').expect

const client = helper.getESClient()

/**
* function to deeply compare arrays regardeless of the order
*
* @param {Array} arr1 The first array to compare
* @param {Array} arr2 The second array to compare
* @returns {Boolean} The flag indicating whether the arrays have the same content regardless of the order
*/
const deepCompareArrays = (arr1, arr2) => {
return _(arr1).xorWith(arr2, _.isEqual).isEmpty()
}

/**
* Get elastic search data.
* @param {String} id the Elastic search data id
Expand Down Expand Up @@ -54,5 +65,6 @@ function expectSamePhase (phase1, phase2) {
module.exports = {
getESData,
expectObj,
expectSamePhase
expectSamePhase,
deepCompareArrays
}
92 changes: 92 additions & 0 deletions test/e2e/processor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe('TC Challenge Processor E2E Tests', () => {
}
expect(data.endDate).to.exist // eslint-disable-line
expect(new Date(data.endDate).getTime() - new Date(challengeUpdatedMessage.payload.startDate).getTime()).to.equal(300000)
expect(testHelper.deepCompareArrays(challengeUpdatedMessage.payload.terms, data.terms), true)
})

it('partially update challenge message', async () => {
Expand All @@ -100,6 +101,97 @@ describe('TC Challenge Processor E2E Tests', () => {
}
expect(data.endDate).to.exist // eslint-disable-line
expect(new Date(data.endDate).getTime() - new Date(expectedData.startDate).getTime()).to.equal(300000)
expect(testHelper.deepCompareArrays(challengePartiallyUpdatedMessage.payload.terms, data.terms), true)
})

it('update challenge message - invalid parameters, terms with negative id message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].id = -20
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"id" must be a positive number'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with invalid aggreeability type message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].agreeabilityType = 800
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"agreeabilityType" must be a string'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with missing aggreeability type message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
delete message.payload.terms[0].agreeabilityType
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"agreeabilityType" is required'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with invalid title message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].title = 800
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"title" must be a string'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with invalid url message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].url = 800
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"url" must be a string'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with invalid templateId message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].templateId = 800
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"templateId" must be a string'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - not found', async () => {
Expand Down
92 changes: 92 additions & 0 deletions test/unit/processor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe('TC Challenge Processor Unit Tests', () => {
}
expect(data.endDate).to.exist // eslint-disable-line
expect(new Date(data.endDate).getTime() - new Date(challengeUpdatedMessage.payload.startDate).getTime()).to.equal(300000)
expect(testHelper.deepCompareArrays(challengeUpdatedMessage.payload.terms, data.terms), true)
})

it('partially update challenge message', async () => {
Expand All @@ -100,6 +101,97 @@ describe('TC Challenge Processor Unit Tests', () => {
}
expect(data.endDate).to.exist // eslint-disable-line
expect(new Date(data.endDate).getTime() - new Date(expectedData.startDate).getTime()).to.equal(300000)
expect(testHelper.deepCompareArrays(challengePartiallyUpdatedMessage.payload.terms, data.terms), true)
})

it('update challenge message - invalid parameters, terms with negative id message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].id = -20
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"id" must be a positive number'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with invalid aggreeability type message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].agreeabilityType = 800
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"agreeabilityType" must be a string'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with missing aggreeability type message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
delete message.payload.terms[0].agreeabilityType
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"agreeabilityType" is required'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with invalid title message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].title = 800
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"title" must be a string'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with invalid url message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].url = 800
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"url" must be a string'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - invalid parameters, terms with invalid templateId message', async () => {
const message = _.cloneDeep(challengeUpdatedMessage)
message.payload.terms[0].templateId = 800
try {
await ProcessorService.update(message)
} catch (err) {
expect(err).to.exist // eslint-disable-line
expect(err.name).to.equal('ValidationError')
const msg = '"templateId" must be a string'
expect(err.message.indexOf(msg) >= 0).to.equal(true)
return
}
throw new Error('There should be validation error.')
})

it('update challenge message - not found', async () => {
Expand Down