summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/general/browser_save_link_when_window_navigates.js
blob: 65daef5f1bd5bc9b41cbb1a9b50bfba3c6adc861 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window.browsingContext);

const SAVE_PER_SITE_PREF = "browser.download.lastDir.savePerSite";
const ALWAYS_DOWNLOAD_DIR_PREF = "browser.download.useDownloadDir";
const ALWAYS_ASK_PREF = "browser.download.always_ask_before_handling_new_types";
const UCT_URI = "chrome://mozapps/content/downloads/unknownContentType.xhtml";

Services.scriptloader.loadSubScript(
  "chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
  this
);

function createTemporarySaveDirectory() {
  var saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
  saveDir.append("testsavedir");
  if (!saveDir.exists()) {
    info("create testsavedir!");
    saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
  }

  Services.prefs.setIntPref("browser.download.folderList", 2);
  Services.prefs.setCharPref("browser.download.dir", saveDir);
  info("return from createTempSaveDir: " + saveDir.path);
  return saveDir;
}

function triggerSave(aWindow, aCallback) {
  info(
    "started triggerSave, persite downloads: " +
      (Services.prefs.getBoolPref(SAVE_PER_SITE_PREF) ? "on" : "off")
  );
  var fileName;
  let testBrowser = aWindow.gBrowser.selectedBrowser;
  let testURI =
    "https://example.com/browser/browser/base/content/test/general/navigating_window_with_download.html";

  // Only observe the UTC dialog if it's enabled by pref
  if (Services.prefs.getBoolPref(ALWAYS_ASK_PREF)) {
    windowObserver.setCallback(onUCTDialog);
  }

  BrowserTestUtils.startLoadingURIString(testBrowser, testURI);

  // Create the folder the link will be saved into.
  var destDir = createTemporarySaveDirectory();
  var destFile = destDir.clone();

  MockFilePicker.displayDirectory = destDir;
  MockFilePicker.showCallback = function (fp) {
    info("showCallback");
    fileName = fp.defaultString;
    info("fileName: " + fileName);
    destFile.append(fileName);
    MockFilePicker.setFiles([destFile]);
    MockFilePicker.filterIndex = 1; // kSaveAsType_URL
    info("done showCallback");
  };

  mockTransferCallback = function (downloadSuccess) {
    info("mockTransferCallback");
    onTransferComplete(aWindow, downloadSuccess, destDir);
    destDir.remove(true);
    ok(!destDir.exists(), "Destination dir should be removed");
    ok(!destFile.exists(), "Destination file should be removed");
    mockTransferCallback = null;
    info("done mockTransferCallback");
  };

  function onUCTDialog(dialog) {
    SpecialPowers.spawn(testBrowser, [], async () => {
      content.document.querySelector("iframe").remove();
    }).then(() => executeSoon(continueDownloading));
  }

  function continueDownloading() {
    for (let win of Services.wm.getEnumerator("")) {
      if (win.location && win.location.href == UCT_URI) {
        win.document
          .getElementById("unknownContentType")
          ._fireButtonEvent("accept");
        win.close();
        return;
      }
    }
    ok(false, "No Unknown Content Type dialog yet?");
  }

  function onTransferComplete(aWindow2, downloadSuccess) {
    ok(downloadSuccess, "Link should have been downloaded successfully");
    aWindow2.close();

    executeSoon(aCallback);
  }
}

var windowObserver = {
  setCallback(aCallback) {
    if (this._callback) {
      ok(false, "Should only be dealing with one callback at a time.");
    }
    this._callback = aCallback;
  },
  observe(aSubject, aTopic, aData) {
    if (aTopic != "domwindowopened") {
      return;
    }

    let win = aSubject;

    win.addEventListener(
      "load",
      function (event) {
        if (win.location == UCT_URI) {
          SimpleTest.executeSoon(function () {
            if (windowObserver._callback) {
              windowObserver._callback(win);
              delete windowObserver._callback;
            } else {
              ok(false, "Unexpected UCT dialog!");
            }
          });
        }
      },
      { once: true }
    );
  },
};

Services.ww.registerNotification(windowObserver);

function test() {
  waitForExplicitFinish();
  Services.prefs.setBoolPref(ALWAYS_ASK_PREF, false);

  function testOnWindow(options, callback) {
    info("testOnWindow(" + options + ")");
    var win = OpenBrowserWindow(options);
    info("got " + win);
    whenDelayedStartupFinished(win, () => callback(win));
  }

  function whenDelayedStartupFinished(aWindow, aCallback) {
    info("whenDelayedStartupFinished");
    Services.obs.addObserver(function observer(aSubject, aTopic) {
      info(
        "whenDelayedStartupFinished, got topic: " +
          aTopic +
          ", got subject: " +
          aSubject +
          ", waiting for " +
          aWindow
      );
      if (aWindow == aSubject) {
        Services.obs.removeObserver(observer, aTopic);
        executeSoon(aCallback);
        info("whenDelayedStartupFinished found our window");
      }
    }, "browser-delayed-startup-finished");
  }

  mockTransferRegisterer.register();

  registerCleanupFunction(function () {
    info("Running the cleanup code");
    mockTransferRegisterer.unregister();
    MockFilePicker.cleanup();
    Services.ww.unregisterNotification(windowObserver);
    Services.prefs.clearUserPref(ALWAYS_DOWNLOAD_DIR_PREF);
    Services.prefs.clearUserPref(SAVE_PER_SITE_PREF);
    Services.prefs.clearUserPref(ALWAYS_ASK_PREF);
    Services.prefs.clearUserPref("browser.download.folderList");
    Services.prefs.clearUserPref("browser.download.dir");
    info("Finished running the cleanup code");
  });

  info(
    `Running test with ${ALWAYS_ASK_PREF} set to ${Services.prefs.getBoolPref(
      ALWAYS_ASK_PREF,
      false
    )}`
  );
  testOnWindow(undefined, function (win) {
    let windowGonePromise = BrowserTestUtils.domWindowClosed(win);
    Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, true);
    triggerSave(win, async function () {
      await windowGonePromise;
      Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, false);
      testOnWindow(undefined, function (win2) {
        triggerSave(win2, finish);
      });
    });
  });
}