angular.js/test/service/xhrSpec.js
Misko Hevery 8f0dcbab80 feat(scope): new and improved scope implementation
- Speed improvements (about 4x on flush phase)
- Memory improvements (uses no function closures)
- Break $eval into $apply, $dispatch, $flush
- Introduced $watch and $observe

Breaks angular.equals() use === instead of ==
Breaks angular.scope() does not take parent as first argument
Breaks scope.$watch() takes scope as first argument
Breaks scope.$set(), scope.$get are removed
Breaks scope.$config is removed
Breaks $route.onChange callback has not "this" bounded
2011-08-02 01:00:03 +02:00

279 lines
9.2 KiB
JavaScript

'use strict';
describe('$xhr', function() {
var scope, $browser, $browserXhr, $log, $xhr, $xhrErr, log;
beforeEach(function(){
var scope = angular.scope(angular.service, {
'$xhr.error': $xhrErr = jasmine.createSpy('xhr.error')});
$log = scope.$service('$log');
$browser = scope.$service('$browser');
$browserXhr = $browser.xhr;
$xhr = scope.$service('$xhr');
log = '';
});
afterEach(function(){
dealoc(scope);
});
function callback(code, response) {
log = log + '{code=' + code + '; response=' + toJson(response) + '}';
}
it('should forward the request to $browser and decode JSON', function(){
$browserXhr.expectGET('/reqGET').respond('first');
$browserXhr.expectGET('/reqGETjson').respond('["second"]');
$browserXhr.expectPOST('/reqPOST', {post:'data'}).respond('third');
$xhr('GET', '/reqGET', null, callback);
$xhr('GET', '/reqGETjson', null, callback);
$xhr('POST', '/reqPOST', {post:'data'}, callback);
$browserXhr.flush();
expect(log).toEqual(
'{code=200; response="third"}' +
'{code=200; response=["second"]}' +
'{code=200; response="first"}');
});
it('should allow all 2xx requests', function(){
$browserXhr.expectGET('/req1').respond(200, '1');
$xhr('GET', '/req1', null, callback);
$browserXhr.flush();
$browserXhr.expectGET('/req2').respond(299, '2');
$xhr('GET', '/req2', null, callback);
$browserXhr.flush();
expect(log).toEqual(
'{code=200; response="1"}' +
'{code=299; response="2"}');
});
it('should handle exceptions in callback', function(){
$browserXhr.expectGET('/reqGET').respond('first');
$xhr('GET', '/reqGET', null, function(){ throw "MyException"; });
$browserXhr.flush();
expect($log.error.logs.shift()).toContain('MyException');
});
it('should automatically deserialize json objects', function() {
var response;
$browserXhr.expectGET('/foo').respond('{"foo":"bar","baz":23}');
$xhr('GET', '/foo', function(code, resp) {
response = resp;
});
$browserXhr.flush();
expect(response).toEqual({foo:'bar', baz:23});
});
it('should automatically deserialize json arrays', function() {
var response;
$browserXhr.expectGET('/foo').respond('[1, "abc", {"foo":"bar"}]');
$xhr('GET', '/foo', function(code, resp) {
response = resp;
});
$browserXhr.flush();
expect(response).toEqual([1, 'abc', {foo:'bar'}]);
});
it('should automatically deserialize json with security prefix', function() {
var response;
$browserXhr.expectGET('/foo').respond(')]}\',\n[1, "abc", {"foo":"bar"}]');
$xhr('GET', '/foo', function(code, resp) {
response = resp;
});
$browserXhr.flush();
expect(response).toEqual([1, 'abc', {foo:'bar'}]);
});
it('should call $xhr.error on error if no error callback provided', function() {
var successSpy = jasmine.createSpy('success');
$browserXhr.expectGET('/url').respond(500, 'error');
$xhr('GET', '/url', null, successSpy);
$browserXhr.flush();
expect(successSpy).not.toHaveBeenCalled();
expect($xhrErr).toHaveBeenCalledWith(
{method: 'GET', url: '/url', data: null, success: successSpy},
{status: 500, body: 'error'}
);
});
it('should call the error callback on error if provided', function() {
var errorSpy = jasmine.createSpy('error'),
successSpy = jasmine.createSpy('success');
$browserXhr.expectGET('/url').respond(500, 'error');
$xhr('GET', '/url', null, successSpy, errorSpy);
$browserXhr.flush();
expect(errorSpy).toHaveBeenCalledWith(500, 'error');
expect(successSpy).not.toHaveBeenCalled();
errorSpy.reset();
$xhr('GET', '/url', successSpy, errorSpy);
$browserXhr.flush();
expect(errorSpy).toHaveBeenCalledWith(500, 'error');
expect(successSpy).not.toHaveBeenCalled();
});
describe('http headers', function() {
describe('default headers', function() {
it('should set default headers for GET request', function(){
var callback = jasmine.createSpy('callback');
$browserXhr.expectGET('URL', '', {'Accept': 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest'}).
respond(234, 'OK');
$xhr('GET', 'URL', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
});
it('should set default headers for POST request', function(){
var callback = jasmine.createSpy('callback');
$browserXhr.expectPOST('URL', 'xx', {'Accept': 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded'}).
respond(200, 'OK');
$xhr('POST', 'URL', 'xx', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
});
it('should set default headers for custom HTTP method', function(){
var callback = jasmine.createSpy('callback');
$browserXhr.expect('FOO', 'URL', '', {'Accept': 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest'}).
respond(200, 'OK');
$xhr('FOO', 'URL', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
});
describe('custom headers', function() {
it('should allow appending a new header to the common defaults', function() {
var callback = jasmine.createSpy('callback');
$browserXhr.expectGET('URL', '', {'Accept': 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest',
'Custom-Header': 'value'}).
respond(200, 'OK');
$xhr.defaults.headers.common['Custom-Header'] = 'value';
$xhr('GET', 'URL', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
callback.reset();
$browserXhr.expectPOST('URL', 'xx', {'Accept': 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded',
'Custom-Header': 'value'}).
respond(200, 'OK');
$xhr('POST', 'URL', 'xx', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
});
it('should allow appending a new header to a method specific defaults', function() {
var callback = jasmine.createSpy('callback');
$browserXhr.expectGET('URL', '', {'Accept': 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'}).
respond(200, 'OK');
$xhr.defaults.headers.get['Content-Type'] = 'application/json';
$xhr('GET', 'URL', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
callback.reset();
$browserXhr.expectPOST('URL', 'x', {'Accept': 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded'}).
respond(200, 'OK');
$xhr('POST', 'URL', 'x', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
});
it('should support overwriting and deleting default headers', function() {
var callback = jasmine.createSpy('callback');
$browserXhr.expectGET('URL', '', {'Accept': 'application/json, text/plain, */*'}).
respond(200, 'OK');
//delete a default header
delete $xhr.defaults.headers.common['X-Requested-With'];
$xhr('GET', 'URL', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
callback.reset();
$browserXhr.expectPOST('URL', 'xx', {'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'}).
respond(200, 'OK');
//overwrite a default header
$xhr.defaults.headers.post['Content-Type'] = 'application/json';
$xhr('POST', 'URL', 'xx', callback);
$browserXhr.flush();
expect(callback).toHaveBeenCalled();
});
});
});
});
describe('xsrf', function(){
it('should copy the XSRF cookie into a XSRF Header', function(){
var code, response;
$browserXhr
.expectPOST('URL', 'DATA', {'X-XSRF-TOKEN': 'secret'})
.respond(234, 'OK');
$browser.cookies('XSRF-TOKEN', 'secret');
$xhr('POST', 'URL', 'DATA', function(c, r){
code = c;
response = r;
});
$browserXhr.flush();
expect(code).toEqual(234);
expect(response).toEqual('OK');
});
});
});