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

function createXHRForText() {
    xhrGet("resources/data.txt");
}

function createXHRForHTML() {
    xhrGet("resources/data.html");
}

function createXHRForJSON() {
    xhrGet("resources/data.json");
}

function createXHRForJSON2() {
    xhrGet(`resources/echo.py?mimetype=application/json&content={"json":true,"value":42}`);
}

function createXHRForJSON3() {
    xhrGet(`resources/echo.py?mimetype=application/vnd.api%2Bjson&content={"json":true,"value":999}`);
}

function createXHRForSVG() {
    xhrGet("resources/data.svg");
}

function createXHRForPNG() {
    xhrGet("/resources/square100.png");
}

function createSyncXHRForText() {
    xhrGet("resources/data.txt?sync", false);
}

function createSyncXHRForPNG() {
    xhrGet("/resources/square100.png?sync", false);
}

function test()
{
    let suite = InspectorTest.createAsyncSuite("Network.getResponseBody.XHR");

    function contentAsText(content) {
        return new Promise((resolve) => {
            if (typeof content === "string") {
                resolve(content)
                return;
            }
            WI.BlobUtilities.blobAsText(content, (text) => {
                resolve(text);
            });
        });
    }

    function addTestCase({name, description, expression, contentHandler}) {
        suite.addTestCase({
            name, description,
            test(resolve, reject) {
                InspectorTest.evaluateInPage(expression);
                WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
                    .then((event) => {
                        let resource = event.data.resource;
                        InspectorTest.expectEqual(resource.type, WI.Resource.Type.XHR, "Resource should be XHR type.");
                        return resource.requestContent();
                    })
                    .then(contentHandler)
                    .then(resolve, reject);
            }
        });
    }

    addTestCase({
        name: "Network.getResponseBody.XHR.Text",
        description: "Get text/plain content as text.",
        expression: `createXHRForText()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "text/plain", "MIMEType should be 'text/plain'.");
            InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded.");
            InspectorTest.expectEqual(content, "Plain text resource.\n", "Text content should match data.txt.");
        }
    });

    addTestCase({
        name: "Network.getResponseBody.XHR.HTML",
        description: "Get text/html content as text.",
        expression: `createXHRForHTML()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "text/html", "MIMEType should be 'text/html'.");
            InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded.");
            InspectorTest.expectEqual(content, "<span>Hello World</span>\n", "Text content should match data.html.");
        }
    });

    addTestCase({
        name: "Network.getResponseBody.XHR.JSON",
        description: "Get application/octet-stream content as base64Encoded text.",
        expression: `createXHRForJSON()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "application/octet-stream", "MIMEType should be 'application/octet-stream'.");
            InspectorTest.expectEqual(rawBase64Encoded, true, "Content should be base64Encoded.");
            return contentAsText(content).then((text) => {
                InspectorTest.expectEqual(text, `{"json": true, "value": 42}\n`, "JSON content should match data.json.");
            });
        }
    });

    addTestCase({
        name: "Network.getResponseBody.XHR.JSON2",
        description: "Get application/json content as text.",
        expression: `createXHRForJSON2()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "application/json", "MIMEType should be 'application/json'.");
            InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded.");
            InspectorTest.expectEqual(content, `{"json":true,"value":42}`, "JSON content should match specified content.");
        }
    });

    addTestCase({
        name: "Network.getResponseBody.XHR.JSON3",
        description: "Get arbitrary +json content as text.",
        expression: `createXHRForJSON3()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "application/vnd.api+json", "MIMEType should be 'application/vnd.api+json'.");
            InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded.");
            InspectorTest.expectEqual(content, `{"json":true,"value":999}`, "JSON content should match specified content.");
        }
    });

    addTestCase({
        name: "Network.getResponseBody.XHR.SVG",
        description: "Get image/svg+xml content as text.",
        expression: `createXHRForSVG()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "image/svg+xml", "MIMEType should be 'image/svg+xml'.");
            InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded.");
            InspectorTest.expectEqual(content,
`<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 200">
  <rect width="100%" height="50%" fill="green"/>
</svg>
`, "SVG content should be text.");
        }
    });

    addTestCase({
        name: "Network.getResponseBody.XHR.PNG",
        description: "Get image/png content.",
        expression: `createXHRForPNG()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "image/png", "MIMEType should be 'image/png'.");
            InspectorTest.expectEqual(rawBase64Encoded, true, "Content should be base64Encoded.");
            InspectorTest.expectThat(content instanceof Blob, "Image content should be a Blob.");
        }
    });

    addTestCase({
        name: "Network.getResponseBody.XHR.Sync.Text",
        description: "Get text/plain content as text from a synchronous XHR.",
        expression: `createSyncXHRForText()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "text/plain", "MIMEType should be 'text/plain'.");
            InspectorTest.expectEqual(rawBase64Encoded, false, "Content should not be base64Encoded.");
            InspectorTest.expectEqual(content, "Plain text resource.\n", "Text content should match data.txt.");
        }
    });

    addTestCase({
        name: "Network.getResponseBody.XHR.Sync.PNG",
        description: "Get image/png content from a synchronous XHR.",
        expression: `createSyncXHRForPNG()`,
        contentHandler({error, sourceCode, content, rawBase64Encoded}) {
            InspectorTest.expectEqual(sourceCode.mimeType, "image/png", "MIMEType should be 'image/png'.");
            InspectorTest.expectEqual(rawBase64Encoded, true, "Content should be base64Encoded.");
            InspectorTest.expectThat(content instanceof Blob, "Image content should be a Blob.");
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Tests for getting the content of XHR requests.</p>
</body>
</html>
