tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_persist_image_accept.js (4889B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const TEST_PATH = getRootDirectory(gTestPath).replace(
      7  "chrome://mochitests/content",
      8  "https://example.org"
      9 );
     10 
     11 var MockFilePicker = SpecialPowers.MockFilePicker;
     12 MockFilePicker.init(window.browsingContext);
     13 
     14 registerCleanupFunction(async function () {
     15  info("Running the cleanup code");
     16  MockFilePicker.cleanup();
     17  if (gTestDir && gTestDir.exists()) {
     18    // On Windows, sometimes nsIFile.remove() throws, probably because we're
     19    // still writing to the directory we're trying to remove, despite
     20    // waiting for the download to complete. Just retry a bit later...
     21    let succeeded = false;
     22    while (!succeeded) {
     23      try {
     24        gTestDir.remove(true);
     25        succeeded = true;
     26      } catch (ex) {
     27        await new Promise(requestAnimationFrame);
     28      }
     29    }
     30  }
     31 });
     32 
     33 let gTestDir = null;
     34 
     35 function createTemporarySaveDirectory() {
     36  var saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
     37  saveDir.append("testsavedir");
     38  if (!saveDir.exists()) {
     39    info("create testsavedir!");
     40    saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
     41  }
     42  info("return from createTempSaveDir: " + saveDir.path);
     43  return saveDir;
     44 }
     45 
     46 function expectedImageAcceptHeader() {
     47  if (Services.prefs.prefHasUserValue("image.http.accept")) {
     48    return Services.prefs.getCharPref("image.http.accept");
     49  }
     50 
     51  let header = "";
     52 
     53  // Check if AVIF is supported (compiled with MOZ_AV1)
     54  try {
     55    Services.catMan.getCategoryEntry("Gecko-Content-Viewers", "image/avif");
     56    header += "image/avif,";
     57  } catch (e) {
     58    // AVIF not registered, skip it
     59  }
     60 
     61  if (Services.prefs.getBoolPref("image.jxl.enabled")) {
     62    header += "image/jxl,";
     63  }
     64 
     65  header += "image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5";
     66 
     67  return header;
     68 }
     69 
     70 add_task(async function test_image_download() {
     71  await BrowserTestUtils.withNewTab(TEST_PATH + "dummy.html", async browser => {
     72    // Add the image, and wait for it to load.
     73    await SpecialPowers.spawn(browser, [], async function () {
     74      let loc = content.document.location.href;
     75      let imgloc = new content.URL("dummy.png", loc);
     76      let img = content.document.createElement("img");
     77      img.src = imgloc;
     78      await new Promise(resolve => {
     79        img.onload = resolve;
     80        content.document.body.appendChild(img);
     81      });
     82    });
     83    gTestDir = createTemporarySaveDirectory();
     84 
     85    let destFile = gTestDir.clone();
     86 
     87    MockFilePicker.displayDirectory = gTestDir;
     88    let fileName;
     89    MockFilePicker.showCallback = function (fp) {
     90      info("showCallback");
     91      fileName = fp.defaultString;
     92      info("fileName: " + fileName);
     93      destFile.append(fileName);
     94      info("path: " + destFile.path);
     95      MockFilePicker.setFiles([destFile]);
     96      MockFilePicker.filterIndex = 0; // just save the file
     97      info("done showCallback");
     98    };
     99    let publicDownloads = await Downloads.getList(Downloads.PUBLIC);
    100    let downloadFinishedPromise = new Promise(resolve => {
    101      publicDownloads.addView({
    102        onDownloadChanged(download) {
    103          info("Download changed!");
    104          if (download.succeeded || download.error) {
    105            info("Download succeeded or errored");
    106            publicDownloads.removeView(this);
    107            publicDownloads.removeFinished();
    108            resolve(download);
    109          }
    110        },
    111      });
    112    });
    113    let httpOnModifyPromise = TestUtils.topicObserved(
    114      "http-on-modify-request",
    115      s => {
    116        let channel = s.QueryInterface(Ci.nsIChannel);
    117        let uri = channel.URI && channel.URI.spec;
    118        if (!uri.endsWith("dummy.png")) {
    119          info("Ignoring request for " + uri);
    120          return false;
    121        }
    122        ok(channel instanceof Ci.nsIHttpChannel, "Should be HTTP channel");
    123        channel.QueryInterface(Ci.nsIHttpChannel);
    124        is(
    125          channel.getRequestHeader("Accept"),
    126          expectedImageAcceptHeader(),
    127          "Header should be image header"
    128        );
    129        return true;
    130      }
    131    );
    132    // open the context menu.
    133    let popup = document.getElementById("contentAreaContextMenu");
    134    let popupShown = BrowserTestUtils.waitForEvent(popup, "popupshown");
    135    BrowserTestUtils.synthesizeMouseAtCenter(
    136      "img",
    137      { type: "contextmenu", button: 2 },
    138      browser
    139    );
    140    await popupShown;
    141    let popupHidden = BrowserTestUtils.waitForEvent(popup, "popuphidden");
    142    popup.activateItem(popup.querySelector("#context-saveimage"));
    143    await popupHidden;
    144    info("Context menu hidden, waiting for download to finish");
    145    let imageDownload = await downloadFinishedPromise;
    146    ok(imageDownload.succeeded, "Image should have downloaded successfully");
    147    info("Waiting for http request to complete.");
    148    // Ensure we got the http request:
    149    await httpOnModifyPromise;
    150  });
    151 });