Skip to content

Commit

Permalink
feat(ajax): add FormData support in AjaxObservable and add percent en…
Browse files Browse the repository at this point in the history
…coding for parameter key in body

FormData spec https://xhr.spec.whatwg.org/#interface-formdata
add some tests for ajax request body.
  • Loading branch information
vvakame authored and benlesh committed Mar 29, 2016
1 parent d5b9d11 commit 1f6119c
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 1 deletion.
95 changes: 95 additions & 0 deletions spec/observables/dom/ajax-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,101 @@ describe('Observable.ajax', () => {
});
});

describe('ajax request body', () => {
let rFormData: FormData;

beforeEach(() => {
rFormData = root.FormData;
root.FormData = root.FormData || class {};
});

afterEach(() => {
root.FormData = rFormData;
});

it('can take string body', () => {
const obj = {
url: '/flibbertyJibbet',
method: '',
body: 'foobar'
};

Rx.Observable.ajax(obj).subscribe();

expect(MockXMLHttpRequest.mostRecent.url).toBe('/flibbertyJibbet');
expect(MockXMLHttpRequest.mostRecent.data).toBe('foobar');
});

it('can take FormData body', () => {
const body = new root.FormData();
const obj = {
url: '/flibbertyJibbet',
method: '',
body: body
};

Rx.Observable.ajax(obj).subscribe();

expect(MockXMLHttpRequest.mostRecent.url).toBe('/flibbertyJibbet');
expect(MockXMLHttpRequest.mostRecent.data).toBe(body);
});

it('should not fail when FormData is undefined', () => {
root.FormData = void 0;

const obj = {
url: '/flibbertyJibbet',
method: '',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: { '🌟': '🚀' }
};

Rx.Observable.ajax(obj).subscribe();

expect(MockXMLHttpRequest.mostRecent.url).toBe('/flibbertyJibbet');
});

it('should send by form-urlencoded format', () => {
const body = {
'🌟': '🚀'
};
const obj = {
url: '/flibbertyJibbet',
method: '',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: body
};

Rx.Observable.ajax(obj).subscribe();

expect(MockXMLHttpRequest.mostRecent.url).toBe('/flibbertyJibbet');
expect(MockXMLHttpRequest.mostRecent.data).toBe('%F0%9F%8C%9F=%F0%9F%9A%80');
});

it('should send by JSON', () => {
const body = {
'🌟': '🚀'
};
const obj = {
url: '/flibbertyJibbet',
method: '',
headers: {
'Content-Type': 'application/json'
},
body: body
};

Rx.Observable.ajax(obj).subscribe();

expect(MockXMLHttpRequest.mostRecent.url).toBe('/flibbertyJibbet');
expect(MockXMLHttpRequest.mostRecent.data).toBe('{"🌟":"🚀"}');
});
});

describe('ajax.get', () => {
it('should succeed on 200', () => {
const expected = { foo: 'bar' };
Expand Down
4 changes: 3 additions & 1 deletion src/observable/dom/AjaxObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
private serializeBody(body: any, contentType: string) {
if (!body || typeof body === 'string') {
return body;
} else if (root.FormData && body instanceof root.FormData) {
return body;
}

const splitIndex = contentType.indexOf(';');
Expand All @@ -254,7 +256,7 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {

switch (contentType) {
case 'application/x-www-form-urlencoded':
return Object.keys(body).map(key => `${key}=${encodeURI(body[key])}`).join('&');
return Object.keys(body).map(key => `${encodeURI(key)}=${encodeURI(body[key])}`).join('&');
case 'application/json':
return JSON.stringify(body);
}
Expand Down

0 comments on commit 1f6119c

Please sign in to comment.