Skip to content

Commit

Permalink
handle text/plain content type in get.js, added additional tests for …
Browse files Browse the repository at this point in the history
…post
  • Loading branch information
Bregwin Jogi committed Jun 8, 2024
1 parent 8e52709 commit 8623189
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/model/fragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class Fragment {
* @returns {Array<string>} list of supported mime types
*/
get formats() {
return ['text/plain'];
return ['text/plain'];
}

/**
Expand Down
45 changes: 25 additions & 20 deletions src/routes/api/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,46 @@ const logger = require('../../logger');
module.exports = (req, res, next) => {
const expand = req.query.expand;
const ownerId = req.user;
const id = req.params.id;

const idExtension = req.params.id;

if (id) {
if (idExtension) {
logger.info(`GET /fragments/${idExtension} for user ${ownerId}`);

logger.info(`GET /fragments/${id} for user ${ownerId}`)
let id = '';
let extension = '';
if (idExtension.includes('.')) {
extension = idExtension.split('.')[1];
id = idExtension.split('.')[0];
} else {
id = idExtension;
}

let extension = '';
if (id.includes('.')) {
extension = id.split('.').pop();
}
logger.info(`Extension: ${extension}`);
logger.info(`ID: ${id}`);

Fragment.byId(ownerId, id, expand)
.then(
(fragment) => {
.then((fragment) => {
fragment.getData().then((data) => {

if (extension === 'txt') {
if (extension) {
// Check if the fragment is text/plain
if (fragment.contentType === 'text/plain') {
res.status(200)
logger.info(`Fragment content type: ${fragment.mimeType}`);
if (fragment.mimeType === 'text/plain' && extension === 'txt') {
res
.status(200)
.header('Content-Type', 'text/plain')
.header('Content-Disposition', 'attachment; filename="fragment.txt"')
.send(data.toString());
} else {
res.status(415).json(createErrorResponse(415, 'Not allowed to convert to specified format'));
res
.status(415)
.json(createErrorResponse(415, 'Not allowed to convert to specified format'));
}
} else {
// Return the data with original content type it had
res.status(200).send(data);
res.status(200).send(data.toString());
}


})})
});
})
.catch((err) => {
logger.error(err);
next(err);
Expand All @@ -63,5 +69,4 @@ module.exports = (req, res, next) => {
res.status(500).json(createErrorResponse(500, 'ERROR: ' + err));
});
}

};
14 changes: 9 additions & 5 deletions src/routes/api/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ const { Fragment } = require('../../model/fragment');
const logger = require('../../logger');

module.exports = (req, res) => {

if (Fragment.isSupportedType(req.get('Content-Type')) === false) {
const type = req.get('Content-Type');
logger.error(`unsupported media type: ${type}`);
res.status(415).json(createErrorResponse(415, 'unsupported media type'));
return;
}

if (!Buffer.isBuffer(req.body)) {
logger.error('no buffer found in request body');
res.status(400).json(createErrorResponse(400, 'no buffer found in request body'));
return;
}

if (Fragment.isSupportedType(req.get('Content-Type')) === false) {
logger.error(`unsupported media type: ${fragment.type}`);
res.status(400).json(createErrorResponse(415, 'unsupported media type'));
return;
}


const fragment = new Fragment({ ownerId: req.user, type: req.get('Content-Type') });

Expand Down
43 changes: 43 additions & 0 deletions tests/unit/get.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,48 @@ describe('GET /v1/fragments', () => {
expect(Array.isArray(res.body.fragments)).toBe(true);
});

// Test for getting a fragment by id
test('authenticated users can get a fragment by id', async () => {

const postRequest = await request(app)
.post('/v1/fragments')
.auth('user1@email.com', 'password1')
.set('Content-Type', 'text/plain')
.send(Buffer.from('hello world'));

const res = await request(app).get(`/v1/fragments/${postRequest.body.fragment.id}`).auth('user1@email.com', 'password1');

expect(res.statusCode).toBe(200);
expect(res.text).toBe('hello world');
});

test('authenticated users can get a fragment by id with .txt extension', async () => {
const postRequest = await request(app)
.post('/v1/fragments')
.auth('user1@email.com', 'password1')
.set('Content-Type', 'text/plain')
.send(Buffer.from('test 123'));

const res = await request(app).get(`/v1/fragments/${postRequest.body.fragment.id}.txt`).auth('user1@email.com', 'password1');

expect(res.statusCode).toBe(200);
expect(res.headers['content-type']).toBe('text/plain; charset=utf-8');
expect(res.headers['content-disposition']).toBe('attachment; filename="fragment.txt"');
expect(res.text).toBe('test 123');
});

test('error when fragment cannot be converted to .txt', async () => {
const postRequest = await request(app)
.post('/v1/fragments')
.auth('user1@email.com', 'password1')
.set('Content-Type', 'text/plain')
.send(Buffer.from('hihihi'));

const res = await request(app).get(`/v1/fragments/${postRequest.body.fragment.id}.html`).auth('user1@email.com', 'password1');
expect(res.statusCode).toBe(415);
expect(res.body.status).toBe('error');
expect(res.body.error.message).toBe('Not allowed to convert to specified format');
});


});
28 changes: 27 additions & 1 deletion tests/unit/post.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const request = require('supertest');

const app = require('../../src/app');

describe('GET /v1/fragments', () => {
describe('POST /v1/fragments', () => {
// If the request is missing the Authorization header, it should be forbidden
test('unauthenticated requests are denied', () => request(app).post('/v1/fragments').expect(401));

Expand Down Expand Up @@ -40,5 +40,31 @@ describe('GET /v1/fragments', () => {
expect(res.body.status).toBe('error');
});

// If the Content-Type is not supported, it should return a 415 error
test('unsupported media type', async () => {
const res = await request(app)
.post('/v1/fragments')
.auth('user1@email.com', 'password1')
.set('Content-Type', 'application/unsupported')
.send(Buffer.from('hello world'));

expect(res.statusCode).toBe(415);
expect(res.body.status).toBe('error');
expect(res.body.error.message).toBe('unsupported media type');
});

// Location header is being set correctly
test('successful fragment creation sets Location header', async () => {
const res = await request(app)
.post('/v1/fragments')
.auth('user1@email.com', 'password1')
.set('Content-Type', 'text/plain')
.send(Buffer.from('hello world'));

expect(res.statusCode).toBe(201);
expect(res.body.status).toBe('ok');
expect(res.header.location).toBeTruthy();
});


});

0 comments on commit 8623189

Please sign in to comment.