forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			864 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			864 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 | |
| /* vim: set sts=2 sw=2 et tw=80: */
 | |
| "use strict";
 | |
| 
 | |
| const { AddonTestUtils } = ChromeUtils.importESModule(
 | |
|   "resource://testing-common/AddonTestUtils.sys.mjs"
 | |
| );
 | |
| 
 | |
| ChromeUtils.defineESModuleGetters(this, {
 | |
|   ExtensionCommon: "resource://gre/modules/ExtensionCommon.sys.mjs",
 | |
|   PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
 | |
|   PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
 | |
| });
 | |
| 
 | |
| AddonTestUtils.init(this);
 | |
| AddonTestUtils.overrideCertDB();
 | |
| AddonTestUtils.createAppInfo(
 | |
|   "xpcshell@tests.mozilla.org",
 | |
|   "XPCShell",
 | |
|   "1",
 | |
|   "43"
 | |
| );
 | |
| 
 | |
| add_task(async function test_delete() {
 | |
|   function background() {
 | |
|     let historyClearedCount = 0;
 | |
|     let removedUrls = [];
 | |
| 
 | |
|     browser.history.onVisitRemoved.addListener(data => {
 | |
|       if (data.allHistory) {
 | |
|         historyClearedCount++;
 | |
|         browser.test.assertEq(
 | |
|           0,
 | |
|           data.urls.length,
 | |
|           "onVisitRemoved received an empty urls array"
 | |
|         );
 | |
|       } else {
 | |
|         removedUrls.push(...data.urls);
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     browser.test.onMessage.addListener((msg, arg) => {
 | |
|       if (msg === "delete-url") {
 | |
|         browser.history.deleteUrl({ url: arg }).then(result => {
 | |
|           browser.test.assertEq(
 | |
|             undefined,
 | |
|             result,
 | |
|             "browser.history.deleteUrl returns nothing"
 | |
|           );
 | |
|           browser.test.sendMessage("url-deleted");
 | |
|         });
 | |
|       } else if (msg === "delete-range") {
 | |
|         browser.history.deleteRange(arg).then(result => {
 | |
|           browser.test.assertEq(
 | |
|             undefined,
 | |
|             result,
 | |
|             "browser.history.deleteRange returns nothing"
 | |
|           );
 | |
|           browser.test.sendMessage("range-deleted", removedUrls);
 | |
|         });
 | |
|       } else if (msg === "delete-all") {
 | |
|         browser.history.deleteAll().then(result => {
 | |
|           browser.test.assertEq(
 | |
|             undefined,
 | |
|             result,
 | |
|             "browser.history.deleteAll returns nothing"
 | |
|           );
 | |
|           browser.test.sendMessage("history-cleared", [
 | |
|             historyClearedCount,
 | |
|             removedUrls,
 | |
|           ]);
 | |
|         });
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     browser.test.sendMessage("ready");
 | |
|   }
 | |
| 
 | |
|   const BASE_URL = "http://mozilla.com/test_history/";
 | |
| 
 | |
|   let extension = ExtensionTestUtils.loadExtension({
 | |
|     manifest: {
 | |
|       permissions: ["history"],
 | |
|     },
 | |
|     background: `(${background})()`,
 | |
|   });
 | |
| 
 | |
|   await extension.startup();
 | |
|   await extension.awaitMessage("ready");
 | |
|   await PlacesUtils.history.clear();
 | |
| 
 | |
|   let historyClearedCount;
 | |
|   let visits = [];
 | |
|   let visitDate = new Date(1999, 9, 9, 9, 9).getTime();
 | |
| 
 | |
|   function pushVisit(subvisits) {
 | |
|     visitDate += 1000;
 | |
|     subvisits.push({ date: new Date(visitDate) });
 | |
|   }
 | |
| 
 | |
|   // Add 5 visits for one uri and 3 visits for 3 others
 | |
|   for (let i = 0; i < 4; ++i) {
 | |
|     let visit = {
 | |
|       url: `${BASE_URL}${i}`,
 | |
|       title: "visit " + i,
 | |
|       visits: [],
 | |
|     };
 | |
|     if (i === 0) {
 | |
|       for (let j = 0; j < 5; ++j) {
 | |
|         pushVisit(visit.visits);
 | |
|       }
 | |
|     } else {
 | |
|       pushVisit(visit.visits);
 | |
|     }
 | |
|     visits.push(visit);
 | |
|   }
 | |
| 
 | |
|   await PlacesUtils.history.insertMany(visits);
 | |
|   equal(
 | |
|     await PlacesTestUtils.visitsInDB(visits[0].url),
 | |
|     5,
 | |
|     "5 visits for uri found in history database"
 | |
|   );
 | |
| 
 | |
|   let testUrl = visits[2].url;
 | |
|   ok(
 | |
|     await PlacesTestUtils.isPageInDB(testUrl),
 | |
|     "expected url found in history database"
 | |
|   );
 | |
| 
 | |
|   extension.sendMessage("delete-url", testUrl);
 | |
|   await extension.awaitMessage("url-deleted");
 | |
|   equal(
 | |
|     await PlacesTestUtils.isPageInDB(testUrl),
 | |
|     false,
 | |
|     "expected url not found in history database"
 | |
|   );
 | |
| 
 | |
|   // delete 3 of the 5 visits for url 1
 | |
|   let filter = {
 | |
|     startTime: visits[0].visits[0].date,
 | |
|     endTime: visits[0].visits[2].date,
 | |
|   };
 | |
| 
 | |
|   extension.sendMessage("delete-range", filter);
 | |
|   let removedUrls = await extension.awaitMessage("range-deleted");
 | |
|   ok(
 | |
|     !removedUrls.includes(visits[0].url),
 | |
|     `${visits[0].url} not received by onVisitRemoved`
 | |
|   );
 | |
|   ok(
 | |
|     await PlacesTestUtils.isPageInDB(visits[0].url),
 | |
|     "expected uri found in history database"
 | |
|   );
 | |
|   equal(
 | |
|     await PlacesTestUtils.visitsInDB(visits[0].url),
 | |
|     2,
 | |
|     "2 visits for uri found in history database"
 | |
|   );
 | |
|   ok(
 | |
|     await PlacesTestUtils.isPageInDB(visits[1].url),
 | |
|     "expected uri found in history database"
 | |
|   );
 | |
|   equal(
 | |
|     await PlacesTestUtils.visitsInDB(visits[1].url),
 | |
|     1,
 | |
|     "1 visit for uri found in history database"
 | |
|   );
 | |
| 
 | |
|   // delete the rest of the visits for url 1, and the visit for url 2
 | |
|   filter.startTime = visits[0].visits[0].date;
 | |
|   filter.endTime = visits[1].visits[0].date;
 | |
| 
 | |
|   extension.sendMessage("delete-range", filter);
 | |
|   await extension.awaitMessage("range-deleted");
 | |
| 
 | |
|   equal(
 | |
|     await PlacesTestUtils.isPageInDB(visits[0].url),
 | |
|     false,
 | |
|     "expected uri not found in history database"
 | |
|   );
 | |
|   equal(
 | |
|     await PlacesTestUtils.visitsInDB(visits[0].url),
 | |
|     0,
 | |
|     "0 visits for uri found in history database"
 | |
|   );
 | |
|   equal(
 | |
|     await PlacesTestUtils.isPageInDB(visits[1].url),
 | |
|     false,
 | |
|     "expected uri not found in history database"
 | |
|   );
 | |
|   equal(
 | |
|     await PlacesTestUtils.visitsInDB(visits[1].url),
 | |
|     0,
 | |
|     "0 visits for uri found in history database"
 | |
|   );
 | |
| 
 | |
|   ok(
 | |
|     await PlacesTestUtils.isPageInDB(visits[3].url),
 | |
|     "expected uri found in history database"
 | |
|   );
 | |
| 
 | |
|   extension.sendMessage("delete-all");
 | |
|   [historyClearedCount, removedUrls] = await extension.awaitMessage(
 | |
|     "history-cleared"
 | |
|   );
 | |
|   equal(
 | |
|     historyClearedCount,
 | |
|     2,
 | |
|     "onVisitRemoved called for each clearing of history"
 | |
|   );
 | |
|   equal(
 | |
|     removedUrls.length,
 | |
|     3,
 | |
|     "onVisitRemoved called the expected number of times"
 | |
|   );
 | |
|   for (let i = 1; i < 3; ++i) {
 | |
|     let url = visits[i].url;
 | |
|     ok(removedUrls.includes(url), `${url} received by onVisitRemoved`);
 | |
|   }
 | |
|   await extension.unload();
 | |
| });
 | |
| 
 | |
| const SINGLE_VISIT_URL = "http://example.com/";
 | |
| const DOUBLE_VISIT_URL = "http://example.com/2/";
 | |
| const MOZILLA_VISIT_URL = "http://mozilla.com/";
 | |
| const REFERENCE_DATE = new Date();
 | |
| // pages/visits to add via History.insert
 | |
| const PAGE_INFOS = [
 | |
|   {
 | |
|     url: SINGLE_VISIT_URL,
 | |
|     title: `test visit for ${SINGLE_VISIT_URL}`,
 | |
|     visits: [{ date: new Date(Number(REFERENCE_DATE) - 1000) }],
 | |
|   },
 | |
|   {
 | |
|     url: DOUBLE_VISIT_URL,
 | |
|     title: `test visit for ${DOUBLE_VISIT_URL}`,
 | |
|     visits: [
 | |
|       { date: REFERENCE_DATE },
 | |
|       { date: new Date(Number(REFERENCE_DATE) - 2000) },
 | |
|     ],
 | |
|   },
 | |
|   {
 | |
|     url: MOZILLA_VISIT_URL,
 | |
|     title: `test visit for ${MOZILLA_VISIT_URL}`,
 | |
|     visits: [{ date: new Date(Number(REFERENCE_DATE) - 3000) }],
 | |
|   },
 | |
| ];
 | |
| 
 | |
| add_task(async function test_search() {
 | |
|   function background(BGSCRIPT_REFERENCE_DATE) {
 | |
|     const futureTime = Date.now() + 24 * 60 * 60 * 1000;
 | |
| 
 | |
|     browser.test.onMessage.addListener(() => {
 | |
|       browser.history
 | |
|         .search({ text: "" })
 | |
|         .then(results => {
 | |
|           browser.test.sendMessage("empty-search", results);
 | |
|           return browser.history.search({ text: "mozilla.com" });
 | |
|         })
 | |
|         .then(results => {
 | |
|           browser.test.sendMessage("text-search", results);
 | |
|           return browser.history.search({ text: "example.com", maxResults: 1 });
 | |
|         })
 | |
|         .then(results => {
 | |
|           browser.test.sendMessage("max-results-search", results);
 | |
|           return browser.history.search({
 | |
|             text: "",
 | |
|             startTime: BGSCRIPT_REFERENCE_DATE - 2000,
 | |
|             endTime: BGSCRIPT_REFERENCE_DATE - 1000,
 | |
|           });
 | |
|         })
 | |
|         .then(results => {
 | |
|           browser.test.sendMessage("date-range-search", results);
 | |
|           return browser.history.search({ text: "", startTime: futureTime });
 | |
|         })
 | |
|         .then(results => {
 | |
|           browser.test.assertEq(
 | |
|             0,
 | |
|             results.length,
 | |
|             "no results returned for late start time"
 | |
|           );
 | |
|           return browser.history.search({ text: "", endTime: 0 });
 | |
|         })
 | |
|         .then(results => {
 | |
|           browser.test.assertEq(
 | |
|             0,
 | |
|             results.length,
 | |
|             "no results returned for early end time"
 | |
|           );
 | |
|           return browser.history.search({
 | |
|             text: "",
 | |
|             startTime: Date.now(),
 | |
|             endTime: 0,
 | |
|           });
 | |
|         })
 | |
|         .then(
 | |
|           () => {
 | |
|             browser.test.fail(
 | |
|               "history.search rejects with startTime that is after the endTime"
 | |
|             );
 | |
|           },
 | |
|           error => {
 | |
|             browser.test.assertEq(
 | |
|               "The startTime cannot be after the endTime",
 | |
|               error.message,
 | |
|               "history.search rejects with startTime that is after the endTime"
 | |
|             );
 | |
|           }
 | |
|         )
 | |
|         .then(() => {
 | |
|           browser.test.notifyPass("search");
 | |
|         });
 | |
|     });
 | |
| 
 | |
|     browser.test.sendMessage("ready");
 | |
|   }
 | |
| 
 | |
|   let extension = ExtensionTestUtils.loadExtension({
 | |
|     manifest: {
 | |
|       permissions: ["history"],
 | |
|     },
 | |
|     background: `(${background})(${Number(REFERENCE_DATE)})`,
 | |
|   });
 | |
| 
 | |
|   function findResult(url, results) {
 | |
|     return results.find(r => r.url === url);
 | |
|   }
 | |
| 
 | |
|   function checkResult(results, url, expectedCount) {
 | |
|     let result = findResult(url, results);
 | |
|     notEqual(result, null, `history.search result was found for ${url}`);
 | |
|     equal(
 | |
|       result.visitCount,
 | |
|       expectedCount,
 | |
|       `history.search reports ${expectedCount} visit(s)`
 | |
|     );
 | |
|     equal(
 | |
|       result.title,
 | |
|       `test visit for ${url}`,
 | |
|       "title for search result is correct"
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   await extension.startup();
 | |
|   await extension.awaitMessage("ready");
 | |
|   await PlacesUtils.history.clear();
 | |
| 
 | |
|   await PlacesUtils.history.insertMany(PAGE_INFOS);
 | |
| 
 | |
|   extension.sendMessage("check-history");
 | |
| 
 | |
|   let results = await extension.awaitMessage("empty-search");
 | |
|   equal(results.length, 3, "history.search with empty text returned 3 results");
 | |
|   checkResult(results, SINGLE_VISIT_URL, 1);
 | |
|   checkResult(results, DOUBLE_VISIT_URL, 2);
 | |
|   checkResult(results, MOZILLA_VISIT_URL, 1);
 | |
| 
 | |
|   results = await extension.awaitMessage("text-search");
 | |
|   equal(
 | |
|     results.length,
 | |
|     1,
 | |
|     "history.search with specific text returned 1 result"
 | |
|   );
 | |
|   checkResult(results, MOZILLA_VISIT_URL, 1);
 | |
| 
 | |
|   results = await extension.awaitMessage("max-results-search");
 | |
|   equal(results.length, 1, "history.search with maxResults returned 1 result");
 | |
|   checkResult(results, DOUBLE_VISIT_URL, 2);
 | |
| 
 | |
|   results = await extension.awaitMessage("date-range-search");
 | |
|   equal(
 | |
|     results.length,
 | |
|     2,
 | |
|     "history.search with a date range returned 2 result"
 | |
|   );
 | |
|   checkResult(results, DOUBLE_VISIT_URL, 2);
 | |
|   checkResult(results, SINGLE_VISIT_URL, 1);
 | |
| 
 | |
|   await extension.awaitFinish("search");
 | |
|   await extension.unload();
 | |
|   await PlacesUtils.history.clear();
 | |
| });
 | |
| 
 | |
| add_task(async function test_add_url() {
 | |
|   function background() {
 | |
|     const TEST_DOMAIN = "http://example.com/";
 | |
| 
 | |
|     browser.test.onMessage.addListener((msg, testData) => {
 | |
|       let [details, type] = testData;
 | |
|       details.url = details.url || `${TEST_DOMAIN}${type}`;
 | |
|       if (msg === "add-url") {
 | |
|         details.title = `Title for ${type}`;
 | |
|         browser.history
 | |
|           .addUrl(details)
 | |
|           .then(() => {
 | |
|             return browser.history.search({ text: details.url });
 | |
|           })
 | |
|           .then(results => {
 | |
|             browser.test.assertEq(
 | |
|               1,
 | |
|               results.length,
 | |
|               "1 result found when searching for added URL"
 | |
|             );
 | |
|             browser.test.sendMessage("url-added", {
 | |
|               details,
 | |
|               result: results[0],
 | |
|             });
 | |
|           });
 | |
|       } else if (msg === "expect-failure") {
 | |
|         let expectedMsg = testData[2];
 | |
|         browser.history.addUrl(details).then(
 | |
|           () => {
 | |
|             browser.test.fail(`Expected error thrown for ${type}`);
 | |
|           },
 | |
|           error => {
 | |
|             browser.test.assertTrue(
 | |
|               error.message.includes(expectedMsg),
 | |
|               `"Expected error thrown when trying to add a URL with  ${type}`
 | |
|             );
 | |
|             browser.test.sendMessage("add-failed");
 | |
|           }
 | |
|         );
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     browser.test.sendMessage("ready");
 | |
|   }
 | |
| 
 | |
|   let addTestData = [
 | |
|     [{}, "default"],
 | |
|     [{ visitTime: new Date() }, "with_date"],
 | |
|     [{ visitTime: Date.now() }, "with_ms_number"],
 | |
|     [{ visitTime: new Date().toISOString() }, "with_iso_string"],
 | |
|     [{ transition: "typed" }, "valid_transition"],
 | |
|   ];
 | |
| 
 | |
|   let failTestData = [
 | |
|     [
 | |
|       { transition: "generated" },
 | |
|       "an invalid transition",
 | |
|       "|generated| is not a supported transition for history",
 | |
|     ],
 | |
|     [{ visitTime: Date.now() + 1000000 }, "a future date", "Invalid value"],
 | |
|     [{ url: "about.config" }, "an invalid url", "Invalid value"],
 | |
|   ];
 | |
| 
 | |
|   async function checkUrl(results) {
 | |
|     ok(
 | |
|       await PlacesTestUtils.isPageInDB(results.details.url),
 | |
|       `${results.details.url} found in history database`
 | |
|     );
 | |
|     ok(
 | |
|       PlacesUtils.isValidGuid(results.result.id),
 | |
|       "URL was added with a valid id"
 | |
|     );
 | |
|     equal(
 | |
|       results.result.title,
 | |
|       results.details.title,
 | |
|       "URL was added with the correct title"
 | |
|     );
 | |
|     if (results.details.visitTime) {
 | |
|       equal(
 | |
|         results.result.lastVisitTime,
 | |
|         Number(ExtensionCommon.normalizeTime(results.details.visitTime)),
 | |
|         "URL was added with the correct date"
 | |
|       );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   let extension = ExtensionTestUtils.loadExtension({
 | |
|     manifest: {
 | |
|       permissions: ["history"],
 | |
|     },
 | |
|     background: `(${background})()`,
 | |
|   });
 | |
| 
 | |
|   await PlacesUtils.history.clear();
 | |
|   await extension.startup();
 | |
|   await extension.awaitMessage("ready");
 | |
| 
 | |
|   for (let data of addTestData) {
 | |
|     extension.sendMessage("add-url", data);
 | |
|     let results = await extension.awaitMessage("url-added");
 | |
|     await checkUrl(results);
 | |
|   }
 | |
| 
 | |
|   for (let data of failTestData) {
 | |
|     extension.sendMessage("expect-failure", data);
 | |
|     await extension.awaitMessage("add-failed");
 | |
|   }
 | |
| 
 | |
|   await extension.unload();
 | |
| });
 | |
| 
 | |
| add_task(async function test_get_visits() {
 | |
|   async function background() {
 | |
|     const TEST_DOMAIN = "http://example.com/";
 | |
|     const FIRST_DATE = Date.now();
 | |
|     const INITIAL_DETAILS = {
 | |
|       url: TEST_DOMAIN,
 | |
|       visitTime: FIRST_DATE,
 | |
|       transition: "link",
 | |
|     };
 | |
| 
 | |
|     let visitIds = new Set();
 | |
| 
 | |
|     async function checkVisit(visit, expected) {
 | |
|       visitIds.add(visit.visitId);
 | |
|       browser.test.assertEq(
 | |
|         expected.visitTime,
 | |
|         visit.visitTime,
 | |
|         "visit has the correct visitTime"
 | |
|       );
 | |
|       browser.test.assertEq(
 | |
|         expected.transition,
 | |
|         visit.transition,
 | |
|         "visit has the correct transition"
 | |
|       );
 | |
|       let results = await browser.history.search({ text: expected.url });
 | |
|       // all results will have the same id, so we only need to use the first one
 | |
|       browser.test.assertEq(
 | |
|         results[0].id,
 | |
|         visit.id,
 | |
|         "visit has the correct id"
 | |
|       );
 | |
|     }
 | |
| 
 | |
|     let details = Object.assign({}, INITIAL_DETAILS);
 | |
| 
 | |
|     await browser.history.addUrl(details);
 | |
|     let results = await browser.history.getVisits({ url: details.url });
 | |
| 
 | |
|     browser.test.assertEq(
 | |
|       1,
 | |
|       results.length,
 | |
|       "the expected number of visits were returned"
 | |
|     );
 | |
|     await checkVisit(results[0], details);
 | |
| 
 | |
|     details.url = `${TEST_DOMAIN}/1/`;
 | |
|     await browser.history.addUrl(details);
 | |
| 
 | |
|     results = await browser.history.getVisits({ url: details.url });
 | |
|     browser.test.assertEq(
 | |
|       1,
 | |
|       results.length,
 | |
|       "the expected number of visits were returned"
 | |
|     );
 | |
|     await checkVisit(results[0], details);
 | |
| 
 | |
|     details.visitTime = FIRST_DATE - 1000;
 | |
|     details.transition = "typed";
 | |
|     await browser.history.addUrl(details);
 | |
|     results = await browser.history.getVisits({ url: details.url });
 | |
| 
 | |
|     browser.test.assertEq(
 | |
|       2,
 | |
|       results.length,
 | |
|       "the expected number of visits were returned"
 | |
|     );
 | |
|     await checkVisit(results[0], INITIAL_DETAILS);
 | |
|     await checkVisit(results[1], details);
 | |
|     browser.test.assertEq(3, visitIds.size, "each visit has a unique visitId");
 | |
|     await browser.test.notifyPass("get-visits");
 | |
|   }
 | |
| 
 | |
|   let extension = ExtensionTestUtils.loadExtension({
 | |
|     manifest: {
 | |
|       permissions: ["history"],
 | |
|     },
 | |
|     background: `(${background})()`,
 | |
|   });
 | |
| 
 | |
|   await PlacesUtils.history.clear();
 | |
|   await extension.startup();
 | |
| 
 | |
|   await extension.awaitFinish("get-visits");
 | |
|   await extension.unload();
 | |
| });
 | |
| 
 | |
| add_task(async function test_transition_types() {
 | |
|   const VISIT_URL_PREFIX = "http://example.com/";
 | |
|   const TRANSITIONS = [
 | |
|     ["link", Ci.nsINavHistoryService.TRANSITION_LINK],
 | |
|     ["typed", Ci.nsINavHistoryService.TRANSITION_TYPED],
 | |
|     ["auto_bookmark", Ci.nsINavHistoryService.TRANSITION_BOOKMARK],
 | |
|     // Only session history contains TRANSITION_EMBED visits,
 | |
|     // So global history query cannot find them.
 | |
|     // ["auto_subframe", Ci.nsINavHistoryService.TRANSITION_EMBED],
 | |
|     // Redirects are not correctly tested here because History
 | |
|     // will not make redirect entries hidden.
 | |
|     ["link", Ci.nsINavHistoryService.TRANSITION_REDIRECT_PERMANENT],
 | |
|     ["link", Ci.nsINavHistoryService.TRANSITION_REDIRECT_TEMPORARY],
 | |
|     ["link", Ci.nsINavHistoryService.TRANSITION_DOWNLOAD],
 | |
|     ["manual_subframe", Ci.nsINavHistoryService.TRANSITION_FRAMED_LINK],
 | |
|     ["reload", Ci.nsINavHistoryService.TRANSITION_RELOAD],
 | |
|   ];
 | |
| 
 | |
|   // pages/visits to add via History.insertMany
 | |
|   let pageInfos = [];
 | |
|   let visitDate = new Date(1999, 9, 9, 9, 9).getTime();
 | |
|   for (let [, transitionType] of TRANSITIONS) {
 | |
|     pageInfos.push({
 | |
|       url: VISIT_URL_PREFIX + transitionType + "/",
 | |
|       visits: [
 | |
|         { transition: transitionType, date: new Date((visitDate -= 1000)) },
 | |
|       ],
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   function background() {
 | |
|     browser.test.onMessage.addListener(async (msg, url) => {
 | |
|       switch (msg) {
 | |
|         case "search": {
 | |
|           let results = await browser.history.search({
 | |
|             text: "",
 | |
|             startTime: new Date(0),
 | |
|           });
 | |
|           browser.test.sendMessage("search-result", results);
 | |
|           break;
 | |
|         }
 | |
|         case "get-visits": {
 | |
|           let results = await browser.history.getVisits({ url });
 | |
|           browser.test.sendMessage("get-visits-result", results);
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     browser.test.sendMessage("ready");
 | |
|   }
 | |
| 
 | |
|   let extension = ExtensionTestUtils.loadExtension({
 | |
|     manifest: {
 | |
|       permissions: ["history"],
 | |
|     },
 | |
|     background,
 | |
|   });
 | |
| 
 | |
|   await PlacesUtils.history.clear();
 | |
|   await extension.startup();
 | |
|   await extension.awaitMessage("ready");
 | |
| 
 | |
|   await PlacesUtils.history.insertMany(pageInfos);
 | |
| 
 | |
|   extension.sendMessage("search");
 | |
|   let results = await extension.awaitMessage("search-result");
 | |
|   equal(
 | |
|     results.length,
 | |
|     pageInfos.length,
 | |
|     "search returned expected length of results"
 | |
|   );
 | |
|   for (let i = 0; i < pageInfos.length; ++i) {
 | |
|     equal(results[i].url, pageInfos[i].url, "search returned the expected url");
 | |
| 
 | |
|     extension.sendMessage("get-visits", pageInfos[i].url);
 | |
|     let visits = await extension.awaitMessage("get-visits-result");
 | |
|     equal(visits.length, 1, "getVisits returned expected length of visits");
 | |
|     equal(
 | |
|       visits[0].transition,
 | |
|       TRANSITIONS[i][0],
 | |
|       "getVisits returned the expected transition"
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   await extension.unload();
 | |
| });
 | |
| 
 | |
| add_task(async function test_on_visited() {
 | |
|   const SINGLE_VISIT_URL = "http://example.com/1/";
 | |
|   const DOUBLE_VISIT_URL = "http://example.com/2/";
 | |
|   let visitDate = new Date(1999, 9, 9, 9, 9).getTime();
 | |
| 
 | |
|   // pages/visits to add via History.insertMany
 | |
|   const PAGE_INFOS = [
 | |
|     {
 | |
|       url: SINGLE_VISIT_URL,
 | |
|       title: `visit to ${SINGLE_VISIT_URL}`,
 | |
|       visits: [{ date: new Date(visitDate) }],
 | |
|     },
 | |
|     {
 | |
|       url: DOUBLE_VISIT_URL,
 | |
|       title: `visit to ${DOUBLE_VISIT_URL}`,
 | |
|       visits: [
 | |
|         { date: new Date((visitDate += 1000)) },
 | |
|         { date: new Date((visitDate += 1000)) },
 | |
|       ],
 | |
|     },
 | |
|     {
 | |
|       url: SINGLE_VISIT_URL,
 | |
|       title: "Title Changed",
 | |
|       visits: [{ date: new Date(visitDate) }],
 | |
|     },
 | |
|   ];
 | |
| 
 | |
|   function background() {
 | |
|     let onVisitedData = [];
 | |
| 
 | |
|     browser.history.onVisited.addListener(data => {
 | |
|       if (data.url.includes("moz-extension")) {
 | |
|         return;
 | |
|       }
 | |
|       onVisitedData.push(data);
 | |
|       if (onVisitedData.length == 4) {
 | |
|         browser.test.sendMessage("on-visited-data", onVisitedData);
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     // Verifying onTitleChange Event along with onVisited event
 | |
|     browser.history.onTitleChanged.addListener(data => {
 | |
|       browser.test.sendMessage("on-title-changed-data", data);
 | |
|     });
 | |
| 
 | |
|     browser.test.sendMessage("ready");
 | |
|   }
 | |
| 
 | |
|   let extension = ExtensionTestUtils.loadExtension({
 | |
|     manifest: {
 | |
|       permissions: ["history"],
 | |
|     },
 | |
|     background: `(${background})()`,
 | |
|   });
 | |
| 
 | |
|   await PlacesUtils.history.clear();
 | |
|   await extension.startup();
 | |
|   await extension.awaitMessage("ready");
 | |
| 
 | |
|   await PlacesUtils.history.insertMany(PAGE_INFOS);
 | |
| 
 | |
|   let onVisitedData = await extension.awaitMessage("on-visited-data");
 | |
| 
 | |
|   function checkOnVisitedData(index, expected) {
 | |
|     let onVisited = onVisitedData[index];
 | |
|     ok(PlacesUtils.isValidGuid(onVisited.id), "onVisited received a valid id");
 | |
|     equal(onVisited.url, expected.url, "onVisited received the expected url");
 | |
|     equal(
 | |
|       onVisited.title,
 | |
|       expected.title,
 | |
|       "onVisited received the expected title"
 | |
|     );
 | |
|     equal(
 | |
|       onVisited.lastVisitTime,
 | |
|       expected.time,
 | |
|       "onVisited received the expected time"
 | |
|     );
 | |
|     equal(
 | |
|       onVisited.visitCount,
 | |
|       expected.visitCount,
 | |
|       "onVisited received the expected visitCount"
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   let expected = {
 | |
|     url: PAGE_INFOS[0].url,
 | |
|     title: PAGE_INFOS[0].title,
 | |
|     time: PAGE_INFOS[0].visits[0].date.getTime(),
 | |
|     visitCount: 1,
 | |
|   };
 | |
|   checkOnVisitedData(0, expected);
 | |
| 
 | |
|   expected.url = PAGE_INFOS[1].url;
 | |
|   expected.title = PAGE_INFOS[1].title;
 | |
|   expected.time = PAGE_INFOS[1].visits[0].date.getTime();
 | |
|   checkOnVisitedData(1, expected);
 | |
| 
 | |
|   expected.time = PAGE_INFOS[1].visits[1].date.getTime();
 | |
|   expected.visitCount = 2;
 | |
|   checkOnVisitedData(2, expected);
 | |
| 
 | |
|   expected.url = PAGE_INFOS[2].url;
 | |
|   expected.title = PAGE_INFOS[2].title;
 | |
|   expected.time = PAGE_INFOS[2].visits[0].date.getTime();
 | |
|   expected.visitCount = 2;
 | |
|   checkOnVisitedData(3, expected);
 | |
| 
 | |
|   let onTitleChangedData = await extension.awaitMessage(
 | |
|     "on-title-changed-data"
 | |
|   );
 | |
|   Assert.deepEqual(
 | |
|     {
 | |
|       id: onVisitedData[3].id,
 | |
|       url: SINGLE_VISIT_URL,
 | |
|       title: "Title Changed",
 | |
|     },
 | |
|     onTitleChangedData,
 | |
|     "expected event data for onTitleChanged"
 | |
|   );
 | |
| 
 | |
|   await extension.unload();
 | |
| });
 | |
| 
 | |
| add_task(
 | |
|   {
 | |
|     pref_set: [["extensions.eventPages.enabled", true]],
 | |
|   },
 | |
|   async function test_history_event_page() {
 | |
|     await AddonTestUtils.promiseStartupManager();
 | |
|     let extension = ExtensionTestUtils.loadExtension({
 | |
|       useAddonManager: "permanent",
 | |
|       manifest: {
 | |
|         browser_specific_settings: { gecko: { id: "eventpage@history" } },
 | |
|         permissions: ["history"],
 | |
|         background: { persistent: false },
 | |
|       },
 | |
|       background() {
 | |
|         browser.history.onVisited.addListener(() => {
 | |
|           browser.test.sendMessage("onVisited");
 | |
|         });
 | |
|         browser.history.onVisitRemoved.addListener(() => {
 | |
|           browser.test.sendMessage("onVisitRemoved");
 | |
|         });
 | |
|         browser.history.onTitleChanged.addListener(() => {});
 | |
|         browser.test.sendMessage("ready");
 | |
|       },
 | |
|     });
 | |
| 
 | |
|     const EVENTS = ["onVisited", "onVisitRemoved", "onTitleChanged"];
 | |
|     await PlacesUtils.history.clear();
 | |
| 
 | |
|     await extension.startup();
 | |
|     await extension.awaitMessage("ready");
 | |
|     for (let event of EVENTS) {
 | |
|       assertPersistentListeners(extension, "history", event, {
 | |
|         primed: false,
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     // test events waken background
 | |
|     await extension.terminateBackground();
 | |
|     for (let event of EVENTS) {
 | |
|       assertPersistentListeners(extension, "history", event, {
 | |
|         primed: true,
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     await PlacesUtils.history.insertMany(PAGE_INFOS);
 | |
| 
 | |
|     await extension.awaitMessage("ready");
 | |
|     await extension.awaitMessage("onVisited");
 | |
|     ok(true, "persistent event woke background");
 | |
|     for (let event of EVENTS) {
 | |
|       assertPersistentListeners(extension, "history", event, {
 | |
|         primed: false,
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     await AddonTestUtils.promiseRestartManager();
 | |
|     await extension.awaitStartup();
 | |
| 
 | |
|     for (let event of EVENTS) {
 | |
|       assertPersistentListeners(extension, "history", event, {
 | |
|         primed: true,
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     await PlacesUtils.history.clear();
 | |
|     await extension.awaitMessage("ready");
 | |
|     await extension.awaitMessage("onVisitRemoved");
 | |
| 
 | |
|     await extension.unload();
 | |
|     await AddonTestUtils.promiseShutdownManager();
 | |
|   }
 | |
| );
 | 
