summaryrefslogtreecommitdiffstats
path: root/services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js
diff options
context:
space:
mode:
Diffstat (limited to 'services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js')
-rw-r--r--services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js308
1 files changed, 308 insertions, 0 deletions
diff --git a/services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js b/services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js
new file mode 100644
index 0000000000..76134bc1e1
--- /dev/null
+++ b/services/fxaccounts/tests/xpcshell/test_oauth_grant_client.js
@@ -0,0 +1,308 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const {
+ ERRNO_INVALID_FXA_ASSERTION,
+ ERRNO_NETWORK,
+ ERRNO_PARSE,
+ ERRNO_UNKNOWN_ERROR,
+ ERROR_CODE_METHOD_NOT_ALLOWED,
+ ERROR_MSG_METHOD_NOT_ALLOWED,
+ ERROR_NETWORK,
+ ERROR_PARSE,
+ ERROR_UNKNOWN,
+} = ChromeUtils.import("resource://gre/modules/FxAccountsCommon.js");
+const {
+ FxAccountsOAuthGrantClient,
+ FxAccountsOAuthGrantClientError,
+} = ChromeUtils.import("resource://gre/modules/FxAccountsOAuthGrantClient.jsm");
+
+const CLIENT_OPTIONS = {
+ serverURL: "https://127.0.0.1:9010/v1",
+ client_id: "abc123",
+};
+
+const STATUS_SUCCESS = 200;
+
+/**
+ * Mock request responder
+ * @param {String} response
+ * Mocked raw response from the server
+ * @returns {Function}
+ */
+var mockResponse = function(response) {
+ return function() {
+ return {
+ setHeader() {},
+ async post() {
+ this.response = response;
+ return response;
+ },
+ };
+ };
+};
+
+/**
+ * Mock request error responder
+ * @param {Error} error
+ * Error object
+ * @returns {Function}
+ */
+var mockResponseError = function(error) {
+ return function() {
+ return {
+ setHeader() {},
+ async post() {
+ throw error;
+ },
+ };
+ };
+};
+
+add_test(function missingParams() {
+ let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
+ try {
+ client.getTokenFromAssertion();
+ } catch (e) {
+ Assert.equal(e.message, "Missing 'assertion' parameter");
+ }
+
+ try {
+ client.getTokenFromAssertion("assertion");
+ } catch (e) {
+ Assert.equal(e.message, "Missing 'scope' parameter");
+ }
+
+ run_next_test();
+});
+
+add_test(function successfulResponse() {
+ let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
+ let response = {
+ success: true,
+ status: STATUS_SUCCESS,
+ body: JSON.stringify({
+ access_token: "http://example.com/image.jpeg",
+ id: "0d5c1a89b8c54580b8e3e8adadae864a",
+ }),
+ };
+
+ client._Request = new mockResponse(response);
+ client.getTokenFromAssertion("assertion", "scope").then(function(result) {
+ Assert.equal(result.access_token, "http://example.com/image.jpeg");
+ run_next_test();
+ });
+});
+
+add_test(function parseErrorResponse() {
+ let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
+ let response = {
+ success: true,
+ status: STATUS_SUCCESS,
+ body: "unexpected",
+ };
+
+ client._Request = new mockResponse(response);
+ client.getTokenFromAssertion("assertion", "scope").catch(function(e) {
+ Assert.equal(e.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(e.code, STATUS_SUCCESS);
+ Assert.equal(e.errno, ERRNO_PARSE);
+ Assert.equal(e.error, ERROR_PARSE);
+ Assert.equal(e.message, "unexpected");
+ run_next_test();
+ });
+});
+
+add_task(async function serverErrorResponse() {
+ let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
+ let response = {
+ status: 400,
+ body: JSON.stringify({
+ code: 400,
+ errno: 104,
+ error: "Bad Request",
+ message: "Unauthorized",
+ reason: "Invalid fxa assertion",
+ }),
+ };
+
+ client._Request = new mockResponse(response);
+ client.getTokenFromAssertion("blah", "scope").catch(function(e) {
+ Assert.equal(e.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(e.code, 400);
+ Assert.equal(e.errno, ERRNO_INVALID_FXA_ASSERTION);
+ Assert.equal(e.error, "Bad Request");
+ Assert.equal(e.message, "Unauthorized");
+ run_next_test();
+ });
+});
+
+add_task(async function networkErrorResponse() {
+ let client = new FxAccountsOAuthGrantClient({
+ serverURL: "https://domain.dummy",
+ client_id: "abc123",
+ });
+ client.getTokenFromAssertion("assertion", "scope").catch(function(e) {
+ Assert.equal(e.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(e.code, null);
+ Assert.equal(e.errno, ERRNO_NETWORK);
+ Assert.equal(e.error, ERROR_NETWORK);
+ run_next_test();
+ });
+});
+
+add_test(function unsupportedMethod() {
+ let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
+
+ return client._createRequest("/", "PUT").catch(function(e) {
+ Assert.equal(e.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(e.code, ERROR_CODE_METHOD_NOT_ALLOWED);
+ Assert.equal(e.errno, ERRNO_NETWORK);
+ Assert.equal(e.error, ERROR_NETWORK);
+ Assert.equal(e.message, ERROR_MSG_METHOD_NOT_ALLOWED);
+ run_next_test();
+ });
+});
+
+add_test(function onCompleteRequestError() {
+ let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
+ client._Request = new mockResponseError(new Error("onComplete error"));
+ client.getTokenFromAssertion("assertion", "scope").catch(function(e) {
+ Assert.equal(e.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(e.code, null);
+ Assert.equal(e.errno, ERRNO_NETWORK);
+ Assert.equal(e.error, ERROR_NETWORK);
+ Assert.equal(e.message, "Error: onComplete error");
+ run_next_test();
+ });
+});
+
+add_test(function incorrectErrno() {
+ let client = new FxAccountsOAuthGrantClient(CLIENT_OPTIONS);
+ let response = {
+ status: 400,
+ body: JSON.stringify({
+ code: 400,
+ errno: "bad errno",
+ error: "Bad Request",
+ message: "Unauthorized",
+ reason: "Invalid fxa assertion",
+ }),
+ };
+
+ client._Request = new mockResponse(response);
+ client.getTokenFromAssertion("blah", "scope").catch(function(e) {
+ Assert.equal(e.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(e.code, 400);
+ Assert.equal(e.errno, ERRNO_UNKNOWN_ERROR);
+ Assert.equal(e.error, "Bad Request");
+ Assert.equal(e.message, "Unauthorized");
+ run_next_test();
+ });
+});
+
+add_test(function constructorTests() {
+ try {
+ Services.prefs.setCharPref(
+ "identity.fxaccounts.remote.oauth.uri",
+ "https://example.com/v1"
+ );
+ validationHelper({}, "Error: Missing 'client_id' parameter");
+ } finally {
+ Services.prefs.clearUserPref("identity.fxaccounts.remote.oauth.uri");
+ }
+
+ validationHelper(
+ { serverURL: "https://example.com" },
+ "Error: Missing 'client_id' parameter"
+ );
+
+ validationHelper(
+ { serverURL: "https://example.com" },
+ "Error: Missing 'client_id' parameter"
+ );
+
+ validationHelper(
+ { client_id: "123ABC", serverURL: "http://example.com" },
+ "Error: 'serverURL' must be HTTPS"
+ );
+
+ try {
+ Services.prefs.setBoolPref("identity.fxaccounts.allowHttp", true);
+ validationHelper(
+ { client_id: "123ABC", serverURL: "http://example.com" },
+ null
+ );
+ } finally {
+ Services.prefs.clearUserPref("identity.fxaccounts.allowHttp");
+ }
+
+ run_next_test();
+});
+
+add_test(function errorTests() {
+ let error1 = new FxAccountsOAuthGrantClientError();
+ Assert.equal(error1.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(error1.code, null);
+ Assert.equal(error1.errno, ERRNO_UNKNOWN_ERROR);
+ Assert.equal(error1.error, ERROR_UNKNOWN);
+ Assert.equal(error1.message, null);
+
+ let error2 = new FxAccountsOAuthGrantClientError({
+ code: STATUS_SUCCESS,
+ errno: 1,
+ error: "Error",
+ message: "Something",
+ });
+ let fields2 = error2._toStringFields();
+ let statusCode = 1;
+
+ Assert.equal(error2.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(error2.code, STATUS_SUCCESS);
+ Assert.equal(error2.errno, statusCode);
+ Assert.equal(error2.error, "Error");
+ Assert.equal(error2.message, "Something");
+
+ Assert.equal(fields2.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(fields2.code, STATUS_SUCCESS);
+ Assert.equal(fields2.errno, statusCode);
+ Assert.equal(fields2.error, "Error");
+ Assert.equal(fields2.message, "Something");
+
+ Assert.ok(error2.toString().includes("Something"));
+ run_next_test();
+});
+
+add_test(function networkErrorResponse() {
+ let client = new FxAccountsOAuthGrantClient({
+ serverURL: "https://domain.dummy",
+ client_id: "abc123",
+ });
+ client.getTokenFromAssertion("assertion", "scope").catch(function(e) {
+ Assert.equal(e.name, "FxAccountsOAuthGrantClientError");
+ Assert.equal(e.code, null);
+ Assert.equal(e.errno, ERRNO_NETWORK);
+ Assert.equal(e.error, ERROR_NETWORK);
+ run_next_test();
+ });
+});
+
+/**
+ * Quick way to test the "FxAccountsOAuthGrantClient" constructor.
+ *
+ * @param {Object} options
+ * FxAccountsOAuthGrantClient constructor options
+ * @param {String} expected
+ * Expected error message, or null if it's expected to pass.
+ * @returns {*}
+ */
+function validationHelper(options, expected) {
+ try {
+ new FxAccountsOAuthGrantClient(options);
+ } catch (e) {
+ return Assert.equal(e.toString(), expected);
+ }
+ return Assert.equal(expected, null);
+}