/
single-check-form-validator.js
92 lines (87 loc) · 3.24 KB
/
single-check-form-validator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
const csv = require('fast-csv')
const fs = require('fs-extra')
const path = require('path')
const checkFormErrorMessages = require('../../errors/check-form')
const config = require('../../../config')
const singleCheckFormValidator = {}
/**
* Single check form data validation
* @param {Object} uploadedFile
* @returns {Array<String>} list of errors
*/
singleCheckFormValidator.validate = async (uploadedFile) => {
let fileBuffer
const csvErrors = []
// No file provided
if (!uploadedFile || !uploadedFile.filename) {
csvErrors.push(checkFormErrorMessages.noFile)
return csvErrors
}
// Fetch file name without extension
const checkFormName = uploadedFile.filename.replace(/\.[^/.]+$/, '')
// File type not CSV
if (path.extname(uploadedFile.filename.toLowerCase()) !== '.csv') {
csvErrors.push(`${checkFormName} ${checkFormErrorMessages.wrongFormat}`)
}
// File name longer than max allowed characters
if (checkFormName.length > config.CHECK_FORM_NAME_MAX_CHARACTERS) {
csvErrors.push(`${checkFormName} ${checkFormErrorMessages.checkFormNameMaxLength}`)
}
// File not readable
try {
fileBuffer = fs.readFileSync(uploadedFile.file, 'utf8')
} catch (err) {
csvErrors.push(`${checkFormName} ${checkFormErrorMessages.isNotReadable}`)
return csvErrors
}
const fileContent = fileBuffer && fileBuffer.toString().trim()
const fileLines = fileContent && fileContent.split('\n').length
// Invalid total file lines
const linesPerCheckForm = config.LINES_PER_CHECK_FORM
if (fileLines !== linesPerCheckForm) {
csvErrors.push(`${checkFormName} ${checkFormErrorMessages.invalidNumberOfItems}`)
}
let hasInvalidNumberOfColumns = false
let hasInvalidIntegers = false
let hasInvalidFileCharacters = false
let checkFormIntegerCount = 0
await new Promise((resolve, reject) => {
csv.parseString(fileContent, { headers: false, trim: true })
.validate((row) => {
// Invalid column count
if (row.length !== 2) {
hasInvalidNumberOfColumns = true
}
// Invalid integers
if (row && row[0] && row[1] &&
(row[0] < config.CHECK_FORM_MIN_INTEGER || row[0] > config.CHECK_FORM_MAX_INTEGER ||
row[1] < config.CHECK_FORM_MIN_INTEGER || row[1] > config.CHECK_FORM_MAX_INTEGER)) {
hasInvalidIntegers = true
}
// Invalid characters
if ((!row[0] || row[0].match(/[^0-9]/)) || (!row[1] || row[1].match(/[^0-9]/))) {
hasInvalidFileCharacters = true
}
checkFormIntegerCount += row.length
})
.on('data', () => {})
.on('end', () => resolve()
)
.on('error', error => reject(error)
)
})
if (hasInvalidNumberOfColumns) {
csvErrors.push(`${checkFormName} ${checkFormErrorMessages.invalidNumberOfColumns}`)
}
if (hasInvalidIntegers) {
csvErrors.push(`${checkFormName} ${checkFormErrorMessages.invalidIntegers}`)
}
if (hasInvalidFileCharacters) {
csvErrors.push(`${checkFormErrorMessages.invalidFileCharacters} ${checkFormName}`)
}
if (checkFormIntegerCount !== (config.LINES_PER_CHECK_FORM * 2)) {
csvErrors.push(`${checkFormName} ${checkFormErrorMessages.invalidNumberOfTotalQuestionFactors}`)
}
return csvErrors
}
module.exports = singleCheckFormValidator