Skip to content

Commit 582eac0

Browse files
Duncan Ranceaydrian
authored andcommitted
Fixes Issue #124
Refactored toApiFormat.js to use json-pointer
1 parent 3cdeb14 commit 582eac0

File tree

4 files changed

+74
-35
lines changed

4 files changed

+74
-35
lines changed

lib/toApiFormat.js

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,59 @@
11
'use strict';
2-
var _ = require('lodash');
2+
var _ = require('lodash')
3+
, pointer = require('json-pointer');
4+
5+
var excludeList = [
6+
'/substitution_data',
7+
'/tags',
8+
'/metadata',
9+
'/attributes',
10+
'/headers',
11+
'/content/email_rfc822'
12+
];
13+
14+
function snakedKeyClone(source) {
15+
16+
if (!_.isObject(source)) {
17+
return source;
18+
}
19+
20+
var target = {};
21+
22+
if (Array.isArray(source)) {
23+
target = [];
24+
for (var i = 0; i < source.length; i++) {
25+
target.push(snakedKeyClone(source[i]));
26+
}
27+
return target;
28+
}
29+
30+
Object.keys(source).forEach(function(key) {
31+
target[_.snakeCase(key)] = snakedKeyClone(source[key]);
32+
});
33+
34+
return target;
35+
}
336

437
module.exports = function toApiFormat(source) {
538

6-
var dest = {};
7-
// List of property names which we do not want to modify the sub-property names
8-
var excludeList = ['substitution_data', 'tags', 'metadata', 'attributes', 'headers'];
9-
10-
try{
11-
// Handle arrays (Only need to handle arrays of objects for our use case.)
12-
if(Array.isArray(source) && _.isPlainObject(source[0])) {
13-
dest = [];
14-
for(var i = 0; i < source.length; i++) {
15-
dest.push(toApiFormat(source[i]));
16-
}
17-
return dest;
39+
var excludedObjects = {};
40+
41+
// Look in the source object for the excluded pointers and take a copy of the
42+
// objects pointed to by those keys. Then remove them from the source object.
43+
excludeList.forEach(function(exclusionPointer) {
44+
if (pointer.has(source, exclusionPointer)) {
45+
pointer.set(excludedObjects, exclusionPointer, pointer.get(source, exclusionPointer));
46+
pointer.remove(source, exclusionPointer);
1847
}
48+
});
1949

20-
// Handle objects
21-
Object.keys(source).forEach(function(key) {
22-
23-
// Cache snake_cased keys
24-
var snakedKey = _.snakeCase(key);
25-
26-
// Exclude appropriately
27-
if( -1 === excludeList.indexOf(key)) {
28-
dest[snakedKey] = source[key];
29-
if( _.isObject (source[key] ) ) {
30-
dest[snakedKey] = toApiFormat(source[key]);
31-
}
32-
} else {
33-
dest[snakedKey] = source[key];
34-
}
35-
});
36-
} catch(e) {
37-
// Errors
38-
return e;
39-
}
40-
// No errors return results
41-
return dest;
50+
// Make a clone of the remaining source object but with snaked case keys
51+
var target = snakedKeyClone(source);
52+
53+
// Reinstated the un-modified objects into the target
54+
pointer.walk(excludedObjects, function(val, ptr) {
55+
pointer.set(target, ptr, val);
56+
});
57+
58+
return target;
4259
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"xunit-file": "0.0.5"
4141
},
4242
"dependencies": {
43+
"json-pointer": "^0.5.0",
4344
"lodash": "^3.9.3",
4445
"request": "2.42.0"
4546
}

test/spec/toApiFormat.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ describe('toApiFormat', function() {
2424
{name: 'John Doe', address: '[email protected]'}
2525
, {name: 'Sam Jones', address: '[email protected]'}
2626
]
27+
, content: {
28+
email_rfc822: 'a message'
29+
}
2730
, fizzArr: [
2831
{
2932
buzzInga: "buzz"
@@ -53,6 +56,9 @@ describe('toApiFormat', function() {
5356
{name: 'John Doe', address: '[email protected]'}
5457
, {name: 'Sam Jones', address: '[email protected]'}
5558
]
59+
, content: {
60+
email_rfc822: 'a message'
61+
}
5662
, fizz_arr: [
5763
{
5864
buzz_inga: "buzz"

test/spec/transmissions.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,20 @@ describe('Transmissions Library', function() {
108108
done();
109109
});
110110
});
111+
112+
it('should leave email_rfc822 content keys intact', function(done) {
113+
var options = {
114+
transmissionBody: {
115+
content: {
116+
email_rfc822: 'Content-Type: text/plain\nFrom: From Envelope <[email protected]>\nSubject: Example Email\n\nHello World'
117+
}
118+
}
119+
};
120+
121+
transmission.send(options, function(err, data) {
122+
expect(client.post.firstCall.args[0].json.content).to.have.property('email_rfc822');
123+
done();
124+
});
125+
});
111126
});
112127
});

0 commit comments

Comments
 (0)