Skip to content
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

add test coverage #26

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
17 changes: 12 additions & 5 deletions app/config/database.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
const { DefaultAzureCredential } = require('@azure/identity')
const { PRODUCTION } = require('../constants/environments')
const portNumber = 5432
const timeout = 60000
const backoffBase = 500
const maxRetries = 10

function isProd () {
return process.env.NODE_ENV === PRODUCTION
Expand All @@ -9,19 +13,22 @@ const hooks = {
beforeConnect: async (cfg) => {
if (isProd()) {
const credential = new DefaultAzureCredential()
const accessToken = await credential.getToken('https://ossrdbms-aad.database.windows.net', { requestOptions: { timeout: 1000 } })
const accessToken = await credential.getToken(
'https://ossrdbms-aad.database.windows.net',
{ requestOptions: { timeout: 1000 } }
)
cfg.password = accessToken.token
}
}
}

const retry = {
backoffBase: 500,
backoffBase,
backoffExponent: 1.1,
match: [/SequelizeConnectionError/],
max: 10,
max: maxRetries,
name: 'connection',
timeout: 60000
timeout
}

const config = {
Expand All @@ -33,7 +40,7 @@ const config = {
hooks,
host: process.env.POSTGRES_HOST || 'ffc-pay-dps-postgres',
password: process.env.POSTGRES_PASSWORD,
port: process.env.POSTGRES_PORT || 5432,
port: process.env.POSTGRES_PORT || portNumber,
logging: process.env.POSTGRES_LOGGING || false,
retry,
schema: process.env.POSTGRES_SCHEMA_NAME || 'public',
Expand Down
6 changes: 4 additions & 2 deletions app/config/processing.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const Joi = require('joi')
const pollingInterval = 10000
const maxProcessingTries = 3

// Define config schema
const schema = Joi.object({
pollingInterval: Joi.number().default(10000), // 10 seconds
maxProcessingTries: Joi.number().default(3),
pollingInterval: Joi.number().default(pollingInterval), // 10 seconds
maxProcessingTries: Joi.number().default(maxProcessingTries),
useEvents: Joi.boolean().default(true),
pollingActive: Joi.boolean().default(true)
})
Expand Down
13 changes: 11 additions & 2 deletions app/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@ const { databaseConfig } = require('../config')
const modelPath = path.join(__dirname, 'models')
const db = {}

const sequelize = new Sequelize(databaseConfig.database, databaseConfig.username, databaseConfig.password, databaseConfig)
const sequelize = new Sequelize(
databaseConfig.database,
databaseConfig.username,
databaseConfig.password,
databaseConfig
)

fs.readdirSync(modelPath)
.filter(file => {
return (file.indexOf('.') !== 0) && (file !== 'index.js') && (file.slice(-3) === '.js')
return (
!file.startsWith('.') &&
!file.startsWith('index.js') &&
file.endsWith('.js')
)
})
.forEach(file => {
const model = require(path.join(modelPath, file))(sequelize, DataTypes)
Expand Down
26 changes: 18 additions & 8 deletions app/processing/dax/transform-line.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
const { v4: uuidv4 } = require('uuid')
const { DAX } = require('../../constants/file-types')
const BATCH_LINES = {
PRIMARY_TRADER: 0,
USED_BY_TRADER: 1,
REFERENCE: 2,
LOADED: 3,
DAX_REFERENCE: 4,
REASON: 5,
POSTED: 6
}

const transformLine = (batchLine, filename) => {
return {
correlationId: uuidv4(),
batch: filename,
fileTypeId: DAX.fileTypeId,
primaryTrader: batchLine[0],
usedByTrader: batchLine[1],
reference: batchLine[2],
loaded: batchLine[3],
daxReference: batchLine[4],
reason: batchLine[5],
posted: batchLine[6]
primaryTrader: batchLine[BATCH_LINES.PRIMARY_TRADER],
usedByTrader: batchLine[BATCH_LINES.USED_BY_TRADER],
reference: batchLine[BATCH_LINES.REFERENCE],
loaded: batchLine[BATCH_LINES.LOADED],
daxReference: batchLine[BATCH_LINES.DAX_REFERENCE],
reason: batchLine[BATCH_LINES.REASON],
posted: batchLine[BATCH_LINES.POSTED]
}
}

module.exports = {
transformLine
transformLine,
BATCH_LINES
}
44 changes: 30 additions & 14 deletions app/processing/dps/transform-line.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
const { v4: uuidv4 } = require('uuid')
const { DPS } = require('../../constants/file-types')
const BATCH_LINES = {
PRIMARY_TRADER: 0,
USED_BY_TRADER: 1,
REFERENCE: 2,
FULL_REFERENCE: 3,
GUARANTEE_NUMBER: 4,
SCHEME: 5,
DEBIT: 6,
CREDIT: 7,
CURRENCY: 8,
TRANSACTION_CATEGORY: 9,
MAKE_FORWARD_DATE: 10,
MEASUREMENT_START_DATE: 11,
DESCRIPTION: 12
}

const transformLine = (batchLine, filename) => {
return {
correlationId: uuidv4(),
batch: filename,
fileTypeId: DPS.fileTypeId,
primaryTrader: batchLine[0],
usedByTrader: batchLine[1],
reference: batchLine[2],
fullReference: batchLine[3],
guaranteeNumber: batchLine[4],
scheme: batchLine[5],
debit: batchLine[6],
credit: batchLine[7],
currency: batchLine[8],
transactionCategory: batchLine[9],
makeForwardDate: batchLine[10],
measurementStartDate: batchLine[11],
description: batchLine[12]
primaryTrader: batchLine[BATCH_LINES.PRIMARY_TRADER],
usedByTrader: batchLine[BATCH_LINES.USED_BY_TRADER],
reference: batchLine[BATCH_LINES.REFERENCE],
fullReference: batchLine[BATCH_LINES.FULL_REFERENCE],
guaranteeNumber: batchLine[BATCH_LINES.GUARANTEE_NUMBER],
scheme: batchLine[BATCH_LINES.SCHEME],
debit: batchLine[BATCH_LINES.DEBIT],
credit: batchLine[BATCH_LINES.CREDIT],
currency: batchLine[BATCH_LINES.CURRENCY],
transactionCategory: batchLine[BATCH_LINES.TRANSACTION_CATEGORY],
makeForwardDate: batchLine[BATCH_LINES.MAKE_FORWARD_DATE],
measurementStartDate: batchLine[BATCH_LINES.MEASUREMENT_START_DATE],
description: batchLine[BATCH_LINES.DESCRIPTION]
}
}

module.exports = {
transformLine
transformLine,
BATCH_LINES
}
7 changes: 5 additions & 2 deletions app/processing/get-new-filename.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
const { DAX } = require('../constants/file-types')
const removeFileType = 3
const startIndex = 0
const removeExtension = -4

const getNewFileName = (filename, fileType) => {
if (fileType === DAX) {
return filename.substring(3)
return filename.substring(removeFileType)
}
return `FFC${filename.slice(0, -4)}.csv`
return `FFC${filename.slice(startIndex, removeExtension)}.csv`
}

module.exports = {
Expand Down
26 changes: 20 additions & 6 deletions app/processing/get-security-requests-from-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,28 @@ const { DPS, DAX } = require('../constants/file-types')
const { readDPSFile } = require('./dps/read-dps-file')
const { readDAXFile } = require('./dax/read-dax-file')

const getSecurityRequestsFromFile = (fileBuffer, fileType, filename) => {
const getSecurityRequestsFromFile = async (fileBuffer, fileType, filename) => {
const input = Readable.from(fileBuffer)
const readBatchLines = readline.createInterface(input)
switch (fileType) {
case DPS:
return readDPSFile(readBatchLines, input, filename)
case DAX:
return readDAXFile(readBatchLines, input, filename)

try {
let result
switch (fileType) {
case DPS:
result = await readDPSFile(readBatchLines, input, filename)
break
case DAX:
result = await readDAXFile(readBatchLines, input, filename)
break
default:
result = {
error: `Unsupported file type: ${fileType?.fileType ?? 'undefined'}`
}
}
return result
} finally {
readBatchLines.close()
input.destroy()
}
}

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ffc-pay-dps",
"version": "1.1.9",
"version": "1.1.10",
"description": "DPS processing",
"homepage": "https://github.com/DEFRA/ffc-pay-dps",
"main": "app/index.js",
Expand Down
30 changes: 30 additions & 0 deletions test/unit/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ const mockPolling = {
}
jest.mock('../../app/polling', () => mockPolling)

const mockEnv = {
POLLING_INTERVAL: 'invalid',
MAX_PROCESSING_TRIES: 'invalid',
USE_EVENTS: 'invalid'
}

const mockMessageService = {
start: jest.fn(),
stop: jest.fn()
Expand Down Expand Up @@ -49,3 +55,27 @@ describe('index.js', () => {
expect(process.exit).toHaveBeenCalledWith(0)
})
})
describe('processing config', () => {
beforeEach(() => {
jest.resetModules()
process.env = { ...mockEnv }
})

test('throws error when config is invalid', () => {
expect(() => {
require('../../app/config/processing')
}).toThrow(/The processing config is invalid./)
})

test('includes details of validation error in message', () => {
expect(() => {
require('../../app/config/processing')
}).toThrow(
/The processing config is invalid. "pollingInterval" must be a number/
)
})

afterEach(() => {
jest.clearAllMocks()
})
})
Loading