<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script>
description("Tests for multi-file promise drag onto file input elements");
jsTestIsAsync = true;

var fileInput = document.createElement("input");
fileInput.type = 'file';
fileInput.style.width = "100%"; // So that any manual testing will show full file names
// Important that we put this at the top of the doc so that logging does not cause it to go out of view (where it can't be dragged to)
document.body.insertBefore(fileInput, document.body.firstChild);

function moveMouseToCenterOfElement(element)
{
    var centerX = element.offsetLeft + element.offsetWidth / 2;
    var centerY = element.offsetTop + element.offsetHeight / 2;
    eventSender.mouseMoveTo(centerX, centerY);
}

function dragFilesOntoInput(files)
{
    fileInput.value = ""; // Clear the <input>

    eventSender.beginDragWithFilePromises(files);
    moveMouseToCenterOfElement(fileInput);
    eventSender.mouseUp();
}

function fileListShouldBe(fileListString, filesArray)
{
    shouldBe(fileListString + ".length", "" + filesArray.length);
    for (var x = 0; x < filesArray.length; x++) {
        var fileValueString = fileListString + "[" + x + "]";
        shouldBeEqualToString(fileValueString + ".name", filesArray[x]['name']);
        shouldBeEqualToString(fileValueString + ".type", filesArray[x]['type']);
        shouldBe(fileValueString + ".size", "" + filesArray[x]['size']);
    }
}

function filesShouldBe(filesArray)
{
    fileListShouldBe("fileInput.files", filesArray);
}

async function draggingPathsShouldResultInFiles(pathsArray, filesArray)
{
    const dropPromise = new Promise(resolve => fileInput.ondrop = () => window.setTimeout(resolve, 0));
    const dragleavePromise = new Promise(resolve => fileInput.ondragleave = () => window.setTimeout(resolve, 0));
    dragFilesOntoInput(pathsArray);
    await Promise.race([dropPromise, dragleavePromise]);
    shouldBeEqualToString("fileInput.value", filesArray[0] ? "C:\\fakepath\\" + filesArray[0]['name'] : '');
    filesShouldBe(filesArray);
}

async function testDraggingFiles(filesArray)
{
    // We could make a way to parse the filename from the path, and then only need to pass
    // the path in the filesArray.
    var pathsOnly = filesArray.map(function(fileSpec) { return fileSpec['path']; });
    await draggingPathsShouldResultInFiles(pathsOnly, filesArray);
}

async function runTest()
{
    debug("Dragging a real file to a file input control:");
    await testDraggingFiles([
        { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476, 'type' : 'image/gif' }
    ]);

    debug("Dragging two files to a single-file input control:")
    await draggingPathsShouldResultInFiles(['resources/apple.gif', 'resources/mozilla.gif'], []);

    fileInput.multiple = true;

    debug("Dragging three files to a multi-file input control:");
    await testDraggingFiles([
        { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476, 'type' : 'image/gif' },
        { 'path': 'resources/mozilla.gif', 'name' : 'mozilla.gif', 'size' : 2593, 'type' : 'image/gif' },
    ]);

    // Clean up after ourselves
    fileInput.parentNode.removeChild(fileInput);

    finishJSTest();
}

var successfullyParsed = true;

if (window.eventSender) {
    runTest();
} else {
    testFailed("This test is not interactive, please run using run-webkit-tests");
}

</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
