<!doctype html>
<title>Credential Manager: get() basics.</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="/gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="/gen/third_party/WebKit/public/platform/modules/credentialmanager/credential_manager.mojom.js"></script>
<script src="/gen/third_party/WebKit/public/platform/modules/webauth/authenticator.mojom.js"></script>
<script src="resources/credential-helpers.js"></script>
<script>

if (document.location.hostname == "127.0.0.1")
document.location = "https://subdomain.example.test:8443/credentialmanager/credentialscontainer-get-basics.html";

add_completion_callback(() => {
  mockCredentialManager.reset();
});

promise_test(_ => {
  return navigator.credentials.get().then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get() with no argument.");

promise_test(_ => {
  return navigator.credentials.get({}).then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get({}).");

promise_test(_ => {
  return navigator.credentials.get({
    federated: {
      providers: [ 'https://example.com/' ]
    }
  }).then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get() with a valid options including FederatedCredentialRequestOptions.");

promise_test(_ => {
  return navigator.credentials.get({
    password: true,
    unmediated: true
  }).then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get() with a valid options including password and unmediated.");

promise_test(_ => {
  return navigator.credentials.get({
    federated: {
      providers: [ 'https://example.com/' ]
    },
    unmediated: true
  }).then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get() with a valid options including federated and unmediated.");

promise_test(_ => {
  return navigator.credentials.get({
    password: true,
    federated: {
      providers: [ 'https://example.com/' ]
    },
    unmediated: true
  }).then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get() with a valid options including federated, password and unmediated.");

promise_test(_ => {
  return navigator.credentials.get({
    unmediated: true
  }).then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get() with a valid options including unmediated.");

promise_test(_ => {
  return navigator.credentials.get({
    mediation: "silent"
  }).then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get() with a valid options including mediation.");

promise_test(_ => {
  return navigator.credentials.get({
    notValid: 'yay!'
  }).then(r => {
    assert_equals(r, null);
  });
}, "navigator.credentials.get() with an options including an unknown attribute.");

promise_test(_ => {
  var id = "id";
  var password = "pencil";
  var name = "name";
  var icon = "http://example.com/";

  mockCredentialManager.setResponse(id, password, name, icon);

  return navigator.credentials.get({
    password: true
  }).then(r => {
    assert_equals(r.id, id, "id");
    assert_equals(r.password, password, "password");
    assert_equals(r.name, name, "name");
    assert_equals(r.iconURL, icon, "icon");
  });
}, "Verify that the mock returns the values we give it.");

promise_test(_ => {
  mockAuthenticator.setRawId(RAW_ID);
  mockAuthenticator.setId(ID);
  mockAuthenticator.setClientDataJson(CLIENT_DATA_JSON);
  mockAuthenticator.setAuthenticatorData(AUTHENTICATOR_DATA);
  mockAuthenticator.setSignature(SIGNATURE);
  mockAuthenticator.setAuthenticatorStatus(
    webauth.mojom.AuthenticatorStatus.SUCCESS);

    return navigator.credentials.get({publicKey : GET_CREDENTIAL_OPTIONS}).then(r => {
        assertValidGetCredentialResponse(r);
    });
}, "Verify that mockAuthenticator returns the values we give it.");

promise_test(t => {
  mockAuthenticator.setAuthenticatorStatus(
      webauth.mojom.AuthenticatorStatus.PENDING_REQUEST);
  return promise_rejects(t, "InvalidStateError",
    navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that pending request error returned by mock is properly handled.");

promise_test(function (t) {
  mockAuthenticator.setAuthenticatorStatus(
      webauth.mojom.AuthenticatorStatus.UNKNOWN_ERROR);
  return promise_rejects(t, "NotReadableError",
      navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that unknown error returned by mock is properly handled.");

promise_test(t => {
  mockAuthenticator.setAuthenticatorStatus(
      webauth.mojom.AuthenticatorStatus.NOT_ALLOWED_ERROR);
  return promise_rejects(t, "NotAllowedError",
      navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that not allowed error returned by mock is properly handled.");

promise_test(t => {
  mockAuthenticator.setAuthenticatorStatus(
      webauth.mojom.AuthenticatorStatus.NOT_SUPPORTED_ERROR);
  return promise_rejects(t, "NotSupportedError",
      navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that not supported error returned by mock is properly handled.");

promise_test(t => {
  mockAuthenticator.setAuthenticatorStatus(
      webauth.mojom.AuthenticatorStatus.TIMED_OUT);
  return promise_rejects(t, "NotAllowedError",
      navigator.credentials.get({ publicKey : GET_CREDENTIAL_OPTIONS}));
}, "Verify that timed out error returned by mock is properly handled.");

promise_test(function(t) {
    var customGetCredentialOptions = {
        // No challenge.
        rpId: "google.com",
        allowCredentials: [ACCEPTABLE_CREDENTIAL]
    };

    return promise_rejects(t, new TypeError(),
            navigator.credentials.get({publicKey: customGetCredentialOptions}));
}, "navigator.credentials.get() with missing challenge");

promise_test(_ => {
  mockAuthenticator.reset();
  mockAuthenticator.setRawId(RAW_ID);
  mockAuthenticator.setId(ID);
  mockAuthenticator.setClientDataJson(CLIENT_DATA_JSON);
  mockAuthenticator.setAuthenticatorData(AUTHENTICATOR_DATA);
  mockAuthenticator.setSignature(SIGNATURE);
  mockAuthenticator.setAuthenticatorStatus(
      webauth.mojom.AuthenticatorStatus.SUCCESS);

  var customPublicKey = {
      challenge: CHALLENGE,
      allowCredentials: [ACCEPTABLE_CREDENTIAL]
  };

  return navigator.credentials.get({publicKey: customPublicKey}).then(r => {
      assertValidGetCredentialResponse(r);
  });
}, "navigator.credentials.get() with missing rpId");

</script>
