blob: c72005c710b6ae226b44fbea25de09a1a2c5dc9c [file] [log] [blame]
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.testing.net.XhrIoTest');
goog.setTestOnly('goog.testing.net.XhrIoTest');
goog.require('goog.dom.xml');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.net.ErrorCode');
goog.require('goog.net.EventType');
goog.require('goog.net.XmlHttp');
goog.require('goog.object');
goog.require('goog.testing.MockControl');
goog.require('goog.testing.asserts');
goog.require('goog.testing.jsunit');
goog.require('goog.testing.mockmatchers.InstanceOf');
goog.require('goog.testing.net.XhrIo');
var mockControl;
function setUp() {
mockControl = new goog.testing.MockControl();
}
function testStaticSend() {
sendInstances = goog.testing.net.XhrIo.getSendInstances();
var returnedXhr = goog.testing.net.XhrIo.send('url');
assertEquals('sendInstances_ after send',
1, sendInstances.length);
xhr = sendInstances[sendInstances.length - 1];
assertTrue('isActive after request', xhr.isActive());
assertEquals(returnedXhr, xhr);
assertEquals('readyState after request',
goog.net.XmlHttp.ReadyState.LOADING,
xhr.getReadyState());
xhr.simulateResponse(200, '');
assertFalse('isActive after response', xhr.isActive());
assertEquals('readyState after response',
goog.net.XmlHttp.ReadyState.COMPLETE,
xhr.getReadyState());
xhr.simulateReady();
assertEquals('sendInstances_ after READY',
0, sendInstances.length);
}
function testStaticSendWithException() {
goog.testing.net.XhrIo.send('url', function() {
if (!this.isSuccess()) {
throw Error('The xhr did not complete successfully!');
}
});
var sendInstances = goog.testing.net.XhrIo.getSendInstances();
var xhr = sendInstances[sendInstances.length - 1];
try {
xhr.simulateResponse(400, '');
} catch (e) {
// Do nothing with the exception; we just want to make sure
// the class cleans itself up properly when an exception is
// thrown.
}
assertEquals('Send instance array not cleaned up properly!',
0, sendInstances.length);
}
function testMultipleSend() {
var xhr = new goog.testing.net.XhrIo();
assertFalse('isActive before first request', xhr.isActive());
assertEquals('readyState before first request',
goog.net.XmlHttp.ReadyState.UNINITIALIZED,
xhr.getReadyState());
xhr.send('url');
assertTrue('isActive after first request', xhr.isActive());
assertEquals('readyState after first request',
goog.net.XmlHttp.ReadyState.LOADING,
xhr.getReadyState());
xhr.simulateResponse(200, '');
assertFalse('isActive after first response', xhr.isActive());
assertEquals('readyState after first response',
goog.net.XmlHttp.ReadyState.COMPLETE,
xhr.getReadyState());
xhr.send('url');
assertTrue('isActive after second request', xhr.isActive());
assertEquals('readyState after second request',
goog.net.XmlHttp.ReadyState.LOADING,
xhr.getReadyState());
}
function testGetLastUri() {
var xhr = new goog.testing.net.XhrIo();
assertEquals('nothing sent yet, empty URI', '', xhr.getLastUri());
var requestUrl = 'http://www.example.com/';
xhr.send(requestUrl);
assertEquals('message sent, URI saved', requestUrl, xhr.getLastUri());
}
function testGetLastMethod() {
var xhr = new goog.testing.net.XhrIo();
assertUndefined('nothing sent yet, empty method', xhr.getLastMethod());
var method = 'POKE';
xhr.send('http://www.example.com/', method);
assertEquals('message sent, method saved', method, xhr.getLastMethod());
xhr.simulateResponse(200, '');
xhr.send('http://www.example.com/');
assertEquals('message sent, method saved', 'GET', xhr.getLastMethod());
}
function testGetLastContent() {
var xhr = new goog.testing.net.XhrIo();
assertUndefined('nothing sent yet, empty content', xhr.getLastContent());
var postContent = 'var=value&var2=value2';
xhr.send('http://www.example.com/', undefined, postContent);
assertEquals('POST message sent, content saved',
postContent, xhr.getLastContent());
xhr.simulateResponse(200, '');
xhr.send('http://www.example.com/');
assertUndefined('GET message sent, content cleaned', xhr.getLastContent());
}
function testGetLastRequestHeaders() {
var xhr = new goog.testing.net.XhrIo();
assertUndefined('nothing sent yet, empty headers',
xhr.getLastRequestHeaders());
xhr.send('http://www.example.com/', undefined, undefined,
{'From': 'page@google.com'});
assertObjectEquals('Request sent with extra headers, headers saved',
{'From': 'page@google.com'},
xhr.getLastRequestHeaders());
xhr.simulateResponse(200, '');
xhr.send('http://www.example.com');
assertUndefined('New request sent without extra headers',
xhr.getLastRequestHeaders());
}
function testGetResponseText() {
// Text response came.
var called = false;
var xhr = new goog.testing.net.XhrIo();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
called = true;
assertEquals('text', e.target.getResponseText());
});
xhr.simulateResponse(200, 'text');
assertTrue(called);
// XML response came.
var called = false;
var xhr = new goog.testing.net.XhrIo();
var xml = goog.dom.xml.createDocument();
xml.appendChild(xml.createElement('root'));
goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
called = true;
var text = e.target.getResponseText();
assertTrue(/<root ?\/>/.test(text));
});
xhr.simulateResponse(200, xml);
assertTrue(called);
}
function testGetResponseJson() {
// Valid JSON response came.
var called = false;
var xhr = new goog.testing.net.XhrIo();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
called = true;
assertArrayEquals([0, 1], e.target.getResponseJson());
});
xhr.simulateResponse(200, '[0, 1]');
assertTrue(called);
// Valid JSON response with XSSI prefix encoded came.
var called = false;
var xhr = new goog.testing.net.XhrIo();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
called = true;
assertArrayEquals([0, 1], e.target.getResponseJson(')]}\', \n'));
});
xhr.simulateResponse(200, ')]}\', \n[0, 1]');
assertTrue(called);
// Invalid JSON response came.
var called = false;
var xhr = new goog.testing.net.XhrIo();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
called = true;
assertThrows(e.target.getResponseJson);
});
xhr.simulateResponse(200, '[0, 1');
assertTrue(called);
// XML response came.
var called = false;
var xhr = new goog.testing.net.XhrIo();
var xml = goog.dom.xml.createDocument();
xml.appendChild(xml.createElement('root'));
goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
called = true;
assertThrows(e.target.getResponseJson);
});
xhr.simulateResponse(200, xml);
assertTrue(called);
}
function testGetResponseXml() {
// Text response came.
var called = false;
var xhr = new goog.testing.net.XhrIo();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
called = true;
assertNull(e.target.getResponseXml());
});
xhr.simulateResponse(200, 'text');
assertTrue(called);
// XML response came.
var called = false;
var xhr = new goog.testing.net.XhrIo();
var xml = goog.dom.xml.createDocument();
xml.appendChild(xml.createElement('root'));
goog.events.listen(xhr, goog.net.EventType.SUCCESS, function(e) {
called = true;
assertEquals(xml, e.target.getResponseXml());
});
xhr.simulateResponse(200, xml);
assertTrue(called);
}
function testGetResponseHeaders_noHeadersPresent() {
var xhr = new goog.testing.net.XhrIo();
var mockListener = mockControl.createFunctionMock();
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
assertTrue(e.type == goog.net.EventType.SUCCESS);
assertUndefined(e.target.getResponseHeader('XHR'));
});
mockControl.$replayAll();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, mockListener);
xhr.simulateResponse(200, '');
mockControl.$verifyAll();
mockControl.$resetAll();
}
function testGetResponseHeaders_headersPresent() {
var xhr = new goog.testing.net.XhrIo();
var mockListener = mockControl.createFunctionMock();
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
assertTrue(e.type == goog.net.EventType.SUCCESS);
assertUndefined(e.target.getResponseHeader('XHR'));
assertEquals(e.target.getResponseHeader('Pragma'), 'no-cache');
});
mockControl.$replayAll();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, mockListener);
xhr.simulateResponse(200, '', {'Pragma': 'no-cache'});
mockControl.$verifyAll();
mockControl.$resetAll();
}
function testAbort_WhenNoPendingSentRequests() {
var xhr = new goog.testing.net.XhrIo();
var eventListener = mockControl.createFunctionMock();
mockControl.$replayAll();
goog.events.listen(xhr, goog.net.EventType.COMPLETE, eventListener);
goog.events.listen(xhr, goog.net.EventType.SUCCESS, eventListener);
goog.events.listen(xhr, goog.net.EventType.ABORT, eventListener);
goog.events.listen(xhr, goog.net.EventType.ERROR, eventListener);
goog.events.listen(xhr, goog.net.EventType.READY, eventListener);
xhr.abort();
mockControl.$verifyAll();
mockControl.$resetAll();
}
function testAbort_PendingSentRequest() {
var xhr = new goog.testing.net.XhrIo();
var mockListener = mockControl.createFunctionMock();
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
assertTrue(e.type == goog.net.EventType.COMPLETE);
assertObjectEquals(e.target, xhr);
assertEquals(e.target.getLastErrorCode(), goog.net.ErrorCode.ABORT);
assertTrue(e.target.isActive());
});
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
assertTrue(e.type == goog.net.EventType.ABORT);
assertObjectEquals(e.target, xhr);
assertTrue(e.target.isActive());
});
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
assertTrue(e.type == goog.net.EventType.READY);
assertObjectEquals(e.target, xhr);
assertFalse(e.target.isActive());
});
mockControl.$replayAll();
goog.events.listen(xhr, goog.net.EventType.COMPLETE, mockListener);
goog.events.listen(xhr, goog.net.EventType.SUCCESS, mockListener);
goog.events.listen(xhr, goog.net.EventType.ABORT, mockListener);
goog.events.listen(xhr, goog.net.EventType.ERROR, mockListener);
goog.events.listen(xhr, goog.net.EventType.READY, mockListener);
xhr.send('dummyurl');
xhr.abort();
mockControl.$verifyAll();
mockControl.$resetAll();
}
function testEvents_Success() {
var xhr = new goog.testing.net.XhrIo();
var mockListener = mockControl.createFunctionMock();
var readyState = goog.net.XmlHttp.ReadyState.UNINITIALIZED;
function readyStateListener(e) {
assertEquals(e.type, goog.net.EventType.READY_STATE_CHANGE);
assertObjectEquals(e.target, xhr);
readyState++;
assertEquals(e.target.getReadyState(), readyState);
assertTrue(e.target.isActive());
}
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
assertEquals(e.type, goog.net.EventType.COMPLETE);
assertObjectEquals(e.target, xhr);
assertEquals(e.target.getLastErrorCode(), goog.net.ErrorCode.NO_ERROR);
assertTrue(e.target.isActive());
});
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
assertEquals(e.type, goog.net.EventType.SUCCESS);
assertObjectEquals(e.target, xhr);
assertTrue(e.target.isActive());
});
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
assertEquals(e.type, goog.net.EventType.READY);
assertObjectEquals(e.target, xhr);
assertFalse(e.target.isActive());
});
mockControl.$replayAll();
goog.events.listen(xhr, goog.net.EventType.READY_STATE_CHANGE,
readyStateListener);
goog.events.listen(xhr, goog.net.EventType.COMPLETE, mockListener);
goog.events.listen(xhr, goog.net.EventType.SUCCESS, mockListener);
goog.events.listen(xhr, goog.net.EventType.ABORT, mockListener);
goog.events.listen(xhr, goog.net.EventType.ERROR, mockListener);
goog.events.listen(xhr, goog.net.EventType.READY, mockListener);
xhr.send('dummyurl');
xhr.simulateResponse(200, null);
mockControl.$verifyAll();
mockControl.$resetAll();
}
function testGetResponseHeaders() {
var xhr = new goog.testing.net.XhrIo();
var mockListener = mockControl.createFunctionMock();
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
var headers = e.target.getResponseHeaders();
assertEquals(2, goog.object.getCount(headers));
assertEquals('foo', headers['test1']);
assertEquals('bar', headers['test2']);
});
mockControl.$replayAll();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, mockListener);
// Simulate an XHR with 2 headers.
xhr.simulateResponse(200, '', {'test1': 'foo', 'test2': 'bar'});
mockControl.$verifyAll();
mockControl.$resetAll();
}
function testGetResponseHeadersWithColonInValue() {
var xhr = new goog.testing.net.XhrIo();
var mockListener = mockControl.createFunctionMock();
mockListener(new goog.testing.mockmatchers.InstanceOf(goog.events.Event))
.$does(function(e) {
var headers = e.target.getResponseHeaders();
assertEquals(1, goog.object.getCount(headers));
assertEquals('f:o:o', headers['test1']);
});
mockControl.$replayAll();
goog.events.listen(xhr, goog.net.EventType.SUCCESS, mockListener);
// Simulate an XHR with a colon in the http header value.
xhr.simulateResponse(200, '', {'test1': 'f:o:o'});
mockControl.$verifyAll();
mockControl.$resetAll();
}