Skip to content

Commit

Permalink
Test routesUtils
Browse files Browse the repository at this point in the history
Issue: ARSN-441
  • Loading branch information
williamlardier committed Oct 23, 2024
1 parent 5df60de commit 2079ec6
Show file tree
Hide file tree
Showing 4 changed files with 397 additions and 3 deletions.
6 changes: 3 additions & 3 deletions lib/s3routes/routesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export type CallApiMethod = (
* @param log - Werelogs logger
* @return response - response object with additional headers
*/
function setCommonResponseHeaders(
export function setCommonResponseHeaders(
headers: { [key: string]: string } | undefined | null,
response: http.ServerResponse,
log: RequestLogger,
Expand Down Expand Up @@ -77,7 +77,7 @@ function okHeaderResponse(
});
}

const XMLResponseBackend = {
export const XMLResponseBackend = {

/**
* okXMLResponse - Response with XML body
Expand Down Expand Up @@ -177,7 +177,7 @@ const XMLResponseBackend = {
},
};

const JSONResponseBackend = {
export const JSONResponseBackend = {

/**
* okJSONResponse - Response with JSON body
Expand Down
134 changes: 134 additions & 0 deletions tests/unit/s3routes/routesUtils/JSONResponseBackend.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
const http = require('http');
const werelogs = require('werelogs');
const { default: errors } = require('../../../../lib/errors');
const { JSONResponseBackend } = require('../../../../lib/s3routes/routesUtils');
const logger = new werelogs.Logger('JSONResponseBackend', 'debug', 'debug');
const log = logger.newRequestLogger();

describe('JSONResponseBackend', () => {
let request;
let response;

beforeEach(() => {
request = new http.IncomingMessage();
response = new http.ServerResponse(request);
response.writeHead = jest.fn();
response.end = jest.fn();
response.setHeader = jest.fn();
log.addDefaultFields = jest.fn();
});

describe('okResponse', () => {
it('should send a JSON response with 200 status code', () => {
const json = '{"message":"Success"}';

JSONResponseBackend.okResponse(json, response, log);

const bytesSent = Buffer.byteLength(json);
expect(response.writeHead).toHaveBeenCalledWith(200, { 'Content-type': 'application/json' });
expect(response.end).toHaveBeenCalledWith(json, 'utf8', expect.any(Function));
expect(log.addDefaultFields).toHaveBeenCalledWith({ bytesSent });
});

it('should include additional headers in the response', () => {
const json = '{"message":"Success"}';
const additionalHeaders = { 'x-custom-header': 'value' };

JSONResponseBackend.okResponse(json, response, log, additionalHeaders);

expect(response.setHeader).toHaveBeenCalledWith('x-custom-header', 'value');
expect(response.writeHead).toHaveBeenCalledWith(200, {
'Content-type': 'application/json',
});
});
});

describe('errorResponse', () => {
it('should handle ArsenalError and return appropriate JSON error response', () => {
const errCode = errors.NoSuchKey;

JSONResponseBackend.errorResponse(errCode, response, log);

const expectedJSON = JSON.stringify({
code: 'NoSuchKey',
message: 'The specified key does not exist.',
resource: null,
requestId: log.getSerializedUids(),
});

const bytesSent = Buffer.byteLength(expectedJSON);

expect(response.end).toHaveBeenCalledWith(expectedJSON, 'utf8', expect.any(Function));
expect(response.writeHead).toHaveBeenCalledWith(404, {
'Content-Type': 'application/json',
'Content-Length': bytesSent,
});
expect(log.addDefaultFields).toHaveBeenCalledWith({ bytesSent });
});

it('should handle standard Error and return InternalError as JSON', () => {
const errCode = new Error('Some error occurred');

JSONResponseBackend.errorResponse(errCode, response, log);

const internalError = errors.InternalError.customizeDescription('Some error occurred');

const expectedJSON = JSON.stringify({
code: internalError.message,
message: internalError.description,
resource: null,
requestId: log.getSerializedUids(),
});

const bytesSent = Buffer.byteLength(expectedJSON);

expect(response.writeHead).toHaveBeenCalledWith(500, {
'Content-Type': 'application/json',
'Content-Length': bytesSent,
});
expect(response.end).toHaveBeenCalledWith(expectedJSON, 'utf8', expect.any(Function));
expect(log.addDefaultFields).toHaveBeenCalledWith({ bytesSent });
});

it('should return 304 without body if error code is 304', () => {
const errCode = errors.NotModified;

JSONResponseBackend.errorResponse(errCode, response, log);

expect(response.writeHead).toHaveBeenCalledWith(304, {
'Content-Length': 99,
'Content-Type': 'application/json',
});
});

it('should include invalidArguments metadata if present in the error', () => {
const errCode = errors.InvalidArgument;
errCode.metadata.set('invalidArguments', [
{ ArgumentName: 'arg1', ArgumentValue: 'value1' },
{ ArgumentName: 'arg2', ArgumentValue: 'value2' },
]);

JSONResponseBackend.errorResponse(errCode, response, log);

const expectedJSON = JSON.stringify({
code: 'InvalidArgument',
message: 'Invalid Argument',
ArgumentName1: 'arg1',
ArgumentValue1: 'value1',
ArgumentName2: 'arg2',
ArgumentValue2: 'value2',
resource: null,
requestId: log.getSerializedUids(),
});

const bytesSent = Buffer.byteLength(expectedJSON);

expect(response.end).toHaveBeenCalledWith(expectedJSON, 'utf8', expect.any(Function));
expect(response.writeHead).toHaveBeenCalledWith(400, {
'Content-Type': 'application/json',
'Content-Length': bytesSent,
});
expect(log.addDefaultFields).toHaveBeenCalledWith({ bytesSent });
});
});
});
141 changes: 141 additions & 0 deletions tests/unit/s3routes/routesUtils/XMLResponseBackend.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
const http = require('http');
const werelogs = require('werelogs');
const { default: errors } = require('../../../../lib/errors');
const { XMLResponseBackend } = require('../../../../lib/s3routes/routesUtils');
const logger = new werelogs.Logger('XMLResponseBackend', 'debug', 'debug');
const log = logger.newRequestLogger();

describe('XMLResponseBackend', () => {
let request;
let response;

beforeEach(() => {
request = new http.IncomingMessage();
response = new http.ServerResponse(request);
response.writeHead = jest.fn();
response.end = jest.fn();
response.setHeader = jest.fn();
log.addDefaultFields = jest.fn();
});

describe('okResponse', () => {
it('should send an XML response with 200 status code', () => {
const xml = '<Response>Success</Response>';

XMLResponseBackend.okResponse(xml, response, log);

const bytesSent = Buffer.byteLength(xml);
expect(response.writeHead).toHaveBeenCalledWith(200, { 'Content-type': 'application/xml' });
expect(response.end).toHaveBeenCalledWith(xml, 'utf8', expect.any(Function));
expect(log.addDefaultFields).toHaveBeenCalledWith({ bytesSent });
});

it('should include additional headers in the response', () => {
const xml = '<Response>Success</Response>';
const additionalHeaders = { 'x-custom-header': 'value' };

XMLResponseBackend.okResponse(xml, response, log, additionalHeaders);

expect(response.setHeader).toHaveBeenCalledWith('x-custom-header', 'value');
expect(response.writeHead).toHaveBeenCalledWith(200, {
'Content-type': 'application/xml',
});
});
});

describe('errorResponse', () => {
it('should handle ArsenalError and return appropriate XML error response', () => {
const errCode = errors.NoSuchKey;

XMLResponseBackend.errorResponse(errCode, response, log);

const expectedXML = [
'<?xml version="1.0" encoding="UTF-8"?>',
'<Error>',
'<Code>NoSuchKey</Code>',
'<Message>The specified key does not exist.</Message>',
'<Resource></Resource>',
`<RequestId>${log.getSerializedUids()}</RequestId>`,
'</Error>',
].join('');

const bytesSent = Buffer.byteLength(expectedXML);

expect(response.end).toHaveBeenCalledWith(expectedXML, 'utf8', expect.any(Function));
expect(response.writeHead).toHaveBeenCalledWith(404, {
'Content-Type': 'application/xml',
'Content-Length': bytesSent,
});
expect(log.addDefaultFields).toHaveBeenCalledWith({ bytesSent });
});

it('should handle standard Error and return InternalError as XML', () => {
const errCode = new Error('Some error occurred');

XMLResponseBackend.errorResponse(errCode, response, log);

const internalError = errors.InternalError.customizeDescription('Some error occurred');

const expectedXML = [
'<?xml version="1.0" encoding="UTF-8"?>',
'<Error>',
`<Code>${internalError.message}</Code>`,
`<Message>${internalError.description}</Message>`,
'<Resource></Resource>',
`<RequestId>${log.getSerializedUids()}</RequestId>`,
'</Error>',
].join('');

const bytesSent = Buffer.byteLength(expectedXML);

expect(response.writeHead).toHaveBeenCalledWith(500, {
'Content-Type': 'application/xml',
'Content-Length': bytesSent,
});
expect(response.end).toHaveBeenCalledWith(expectedXML, 'utf8', expect.any(Function));
expect(log.addDefaultFields).toHaveBeenCalledWith({ bytesSent });
});

it('should return 304 without body if error code is 304', () => {
const errCode = errors.NotModified;

XMLResponseBackend.errorResponse(errCode, response, log);

expect(response.writeHead).toHaveBeenCalledWith(304);
expect(response.end).toHaveBeenCalledWith('', 'utf8', expect.any(Function));
});

it('should include invalidArguments metadata if present in the error', () => {
const errCode = errors.InvalidArgument;
errCode.metadata.set('invalidArguments', [
{ ArgumentName: 'arg1', ArgumentValue: 'value1' },
{ ArgumentName: 'arg2', ArgumentValue: 'value2' },
]);

XMLResponseBackend.errorResponse(errCode, response, log);

const expectedXML = [
'<?xml version="1.0" encoding="UTF-8"?>',
'<Error>',
'<Code>InvalidArgument</Code>',
'<Message>Invalid Argument</Message>',
'<ArgumentName1>arg1</ArgumentName1>',
'<ArgumentValue1>value1</ArgumentValue1>',
'<ArgumentName2>arg2</ArgumentName2>',
'<ArgumentValue2>value2</ArgumentValue2>',
'<Resource></Resource>',
`<RequestId>${log.getSerializedUids()}</RequestId>`,
'</Error>',
].join('');

const bytesSent = Buffer.byteLength(expectedXML);

expect(response.end).toHaveBeenCalledWith(expectedXML, 'utf8', expect.any(Function));
expect(response.writeHead).toHaveBeenCalledWith(400, {
'Content-Type': 'application/xml',
'Content-Length': bytesSent,
});
expect(log.addDefaultFields).toHaveBeenCalledWith({ bytesSent });
});
});
});
Loading

0 comments on commit 2079ec6

Please sign in to comment.