Skip to content

Commit 04fe63d

Browse files
authored
Merge pull request #211 from imcaizheng/feature/allow-toggle-actual-payments
Add ability to switch on/off actual payments via config
2 parents ab78d6f + 700b68e commit 04fe63d

File tree

10 files changed

+119
-16
lines changed

10 files changed

+119
-16
lines changed

app-constants.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,15 @@ const ChallengeStatus = {
5353
COMPLETED: 'Completed'
5454
}
5555

56+
const PaymentProcessingSwitch = {
57+
ON: 'ON',
58+
OFF: 'OFF'
59+
}
60+
5661
module.exports = {
5762
UserRoles,
5863
FullManagePermissionRoles,
5964
Scopes,
60-
ChallengeStatus
65+
ChallengeStatus,
66+
PaymentProcessingSwitch
6167
}

config/default.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,6 @@ module.exports = {
148148
DEFAULT_TRACK_ID: process.env.DEFAULT_TRACK_ID || '9b6fc876-f4d9-4ccb-9dfd-419247628825',
149149

150150
// default time zone for Work Periods
151-
WORK_PERIOD_TIME_ZONE: process.env.WORK_PERIOD_TIME_ZONE || 'America/New_York'
151+
WORK_PERIOD_TIME_ZONE: process.env.WORK_PERIOD_TIME_ZONE || 'America/New_York',
152+
PAYMENT_PROCESSING_SWITCH: process.env.PAYMENT_PROCESSING_SWITCH || 'OFF'
152153
}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@
2020
"data:import": "node scripts/data/importData.js",
2121
"migrate": "npx sequelize db:migrate",
2222
"migrate:undo": "npx sequelize db:migrate:undo",
23-
"test": "mocha test/unit/*.test.js --timeout 30000 --exit",
23+
"test": "mocha test/unit/*.test.js --timeout 30000 --require test/prepare.js --exit",
2424
"services:up": "docker-compose -f ./local/docker-compose.yml up -d",
2525
"services:down": "docker-compose -f ./local/docker-compose.yml down",
2626
"services:logs": "docker-compose -f ./local/docker-compose.yml logs",
2727
"local:init": "npm run local:reset && npm run data:import -- --force",
2828
"local:reset": "npm run delete-index -- --force || true && npm run create-index -- --force && npm run init-db force",
29-
"cov": "nyc --reporter=html --reporter=text mocha test/unit/*.test.js --timeout 30000 --exit",
29+
"cov": "nyc --reporter=html --reporter=text npm run test",
3030
"demo-payment": "node scripts/demo-payment"
3131
},
3232
"keywords": [],
@@ -87,4 +87,4 @@
8787
"test/unit/**"
8888
]
8989
}
90-
}
90+
}

src/bootstrap.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ const fs = require('fs')
22
const Joi = require('joi')
33
const path = require('path')
44
const logger = require('./common/logger')
5+
const constants = require('../app-constants')
6+
const config = require('config')
57

68
Joi.page = () => Joi.number().integer().min(1).default(1)
79
Joi.perPage = () => Joi.number().integer().min(1).default(20)
@@ -36,3 +38,14 @@ function buildServices (dir) {
3638
}
3739

3840
buildServices(path.join(__dirname, 'services'))
41+
42+
// validate some configurable parameters for the app
43+
const paymentProcessingSwitchSchema = Joi.string().label('PAYMENT_PROCESSING_SWITCH').valid(
44+
...Object.values(constants.PaymentProcessingSwitch)
45+
)
46+
try {
47+
Joi.attempt(config.PAYMENT_PROCESSING_SWITCH, paymentProcessingSwitchSchema)
48+
} catch (err) {
49+
console.error(err.message)
50+
process.exit(1)
51+
}

src/controllers/WorkPeriodPaymentController.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44
const service = require('../services/WorkPeriodPaymentService')
55
const helper = require('../common/helper')
6+
const config = require('config')
67

78
/**
89
* Get workPeriodPayment by id
@@ -19,7 +20,7 @@ async function getWorkPeriodPayment (req, res) {
1920
* @param res the response
2021
*/
2122
async function createWorkPeriodPayment (req, res) {
22-
res.send(await service.createWorkPeriodPayment(req.authUser, req.body))
23+
res.send(await service.createWorkPeriodPayment(req.authUser, req.body, { paymentProcessingSwitch: config.PAYMENT_PROCESSING_SWITCH }))
2324
}
2425

2526
/**

src/services/WorkPeriodPaymentService.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ const moment = require('moment')
1212
const helper = require('../common/helper')
1313
const logger = require('../common/logger')
1414
const errors = require('../common/errors')
15+
const constants = require('../../app-constants')
1516
const models = require('../models')
16-
const { createPayment } = require('./PaymentService')
17+
const PaymentService = require('./PaymentService')
1718

1819
const WorkPeriodPayment = models.WorkPeriodPayment
1920
const esClient = helper.getESClient()
@@ -89,20 +90,21 @@ getWorkPeriodPayment.schema = Joi.object().keys({
8990
* Create workPeriodPayment
9091
* @param {Object} currentUser the user who perform this operation
9192
* @param {Object} workPeriodPayment the workPeriodPayment to be created
93+
* @param {Object} options the extra options to control the function
9294
* @returns {Object} the created workPeriodPayment
9395
*/
94-
async function createWorkPeriodPayment (currentUser, workPeriodPayment) {
96+
async function createWorkPeriodPayment (currentUser, workPeriodPayment, options = { paymentProcessingSwitch: 'OFF' }) {
9597
// check permission
9698
await _checkUserPermissionForCRUWorkPeriodPayment(currentUser)
9799

98100
const { projectId, userHandle, endDate } = await helper.ensureWorkPeriodById(workPeriodPayment.workPeriodId) // ensure work period exists
99-
const paymentChallenge = await createPayment({
101+
const paymentChallenge = options.paymentProcessingSwitch === constants.PaymentProcessingSwitch.ON ? (await PaymentService.createPayment({
100102
projectId,
101103
userHandle,
102104
amount: workPeriodPayment.amount,
103105
name: `TaaS Payment - ${userHandle} - Week Ending ${moment(endDate).format('D/M/YYYY')}`,
104106
description: `TaaS Payment - ${userHandle} - Week Ending ${moment(endDate).format('D/M/YYYY')}`
105-
})
107+
})) : ({ id: '00000000-0000-0000-0000-000000000000' })
106108
workPeriodPayment.id = uuid.v4()
107109
workPeriodPayment.challengeId = paymentChallenge.id
108110
workPeriodPayment.createdBy = await helper.getUserId(currentUser.userId)
@@ -128,7 +130,8 @@ createWorkPeriodPayment.schema = Joi.object().keys({
128130
workPeriodId: Joi.string().uuid().required(),
129131
amount: Joi.number().greater(0).allow(null),
130132
status: Joi.workPeriodPaymentStatus().default('completed')
131-
}).required()
133+
}).required(),
134+
options: Joi.object()
132135
}).required()
133136

134137
/**

test/prepare.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*
2+
* Prepare for tests.
3+
*/
4+
5+
process.env.NODE_ENV = 'test'
6+
require('../src/bootstrap')
7+
require('../src/eventHandlers').init()

test/unit/ResourceBookingService.test.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
/* eslint-disable no-unused-expressions */
2-
process.env.NODE_ENV = 'test'
3-
require('../../src/bootstrap')
42

53
// const _ = require('lodash')
64
const expect = require('chai').expect
@@ -10,12 +8,10 @@ const service = require('../../src/services/ResourceBookingService')
108
const workPeriodService = require('../../src/services/WorkPeriodService')
119
const testData = require('./common/testData')
1210
const helper = require('../../src/common/helper')
13-
const eventHandlers = require('../../src/eventHandlers')
1411
// const esClient = helper.getESClient()
1512
const busApiClient = helper.getBusApiClient()
1613
const ResourceBooking = models.ResourceBooking
1714
const WorkPeriod = models.WorkPeriod
18-
eventHandlers.init()
1915
describe('resourceBooking service test', () => {
2016
let stubEnsureJobById
2117
let stubEnsureUserById
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* eslint-disable no-unused-expressions */
2+
3+
// const _ = require('lodash')
4+
const expect = require('chai').expect
5+
const sinon = require('sinon')
6+
const models = require('../../src/models')
7+
const service = require('../../src/services/WorkPeriodPaymentService')
8+
const paymentService = require('../../src/services/PaymentService')
9+
const testData = require('./common/testData')
10+
const helper = require('../../src/common/helper')
11+
// const esClient = helper.getESClient()
12+
const busApiClient = helper.getBusApiClient()
13+
describe('workPeriod service test', () => {
14+
beforeEach(() => {
15+
sinon.stub(busApiClient, 'postEvent').callsFake(async () => {})
16+
})
17+
18+
afterEach(() => {
19+
sinon.restore()
20+
})
21+
22+
describe('create work period test', () => {
23+
describe('when PAYMENT_PROCESSING_SWITCH is ON/OFF', async () => {
24+
let stubCreatePaymentService
25+
26+
beforeEach(async () => {
27+
sinon.stub(helper, 'ensureWorkPeriodById').callsFake(async () => testData.workPeriodPayment01.ensureWorkPeriodByIdResponse)
28+
sinon.stub(helper, 'getUserId').callsFake(async () => {})
29+
sinon.stub(models.WorkPeriodPayment, 'create').callsFake(() => testData.workPeriodPayment01.response)
30+
stubCreatePaymentService = sinon.stub(paymentService, 'createPayment').callsFake(async () => testData.workPeriodPayment01.createPaymentResponse)
31+
})
32+
33+
it('do not create payment if PAYMENT_PROCESSING_SWITCH is OFF', async () => {
34+
await service.createWorkPeriodPayment(testData.currentUser, testData.workPeriodPayment01.request, { paymentProcessingSwitch: 'OFF' })
35+
expect(stubCreatePaymentService.calledOnce).to.be.false
36+
})
37+
it('create payment if PAYMENT_PROCESSING_SWITCH is ON', async () => {
38+
await service.createWorkPeriodPayment(testData.currentUser, testData.workPeriodPayment01.request, { paymentProcessingSwitch: 'ON' })
39+
expect(stubCreatePaymentService.calledOnce).to.be.true
40+
})
41+
})
42+
})
43+
})

test/unit/common/testData.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,10 +496,43 @@ resourceBookingUpdate.updateResponse4.toJSON = function () {
496496
resourceBookingUpdate.response4.update = function () {
497497
return resourceBookingUpdate.updateResponse4
498498
}
499+
500+
const workPeriodPayment01 = {
501+
request: {
502+
workPeriodId: '467b4df7-ced4-41b9-9710-b83808cddaf4',
503+
amount: 600,
504+
status: 'completed'
505+
},
506+
response: {
507+
workPeriodId: '467b4df7-ced4-41b9-9710-b83808cddaf4',
508+
amount: 600,
509+
status: 'completed',
510+
id: '01971e6f-0f09-4a2a-bc2e-2adac0f00622',
511+
challengeId: '00000000-0000-0000-0000-000000000000',
512+
createdBy: '57646ff9-1cd3-4d3c-88ba-eb09a395366c',
513+
updatedAt: '2021-04-21T12:58:07.535Z',
514+
createdAt: '2021-04-21T12:58:07.535Z',
515+
updatedBy: null
516+
},
517+
ensureWorkPeriodByIdResponse: {
518+
projectId: 111,
519+
userHandle: 'pshah_manager',
520+
endDate: '2021-03-13'
521+
},
522+
createPaymentResponse: {
523+
id: 'c65f0cbf-b197-423d-91cc-db6e3bad9075'
524+
}
525+
}
526+
527+
workPeriodPayment01.response.toJSON = function () {
528+
return workPeriodPayment01.response
529+
}
530+
499531
module.exports = {
500532
currentUser,
501533
UserTCConnCopilot,
502534
resourceBooking5Week,
503535
resourceBooking1Week,
504-
resourceBookingUpdate
536+
resourceBookingUpdate,
537+
workPeriodPayment01
505538
}

0 commit comments

Comments
 (0)