Skip to content

Commit

Permalink
Test parseResponseHeaders function and extract to module
Browse files Browse the repository at this point in the history
This pulls the `parseResponseHeaders` function out of `DS.RestAdapter`
and moves it to its own module.

The main reason for this was to make it easier to unit test in order to
document current behavior before working on fixing the
emberjs#4122
  • Loading branch information
HeroicEric committed Feb 6, 2016
1 parent 567dfc5 commit f029211
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 21 deletions.
27 changes: 27 additions & 0 deletions addon/-private/adapters/parse-response-headers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import EmptyObject from 'ember-data/-private/system/empty-object';

export default function parseResponseHeaders(headersString) {
let headers = new EmptyObject();

if (!headersString) {
return headers;
}

let headerPairs = headersString.split('\u000d\u000a');

for (let i = 0; i < headerPairs.length; i++) {
let headerPair = headerPairs[i];
// Can't use split() here because it does the wrong thing
// if the header value has the string ": " in it.
let index = headerPair.indexOf('\u003a\u0020');

if (index > 0) {
let key = headerPair.substring(0, index);
let val = headerPair.substring(index + 2);

headers[key] = val;
}
}

return headers;
}
22 changes: 1 addition & 21 deletions addon/adapters/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import {
TimeoutError,
AbortError
} from 'ember-data/-private/adapters/errors';
import EmptyObject from "ember-data/-private/system/empty-object";
import BuildURLMixin from "ember-data/-private/adapters/build-url-mixin";
import isEnabled from 'ember-data/-private/features';
import parseResponseHeaders from 'ember-data/-private/adapters/parse-response-headers';

const {
MapWithDefault,
Expand Down Expand Up @@ -1006,26 +1006,6 @@ export default Adapter.extend(BuildURLMixin, {
}
});

function parseResponseHeaders(headerStr) {
var headers = new EmptyObject();
if (!headerStr) { return headers; }

var headerPairs = headerStr.split('\u000d\u000a');
for (var i = 0; i < headerPairs.length; i++) {
var headerPair = headerPairs[i];
// Can't use split() here because it does the wrong thing
// if the header value has the string ": " in it.
var index = headerPair.indexOf('\u003a\u0020');
if (index > 0) {
var key = headerPair.substring(0, index);
var val = headerPair.substring(index + 2);
headers[key] = val;
}
}

return headers;
}

//From http://stackoverflow.com/questions/280634/endswith-in-javascript
function endsWith(string, suffix) {
if (typeof String.prototype.endsWith !== 'function') {
Expand Down
43 changes: 43 additions & 0 deletions tests/unit/adapters/parse-response-headers-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import EmptyObject from 'ember-data/-private/system/empty-object';
import parseResponseHeaders from 'ember-data/-private/adapters/parse-response-headers';
import { module, test } from 'qunit';

const CRLF = '\u000d\u000a';

module('unit/adapters/parse-response-headers');

test('returns an EmptyObject when headersString is undefined', function(assert) {
let headers = parseResponseHeaders(undefined);

assert.deepEqual(headers, new EmptyObject(), 'EmptyObject is returned');
});

test('header parsing', function(assert) {
let headersString = [
'Content-Encoding: gzip',
'content-type: application/json; charset=utf-8',
'date: Fri, 05 Feb 2016 21:47:56 GMT',
'Apple-Field: value with leading whitespace',
'Bear-Field: value that contains: a colon'
].join(CRLF);

let headers = parseResponseHeaders(headersString);

assert.equal(headers['Content-Encoding'], 'gzip', 'parses basic header pair');
assert.equal(headers['content-type'], 'application/json; charset=utf-8', 'parses header with complex value');
assert.equal(headers['date'], 'Fri, 05 Feb 2016 21:47:56 GMT', 'parses header with date value');
assert.equal(headers['Apple-Field'], 'value with leading whitespace', 'strips leading whitespace from field-value');
assert.equal(headers['Bear-Field'], 'value that contains: a colon', 'has correct value when value contins a colon');
});

test('ignores headers that do not contain a colon', function(assert) {
let headersString = [
'Content-Encoding: gzip',
'I am ignored because I do not contain a colon'
].join(CRLF);

let headers = parseResponseHeaders(headersString);

assert.deepEqual(headers['Content-Encoding'], 'gzip', 'parses basic header pair');
assert.equal(Object.keys(headers).length, 1, 'only has the one valid header');
});

0 comments on commit f029211

Please sign in to comment.