<!DOCTYPE html>
<html>
<head>
    <script src="/js-test-resources/js-test.js"></script>
</head>
<body onload="runTest()">
<script>
    description("Check that only HttpOnly cookies remain if all script-accessible cookies are deleted.");
    jsTestIsAsync = true;

    const httpOnlyCookieName = "http-only-cookie";
    const serverSideCookieName = "server-side-cookie";
    const clientSideCookieName = "client-side-cookie";

    function sortStringArray(a, b) {
        a = a.toLowerCase();
        b = b.toLowerCase();

        return a > b ? 1 : b > a ? -1 : 0;
    }

    function checkCookies(isAfterScriptAccessibleDeletion) {
        let unsortedTestPassedMessages = [];
        let cookies = internals.getCookies();
        if (!cookies.length)
            testFailed((isAfterScriptAccessibleDeletion ? "After" : "Before") + " script-accessible deletion: No cookies found.");
        for (let cookie of cookies) {
            switch (cookie.name) {
                case httpOnlyCookieName:
                    unsortedTestPassedMessages.push((isAfterScriptAccessibleDeletion ? "After" : "Before") + " script-accessible deletion: " + (isAfterScriptAccessibleDeletion ? " " : "") + "HttpOnly cookie exists.");
                    break;
                case serverSideCookieName:
                    if (isAfterScriptAccessibleDeletion)
                        testFailed("After script-accessible deletion:  Regular server-side cookie exists.");
                    else
                        unsortedTestPassedMessages.push("Before script-accessible deletion: Regular server-side cookie exists.");
                    break;
                case clientSideCookieName:
                    if (isAfterScriptAccessibleDeletion)
                        testFailed("After script-accessible deletion:  Client-side cookie exists.");
                    else
                        unsortedTestPassedMessages.push("Before script-accessible deletion: Client-side cookie exists.");
                    break;
            }
        }
        let sortedTestPassedMessages = unsortedTestPassedMessages.sort(sortStringArray);
        for (let testPassedMessage of sortedTestPassedMessages)
            testPassed(testPassedMessage);
    }

    async function runTest() {
        if (!testRunner || !internals) {
            testFailed("No testRunner or no internals.");
            return;
        }

        await fetch("/cookies/resources/set-http-only-cookie.php?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
        await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
        document.cookie = clientSideCookieName + "=1";
        checkCookies(false);
        testRunner.statisticsDeleteCookiesForHost("http://127.0.0.1", false);
        checkCookies(true);
        testRunner.statisticsDeleteCookiesForHost("http://127.0.0.1", true);
        let cookiesLeft = internals.getCookies().length;
        if (cookiesLeft === 0)
            testPassed("After full deletion:               All cookies are gone.");
        else
            testFailed("After full deletion:              " + cookiesLeft + " cookie(s) left.");
        finishJSTest();
    }
</script>
</body>
</html>
