<!DOCTYPE html>
<title>Credential Manager: create() 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_lite.js"></script>
<script src="/gen/mojo/public/mojom/base/unguessable_token.mojom-lite.js"></script>
<script src="/gen/mojo/public/mojom/base/big_buffer.mojom-lite.js"></script>
<script src="/gen/mojo/public/mojom/base/string16.mojom-lite.js"></script>
<script src="/gen/mojo/public/mojom/base/time.mojom-lite.js"></script>
<script src="/gen/url/mojom/origin.mojom-lite.js"></script>
<script src="/gen/url/mojom/url.mojom-lite.js"></script>
<script src="/gen/third_party/blink/public/mojom/credentialmanager/credential_manager.mojom-lite.js"></script>
<script src="/gen/third_party/blink/public/mojom/sms/sms_receiver.mojom-lite.js"></script>
<script src="/gen/third_party/blink/public/mojom/webauthn/authenticator.mojom-lite.js"></script>
<script src="resources/test-inputs.js"></script>
<script src="resources/mock-navigator-credentials.js"></script>
<script>

if (document.location.host != "subdomain.example.test:8443") {
  document.location = "https://subdomain.example.test:8443/credentialmanager/credentialscontainer-create-basics.html";
  promise_test(_ => new Promise(_ => {}), "Stall tests on the wrong host.");
}

promise_test(t => {
    return promise_rejects_dom(t, "NotSupportedError",
        navigator.credentials.create());
}, "navigator.credentials.create() with no argument.");

promise_test(t => {
    mockAuthenticator.setAuthenticatorStatus(
        blink.mojom.AuthenticatorStatus.INVALID_DOMAIN);
    return promise_rejects_dom(t, "SecurityError",
        navigator.credentials.create({publicKey : MAKE_CREDENTIAL_OPTIONS}));
}, "Verify that invalid domain error returned by mock is properly handled.");

promise_test(t => {
    mockAuthenticator.setAuthenticatorStatus(
        blink.mojom.AuthenticatorStatus.ABORT_ERROR);
    return promise_rejects_dom(t, "AbortError",
        navigator.credentials.create({publicKey : MAKE_CREDENTIAL_OPTIONS}));
}, "Verify that abort error returned by mock is properly handled.");

promise_test(t => {
    var authAbortController = new AbortController();
    var authAbortSignal = authAbortController.signal;
    authAbortController.abort();
    return promise_rejects_dom(t, "AbortError",
        navigator.credentials.create({publicKey : MAKE_CREDENTIAL_OPTIONS, signal : authAbortSignal}));
}, "navigator.credentials.create() with abort signal");

promise_test(t => {
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.challenge;
  return promise_rejects_js(t, TypeError,
      navigator.credentials.create({publicKey : customMakeCredOptions}));
}, "navigator.credentials.create() with missing challenge");

promise_test(t => {
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.pubKeyCredParams;
  return promise_rejects_js(t, TypeError,
      navigator.credentials.create({publicKey : customMakeCredOptions}));
}, "navigator.credentials.create() with missing parameters");

promise_test(t => {
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.rp;
  return promise_rejects_js(t, TypeError,
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing rp");

promise_test(t => {
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.user;
  return promise_rejects_js(t, TypeError,
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing user");

promise_test(t => {
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.rp.name;
  return promise_rejects_js(t, TypeError,
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing rp.name");

promise_test(t => {
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.user.id;
  return promise_rejects_js(t, TypeError,
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing user.id");

promise_test(t => {
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.user.name;
  return promise_rejects_js(t, TypeError,
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing user.name");

promise_test(t => {
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.user.displayName;
  return promise_rejects_js(t, TypeError,
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing user.displayName");

promise_test(_ => {
  mockAuthenticator.setRawId(RAW_ID);
  mockAuthenticator.setId(ID);
  mockAuthenticator.setClientDataJson(CLIENT_DATA_JSON);
  mockAuthenticator.setAttestationObject(ATTESTATION_OBJECT);
  mockAuthenticator.setAuthenticatorStatus(
    blink.mojom.AuthenticatorStatus.SUCCESS);

  return navigator.credentials.create({publicKey : MAKE_CREDENTIAL_OPTIONS}).then(r => {
      assertValidMakeCredentialResponse(r);
  });
}, "Verify that the mock returns the values we give it.");

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

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

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

promise_test(t => {
  mockAuthenticator.setAuthenticatorStatus(
      blink.mojom.AuthenticatorStatus.ALGORITHM_UNSUPPORTED);
  return promise_rejects_dom(t, "NotSupportedError",
      navigator.credentials.create({ publicKey : MAKE_CREDENTIAL_OPTIONS}));
}, "Verify that algorithm unsupported error returned by mock is properly handled.");

promise_test(t => {
  mockAuthenticator.setAuthenticatorStatus(
      blink.mojom.AuthenticatorStatus.CREDENTIAL_EXCLUDED);
  return promise_rejects_dom(t, "InvalidStateError",
      navigator.credentials.create({ publicKey : MAKE_CREDENTIAL_OPTIONS}));
}, "Verify that credential excluded error returned by mock is properly handled.");

promise_test(t => {
  mockAuthenticator.setAuthenticatorStatus(
      blink.mojom.AuthenticatorStatus.CREDENTIAL_NOT_RECOGNIZED);
  return promise_rejects_dom(t, "InvalidStateError",
      navigator.credentials.create({ publicKey : MAKE_CREDENTIAL_OPTIONS}));
}, "Verify that credential not recognized error returned by mock is properly handled.");

promise_test(_ => {
  mockAuthenticator.reset();
  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  customMakeCredOptions.rp = { name: "Acme" };
  return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
      assertValidMakeCredentialResponse(r);
  });
}, "navigator.credentials.create() with missing rp.id");

promise_test(_ => {
  mockAuthenticator.reset();
  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.authenticatorSelection;
  return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
      assertValidMakeCredentialResponse(r);
  });
}, "navigator.credentials.create() with missing authenticatorSelection");

promise_test(_ => {
  mockAuthenticator.reset();
  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.authenticatorSelection.requireResidentKey;
  return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
      assertValidMakeCredentialResponse(r);
  });
}, "navigator.credentials.create() with missing requireResidentKey");

promise_test(_ => {
  mockAuthenticator.reset();
  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  delete customMakeCredOptions.authenticatorSelection.userVerification;
  return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
      assertValidMakeCredentialResponse(r);
  });
}, "navigator.credentials.create() with missing userVerification");

promise_test(t => {
  mockAuthenticator.reset();
  mockAuthenticator.setAuthenticatorStatus(
      blink.mojom.AuthenticatorStatus.EMPTY_ALLOW_CREDENTIALS);
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  return promise_rejects_dom(t, "NotSupportedError",
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with requireResidentKey true");

promise_test(t => {
  mockAuthenticator.reset();
  mockAuthenticator.setAuthenticatorStatus(
      blink.mojom.AuthenticatorStatus.USER_VERIFICATION_UNSUPPORTED);
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  customMakeCredOptions.authenticatorSelection.userVerification = 'required';
  return promise_rejects_dom(t, "NotSupportedError",
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with userVerification required");

promise_test(_ => {
  mockAuthenticator.reset();
  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  customMakeCredOptions.authenticatorSelection.userVerification = 'discouraged';
  return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
      assertValidMakeCredentialResponse(r);
  });
}, "navigator.credentials.create() with userVerification discouraged");

promise_test(t => {
  mockAuthenticator.reset();
  mockAuthenticator.setAuthenticatorStatus(
      blink.mojom.AuthenticatorStatus.USER_VERIFICATION_UNSUPPORTED);
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  customMakeCredOptions.authenticatorSelection.authenticatorAttachment = 'platform';
  return promise_rejects_dom(t, "NotSupportedError",
      navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with platform authenticatorAttachment");

promise_test(_ => {
  mockAuthenticator.reset();
  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  customMakeCredOptions.authenticatorSelection.authenticatorAttachment = 'cross-platform';
  return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
      assertValidMakeCredentialResponse(r);
  });
}, "navigator.credentials.create() with cross-platform authenticatorAttachment");

promise_test(t => {
  mockAuthenticator.reset();
  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  customMakeCredOptions.extensions = {cableRegistration: CABLE_REGISTRATION};
  return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
      assertValidMakeCredentialResponse(r);
}, "navigator.credentials.create() with cableRegistration extension");

promise_test(_ => {
  mockAuthenticator.reset();
  mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
  var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
  customMakeCredOptions.extensions = {cableAuthentication: [CABLE_AUTHENTICATION]};
  return promise_rejects_dom(t, "NotSupportedError",
      navigator.credentials.create({ publicKey : customMakeCredOptions}));
  });
}, "navigator.credentials.create() with cableAuthentication extension not supported");

</script>
