summaryrefslogtreecommitdiffstats
path: root/toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js')
-rw-r--r--toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js390
1 files changed, 390 insertions, 0 deletions
diff --git a/toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js b/toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js
new file mode 100644
index 0000000000..9b4c0ffa60
--- /dev/null
+++ b/toolkit/components/contentanalysis/tests/browser/browser_print_content_analysis.js
@@ -0,0 +1,390 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/components/printing/tests/head.js",
+ this
+);
+
+const PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
+ Ci.nsIPrintSettingsService
+);
+
+let mockCA = {
+ isActive: true,
+ mightBeActive: true,
+ errorValue: undefined,
+
+ setupForTest(shouldAllowRequest) {
+ this.shouldAllowRequest = shouldAllowRequest;
+ this.errorValue = undefined;
+ this.calls = [];
+ },
+
+ setupForTestWithError(errorValue) {
+ this.errorValue = errorValue;
+ this.calls = [];
+ },
+
+ clearCalls() {
+ this.calls = [];
+ },
+
+ getAction() {
+ if (this.shouldAllowRequest === undefined) {
+ this.shouldAllowRequest = true;
+ }
+ return this.shouldAllowRequest
+ ? Ci.nsIContentAnalysisResponse.eAllow
+ : Ci.nsIContentAnalysisResponse.eBlock;
+ },
+
+ // nsIContentAnalysis methods
+ async analyzeContentRequest(request, _autoAcknowledge) {
+ info(
+ "Mock ContentAnalysis service: analyzeContentRequest, this.shouldAllowRequest=" +
+ this.shouldAllowRequest +
+ ", this.errorValue=" +
+ this.errorValue
+ );
+ this.calls.push(request);
+ if (this.errorValue) {
+ throw this.errorValue;
+ }
+ // Use setTimeout to simulate an async activity
+ await new Promise(res => setTimeout(res, 0));
+ return makeContentAnalysisResponse(this.getAction(), request.requestToken);
+ },
+
+ analyzeContentRequestCallback(request, autoAcknowledge, callback) {
+ info(
+ "Mock ContentAnalysis service: analyzeContentRequestCallback, this.shouldAllowRequest=" +
+ this.shouldAllowRequest +
+ ", this.errorValue=" +
+ this.errorValue
+ );
+ this.calls.push(request);
+ if (this.errorValue) {
+ throw this.errorValue;
+ }
+ let response = makeContentAnalysisResponse(
+ this.getAction(),
+ request.requestToken
+ );
+ // Use setTimeout to simulate an async activity
+ setTimeout(() => {
+ callback.contentResult(response);
+ }, 0);
+ },
+};
+
+add_setup(async function test_setup() {
+ mockCA = mockContentAnalysisService(mockCA);
+});
+
+const TEST_PAGE_URL =
+ "https://example.com/browser/toolkit/components/printing/tests/simplifyArticleSample.html";
+const TEST_PAGE_URL_2 =
+ "https://example.com/browser/toolkit/components/printing/tests/longerArticle.html";
+
+function addUniqueSuffix(prefix) {
+ return `${prefix}-${Services.uuid
+ .generateUUID()
+ .toString()
+ .slice(1, -1)}.pdf`;
+}
+
+async function printToDestination(aBrowser, aDestination) {
+ let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
+ let fileName = addUniqueSuffix(`printDestinationTest-${aDestination}`);
+ let filePath = PathUtils.join(tmpDir.path, fileName);
+
+ info(`Printing to ${filePath}`);
+
+ let settings = PSSVC.createNewPrintSettings();
+ settings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
+ settings.outputDestination = aDestination;
+
+ settings.headerStrCenter = "";
+ settings.headerStrLeft = "";
+ settings.headerStrRight = "";
+ settings.footerStrCenter = "";
+ settings.footerStrLeft = "";
+ settings.footerStrRight = "";
+
+ settings.unwriteableMarginTop = 1; /* Just to ensure settings are respected on both */
+ let outStream = null;
+ if (aDestination == Ci.nsIPrintSettings.kOutputDestinationFile) {
+ settings.toFileName = PathUtils.join(tmpDir.path, fileName);
+ } else {
+ is(aDestination, Ci.nsIPrintSettings.kOutputDestinationStream);
+ outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
+ Ci.nsIFileOutputStream
+ );
+ let tmpFile = tmpDir.clone();
+ tmpFile.append(fileName);
+ outStream.init(tmpFile, -1, 0o666, 0);
+ settings.outputStream = outStream;
+ }
+
+ await aBrowser.browsingContext.print(settings);
+
+ return filePath;
+}
+
+function assertContentAnalysisRequest(request, expectedUrl) {
+ is(request.url.spec, expectedUrl ?? TEST_PAGE_URL, "request has correct URL");
+ is(
+ request.analysisType,
+ Ci.nsIContentAnalysisRequest.ePrint,
+ "request has print analysisType"
+ );
+ is(
+ request.operationTypeForDisplay,
+ Ci.nsIContentAnalysisRequest.eOperationPrint,
+ "request has print operationTypeForDisplay"
+ );
+ is(request.textContent, "", "request textContent should be empty");
+ is(request.filePath, "", "request filePath should be empty");
+ isnot(request.printDataHandle, 0, "request printDataHandle should not be 0");
+ isnot(request.printDataSize, 0, "request printDataSize should not be 0");
+ ok(!!request.requestToken.length, "request requestToken should not be empty");
+}
+
+// Printing to a stream is different than going through the print preview dialog because it
+// doesn't make a static clone of the document before the print, which causes the
+// Content Analysis code to go through a different code path. This is similar to what
+// happens when various preferences are set to skip the print preview dialog, for example
+// print.prefer_system_dialog.
+add_task(
+ async function testPrintToStreamWithContentAnalysisActiveAndAllowing() {
+ await PrintHelper.withTestPage(
+ async helper => {
+ mockCA.setupForTest(true);
+
+ let filePath = await printToDestination(
+ helper.sourceBrowser,
+ Ci.nsIPrintSettings.kOutputDestinationFile
+ );
+ is(
+ mockCA.calls.length,
+ 1,
+ "Correct number of calls to Content Analysis"
+ );
+ assertContentAnalysisRequest(mockCA.calls[0]);
+
+ await waitForFileToAlmostMatchSize(
+ filePath,
+ mockCA.calls[0].printDataSize
+ );
+
+ await IOUtils.remove(filePath);
+ },
+ TEST_PAGE_URL,
+ true
+ );
+ }
+);
+
+add_task(
+ async function testPrintToStreamAfterNavigationWithContentAnalysisActiveAndAllowing() {
+ await PrintHelper.withTestPage(
+ async helper => {
+ mockCA.setupForTest(true);
+
+ let filePath = await printToDestination(
+ helper.sourceBrowser,
+ Ci.nsIPrintSettings.kOutputDestinationFile
+ );
+ is(
+ mockCA.calls.length,
+ 1,
+ "Correct number of calls to Content Analysis"
+ );
+ assertContentAnalysisRequest(mockCA.calls[0]);
+ mockCA.clearCalls();
+
+ await IOUtils.remove(filePath);
+
+ BrowserTestUtils.startLoadingURIString(
+ helper.sourceBrowser,
+ TEST_PAGE_URL_2
+ );
+ await BrowserTestUtils.browserLoaded(helper.sourceBrowser);
+
+ filePath = await printToDestination(
+ helper.sourceBrowser,
+ Ci.nsIPrintSettings.kOutputDestinationFile
+ );
+ is(
+ mockCA.calls.length,
+ 1,
+ "Correct number of calls to Content Analysis"
+ );
+ assertContentAnalysisRequest(mockCA.calls[0], TEST_PAGE_URL_2);
+ await waitForFileToAlmostMatchSize(
+ filePath,
+ mockCA.calls[0].printDataSize
+ );
+ },
+ TEST_PAGE_URL,
+ true
+ );
+ }
+);
+
+add_task(
+ async function testPrintToStreamWithContentAnalysisActiveAndBlocking() {
+ await PrintHelper.withTestPage(
+ async helper => {
+ mockCA.setupForTest(false);
+
+ try {
+ await printToDestination(
+ helper.sourceBrowser,
+ Ci.nsIPrintSettings.kOutputDestinationFile
+ );
+ ok(false, "Content analysis should make this fail to print");
+ } catch (e) {
+ ok(
+ /NS_ERROR_CONTENT_BLOCKED/.test(e.toString()),
+ "Got content blocked error"
+ );
+ }
+ is(
+ mockCA.calls.length,
+ 1,
+ "Correct number of calls to Content Analysis"
+ );
+ assertContentAnalysisRequest(mockCA.calls[0]);
+ },
+ TEST_PAGE_URL,
+ true
+ );
+ }
+);
+
+add_task(async function testPrintToStreamWithContentAnalysisReturningError() {
+ await PrintHelper.withTestPage(
+ async helper => {
+ expectUncaughtException();
+ mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE);
+
+ try {
+ await printToDestination(
+ helper.sourceBrowser,
+ Ci.nsIPrintSettings.kOutputDestinationFile
+ );
+ ok(false, "Content analysis should make this fail to print");
+ } catch (e) {
+ ok(
+ /NS_ERROR_NOT_AVAILABLE/.test(e.toString()),
+ "Error in mock CA was propagated out"
+ );
+ }
+ is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis");
+ assertContentAnalysisRequest(mockCA.calls[0]);
+ },
+ TEST_PAGE_URL,
+ true
+ );
+});
+
+add_task(async function testPrintThroughDialogWithContentAnalysisActive() {
+ await PrintHelper.withTestPage(
+ async helper => {
+ mockCA.setupForTest(true);
+
+ await helper.startPrint();
+ let fileName = addUniqueSuffix(`printDialogTest`);
+ let file = helper.mockFilePicker(fileName);
+ info(`Printing to ${file.path}`);
+ await helper.assertPrintToFile(file, () => {
+ EventUtils.sendKey("return", helper.win);
+ });
+
+ is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis");
+ assertContentAnalysisRequest(mockCA.calls[0]);
+
+ await waitForFileToAlmostMatchSize(
+ file.path,
+ mockCA.calls[0].printDataSize
+ );
+ },
+ TEST_PAGE_URL,
+ true
+ );
+});
+
+add_task(
+ async function testPrintThroughDialogWithContentAnalysisActiveAndBlocking() {
+ await PrintHelper.withTestPage(
+ async helper => {
+ mockCA.setupForTest(false);
+
+ await helper.startPrint();
+ let fileName = addUniqueSuffix(`printDialogTest`);
+ let file = helper.mockFilePicker(fileName);
+ info(`Printing to ${file.path}`);
+ try {
+ await helper.assertPrintToFile(file, () => {
+ EventUtils.sendKey("return", helper.win);
+ });
+ } catch (e) {
+ ok(
+ /Wait for target file to get created/.test(e.toString()),
+ "Target file should not get created"
+ );
+ }
+ ok(!file.exists(), "File should not exist");
+
+ is(
+ mockCA.calls.length,
+ 1,
+ "Correct number of calls to Content Analysis"
+ );
+ assertContentAnalysisRequest(mockCA.calls[0]);
+ },
+ TEST_PAGE_URL,
+ true
+ );
+ }
+);
+
+add_task(
+ async function testPrintThroughDialogWithContentAnalysisReturningError() {
+ await PrintHelper.withTestPage(
+ async helper => {
+ expectUncaughtException();
+ mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE);
+
+ await helper.startPrint();
+ let fileName = addUniqueSuffix(`printDialogTest`);
+ let file = helper.mockFilePicker(fileName);
+ info(`Printing to ${file.path}`);
+ try {
+ await helper.assertPrintToFile(file, () => {
+ EventUtils.sendKey("return", helper.win);
+ });
+ } catch (e) {
+ ok(
+ /Wait for target file to get created/.test(e.toString()),
+ "Target file should not get created"
+ );
+ }
+ ok(!file.exists(), "File should not exist");
+
+ is(
+ mockCA.calls.length,
+ 1,
+ "Correct number of calls to Content Analysis"
+ );
+ assertContentAnalysisRequest(mockCA.calls[0]);
+ },
+ TEST_PAGE_URL,
+ true
+ );
+ }
+);