From 5f0ffa758f6bdabe8d6fcfe56a605baa97052b09 Mon Sep 17 00:00:00 2001 From: Kumar McMillan Date: Thu, 3 Mar 2011 13:30:54 -0600 Subject: [PATCH] Upgraded mockjax to latest plus a patch (awaiting pull) for inspecting headers --- media/js/zamboni/jquery.mockjax.js | 153 ++++++++++++++++++++--------- 1 file changed, 108 insertions(+), 45 deletions(-) diff --git a/media/js/zamboni/jquery.mockjax.js b/media/js/zamboni/jquery.mockjax.js index 818251d67f..4db0c3bef8 100644 --- a/media/js/zamboni/jquery.mockjax.js +++ b/media/js/zamboni/jquery.mockjax.js @@ -1,8 +1,8 @@ /*! * MockJax - jQuery Plugin to Mock Ajax requests * - * Version: 1.3.2 - * Released: 2010-10-07 + * Version: 1.4.0 + * Released: 2011-02-04 * Source: http://github.com/appendto/jquery-mockjax * Docs: http://enterprisejquery.com/2010/07/mock-your-ajax-requests-with-mockjax-for-rapid-development * Plugin: mockjax @@ -16,7 +16,36 @@ (function($) { var _ajax = $.ajax, mockHandlers = []; - + + function parseXML(xml) { + if ( window['DOMParser'] == undefined && window.ActiveXObject ) { + DOMParser = function() { }; + DOMParser.prototype.parseFromString = function( xmlString ) { + var doc = new ActiveXObject('Microsoft.XMLDOM'); + doc.async = 'false'; + doc.loadXML( xmlString ); + return doc; + }; + } + + try { + var xmlDoc = ( new DOMParser() ).parseFromString( xml, 'text/xml' ); + if ( $.isXMLDoc( xmlDoc ) ) { + var err = $('parsererror', xmlDoc); + if ( err.length == 1 ) { + throw('Error: ' + $(xmlDoc).text() ); + } + } else { + throw('Unable to parse XML'); + } + } catch( e ) { + var msg = ( e.name == undefined ? e : e.name + ': ' + e.message ); + $(document).trigger('xmlParseError', [ msg ]); + return undefined; + } + return xmlDoc; + } + $.extend({ ajax: function(origSettings) { var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings), @@ -94,11 +123,16 @@ } } if ( m ) { - if ( typeof console !== 'undefined' && console.log ) { - console.log('MOCK GET: ' + s.url); - } mock = true; + + // Handle console logging + var c = $.extend({}, $.mockjaxSettings, m); + if ( c.log && $.isFunction(c.log) ) { + c.log('MOCK ' + s.type.toUpperCase() + ': ' + s.url, $.extend({}, s)); + } + var jsre = /=\?(&|$)/, jsc = (new Date()).getTime(); + // Handle JSONP Parameter Callbacks, we need to replicate some of the jQuery core here // because there isn't an easy hook for the cross domain script tag of jsonp if ( s.dataType === "jsonp" ) { @@ -113,7 +147,6 @@ } // Build temporary JSONP function - var jsre = /=\?(&|$)/; if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) { jsonp = s.jsonpCallback || ("jsonp" + jsc++); @@ -188,59 +221,74 @@ (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args); } - //if ( m.response && $.isFunction(m.response) ) { - // m.response(); - //} else { + if ( m.response && $.isFunction(m.response) ) { + m.response(origSettings); + } else { $.globalEval(m.responseText); - //} + } success(); complete(); return false; } - _ajax.call($, $.extend(true, {}, origSettings, { + mock = _ajax.call($, $.extend(true, {}, origSettings, { // Mock the XHR object xhr: function() { // Extend with our default mockjax settings m = $.extend({}, $.mockjaxSettings, m); + + if (typeof m.headers === 'undefined') { + m.headers = {}; + } + if ( m.contentType ) { + m.headers['content-type'] = m.contentType; + } + // Return our mock xhr object return { status: m.status, readyState: 1, open: function() { }, send: function() { - var process = $.proxy(function() { - // The request has returned - this.status = m.status; - this.readyState = 4; + // This is a substitute for < 1.4 which lacks $.proxy + var process = (function(that) { + return function() { + return (function() { + // The request has returned + this.status = m.status; + this.readyState = 4; - // We have an executable function, call it to give - // the mock a chance to update it's data - if ( $.isFunction(m.response) ) { - m.response(origSettings); - } - // Copy over our mock to our xhr object before passing control back to - // jQuery's onreadystatechange callback - if ( s.dataType == 'json' && ( typeof m.responseText == 'object' ) ) { - this.responseText = JSON.stringify(m.responseText); - } else if ( s.dataType == 'xml' ) { - if ( $.xmlDOM && typeof m.responseXML == 'string' ) { - // Parse the XML from a string into a DOM - this.responseXML = $.xmlDOM( m.responseXML )[0]; - } else { - this.responseXML = m.responseXML; - } - } else { - this.responseText = m.responseText; - } - this.onreadystatechange( m.isTimeout ? 'timeout' : undefined ); - }, this); - + // We have an executable function, call it to give + // the mock handler a chance to update it's data + if ( $.isFunction(m.response) ) { + m.response(origSettings); + } + // Copy over our mock to our xhr object before passing control back to + // jQuery's onreadystatechange callback + if ( s.dataType == 'json' && ( typeof m.responseText == 'object' ) ) { + this.responseText = JSON.stringify(m.responseText); + } else if ( s.dataType == 'xml' ) { + if ( typeof m.responseXML == 'string' ) { + this.responseXML = parseXML(m.responseXML); + } else { + this.responseXML = m.responseXML; + } + } else { + this.responseText = m.responseText; + } + // jQuery < 1.4 doesn't have onreadystate change for xhr + if ( $.isFunction(this.onreadystatechange) ) { + this.onreadystatechange( m.isTimeout ? 'timeout' : undefined ); + } + }).apply(that); + }; + })(this); + if ( m.proxy ) { // We're proxying this request and loading in an external file instead _ajax({ global: false, url: m.proxy, - type: m.type, + type: m.proxyType, data: m.data, dataType: s.dataType, complete: function(xhr, txt) { @@ -262,19 +310,28 @@ abort: function() { clearTimeout(this.responseTimer); }, - setRequestHeader: function() { }, + setRequestHeader: function(header, value) { + m.headers[header] = value; + }, getResponseHeader: function(header) { // 'Last-modified', 'Etag', 'content-type' are all checked by jQuery if ( m.headers && m.headers[header] ) { // Return arbitrary headers return m.headers[header]; - } else if ( header == 'Last-modified' ) { + } else if ( header.toLowerCase() == 'last-modified' ) { return m.lastModified || (new Date()).toString(); - } else if ( header == 'Etag' ) { + } else if ( header.toLowerCase() == 'etag' ) { return m.etag || ''; - } else if ( header == 'content-type' ) { + } else if ( header.toLowerCase() == 'content-type' ) { return m.contentType || 'text/plain'; } + }, + getAllResponseHeaders: function() { + var headers = ''; + $.each(m.headers, function(k, v) { + headers += k + ': ' + v + "\n"; + }); + return headers; } }; } @@ -285,6 +342,8 @@ // We don't have a mock request, trigger a normal request if ( !mock ) { return _ajax.apply($, arguments); + } else { + return mock; } } }); @@ -292,6 +351,9 @@ $.mockjaxSettings = { //url: null, //type: 'GET', + log: function(msg) { + window['console'] && window.console.log && window.console.log(msg); + }, status: 200, responseTime: 500, isTimeout: false, @@ -300,9 +362,10 @@ responseText: '', responseXML: '', proxy: '', + proxyType: 'GET', - lastModified: null, - etag: '', + lastModified: null, + etag: '', headers: { etag: 'IJF@H#@923uf8023hFO@I#H#', 'content-type' : 'text/plain'