Skip to content

Commit 21c649a

Browse files
i-b-dimitrovmatteofigus
authored andcommitted
Fix for Custom eaders of one component can appear to another. (#328)
The problem was introduced with #326 - In get-component.js the declaration of responseHeaders variable happens in a more global scope than it should be. For this reason every invocation of renderer function sees the changes in the headers made by previously requested components. The fix is to just move the declaration one scope inner. - Added a unit test to validate the fix - it tries to load two components subsequently. The first one does provide custom headers while the second one - don't. Then we check and expect to see there are no custom headers in the result for the second one.
1 parent 0dac67e commit 21c649a

File tree

5 files changed

+160
-5
lines changed

5 files changed

+160
-5
lines changed

src/registry/routes/helpers/get-component.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ module.exports = function(conf, repository){
2626
cache = new Cache({
2727
verbose: !!conf.verbosity,
2828
refreshInterval: conf.refreshInterval
29-
}),
30-
responseHeaders;
29+
});
3130

3231
var renderer = function(options, cb){
3332

3433
var nestedRenderer = new NestedRenderer(renderer, options.conf),
35-
retrievingInfo = new GetComponentRetrievingInfo(options);
34+
retrievingInfo = new GetComponentRetrievingInfo(options),
35+
responseHeaders;
3636

3737
var getLanguage = function(){
3838
var paramOverride = !!options.parameters && options.parameters['__ocAcceptLanguage'];
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
module.exports = {
4+
package: {
5+
name: 'another-response-headers-component',
6+
version: '1.0.0',
7+
oc: {
8+
container: false,
9+
renderInfo: false,
10+
files: {
11+
template: {
12+
type: 'jade',
13+
hashKey: '8c1fbd954f2b0d8cd5cf11c885fed4805225749f',
14+
src: 'template.js'
15+
},
16+
dataProvider: {
17+
type: 'node.js',
18+
hashKey: '123456',
19+
src: 'server.js'
20+
}
21+
}
22+
}
23+
},
24+
data: '"use strict";module.exports.data = function(ctx, cb){ctx.setHeader("another-test-header","another-test-value"); cb(null, {done:true});};',
25+
view: 'var oc=oc||{};oc.components=oc.components||{},oc.components["8c1fbd954f2b0d8cd5cf11c885fed4805225749f"]' +
26+
'=function(){var o=[];return o.push("<div>hello</div>"),o.join("")};'
27+
};

test/fixtures/mocked-components/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ module.exports = {
88
'plugin-component': require('./plugin'),
99
'timeout-component': require('./timeout'),
1010
'undefined-component': require('./undefined'),
11-
'response-headers-component': require('./response-headers')
11+
'simple-component': require('./simple'),
12+
'response-headers-component': require('./response-headers'),
13+
'another-response-headers-component': require('./another-response-headers')
1214
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
module.exports = {
4+
package: {
5+
name: 'simple-component',
6+
version: '1.0.0',
7+
oc: {
8+
container: false,
9+
renderInfo: false,
10+
files: {
11+
template: {
12+
type: 'jade',
13+
hashKey: '8c1fbd954f2b0d8cd5cf11c885fed4805225749f',
14+
src: 'template.js'
15+
},
16+
dataProvider: {
17+
type: 'node.js',
18+
hashKey: '123457',
19+
src: 'server.js'
20+
}
21+
}
22+
}
23+
},
24+
data: '"use strict";module.exports.data = function(ctx, cb){cb(null, {done:true});};',
25+
view: 'var oc=oc||{};oc.components=oc.components||{},oc.components["8c1fbd954f2b0d8cd5cf11c885fed4805225749f"]' +
26+
'=function(){var o=[];return o.push("<div>hello</div>"),o.join("")};'
27+
};

test/unit/registry-routes-component.js

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,6 @@ describe('registry : routes : component', function(){
419419
});
420420

421421
describe('when getting a component with server.js that sets custom headers', function() {
422-
423422
var code, response, headers;
424423

425424
before(function(done) {
@@ -466,4 +465,104 @@ describe('registry : routes : component', function(){
466465
});
467466
});
468467

468+
describe('when getting a simple component with server.js after headers component no custom headers should be set', function() {
469+
var code={},
470+
response={},
471+
headers={};
472+
473+
before(function(done) {
474+
var headersComponent = mockedComponents['another-response-headers-component'];
475+
var simpleComponent = mockedComponents['simple-component'];
476+
477+
mockedRepository = {
478+
getCompiledView: sinon.stub(),
479+
getComponent: sinon.stub(),
480+
getDataProvider: sinon.stub(),
481+
getStaticFilePath: sinon.stub().returns('//my-cdn.com/files/')
482+
};
483+
484+
//Custom repository initialization to give us two components when invoked twice...
485+
//...the firts one with custom headers and the second - without.
486+
mockedRepository.getCompiledView.onCall(0).yields(null, headersComponent.view);
487+
mockedRepository.getCompiledView.onCall(1).yields(null, simpleComponent.view);
488+
489+
mockedRepository.getComponent.onCall(0).yields(null, headersComponent.package);
490+
mockedRepository.getComponent.onCall(1).yields(null, simpleComponent.package);
491+
492+
mockedRepository.getDataProvider.onCall(0).yields(null, headersComponent.data);
493+
mockedRepository.getDataProvider.onCall(1).yields(null, simpleComponent.data);
494+
495+
componentRoute = new ComponentRoute({}, mockedRepository);
496+
resJsonStub = sinon.stub();
497+
498+
var resJson = function(index, callback) {
499+
return function(calledCode, calledResponse) {
500+
code[index] = calledCode;
501+
response[index] = calledResponse;
502+
callback && callback();
503+
};
504+
};
505+
506+
var resSet = function(index) {
507+
return function(calledHeaders) {
508+
headers[index] = calledHeaders;
509+
};
510+
};
511+
512+
var requestComponent = function(componentName, resultIndex) {
513+
return new Promise(function(resolve, reject) {
514+
componentRoute({
515+
headers: {},
516+
params: { componentName: componentName, componentVersion: '1.X.X' }
517+
}, {
518+
conf: {
519+
baseUrl: 'http://component.com/',
520+
executionTimeout: 0.1
521+
},
522+
json: resJson(resultIndex, function() { resolve(); }),
523+
set: resSet(resultIndex)
524+
});
525+
});
526+
};
527+
528+
requestComponent('another-response-headers-component', 0)
529+
.then(requestComponent('simple-component', 1))
530+
.then(function() { done(); });
531+
});
532+
533+
//The first part of the test - checking that another-response-headers-component
534+
//should return a response with custom headers
535+
it('should return 200 status code for the first component', function() {
536+
expect(code[0]).to.be.equal(200);
537+
});
538+
539+
it('should return "response-headers-component" name for the first component\'s name and request version', function() {
540+
expect(response[0].name).to.equal('another-response-headers-component');
541+
expect(response[0].requestVersion).to.equal('1.X.X');
542+
});
543+
544+
it('should set response headers for the first component', function() {
545+
expect(response[0].headers).to.not.be.null;
546+
expect(response[0].headers['another-test-header']).to.equal('another-test-value');
547+
expect(headers[0]).to.not.be.null;
548+
expect(headers[0]['another-test-header']).to.equal('another-test-value');
549+
});
550+
551+
//The second part of the test - validating that simple-component should not return
552+
//the custom headers previously set by another-headers-component.
553+
it('should return 200 status code for the first component', function() {
554+
expect(code[1]).to.be.equal(200);
555+
});
556+
557+
it('should return "simple-component" name for the first component\'s name and request version', function() {
558+
expect(response[1].name).to.equal('simple-component');
559+
expect(response[1].requestVersion).to.equal('1.X.X');
560+
});
561+
562+
it('should not set custom response', function() {
563+
expect(response[1].headers).to.be.undefined;
564+
expect(headers[1]).to.be.undefined;
565+
});
566+
});
567+
469568
});

0 commit comments

Comments
 (0)