Search code examples
javascriptnode.jsdojodoh

XMLHTTP not available in D.O.H


My D.O.H framework is run by nodejs. (version is 1.10)

I know that nodejs should use xmlhttprequest or other module to complete XHR request. In my case, I am not goona use nodejs XHR directly, but use dojo's xhr instead. Apparently, dojo's xhr is not able to run by nodejs. Because nodejs should not able to run XHR without npm module.

Is that any possibility to solve this problem?

command:

node unittest.js load=doh test=test_custom_ajax.js

unittest.js:

global.dojoConfig = {
  baseUrl: ".",
  packages: [
    { name: "dojo", location: "./dojo" },
    { name: "dojox", location: "./dojox" },
    { name: "dijit", location: "./dijit" },
    { name: "my", location: "./my" }
  ]
}
require("./dojo/dojo.js");

custom_ajax.js:

define([
  "dojo",
  "dojo/_base/declare",
  "dojo/_base/lang",
  "dojo/request/xhr"
], function(dojo, declare, lang, xhr) {

  return declare("my.custom_ajax", null, {

    ajaxGet: function(url, options) {
      options = options || {};

      return xhr(url, {
        method: "GET",
        handleAs: "json",
        headers: {
          "Content-Type":"application/json",
          "Accept":"application/json"
        },
      }).then(
        lang.hitch(this, function(data) { 
            /* handle data */
            if (options.onHandle) {options.onHandle(resp)}
            if (options.onLoad) {options.onLoad(resp)}
            if (options.onComplete) {options.onComplete(resp)}
        }),
        lang.hitch(this, function(err) {
            /* handle error */
            if (options.onError) {options.onError(resp)}
        })
      );
    }
  });
});

test_custom_ajax.js:

define([
  "doh/runner",
  "my/custom_ajax"
], function(doh, custom_ajax) {
  doh.register("test_custom_ajax", [{
    var ca = new custom_ajax();
    var options = {};
    ca.ajaxGet('some_url', options);
  }]);
}

result:

Error: XMLHTTP not available

Solution

  • Here is final solution: stub xhr before load Ajax

    test_custom_ajax.js

    define([
      "doh/runner",
      "dojo/node!sinon",
      "dojo/request/xhr",
      "dojo/Deferred"
    ], function(doh, sinon, xhr, Deferred) {
    
      doh.register("test_custom_ajax",[{
    
    /*--------------------------------------------------
                  stub xhr before load Ajax
    --------------------------------------------------*/
        // original xhr -> custom xhr
        var oldXhr = require.modules["dojo/request/xhr"]["result"];
        var getDeferred;
          require.modules["dojo/request/xhr"]["result"] = function(url, options) {
            if (options.method === 'GET') {
              getDeferred = new Deferred();
              return getDeferred;
            }
          };
          var Ajax;
          require(["my/custom_ajax"], function(custom_ajax) {
            Ajax = custom_ajax;
            // custom xhr -> original xhr 
            require.modules["dojo/request/xhr"]["result"] = oldXhr;
          });
    
          // prepare stub
          var onHandleStub = sinon.stub();
          var onLoadStub = sinon.stub();
          var onCompleteStub = sinon.stub();
          var onErrorStub = sinon.stub();
    
    /*------------------------------------------------*/
    
          // Inside this new Ajax, xhr is customized
          var ca = new Ajax();
    
          // Normal AjaxGet
          ca.ajaxGet('some_url', {
            onHandle: onHandleStub,
            onLoad: onLoadStub,
            onComplete: onCompleteStub
          });
          getDeferred.resolve(); //control xhr
          /* assert stub */
    
          // Error AjaxGet
          ca.ajaxGet('some_url', {
            onError: onErrorStub,
          });
          getDeferred.reject(); //control xhr
          /* assert stub */
        }]
      );
    }