Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prepare-server-get-component-parameters #432

Merged
merged 10 commits into from
Apr 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion client/src/href-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var querystring = require('querystring');
var format = require('stringformat');
var url = require('url');
var settings = require('./settings');
var mergeObjects = require('./utils/merge-objects');

module.exports = function(config){
return {
Expand Down Expand Up @@ -52,7 +53,11 @@ module.exports = function(config){

prepareServerGet: function(baseUrl, component, options) {
var urlPath = component.name + (component.version ? '/' + component.version : '');
var qs = options.parameters ? ('/?' + querystring.stringify(options.parameters)) : '';

var qs = '';
if (component.parameters || options.parameters) {
qs = '/?' + querystring.stringify(mergeObjects(component.parameters, options.parameters));
Copy link
Member

@matteofigus matteofigus Apr 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about using _.extend instead of mergeObjects. We use it a lot everywhere so it would be more consistent.

var _ = require('underscore')
var p = _.extend(options.parameters, component.parameters)
// example
_.extend({b:3, c:4}, {a:1, b:2})
// => { b: 2, c: 4, a: 1 }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about that but looking at the package.json I couldn't see lodash as a dependency (https://github.com/opentable/oc/blob/master/client/package.json#L17-L21) also in ES6 this will be part of the language so I preferred not to add a dependency and go "vanilla". plus the component is a standalone one (and fully tested) so we can always swap its internal implementation.

}

return url.resolve(baseUrl, urlPath + qs);
}
Expand Down
17 changes: 17 additions & 0 deletions client/src/utils/merge-objects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

function addProperties(source, destination) {
for (var key in source) {
if (source.hasOwnProperty(key) && !destination[key]) {
destination[key] = source[key];
}
}
}

// info: use Object.assign() w/ ES6
module.exports = function (obj1, obj2) {
var obj3 = {};
addProperties(obj1, obj3);
addProperties(obj2, obj3);
return obj3;
};
22 changes: 22 additions & 0 deletions test/unit/client-href-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,27 @@ describe('client : href-builder :', () => {
.to.equal('http://localhost:3030/hello-world/1.0.0/?p1=v1&p2=v%202');
});
});

describe('when there are parameters in both "options" and "component"', () => {
it('it should return a valid request for the component with the parameters set as URL query params', () => {
let options = { parameters: { p1: 'v1', p2: 'v 2' } };
let component = { name: 'hello-world', version: '1.0.0', parameters: { message: 'hello' } };
Copy link
Member

@matteofigus matteofigus Apr 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we include a common parameter to ensure our merge goes in the right way, such as { message: 'hello', p1: 'v3'} and be sure qs has ...&p1=v1

Copy link
Member Author

@mattiaerre mattiaerre Apr 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is covered at the mergeObjects level but I will add a specific test for this scenario. and in this case, p1=v3 as the component's parameters win over the option ones (as per your other example above).

let hrefBuilder = new hrefBuilderPrototype({});

expect(hrefBuilder.prepareServerGet('http://localhost:3030', component, options))
.to.equal('http://localhost:3030/hello-world/1.0.0/?message=hello&p1=v1&p2=v%202');
});
});

describe('when there are common parameters in both "options" and "component"', () => {
it('it should return a valid request for the component with the parameters set as URL query params', () => {
let options = { parameters: { p1: 'v1', p2: 'v 2' } };
let component = { name: 'hello-world', version: '1.0.0', parameters: { message: 'hello', p1: 'v3' } };
let hrefBuilder = new hrefBuilderPrototype({});

expect(hrefBuilder.prepareServerGet('http://localhost:3030', component, options))
.to.equal('http://localhost:3030/hello-world/1.0.0/?message=hello&p1=v3&p2=v%202');
});
});
});
});
24 changes: 24 additions & 0 deletions test/unit/client-merge-objects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

const expect = require('chai').expect;
const mergeObjects = require('../../client/src/utils/merge-objects');

describe('client : merge-objects :', () => {
const scenarios = [
{ describe: 'obj1 is empty and obj2 is empty', obj1: {}, obj2: {}, obj3: {} },
{ describe: 'obj1 is not empty and obj2 is empty', obj1: { p1: 'aaa' }, obj2: {}, obj3: { p1: 'aaa' } },
{ describe: 'obj1 is empty and obj2 is not empty', obj1: {}, obj2: { p2: 'bbb' }, obj3: { p2: 'bbb' } },
{ describe: 'obj1 is not empty and obj2 is not empty', obj1: { p1: 'aaa' }, obj2: { p2: 'bbb' }, obj3: { p1: 'aaa', p2: 'bbb' } },
{ describe: 'obj1 is undefined and obj2 is undefined', obj1: undefined, obj2: undefined, obj3: {} },
{ describe: 'obj1 is null and obj2 is null', obj1: null, obj2: null, obj3: {} },
{ describe: 'obj1 and obj2 have a property in common', obj1: { a: 1, b: 2 }, obj2: { b: 3, c: 4 }, obj3: { a: 1, b: 2, c: 4 } }
];

scenarios.forEach((scenario) => {
describe(`when ${scenario.describe}`, () => {
it(`then obj3 is equal to ${JSON.stringify(scenario.obj3)}`, () => {
expect(mergeObjects(scenario.obj1, scenario.obj2)).to.deep.equal(scenario.obj3);
});
});
});
});