<!DOCTYPE html>
<title>Credential Manager: get() basics.</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/interfaces.js"></script>
<script>
function stubResolverUndefinedChecker(c) {
    assert_equals(c, undefined);
    this.done();
}

function stubRejectionChecker(reason) {
    assert_unreached("get(...) should not reject, but did: " + reason.name);
}

add_completion_callback(() => {
    if (window.testRunner)
        window.testRunner.clearMockCredentialManagerResponse();
});

(function() {
    var t = async_test("navigator.credentials.get() with no argument.");
    t.step(function () {
        navigator.credentials.get().then(
            t.step_func(stubResolverUndefinedChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());

(function() {
    var t = async_test("navigator.credentials.get({}).");
    t.step(function () {
        navigator.credentials.get({}).then(
            t.step_func(stubResolverUndefinedChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());

(function() {
    var t = async_test("navigator.credentials.get() with a valid options including FederatedCredentialRequestOptions.");
    t.step(function () {
        navigator.credentials.get({
            federated: {
                providers: [ 'https://example.com/' ]
            }
        }).then(
            t.step_func(stubResolverUndefinedChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());

(function() {
    var t = async_test("navigator.credentials.get() with a valid options including password and unmediated.");
    t.step(function () {
        navigator.credentials.get({
            password: true,
            unmediated: true
        }).then(
            t.step_func(stubResolverUndefinedChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());

(function() {
    var t = async_test("navigator.credentials.get() with a valid options including federated and unmediated.");
    t.step(function () {
        navigator.credentials.get({
            federated: {
                providers: [ 'https://example.com/' ]
            },
            unmediated: true
        }).then(
            t.step_func(stubResolverUndefinedChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());

(function() {
    var t = async_test("navigator.credentials.get() with a valid options including federated, password and unmediated.");
    t.step(function () {
        navigator.credentials.get({
            password: true,
            federated: {
                providers: [ 'https://example.com/' ]
            },
            unmediated: true
        }).then(
            t.step_func(stubResolverUndefinedChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());

(function() {
    var t = async_test("navigator.credentials.get() with a valid options including unmediated.");
    t.step(function () {
        navigator.credentials.get({
            unmediated: true
        }).then(
            t.step_func(stubResolverUndefinedChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());

(function() {
    var t = async_test("navigator.credentials.get() with an options including an unknown attribute.");
    t.step(function () {
        navigator.credentials.get({
            notValid: 'yay!'
        }).then(
            t.step_func(stubResolverUndefinedChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());

(function () {
    var id = "id";
    var name = "name";
    var icon = "http://example.com/";
    var password = "pencil";

    function stubResolverChecker(c) {
        verify_interface('PasswordCredential', c, {
            id: 'string',
            name: 'string',
            iconURL: 'string'
        });

        assert_equals(c.id, id);
        assert_equals(c.name, name);
        assert_equals(c.iconURL, icon);
        assert_equals(c.idName, 'username');
        assert_equals(c.passwordName, 'password');
        assert_equals(c.additionalData, null);

        this.done();
    }

    var t = async_test("Verify that the mock returns the values we give it.");
    t.step(function() {
        if (window.testRunner)
            testRunner.setMockCredentialManagerResponse(id, name, icon, password);
        navigator.credentials.get({
            password: true
        }).then(
            t.step_func(stubResolverChecker.bind(t)),
            t.step_func(stubRejectionChecker.bind(t)));
    });
}());
</script>
