Skip to content
This repository was archived by the owner on Oct 20, 2023. It is now read-only.

Commit 2bd6abb

Browse files
committed
feat: Add possibility to define custom response header
Closes micromata/http-fake-backend#10 This also can be configured via the new setting in `.env` after generation.
1 parent d91b19c commit 2bd6abb

File tree

11 files changed

+278
-16
lines changed

11 files changed

+278
-16
lines changed

__tests__/app.js

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ const helpers = require('yeoman-test');
55
const helper = require('../generators/app/promptingHelpers');
66
const chalk = require('chalk');
77

8-
describe('generator-http-fake-backend → server', () => {
8+
describe('generator-http-fake-backend → server with custom header', () => {
99
beforeAll(done => {
1010
helpers.run(path.join(__dirname, '../generators/app'))
1111
.withPrompts({
1212
serverPort: 8081,
13-
apiPrefix: '/api'
13+
apiPrefix: '/api',
14+
customHeader: true,
15+
customHeaderName: 'HeaderName',
16+
customHeaderValue: 'HeaderValue'
1417
})
1518
.on('end', done);
1619
});
@@ -32,6 +35,12 @@ describe('generator-http-fake-backend → server', () => {
3235
it('should contain the prompted api url prefix', () => {
3336
assert.fileContent('.env', /API_PREFIX=\/api/);
3437
});
38+
it('should contain the prompted custom header name', () => {
39+
assert.fileContent('.env', /CUSTOM_HEADER_NAME=HeaderName/);
40+
});
41+
it('should contain the prompted custom header value', () => {
42+
assert.fileContent('.env', /CUSTOM_HEADER_VALUE=HeaderValue/);
43+
});
3544
});
3645

3746
it('should create meta files', () => {
@@ -62,6 +71,7 @@ describe('generator-http-fake-backend → server', () => {
6271
it('should create server files', () => {
6372
assert.file([
6473
'server/api/setup/lib/getContentDisposition.js',
74+
'server/api/setup/lib/getCustomResponseHeader.js',
6575
'server/api/setup/index.js',
6676
'server/api/setup/supportedMethod.js',
6777
'server/api/setup/unsupportedMethods.js',
@@ -83,6 +93,7 @@ describe('generator-http-fake-backend → server', () => {
8393
'test/config.js',
8494
'test/index.js',
8595
'test/manifest.js',
96+
'test/server/api/customResponseHeader.js',
8697
'test/server/api/endpoint.js',
8798
'test/server/api/fakeStatusCode.js',
8899
'test/server/api/fileTypes.js',
@@ -96,6 +107,27 @@ describe('generator-http-fake-backend → server', () => {
96107
});
97108
});
98109

110+
describe('generator-http-fake-backend → server without custom header', () => {
111+
beforeAll(done => {
112+
helpers.run(path.join(__dirname, '../generators/app'))
113+
.withPrompts({
114+
serverPort: 8081,
115+
apiPrefix: '/api',
116+
customHeader: false
117+
})
118+
.on('end', done);
119+
});
120+
121+
describe('.env', () => {
122+
it('should contain the prompted custom header name', () => {
123+
assert.fileContent('.env', /CUSTOM_HEADER_NAME=\n/);
124+
});
125+
it('should contain the prompted custom header value', () => {
126+
assert.fileContent('.env', /CUSTOM_HEADER_VALUE=\n/);
127+
});
128+
});
129+
});
130+
99131
describe('generator-http-fake-backend → server → prompting helpers', () => {
100132
describe('→ validateApiPrefix()', () => {
101133
it('should accept a leading slash', () => {
@@ -108,4 +140,16 @@ describe('generator-http-fake-backend → server → prompting helpers', () => {
108140
assert.equal(helper.validateApiPrefix('api'), chalk.red('API prefix has to begin with a `/`.'));
109141
});
110142
});
143+
144+
describe('→ validateCustomHeader()', () => {
145+
it('should accept a non empty string', () => {
146+
assert.equal(helper.validateCustomHeader('x-powered-by'), true);
147+
});
148+
it('should fail with a empty string', () => {
149+
assert.equal(helper.validateCustomHeader(''), chalk.red('Can’t be an empty string.'));
150+
});
151+
it('should fail with a empty string', () => {
152+
assert.equal(helper.validateCustomHeader(' '), chalk.red('Can’t be an empty string.'));
153+
});
154+
});
111155
});

generators/app/index.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,27 @@ module.exports = class extends Generator {
2929
default: '/api',
3030
store: true,
3131
validate: helper.validateApiPrefix
32+
}, {
33+
type: 'confirm',
34+
name: 'customHeader',
35+
message: 'Would you like to add a custom response header (e.g. Authorization)?',
36+
default: false
37+
}, {
38+
type: 'input',
39+
name: 'customHeaderName',
40+
message: 'Custom header name:',
41+
validate: helper.validateCustomHeader,
42+
when(answers) {
43+
return answers.customHeader;
44+
}
45+
}, {
46+
type: 'input',
47+
name: 'customHeaderValue',
48+
message: 'Custom header value:',
49+
validate: helper.validateCustomHeader,
50+
when(answers) {
51+
return answers.customHeader;
52+
}
3253
}
3354
];
3455

@@ -50,7 +71,9 @@ module.exports = class extends Generator {
5071
this.templatePath('_env'),
5172
this.destinationPath('.env'), {
5273
serverPort: this.props.serverPort,
53-
apiPrefix: this.props.apiPrefix
74+
apiPrefix: this.props.apiPrefix,
75+
customHeaderName: this.props.customHeaderName,
76+
customHeaderValue: this.props.customHeaderValue
5477
}
5578
);
5679
this.fs.copy(

generators/app/promptingHelpers.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,11 @@ helper.validateApiPrefix = function (value) {
1515
return returnValue;
1616
};
1717

18+
helper.validateCustomHeader = function (value) {
19+
if (value.trim() === '') {
20+
return chalk.red('Can’t be an empty string.');
21+
}
22+
return true;
23+
};
24+
1825
module.exports = helper;

generators/app/templates/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ TEST_PORT=9090
255255
# eg. http://localhost:8081/api/foo
256256
API_PREFIX=/api
257257

258+
# Custom response header
259+
#CUSTOM_HEADER_NAME=Authorization
260+
#CUSTOM_HEADER_VALUE=Bearer eyJhbGciOiJIUzUxMiJ9
261+
258262
```
259263

260264

generators/app/templates/_env

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ TEST_PORT=9090
1111
# URL Prefix for the endpoints
1212
# eg. http://localhost:8081/api/foo
1313
API_PREFIX=<%= apiPrefix %>
14+
15+
# Custom response header
16+
CUSTOM_HEADER_NAME=<%= customHeaderName %>
17+
CUSTOM_HEADER_VALUE=<%= customHeaderValue %>

generators/app/templates/manifest.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const Confidence = require('confidence');
44
const Config = require('./config');
55
const Fs = require('fs');
66
const Path = require('path');
7+
const GetCustomResponseHeader = require('./server/api/setup/lib/getCustomResponseHeader');
78

89
const criteria = {
910
env: process.env.NODE_ENV
@@ -22,7 +23,8 @@ const manifest = {
2223
security: true,
2324
cors: {
2425
origin: ['*'],
25-
credentials: true
26+
credentials: true,
27+
additionalExposedHeaders: [GetCustomResponseHeader(process.env).name]
2628
}
2729
},
2830
router: {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
module.exports = function (env) {
4+
5+
return {
6+
name: env.CUSTOM_HEADER_NAME || 'X-Powered-By',
7+
value: env.CUSTOM_HEADER_VALUE || 'https://hapijs.com'
8+
};
9+
};

generators/app/templates/server/api/setup/supportedMethod.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ const Boom = require('boom');
44
const Fs = require('fs');
55
const Path = require('path');
66

7-
const GetContentDisposition = require('./lib/getContentDisposition.js');
7+
const GetContentDisposition = require('./lib/getContentDisposition');
8+
const CustomResponseHeader = require('./lib/getCustomResponseHeader')(process.env);
89

910
module.exports = function (server, proposedRequest, settings, params, path) {
1011

@@ -39,23 +40,18 @@ module.exports = function (server, proposedRequest, settings, params, path) {
3940

4041
}
4142

42-
if (proposedRequest.statusCode && proposedRequest.response) {
43-
44-
if (sendFile && isFile) {
45-
return reply(response).code(proposedRequest.statusCode).type(mimeType).header('Content-Disposition', GetContentDisposition(proposedRequest.response));
46-
}
47-
return reply(response).code(proposedRequest.statusCode).type(mimeType);
48-
}
49-
5043
if (response.isBoom === true) {
44+
response.output.headers[CustomResponseHeader.name] = CustomResponseHeader.value;
5145
return reply(response);
5246
}
5347

5448
if (sendFile && isFile) {
55-
return reply(response).type(mimeType).header('Content-Disposition', GetContentDisposition(proposedRequest.response));
49+
return reply(response).code(proposedRequest.statusCode || 200).type(mimeType)
50+
.header('Content-Disposition', GetContentDisposition(proposedRequest.response))
51+
.header(CustomResponseHeader.name, CustomResponseHeader.value);
5652
}
57-
58-
return reply(response).type(mimeType);
53+
return reply(response).code(proposedRequest.statusCode || 200).type(mimeType)
54+
.header(CustomResponseHeader.name, CustomResponseHeader.value);
5955
}
6056
};
6157
};

generators/app/templates/server/api/setup/unsupportedMethods.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const Boom = require('boom');
4+
const CustomResponseHeader = require('./lib/getCustomResponseHeader')(process.env);
45

56
module.exports = function (settings, params, path) {
67

@@ -18,6 +19,7 @@ module.exports = function (settings, params, path) {
1819
response = Boom.methodNotAllowed();
1920
}
2021

22+
response.output.headers[CustomResponseHeader.name] = CustomResponseHeader.value;
2123
return reply(response);
2224
}
2325
};

generators/app/templates/test/manifest.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,10 @@ lab.experiment('Manifest', () => {
2222
Code.expect(Manifest.meta('/')).to.match(/hapi server config used by glue to compose the server/i);
2323
done();
2424
});
25+
26+
lab.test('it gets the correct custom response header', (done) => {
27+
28+
Code.expect(Manifest.get('/').server.connections.routes.cors.additionalExposedHeaders).to.equal(['X-Powered-By']);
29+
done();
30+
});
2531
});

0 commit comments

Comments
 (0)