"use strict";

const kTestChars = "ABC~‾¥≈¤･・•∙·☼★星🌟星★☼·∙•・･¤≈¥‾~XYZ";

// formDataPostFileUploadTest - verifies multipart upload structure and
// numeric character reference replacement for filenames, field names,
// and field values using FormData and fetch().
//
// Uses /fetch/api/resources/echo-content.py to echo the upload
// POST (unlike in send-file-form-helper.js, here we expect all
// multipart/form-data request bodies to be UTF-8, so we don't need to
// escape controls and non-ASCII bytes).
//
// Fields in the parameter object:
//
// - fileNameSource: purely explanatory and gives a clue about which
//   character encoding is the source for the non-7-bit-ASCII parts of
//   the fileBaseName, or Unicode if no smaller-than-Unicode source
//   contains all the characters. Used in the test name.
// - fileBaseName: the not-necessarily-just-7-bit-ASCII file basename
//   used for the constructed test file. Used in the test name.
const formDataPostFileUploadTest = ({
  fileNameSource,
  fileBaseName,
}) => {
  promise_test(async (testCase) => {
    const formData = new FormData();
    let file = new Blob([kTestChars], { type: "text/plain" });
    try {
      // Switch to File in browsers that allow this
      file = new File([file], fileBaseName, { type: file.type });
    } catch (ignoredException) {
    }

    // Used to verify that the browser agrees with the test about
    // field value replacement and encoding independently of file system
    // idiosyncracies.
    formData.append("filename", fileBaseName);

    // Same, but with name and value reversed to ensure field names
    // get the same treatment.
    formData.append(fileBaseName, "filename");

    formData.append("file", file, fileBaseName);

    const formDataText = await (await fetch(
      `/fetch/api/resources/echo-content.py`,
      {
        method: "POST",
        body: formData,
      },
    )).text();
    const formDataLines = formDataText.split("\r\n");
    if (formDataLines.length && !formDataLines[formDataLines.length - 1]) {
      --formDataLines.length;
    }
    assert_greater_than(
      formDataLines.length,
      2,
      `${fileBaseName}: multipart form data must have at least 3 lines: ${
        JSON.stringify(formDataText)
      }`,
    );
    const boundary = formDataLines[0];
    assert_equals(
      formDataLines[formDataLines.length - 1],
      boundary + "--",
      `${fileBaseName}: multipart form data must end with ${boundary}--: ${
        JSON.stringify(formDataText)
      }`,
    );

    const asName = fileBaseName.replace(/[\r\n"]/g, encodeURIComponent);
    const expectedText = [
      boundary,
      'Content-Disposition: form-data; name="filename"',
      "",
      fileBaseName,
      boundary,
      `Content-Disposition: form-data; name="${asName}"`,
      "",
      "filename",
      boundary,
      `Content-Disposition: form-data; name="file"; ` +
      `filename="${asName}"`,
      "Content-Type: text/plain",
      "",
      kTestChars,
      boundary + "--",
    ].join("\r\n");

    assert_true(
      formDataText.startsWith(expectedText),
      `Unexpected multipart-shaped form data received:\n${formDataText}\nExpected:\n${expectedText}`,
    );
  }, `Upload ${fileBaseName} (${fileNameSource}) in fetch with FormData`);
};
