-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BUGFIX] Permettre de nouveau l'affichage du message d'erreur en cas …
- Loading branch information
Showing
18 changed files
with
225 additions
and
158 deletions.
There are no files selected for viewing
119 changes: 0 additions & 119 deletions
119
api/lib/application/certification-centers/csvHelpers.js
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
api/src/certification/session/application/session-mass-import-controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
56 changes: 56 additions & 0 deletions
56
api/src/certification/shared/application/helpers/csvHelpers.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import fs from 'fs'; | ||
|
||
const { promises } = fs; | ||
const { readFile, access } = promises; | ||
|
||
import papa from 'papaparse'; | ||
|
||
import { NotFoundError } from '../../../../shared/domain/errors.js'; | ||
import { CsvWithNoSessionDataError } from '../../../session/domain/errors.js'; | ||
|
||
const optionsWithHeader = { | ||
skipEmptyLines: true, | ||
header: true, | ||
transform: (value, columnName) => { | ||
if (typeof value === 'string') { | ||
value = value.trim(); | ||
} | ||
if (columnName === '* Sexe (M ou F)') { | ||
value = value.toUpperCase(); | ||
} | ||
return value; | ||
}, | ||
}; | ||
|
||
async function readCsvFile(filePath) { | ||
try { | ||
await access(filePath, fs.constants.F_OK); | ||
} catch (err) { | ||
throw new NotFoundError(`File ${filePath} not found!`); | ||
} | ||
|
||
const rawData = await readFile(filePath, 'utf8'); | ||
|
||
return rawData.replace(/^\uFEFF/, ''); | ||
} | ||
|
||
async function parseCsv(filePath, options) { | ||
const cleanedData = await readCsvFile(filePath); | ||
return parseCsvData(cleanedData, options); | ||
} | ||
|
||
function parseCsvData(cleanedData, options) { | ||
const { data } = papa.parse(cleanedData, options); | ||
return data; | ||
} | ||
|
||
async function parseCsvWithHeader(filePath, options = optionsWithHeader) { | ||
const parsedCsvData = await parseCsv(filePath, options); | ||
if (parsedCsvData.length === 0) { | ||
throw new CsvWithNoSessionDataError(); | ||
} | ||
|
||
return parsedCsvData; | ||
} | ||
|
||
export { parseCsvWithHeader, parseCsv, readCsvFile }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
118 changes: 118 additions & 0 deletions
118
api/tests/certification/shared/integration/application/helpers/csvHelpers_test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { expect, catchErr } from '../../../../../test-helper.js'; | ||
import { NotFoundError } from '../../../../../../src/shared/domain/errors.js'; | ||
|
||
import { CsvWithNoSessionDataError } from '../../../../../../src/certification/session/domain/errors.js'; | ||
|
||
import { | ||
parseCsv, | ||
readCsvFile, | ||
parseCsvWithHeader, | ||
} from '../../../../../../src/certification/shared/application/helpers/csvHelpers.js'; | ||
|
||
import * as url from 'url'; | ||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); | ||
|
||
describe('Certification | Shared | Integration | Application | Helpers | csvHelpers.js', function () { | ||
const notExistFilePath = 'notExist.csv'; | ||
const emptyFilePath = `${__dirname}/files/empty-file-test.csv`; | ||
const validFilePath = `${__dirname}/files/valid-file-test.csv`; | ||
const utf8FilePath = `${__dirname}/files/utf8_excel-test.csv`; | ||
const withHeaderFilePath = `${__dirname}/files/file-with-header-test.csv`; | ||
const sessionsForMassImportFilePath = `${__dirname}/files/file-with-sex-value-in-lowercase-test.csv`; | ||
|
||
describe('#readCsvFile', function () { | ||
it('should throw a NotFoundError when file does not exist', async function () { | ||
// when | ||
const error = await catchErr(readCsvFile)(notExistFilePath); | ||
|
||
// then | ||
expect(error).to.be.instanceOf(NotFoundError); | ||
expect(error.message).to.equal(`File ${notExistFilePath} not found!`); | ||
}); | ||
}); | ||
|
||
describe('#parseCsv', function () { | ||
it('should throw a NotFoundError when file does not exist', async function () { | ||
// when | ||
const error = await catchErr(parseCsv)(notExistFilePath); | ||
|
||
// then | ||
expect(error).to.be.instanceOf(NotFoundError); | ||
expect(error.message).to.equal(`File ${notExistFilePath} not found!`); | ||
}); | ||
|
||
it('should parse csv file with 2 lines', async function () { | ||
// given | ||
const options = { skipEmptyLines: true }; | ||
|
||
// when | ||
const data = await parseCsv(validFilePath, options); | ||
|
||
// then | ||
expect(data.length).to.equal(2); | ||
expect(data[0][2]).to.equal('Salle Beagle'); | ||
}); | ||
|
||
it('should cast the unexpected utf8 char add by Excel', async function () { | ||
// when | ||
const data = await parseCsv(utf8FilePath); | ||
|
||
// then | ||
expect(data.length).to.equal(4); | ||
}); | ||
}); | ||
|
||
describe('#parseCsvWithHeader', function () { | ||
it('should parse csv file with header', async function () { | ||
// given | ||
const expectedItems = [ | ||
{ | ||
'Numéro de session préexistante': '', | ||
'* Nom de la salle': 'Salle Beagle', | ||
'* Nom de naissance': 'leBeagle', | ||
'* Nom du site': 'Centre des chiens', | ||
'* Prénom': 'Jude', | ||
'* Surveillant(s)': 'Doggo', | ||
}, | ||
{ | ||
'Numéro de session préexistante': '1', | ||
'* Nom de la salle': 'Salle Abyssin', | ||
'* Nom de naissance': 'Abyssin', | ||
'* Nom du site': 'Centre des chats', | ||
'* Prénom': 'Lou', | ||
'* Surveillant(s)': 'Catty', | ||
}, | ||
]; | ||
|
||
// when | ||
const items = await parseCsvWithHeader(withHeaderFilePath); | ||
|
||
// then | ||
expect(items.length).to.equal(2); | ||
expect(items).to.have.deep.members(expectedItems); | ||
}); | ||
|
||
context('with custom transform', function () { | ||
it('should convert sex to uppercase', async function () { | ||
// given & when | ||
const result = await parseCsvWithHeader(sessionsForMassImportFilePath); | ||
|
||
// then | ||
const data = result[0]; | ||
expect(data['* Sexe (M ou F)']).to.equal('F'); | ||
}); | ||
}); | ||
|
||
context('when csv file is empty or contains only the header line', function () { | ||
it(' should return an unprocessable entity error', async function () { | ||
// given & when | ||
const error = await catchErr(parseCsvWithHeader)(emptyFilePath); | ||
|
||
// then | ||
expect(error).to.be.instanceOf(CsvWithNoSessionDataError); | ||
expect(error.message).to.equal('No session data in csv'); | ||
expect(error.code).to.equal('CSV_DATA_REQUIRED'); | ||
}); | ||
}); | ||
}); | ||
}); |
1 change: 1 addition & 0 deletions
1
api/tests/certification/shared/integration/application/helpers/files/empty-file-test.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
3 changes: 3 additions & 0 deletions
3
...ests/certification/shared/integration/application/helpers/files/file-with-header-test.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
"Numéro de session préexistante";"* Nom du site";"* Nom de la salle";"* Surveillant(s)";"* Nom de naissance";"* Prénom" | ||
;Centre des chiens;Salle Beagle;Doggo;leBeagle;Jude | ||
1;Centre des chats;Salle Abyssin;Catty;Abyssin;Lou |
File renamed without changes.
Oops, something went wrong.