Bug 1964606 - make cancelling Content Analysis request from the busy dialog work r=dlp-reviewers,haik
The fix to bug 1963360 broke cancelling in the dialog. This is a small fix but I also added a few tests around the busy/cancel dialog, which will hopefully prevent these kinds of regressions in the future. Differential Revision: https://phabricator.services.mozilla.com/D248103
This commit is contained in:
committed by
gstoll@mozilla.com
parent
435f34d647
commit
358bbfae32
@@ -760,10 +760,7 @@ export const ContentAnalysis = {
|
||||
.finally(() => {
|
||||
// This is also called if the tab/window is closed while a request is
|
||||
// in progress, in which case we need to cancel all related requests.
|
||||
if (this.requestTokenToRequestInfo.delete(aRequestToken)) {
|
||||
// TODO: Is this useful? I think no.
|
||||
this._removeSlowCAMessage(aUserActionId, aRequestToken);
|
||||
}
|
||||
//
|
||||
// If aUserActionId is still in userActionToBusyDialogMap,
|
||||
// this means the dialog wasn't closed by _disconnectFromView(),
|
||||
// so cancel the operation.
|
||||
@@ -772,6 +769,14 @@ export const ContentAnalysis = {
|
||||
aUserActionId
|
||||
);
|
||||
}
|
||||
// Do this after checking userActionToBusyDialogMap, since
|
||||
// _removeSlowCAMessage() will remove the entry from
|
||||
// userActionToBusyDialogMap.
|
||||
if (this.requestTokenToRequestInfo.delete(aRequestToken)) {
|
||||
// I think this is needed to clean up when the tab/window
|
||||
// is closed.
|
||||
this._removeSlowCAMessage(aUserActionId, aRequestToken);
|
||||
}
|
||||
});
|
||||
return {
|
||||
dialogBrowsingContext: aBrowsingContext,
|
||||
|
||||
@@ -58,6 +58,8 @@ support-files = [
|
||||
"clipboard_read_async.html",
|
||||
]
|
||||
|
||||
["browser_content_analysis_busy_dialog.js"]
|
||||
|
||||
["browser_content_analysis_dnd_diff_origin.js"]
|
||||
support-files = [
|
||||
"!/dom/events/test/browser_dragdrop_impl.js",
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let mockCA = makeMockContentAnalysis();
|
||||
|
||||
add_setup(async function test_setup() {
|
||||
mockCA = await mockContentAnalysisService(mockCA);
|
||||
});
|
||||
|
||||
const testPage =
|
||||
"<body style='margin: 0'><input id='input' type='text'></body>";
|
||||
|
||||
const CLIPBOARD_TEXT_STRING = "Just some text";
|
||||
|
||||
function setClipboardData(clipboardString) {
|
||||
const trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
|
||||
Ci.nsITransferable
|
||||
);
|
||||
trans.init(null);
|
||||
trans.addDataFlavor("text/plain");
|
||||
const str = Cc["@mozilla.org/supports-string;1"].createInstance(
|
||||
Ci.nsISupportsString
|
||||
);
|
||||
str.data = clipboardString;
|
||||
trans.setTransferData("text/plain", str);
|
||||
|
||||
// Write to clipboard.
|
||||
Services.clipboard.setData(trans, null, Ci.nsIClipboard.kGlobalClipboard);
|
||||
}
|
||||
|
||||
async function getElementValue(browser, elementId) {
|
||||
return await SpecialPowers.spawn(browser, [elementId], async elementId => {
|
||||
return content.document.getElementById(elementId).value;
|
||||
});
|
||||
}
|
||||
|
||||
async function testBusyDialog(cancel) {
|
||||
mockCA.setupForTest(true, /* waitForEvent */ true, /* showDialogs */ true);
|
||||
let tab = BrowserTestUtils.addTab(gBrowser);
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
gBrowser.selectedTab = tab;
|
||||
await promiseTabLoadEvent(tab, "data:text/html," + escape(testPage));
|
||||
await SimpleTest.promiseFocus(browser);
|
||||
|
||||
setClipboardData(CLIPBOARD_TEXT_STRING);
|
||||
|
||||
let scanStartedPromise = new Promise(res => {
|
||||
mockCA.eventTarget.addEventListener(
|
||||
"inAnalyzeContentRequest",
|
||||
() => {
|
||||
res();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
|
||||
// Paste into content
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.getElementById("input").value = "";
|
||||
content.document.getElementById("input").focus();
|
||||
});
|
||||
|
||||
// Wait for busy dialog and click cancel if specified
|
||||
let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
|
||||
let doPastePromise = BrowserTestUtils.synthesizeKey(
|
||||
"v",
|
||||
{ accelKey: true },
|
||||
browser
|
||||
);
|
||||
await scanStartedPromise;
|
||||
|
||||
let win = await dialogPromise;
|
||||
let dialog = win.document.querySelector("dialog");
|
||||
|
||||
if (cancel) {
|
||||
dialog.getButton("cancel").click();
|
||||
await TestUtils.waitForCondition(
|
||||
() => mockCA.agentCancelCalls === 1,
|
||||
"checking number of cancel calls after dialog closed"
|
||||
);
|
||||
}
|
||||
// Make the request complete.
|
||||
mockCA.eventTarget.dispatchEvent(
|
||||
new CustomEvent("returnContentAnalysisResponse")
|
||||
);
|
||||
|
||||
await doPastePromise;
|
||||
ok(!dialog.open, "dialog should not be open");
|
||||
|
||||
is(
|
||||
mockCA.agentCancelCalls,
|
||||
cancel ? 1 : 0,
|
||||
"checking number of cancel calls after request finishes"
|
||||
);
|
||||
is(
|
||||
await getElementValue(browser, "input"),
|
||||
cancel ? "" : CLIPBOARD_TEXT_STRING,
|
||||
"checking text field contents"
|
||||
);
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
|
||||
async function testClosingTab() {
|
||||
mockCA.setupForTest(true, /* waitForEvent */ true, /* showDialogs */ true);
|
||||
let tab = BrowserTestUtils.addTab(gBrowser);
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
gBrowser.selectedTab = tab;
|
||||
await promiseTabLoadEvent(tab, "data:text/html," + escape(testPage));
|
||||
await SimpleTest.promiseFocus(browser);
|
||||
|
||||
setClipboardData(CLIPBOARD_TEXT_STRING);
|
||||
|
||||
let scanStartedPromise = new Promise(res => {
|
||||
mockCA.eventTarget.addEventListener(
|
||||
"inAnalyzeContentRequest",
|
||||
() => {
|
||||
res();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
|
||||
// Paste into content
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.getElementById("input").value = "";
|
||||
content.document.getElementById("input").focus();
|
||||
});
|
||||
|
||||
let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
|
||||
let doPastePromise = BrowserTestUtils.synthesizeKey(
|
||||
"v",
|
||||
{ accelKey: true },
|
||||
browser
|
||||
);
|
||||
await scanStartedPromise;
|
||||
|
||||
let win = await dialogPromise;
|
||||
let dialog = win.document.querySelector("dialog");
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
await TestUtils.waitForCondition(
|
||||
() => mockCA.agentCancelCalls === 1,
|
||||
"checking number of cancel calls after tab closed"
|
||||
);
|
||||
|
||||
// Make the request complete.
|
||||
mockCA.eventTarget.dispatchEvent(
|
||||
new CustomEvent("returnContentAnalysisResponse")
|
||||
);
|
||||
|
||||
await doPastePromise;
|
||||
ok(!dialog.open, "dialog should not be open");
|
||||
}
|
||||
|
||||
// Ensure that when a DLP request is made, the busy dialog is shown
|
||||
// and when cancel is clicked, the request is cancelled and the
|
||||
// paste is not done.
|
||||
add_task(async function testBusyConfirmationDialogWithCancel() {
|
||||
await testBusyDialog(true);
|
||||
});
|
||||
|
||||
// Ensure that when a DLP request is made, the busy dialog is shown
|
||||
// and when the analysis is done the busy dialog goes away and the
|
||||
// paste is done.
|
||||
add_task(async function testBusyConfirmationDialogWithNoCancel() {
|
||||
await testBusyDialog(false);
|
||||
});
|
||||
|
||||
// Ensure that when a DLP request is made and then the tab is closed,
|
||||
// the busy dialog is closed and the request is cancelled.
|
||||
add_task(async function testClosingTabCancelsRequest() {
|
||||
await testClosingTab();
|
||||
});
|
||||
Reference in New Issue
Block a user