Skip to content

Commit

Permalink
Fixes Issue #124
Browse files Browse the repository at this point in the history
Refactored toApiFormat.js to use json-pointer
orval authored and aydrian committed Apr 4, 2016
1 parent 3cdeb14 commit 582eac0
Showing 4 changed files with 74 additions and 35 deletions.
87 changes: 52 additions & 35 deletions lib/toApiFormat.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,59 @@
'use strict';
var _ = require('lodash');
var _ = require('lodash')
, pointer = require('json-pointer');

var excludeList = [
'/substitution_data',
'/tags',
'/metadata',
'/attributes',
'/headers',
'/content/email_rfc822'
];

function snakedKeyClone(source) {

if (!_.isObject(source)) {
return source;
}

var target = {};

if (Array.isArray(source)) {
target = [];
for (var i = 0; i < source.length; i++) {
target.push(snakedKeyClone(source[i]));
}
return target;
}

Object.keys(source).forEach(function(key) {
target[_.snakeCase(key)] = snakedKeyClone(source[key]);
});

return target;
}

module.exports = function toApiFormat(source) {

var dest = {};
// List of property names which we do not want to modify the sub-property names
var excludeList = ['substitution_data', 'tags', 'metadata', 'attributes', 'headers'];

try{
// Handle arrays (Only need to handle arrays of objects for our use case.)
if(Array.isArray(source) && _.isPlainObject(source[0])) {
dest = [];
for(var i = 0; i < source.length; i++) {
dest.push(toApiFormat(source[i]));
}
return dest;
var excludedObjects = {};

// Look in the source object for the excluded pointers and take a copy of the
// objects pointed to by those keys. Then remove them from the source object.
excludeList.forEach(function(exclusionPointer) {
if (pointer.has(source, exclusionPointer)) {
pointer.set(excludedObjects, exclusionPointer, pointer.get(source, exclusionPointer));
pointer.remove(source, exclusionPointer);
}
});

// Handle objects
Object.keys(source).forEach(function(key) {

// Cache snake_cased keys
var snakedKey = _.snakeCase(key);

// Exclude appropriately
if( -1 === excludeList.indexOf(key)) {
dest[snakedKey] = source[key];
if( _.isObject (source[key] ) ) {
dest[snakedKey] = toApiFormat(source[key]);
}
} else {
dest[snakedKey] = source[key];
}
});
} catch(e) {
// Errors
return e;
}
// No errors return results
return dest;
// Make a clone of the remaining source object but with snaked case keys
var target = snakedKeyClone(source);

// Reinstated the un-modified objects into the target
pointer.walk(excludedObjects, function(val, ptr) {
pointer.set(target, ptr, val);
});

return target;
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@
"xunit-file": "0.0.5"
},
"dependencies": {
"json-pointer": "^0.5.0",
"lodash": "^3.9.3",
"request": "2.42.0"
}
6 changes: 6 additions & 0 deletions test/spec/toApiFormat.spec.js
Original file line number Diff line number Diff line change
@@ -24,6 +24,9 @@ describe('toApiFormat', function() {
{name: 'John Doe', address: 'j.doe@sparkpost.com'}
, {name: 'Sam Jones', address: 's.jones@sparkpost.com'}
]
, content: {
email_rfc822: 'a message'
}
, fizzArr: [
{
buzzInga: "buzz"
@@ -53,6 +56,9 @@ describe('toApiFormat', function() {
{name: 'John Doe', address: 'j.doe@sparkpost.com'}
, {name: 'Sam Jones', address: 's.jones@sparkpost.com'}
]
, content: {
email_rfc822: 'a message'
}
, fizz_arr: [
{
buzz_inga: "buzz"
15 changes: 15 additions & 0 deletions test/spec/transmissions.spec.js
Original file line number Diff line number Diff line change
@@ -108,5 +108,20 @@ describe('Transmissions Library', function() {
done();
});
});

it('should leave email_rfc822 content keys intact', function(done) {
var options = {
transmissionBody: {
content: {
email_rfc822: 'Content-Type: text/plain\nFrom: From Envelope <from@example.com>\nSubject: Example Email\n\nHello World'
}
}
};

transmission.send(options, function(err, data) {
expect(client.post.firstCall.args[0].json.content).to.have.property('email_rfc822');
done();
});
});
});
});

0 comments on commit 582eac0

Please sign in to comment.