forked from mirrors/gecko-dev
		
	# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35951 --HG-- extra : source : 62f3501af4bc1c0bd1ee1977a28aee04706a6663
		
			
				
	
	
		
			366 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			366 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Any copyright is dedicated to the Public Domain.
 | 
						|
   http://creativecommons.org/publicdomain/zero/1.0/ */
 | 
						|
 | 
						|
Cu.importGlobalProperties(["fetch"]);
 | 
						|
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
 | 
						|
 | 
						|
const BinaryInputStream = Components.Constructor(
 | 
						|
  "@mozilla.org/binaryinputstream;1",
 | 
						|
  "nsIBinaryInputStream",
 | 
						|
  "setInputStream"
 | 
						|
);
 | 
						|
 | 
						|
var server;
 | 
						|
 | 
						|
function getBaseUrl() {
 | 
						|
  return "http://localhost:" + server.identity.primaryPort;
 | 
						|
}
 | 
						|
 | 
						|
// a way to create some test defaults
 | 
						|
function createTestData(testPath) {
 | 
						|
  return {
 | 
						|
    testPath,
 | 
						|
    request: {
 | 
						|
      headers: {},
 | 
						|
      contentType: "application/json",
 | 
						|
    },
 | 
						|
    response: {
 | 
						|
      headers: {},
 | 
						|
      contentType: "application/json",
 | 
						|
      body: '{"Look": "Success!"}',
 | 
						|
      status: 200,
 | 
						|
      statusText: "OK",
 | 
						|
    },
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
// read body and content type information from a request
 | 
						|
function readDataFromRequest(aRequest) {
 | 
						|
  let requestData = {};
 | 
						|
  if (aRequest.method == "POST" || aRequest.method == "PUT") {
 | 
						|
    if (aRequest.bodyInputStream) {
 | 
						|
      let inputStream = new BinaryInputStream(aRequest.bodyInputStream);
 | 
						|
      let bytes = [];
 | 
						|
      let available;
 | 
						|
 | 
						|
      while ((available = inputStream.available()) > 0) {
 | 
						|
        Array.prototype.push.apply(bytes, inputStream.readByteArray(available));
 | 
						|
      }
 | 
						|
 | 
						|
      requestData.body = String.fromCharCode.apply(null, bytes);
 | 
						|
      requestData.contentType = aRequest.getHeader("Content-Type");
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return requestData;
 | 
						|
}
 | 
						|
 | 
						|
// write status information, content type information and body to a response
 | 
						|
function writeDataToResponse(aData, aResponse) {
 | 
						|
  aResponse.setStatusLine(null, aData.status, aData.statusText);
 | 
						|
  aResponse.setHeader("Content-Type", aData.contentType);
 | 
						|
  for (let header in aData.headers) {
 | 
						|
    aResponse.setHeader(header, aData.headers[header]);
 | 
						|
  }
 | 
						|
  aResponse.write(aData.body);
 | 
						|
}
 | 
						|
 | 
						|
// test some GET functionality
 | 
						|
add_test(function test_GetData() {
 | 
						|
  do_test_pending();
 | 
						|
 | 
						|
  let testData = createTestData("/getData");
 | 
						|
 | 
						|
  // set up some headers to test
 | 
						|
  let headerNames = ["x-test-header", "x-other-test-header"];
 | 
						|
  for (let headerName of headerNames) {
 | 
						|
    testData.request.headers[headerName] = "test-value-for-" + headerName;
 | 
						|
  }
 | 
						|
 | 
						|
  server.registerPathHandler(testData.testPath, function(aRequest, aResponse) {
 | 
						|
    try {
 | 
						|
      // check our request headers made it OK
 | 
						|
      for (let headerName of headerNames) {
 | 
						|
        Assert.equal(
 | 
						|
          testData.request.headers[headerName],
 | 
						|
          aRequest.getHeader(headerName)
 | 
						|
        );
 | 
						|
      }
 | 
						|
 | 
						|
      // send a response
 | 
						|
      writeDataToResponse(testData.response, aResponse);
 | 
						|
    } catch (e) {
 | 
						|
      do_report_unexpected_exception(e);
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // fetch, via GET, with some request headers set
 | 
						|
  fetch(getBaseUrl() + testData.testPath, { headers: testData.request.headers })
 | 
						|
    .then(function(response) {
 | 
						|
      // check response looks as expected
 | 
						|
      Assert.ok(response.ok);
 | 
						|
      Assert.equal(response.status, testData.response.status);
 | 
						|
      Assert.equal(response.statusText, testData.response.statusText);
 | 
						|
 | 
						|
      // check a response header looks OK:
 | 
						|
      Assert.equal(
 | 
						|
        response.headers.get("Content-Type"),
 | 
						|
        testData.response.contentType
 | 
						|
      );
 | 
						|
 | 
						|
      // ... and again to check header names are case insensitive
 | 
						|
      Assert.equal(
 | 
						|
        response.headers.get("content-type"),
 | 
						|
        testData.response.contentType
 | 
						|
      );
 | 
						|
 | 
						|
      // ensure response.text() returns a promise that resolves appropriately
 | 
						|
      response.text().then(function(text) {
 | 
						|
        Assert.equal(text, testData.response.body);
 | 
						|
        do_test_finished();
 | 
						|
        run_next_test();
 | 
						|
      });
 | 
						|
    })
 | 
						|
    .catch(function(e) {
 | 
						|
      do_report_unexpected_exception(e);
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    });
 | 
						|
});
 | 
						|
 | 
						|
// test a GET with no init
 | 
						|
add_test(function test_GetDataNoInit() {
 | 
						|
  do_test_pending();
 | 
						|
 | 
						|
  let testData = createTestData("/getData");
 | 
						|
 | 
						|
  server.registerPathHandler(testData.testPath, function(aRequest, aResponse) {
 | 
						|
    try {
 | 
						|
      // send a response
 | 
						|
      writeDataToResponse(testData.response, aResponse);
 | 
						|
    } catch (e) {
 | 
						|
      do_report_unexpected_exception(e);
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  fetch(getBaseUrl() + testData.testPath, { headers: testData.request.headers })
 | 
						|
    .then(function(response) {
 | 
						|
      // check response looks as expected
 | 
						|
      Assert.ok(response.ok);
 | 
						|
      Assert.equal(response.status, testData.response.status);
 | 
						|
 | 
						|
      // ensure response.text() returns a promise that resolves appropriately
 | 
						|
      response.text().then(function(text) {
 | 
						|
        Assert.equal(text, testData.response.body);
 | 
						|
        do_test_finished();
 | 
						|
        run_next_test();
 | 
						|
      });
 | 
						|
    })
 | 
						|
    .catch(function(e) {
 | 
						|
      do_report_unexpected_exception(e);
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    });
 | 
						|
});
 | 
						|
 | 
						|
// test some error responses
 | 
						|
add_test(function test_get40x() {
 | 
						|
  do_test_pending();
 | 
						|
 | 
						|
  // prepare a response with some 40x error - a 404 will do
 | 
						|
  let notFoundData = createTestData("/getNotFound");
 | 
						|
  notFoundData.response.status = 404;
 | 
						|
  notFoundData.response.statusText = "Not found";
 | 
						|
  notFoundData.response.body = null;
 | 
						|
 | 
						|
  // No need to register a path handler - httpd will return 404 anyway.
 | 
						|
  // Fetch, via GET, the resource that doesn't exist
 | 
						|
  fetch(getBaseUrl() + notFoundData.testPath).then(function(response) {
 | 
						|
    Assert.equal(response.status, 404);
 | 
						|
    do_test_finished();
 | 
						|
    run_next_test();
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
add_test(function test_get50x() {
 | 
						|
  do_test_pending();
 | 
						|
 | 
						|
  // prepare a response with some server error - a 500 will do
 | 
						|
  let serverErrorData = createTestData("/serverError");
 | 
						|
  serverErrorData.response.status = 500;
 | 
						|
  serverErrorData.response.statusText = "The server broke";
 | 
						|
  serverErrorData.response.body = null;
 | 
						|
 | 
						|
  server.registerPathHandler(serverErrorData.testPath, function(
 | 
						|
    aRequest,
 | 
						|
    aResponse
 | 
						|
  ) {
 | 
						|
    try {
 | 
						|
      // send the error response
 | 
						|
      writeDataToResponse(serverErrorData.response, aResponse);
 | 
						|
    } catch (e) {
 | 
						|
      do_report_unexpected_exception(e);
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // fetch, via GET, the resource that creates a server error
 | 
						|
  fetch(getBaseUrl() + serverErrorData.testPath).then(function(response) {
 | 
						|
    Assert.equal(response.status, 500);
 | 
						|
    do_test_finished();
 | 
						|
    run_next_test();
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
// test a failure to connect
 | 
						|
add_test(function test_getTestFailedConnect() {
 | 
						|
  do_test_pending();
 | 
						|
  // try a server that's not there
 | 
						|
  fetch("http://localhost:4/should/fail")
 | 
						|
    .then(response => {
 | 
						|
      do_throw("Request should not succeed");
 | 
						|
    })
 | 
						|
    .catch(err => {
 | 
						|
      Assert.equal(true, err instanceof TypeError);
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    });
 | 
						|
});
 | 
						|
 | 
						|
add_test(function test_mozError() {
 | 
						|
  do_test_pending();
 | 
						|
  // try a server that's not there
 | 
						|
  fetch("http://localhost:4/should/fail", { mozErrors: true })
 | 
						|
    .then(response => {
 | 
						|
      do_throw("Request should not succeed");
 | 
						|
    })
 | 
						|
    .catch(err => {
 | 
						|
      Assert.equal(err.result, Cr.NS_ERROR_CONNECTION_REFUSED);
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    });
 | 
						|
});
 | 
						|
 | 
						|
add_test(function test_request_mozError() {
 | 
						|
  do_test_pending();
 | 
						|
  // try a server that's not there
 | 
						|
  const r = new Request("http://localhost:4/should/fail", { mozErrors: true });
 | 
						|
  fetch(r)
 | 
						|
    .then(response => {
 | 
						|
      do_throw("Request should not succeed");
 | 
						|
    })
 | 
						|
    .catch(err => {
 | 
						|
      Assert.equal(err.result, Cr.NS_ERROR_CONNECTION_REFUSED);
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    });
 | 
						|
});
 | 
						|
 | 
						|
// test POSTing some JSON data
 | 
						|
add_test(function test_PostJSONData() {
 | 
						|
  do_test_pending();
 | 
						|
 | 
						|
  let testData = createTestData("/postJSONData");
 | 
						|
  testData.request.body = '{"foo": "bar"}';
 | 
						|
 | 
						|
  server.registerPathHandler(testData.testPath, function(aRequest, aResponse) {
 | 
						|
    try {
 | 
						|
      let requestData = readDataFromRequest(aRequest);
 | 
						|
 | 
						|
      // Check the request body is OK
 | 
						|
      Assert.equal(requestData.body, testData.request.body);
 | 
						|
 | 
						|
      // Check the content type is as expected
 | 
						|
      Assert.equal(requestData.contentType, testData.request.contentType);
 | 
						|
 | 
						|
      writeDataToResponse(testData.response, aResponse);
 | 
						|
    } catch (e) {
 | 
						|
      Assert.ok(false);
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  fetch(getBaseUrl() + testData.testPath, {
 | 
						|
    method: "POST",
 | 
						|
    body: testData.request.body,
 | 
						|
    headers: {
 | 
						|
      "Content-Type": "application/json",
 | 
						|
    },
 | 
						|
  })
 | 
						|
    .then(function(aResponse) {
 | 
						|
      Assert.ok(aResponse.ok);
 | 
						|
      Assert.equal(aResponse.status, testData.response.status);
 | 
						|
      Assert.equal(aResponse.statusText, testData.response.statusText);
 | 
						|
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    })
 | 
						|
    .catch(function(e) {
 | 
						|
      do_report_unexpected_exception(e);
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    });
 | 
						|
});
 | 
						|
 | 
						|
// test POSTing some text
 | 
						|
add_test(function test_PostTextData() {
 | 
						|
  do_test_pending();
 | 
						|
 | 
						|
  let testData = createTestData("/postTextData");
 | 
						|
  testData.request.body = "A plain text body";
 | 
						|
  testData.request.contentType = "text/plain";
 | 
						|
  let responseHeaderName = "some-response-header";
 | 
						|
  testData.response.headers[responseHeaderName] = "some header value";
 | 
						|
 | 
						|
  server.registerPathHandler(testData.testPath, function(aRequest, aResponse) {
 | 
						|
    try {
 | 
						|
      let requestData = readDataFromRequest(aRequest);
 | 
						|
 | 
						|
      // Check the request body is OK
 | 
						|
      Assert.equal(requestData.body, testData.request.body);
 | 
						|
 | 
						|
      // Check the content type is as expected
 | 
						|
      Assert.equal(requestData.contentType, testData.request.contentType);
 | 
						|
 | 
						|
      writeDataToResponse(testData.response, aResponse);
 | 
						|
    } catch (e) {
 | 
						|
      Assert.ok(false);
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  fetch(getBaseUrl() + testData.testPath, {
 | 
						|
    method: "POST",
 | 
						|
    body: testData.request.body,
 | 
						|
    headers: {
 | 
						|
      "Content-Type": testData.request.contentType,
 | 
						|
    },
 | 
						|
  })
 | 
						|
    .then(function(aResponse) {
 | 
						|
      Assert.ok(aResponse.ok);
 | 
						|
      Assert.equal(aResponse.status, testData.response.status);
 | 
						|
      Assert.equal(aResponse.statusText, testData.response.statusText);
 | 
						|
 | 
						|
      // check the response header is set OK
 | 
						|
      Assert.equal(
 | 
						|
        aResponse.headers.get(responseHeaderName),
 | 
						|
        testData.response.headers[responseHeaderName]
 | 
						|
      );
 | 
						|
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    })
 | 
						|
    .catch(function(e) {
 | 
						|
      do_report_unexpected_exception(e);
 | 
						|
      do_test_finished();
 | 
						|
      run_next_test();
 | 
						|
    });
 | 
						|
});
 | 
						|
 | 
						|
function run_test() {
 | 
						|
  // Set up an HTTP Server
 | 
						|
  server = new HttpServer();
 | 
						|
  server.start(-1);
 | 
						|
 | 
						|
  run_next_test();
 | 
						|
 | 
						|
  registerCleanupFunction(function() {
 | 
						|
    server.stop(function() {});
 | 
						|
  });
 | 
						|
}
 |