-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(app.ts): create /conversion endpoint for converting a roster file
- Loading branch information
Fredrik Makila
committed
Sep 13, 2020
1 parent
564d8f9
commit 565730c
Showing
2 changed files
with
114 additions
and
0 deletions.
There are no files selected for viewing
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,73 @@ | ||
import app from '../app'; | ||
import request from 'supertest'; | ||
import rosz2js, { Roster } from 'rosz2js'; | ||
import schema from '../schema'; | ||
import { ValidationError, ValidationErrorItem, ValidationResult } from 'joi'; | ||
|
||
jest.mock('rosz2js'); | ||
const mockedRosz2js = rosz2js as jest.Mocked<typeof rosz2js>; | ||
|
||
jest.mock('../schema', () => ({ | ||
validate: jest.fn(() => ({ error: null })) | ||
})); | ||
const mockedSchema = schema as jest.Mocked<typeof schema>; | ||
|
||
describe('POST /conversion - converts roster file to Javascript object', () => { | ||
it('returns a 422 if no form data is included', async () => { | ||
const result = await request(app).post('/conversion'); | ||
expect(result.status).toBe(422); | ||
}); | ||
|
||
it('returns 422 if no file is included in form data', async () => { | ||
const buffer = (null as unknown) as Buffer; | ||
const result = await request(app).post('/conversion').attach('files', buffer); | ||
|
||
expect(result.status).toBe(422); | ||
}); | ||
|
||
it('returns 422 if the files does not have expected format', async () => { | ||
const validationErrorMessage = { | ||
message: 'Validation error' | ||
} as Partial<ValidationErrorItem>; | ||
|
||
const validationError = { | ||
details: [validationErrorMessage as ValidationErrorItem] | ||
} as Partial<ValidationError>; | ||
|
||
const validationResult = { | ||
error: validationError as ValidationError | ||
} as Partial<ValidationResult>; | ||
|
||
mockedSchema.validate.mockImplementationOnce(() => validationResult as ValidationResult); | ||
|
||
const buffer = Buffer.from('hello'); | ||
const result = await request(app).post('/conversion').attach('files', buffer, 'some_name.rosz'); | ||
|
||
expect(result.status).toBe(422); | ||
expect(JSON.parse(result.text)).toEqual({ | ||
validationErrors: [ | ||
{ | ||
message: 'Validation error' | ||
} | ||
] | ||
}); | ||
}); | ||
|
||
it('returns 200 if the roster is converted successfully', async () => { | ||
const roster: Partial<Roster> = {}; | ||
|
||
mockedRosz2js.parse.mockImplementation(() => Promise.resolve(roster as Roster)); | ||
const buffer = Buffer.from('hello'); | ||
const result = await request(app).post('/conversion').attach('files', buffer, 'some_name.rosz'); | ||
|
||
expect(result.status).toBe(200); | ||
}); | ||
|
||
it('returns 500 if the roster is not converted successfully', async () => { | ||
mockedRosz2js.parse.mockImplementation(() => Promise.reject(new Error('Something went wrong'))); | ||
const buffer = Buffer.from('hello'); | ||
const result = await request(app).post('/conversion').attach('files', buffer, 'some_name.rosz'); | ||
|
||
expect(result.status).toBe(500); | ||
}); | ||
}); |
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,41 @@ | ||
import express from 'express'; | ||
import multer from 'multer'; | ||
import parser from 'rosz2js'; | ||
import schema from './schema'; | ||
import { info } from './logger'; | ||
|
||
const app = express(); | ||
app.set('port', process.env.PORT || 8000); | ||
|
||
const upload = multer(); | ||
|
||
app.post('/conversion', upload.any(), async (req, res) => { | ||
info('Receiving request'); | ||
|
||
if (!req.files || !req.files.length) { | ||
return res.status(422).send({ | ||
message: 'File is missing in request' | ||
}); | ||
} | ||
|
||
const { error: validationError } = schema.validate(req); | ||
if (validationError) { | ||
return res.status(422).send({ | ||
validationErrors: validationError.details | ||
}); | ||
} | ||
|
||
const rosterFile = (req.files as Express.Multer.File[])[0]; | ||
|
||
try { | ||
const data = await parser.parse(rosterFile.buffer); | ||
return res.status(200).send({ data }); | ||
} catch (error) { | ||
res.status(500).send({ | ||
message: 'Failed to process uploaded roster', | ||
error | ||
}); | ||
} | ||
}); | ||
|
||
export default app; |