<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../resources/inspector-test.js"></script>
<script>
function createSimpleGETRequest()
{
    let request = new XMLHttpRequest();
    request.open("GET", "resources/url?query=true", true);
    request.send();
}

function createGETRequestWithSpecialURL()
{
    let request = new XMLHttpRequest();
    request.open("GET", "resources/url'with$special{1..20}chars[] .html", true);
    request.send();
}

function createGETRequestWithSpecialCharsInHeaders()
{
    let request = new XMLHttpRequest();
    request.open("GET", "resources/url", true);
    request.setRequestHeader("X-Custom1", "test1");
    request.setRequestHeader("X-Custom2'%", "\'Test'\'1\\'2");
    request.setRequestHeader("X-Custom3", "\'${PWD}");
    request.send();
}

function createGETRequestWithUTF8()
{
    let request = new XMLHttpRequest();
    request.open("GET", "resources/url?utf8=👍", true);
    request.send();
}

function createPOSTRequestWithURLEncodedData()
{
    let request = new XMLHttpRequest();
    request.open("POST", "resources/url", true);
    request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    request.send("lorem=ipsum&$dolor='sit'&amet={1..20}");
}

function createPOSTRequestWithUTF8()
{
    let request = new XMLHttpRequest();
    request.open("POST", "resources/url?utf8=👍", true);
    request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    request.send("🌨=⛄️");
}

function createPUTRequestWithJSON()
{
    let request = new XMLHttpRequest();
    request.open("PUT", "resources/url", true);
    request.setRequestHeader("Content-Type", "application/json");
    request.send("{\"update\":\"now\"}");
}

function test()
{
    let suite = InspectorTest.createAsyncSuite("GenerateCURLValidPOSIXOutput");

    suite.addTestCase({
        name: "SimpleURLGenerateCURL",
        description: "Generate cURL command from a simple URL.",
        test(resolve, reject) {
            WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
            .then((event) => {
                let resource = event.data.resource;
                let curl = resource.generateCURLCommand().split(" \\\n");

                InspectorTest.expectThat(curl[0].match("https?://.*?/resources/url\\?query=true") !== null, "Command should contain URL.");
                InspectorTest.expectThat(curl[1] === "-X 'GET'", "Command should be a GET request.");
                InspectorTest.expectThat(curl.find((cmd) => cmd.includes('User-Agent')) !== undefined, "Command should contain User-Agent header.");
                InspectorTest.expectThat(curl.find((cmd) => cmd.includes('X-Custom')) === undefined, "Command should not contain a custom header.");
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("createSimpleGETRequest()");
        }
    });

    suite.addTestCase({
        name: "SpecialURLGenerateCURL",
        description: "Generate cURL command from a URL containing special characters.",
        test(resolve, reject) {
            WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
            .then((event) => {
                let resource = event.data.resource;
                let curl = resource.generateCURLCommand().split(" \\\n");

                InspectorTest.expectThat(curl[0].match("https?://.*?/resources/url\\\\'with\\$special%7B1\.\.20%7Dchars\\\\\\[\\\\\\]%20.html") !== null, "Command should contain valid POSIX escaped URL.");
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("createGETRequestWithSpecialURL()");
        }
    });

    suite.addTestCase({
        name: "SpecialHeadersGenerateCURLValidPOSIXOutput",
        description: "Generate cURL command from a request containing special characters in the headers and verify valid POSIX output.",
        test(resolve, reject) {
            WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
            .then((event) => {
                let resource = event.data.resource;
                let curl = resource.generateCURLCommand().split(" \\\n");

                InspectorTest.expectThat(curl.find((cmd) => cmd.includes('X-Custom1')) === "-H 'X-Custom1: test1'", "Command should have correct custom header 1.");
                InspectorTest.expectThat(curl.find((cmd) => cmd.includes('X-Custom2')) === "-H $'X-Custom2\\'%: \\'Test\\'\\'1\\\\\\'2'", "Command should have correct custom header 2.");
                InspectorTest.expectThat(curl.find((cmd) => cmd.includes('X-Custom3')) === "-H $'X-Custom3: \\'${PWD}'", "Command should have correct custom header 3.");
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("createGETRequestWithSpecialCharsInHeaders()");
        }
    });

    suite.addTestCase({
        name: "URLWithUTF8GenerateCURL",
        description: "Generate cURL command from a URL containing UTF8 characters.",
        test(resolve, reject) {
            WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
            .then((event) => {
                let resource = event.data.resource;
                let curl = resource.generateCURLCommand().split(" \\\n");

                InspectorTest.expectThat(curl[0].match("https?://.*?/resources/url\\?utf8=%F0%9F%91%8D") !== null, "Command should contain URL with UTF8 characters.");
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("createGETRequestWithUTF8()");
        }
    });

    suite.addTestCase({
        name: "POSTRequestURLEncodedDataGenerateCURL",
        description: "Generate cURL command from a POST request with URL encoded data.",
        test(resolve, reject) {
            WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
            .then((event) => {
                let resource = event.data.resource;
                let curl = resource.generateCURLCommand().split(" \\\n");

                InspectorTest.expectThat(curl[1] === "-X 'POST'", "Command should be a POST request.");
                InspectorTest.expectThat(curl.find((cmd) => cmd.includes('Content-Type')) === "-H 'Content-Type: application/x-www-form-urlencoded'", "Command should have correct Content-Type.");
                InspectorTest.expectThat(curl.find((cmd) => cmd === "--data $'lorem=ipsum&$dolor=\\'sit\\'&amet={1..20}'") !== undefined, "Command should contain correct data.");
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("createPOSTRequestWithURLEncodedData()");
        }
    });

    suite.addTestCase({
        name: "POSTRequestURLEncodedDataUTF8GenerateCURL",
        description: "Generate cURL command from a POST request with URL encoded UTF8 data.",
        test(resolve, reject) {
            WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
            .then((event) => {
                let resource = event.data.resource;
                let curl = resource.generateCURLCommand().split(" \\\n");

                InspectorTest.expectThat(curl[0].match("https?://.*?/resources/url\\?utf8=%F0%9F%91%8D") !== null, "Command should contain URL with UTF8 characters.");
                InspectorTest.expectThat(curl.find((cmd) => cmd === "--data $'\\ud83c\\udf28=\\u26c4\\ufe0f'") !== undefined, "Command should contain correct UTF8 data.");
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("createPOSTRequestWithUTF8()");
        }
    });

    suite.addTestCase({
        name: "PUTRequestWithJSONGenerateCURL",
        description: "Generate cURL command from a PUT request with JSON data.",
        test(resolve, reject) {
            WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
            .then((event) => {
                let resource = event.data.resource;
                let curl = resource.generateCURLCommand().split(" \\\n");

                InspectorTest.expectThat(curl[1] === "-X 'PUT'", "Command should be a PUT request.");
                InspectorTest.expectThat(curl.find((cmd) => cmd.includes('Content-Type')) === "-H 'Content-Type: application/json'", "Command should have JSON Content-Type.");
                InspectorTest.expectThat(curl.find((cmd) => cmd === "--data-binary '{\"update\":\"now\"}'") !== undefined, "Command should contain correct JSON data.");
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("createPUTRequestWithJSON()");
        }
    });

    suite.addTestCase({
        name: "SpecialMethodGenerateCURLValidPOSIXOutput",
        description: "Generate cURL command from a request containing special characters in the method and verify valid POSIX output.",
        test(resolve, reject) {
            let resource = new WI.Resource("TEST", {
                requestMethod: "METHOD&a$b-c",
            });

            let curl = resource.generateCURLCommand().split(" \\\n");

            InspectorTest.expectEqual(curl[1], "-X 'METHOD&a$b-c'", "Command should contain method with properly escaped special characters.");

            resolve();
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
    <p>Tests that "Copy as cURL" returns valid POSIX output.</p>
</body>
</html>