/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ // Makes sure the moz_origins table and origin frecency stats are updated // correctly. "use strict"; // Visiting a URL with a new origin should immediately update moz_origins. add_task(async function visit() { await checkDB([]); await PlacesTestUtils.addVisits([{ uri: "http://example.com/" }]); await checkDB([["http://", "example.com", ["http://example.com/"]]]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([]); await cleanUp(); }); // Repeatedly visiting a URL with an initially new origin should update // moz_origins (with the correct frecency). add_task(async function visitRepeatedly() { await PlacesTestUtils.addVisits([ { uri: "http://example.com/" }, { uri: "http://example.com/" }, { uri: "http://example.com/" }, ]); await checkDB([["http://", "example.com", ["http://example.com/"]]]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([]); await cleanUp(); }); // Same as previous, but visits are added sequentially. add_task(async function visitRepeatedlySequential() { await PlacesTestUtils.addVisits([{ uri: "http://example.com/" }]); await checkDB([["http://", "example.com", ["http://example.com/"]]]); await PlacesTestUtils.addVisits([{ uri: "http://example.com/" }]); await checkDB([["http://", "example.com", ["http://example.com/"]]]); await PlacesTestUtils.addVisits([{ uri: "http://example.com/" }]); await checkDB([["http://", "example.com", ["http://example.com/"]]]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([]); await cleanUp(); }); // After removing an origin's URLs, visiting a URL with the origin should // immediately update moz_origins. add_task(async function vistAfterDelete() { await PlacesTestUtils.addVisits([{ uri: "http://example.com/" }]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([]); await PlacesTestUtils.addVisits([{ uri: "http://example.com/" }]); await checkDB([["http://", "example.com", ["http://example.com/"]]]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([]); await cleanUp(); }); // Visiting different URLs with the same origin should update moz_origins, and // moz_origins.frecency should be the sum of the URL frecencies. add_task(async function visitDifferentURLsSameOrigin() { await PlacesTestUtils.addVisits([ { uri: "http://example.com/1" }, { uri: "http://example.com/2" }, { uri: "http://example.com/3" }, ]); await checkDB([ [ "http://", "example.com", ["http://example.com/1", "http://example.com/2", "http://example.com/3"], ], ]); await PlacesUtils.history.remove("http://example.com/1"); await checkDB([ [ "http://", "example.com", ["http://example.com/2", "http://example.com/3"], ], ]); await PlacesUtils.history.remove("http://example.com/2"); await checkDB([["http://", "example.com", ["http://example.com/3"]]]); await PlacesUtils.history.remove("http://example.com/3"); await checkDB([]); await cleanUp(); }); // Same as previous, but visits are added sequentially. add_task(async function visitDifferentURLsSameOriginSequential() { await PlacesTestUtils.addVisits([{ uri: "http://example.com/1" }]); await checkDB([["http://", "example.com", ["http://example.com/1"]]]); await PlacesTestUtils.addVisits([{ uri: "http://example.com/2" }]); await checkDB([ [ "http://", "example.com", ["http://example.com/1", "http://example.com/2"], ], ]); await PlacesTestUtils.addVisits([{ uri: "http://example.com/3" }]); await checkDB([ [ "http://", "example.com", ["http://example.com/1", "http://example.com/2", "http://example.com/3"], ], ]); await PlacesUtils.history.remove("http://example.com/1"); await checkDB([ [ "http://", "example.com", ["http://example.com/2", "http://example.com/3"], ], ]); await PlacesUtils.history.remove("http://example.com/2"); await checkDB([["http://", "example.com", ["http://example.com/3"]]]); await PlacesUtils.history.remove("http://example.com/3"); await checkDB([]); await cleanUp(); }); // Repeatedly visiting different URLs with the same origin should update // moz_origins (with the correct frecencies), and moz_origins.frecency should be // the sum of the URL frecencies. add_task(async function visitDifferentURLsSameOriginRepeatedly() { await PlacesTestUtils.addVisits([ { uri: "http://example.com/1" }, { uri: "http://example.com/1" }, { uri: "http://example.com/1" }, { uri: "http://example.com/2" }, { uri: "http://example.com/2" }, { uri: "http://example.com/3" }, ]); await checkDB([ [ "http://", "example.com", ["http://example.com/1", "http://example.com/2", "http://example.com/3"], ], ]); await PlacesUtils.history.remove("http://example.com/1"); await checkDB([ [ "http://", "example.com", ["http://example.com/2", "http://example.com/3"], ], ]); await PlacesUtils.history.remove("http://example.com/2"); await checkDB([["http://", "example.com", ["http://example.com/3"]]]); await PlacesUtils.history.remove("http://example.com/3"); await checkDB([]); await cleanUp(); }); // Visiting URLs with different origins should update moz_origins. add_task(async function visitDifferentOrigins() { await PlacesTestUtils.addVisits([ { uri: "http://example1.com/" }, { uri: "http://example2.com/" }, { uri: "http://example3.com/" }, ]); await checkDB([ ["http://", "example1.com", ["http://example1.com/"]], ["http://", "example2.com", ["http://example2.com/"]], ["http://", "example3.com", ["http://example3.com/"]], ]); await PlacesUtils.history.remove("http://example1.com/"); await checkDB([ ["http://", "example2.com", ["http://example2.com/"]], ["http://", "example3.com", ["http://example3.com/"]], ]); await PlacesUtils.history.remove("http://example2.com/"); await checkDB([["http://", "example3.com", ["http://example3.com/"]]]); await PlacesUtils.history.remove("http://example3.com/"); await checkDB([]); await cleanUp(); }); // Same as previous, but visits are added sequentially. add_task(async function visitDifferentOriginsSequential() { await PlacesTestUtils.addVisits([{ uri: "http://example1.com/" }]); await checkDB([["http://", "example1.com", ["http://example1.com/"]]]); await PlacesTestUtils.addVisits([{ uri: "http://example2.com/" }]); await checkDB([ ["http://", "example1.com", ["http://example1.com/"]], ["http://", "example2.com", ["http://example2.com/"]], ]); await PlacesTestUtils.addVisits([{ uri: "http://example3.com/" }]); await checkDB([ ["http://", "example1.com", ["http://example1.com/"]], ["http://", "example2.com", ["http://example2.com/"]], ["http://", "example3.com", ["http://example3.com/"]], ]); await PlacesUtils.history.remove("http://example1.com/"); await checkDB([ ["http://", "example2.com", ["http://example2.com/"]], ["http://", "example3.com", ["http://example3.com/"]], ]); await PlacesUtils.history.remove("http://example2.com/"); await checkDB([["http://", "example3.com", ["http://example3.com/"]]]); await PlacesUtils.history.remove("http://example3.com/"); await checkDB([]); await cleanUp(); }); // Repeatedly visiting URLs with different origins should update moz_origins // (with the correct frecencies). add_task(async function visitDifferentOriginsRepeatedly() { await PlacesTestUtils.addVisits([ { uri: "http://example1.com/" }, { uri: "http://example1.com/" }, { uri: "http://example1.com/" }, { uri: "http://example2.com/" }, { uri: "http://example2.com/" }, { uri: "http://example3.com/" }, ]); await checkDB([ ["http://", "example1.com", ["http://example1.com/"]], ["http://", "example2.com", ["http://example2.com/"]], ["http://", "example3.com", ["http://example3.com/"]], ]); await PlacesUtils.history.remove("http://example1.com/"); await checkDB([ ["http://", "example2.com", ["http://example2.com/"]], ["http://", "example3.com", ["http://example3.com/"]], ]); await PlacesUtils.history.remove("http://example2.com/"); await checkDB([["http://", "example3.com", ["http://example3.com/"]]]); await PlacesUtils.history.remove("http://example3.com/"); await checkDB([]); await cleanUp(); }); // Visiting URLs, some with the same and some with different origins, should // update moz_origins. add_task(async function visitDifferentOriginsDifferentURLs() { await PlacesTestUtils.addVisits([ { uri: "http://example1.com/1" }, { uri: "http://example1.com/2" }, { uri: "http://example1.com/3" }, { uri: "http://example2.com/1" }, { uri: "http://example2.com/2" }, { uri: "http://example3.com/1" }, ]); await checkDB([ [ "http://", "example1.com", [ "http://example1.com/1", "http://example1.com/2", "http://example1.com/3", ], ], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/1"); await checkDB([ [ "http://", "example1.com", ["http://example1.com/2", "http://example1.com/3"], ], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/2"); await checkDB([ ["http://", "example1.com", ["http://example1.com/3"]], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/3"); await checkDB([ [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example2.com/1"); await checkDB([ ["http://", "example2.com", ["http://example2.com/2"]], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example2.com/2"); await checkDB([["http://", "example3.com", ["http://example3.com/1"]]]); await PlacesUtils.history.remove("http://example3.com/1"); await checkDB([]); }); // Same as previous, but visits are added sequentially. add_task(async function visitDifferentOriginsDifferentURLsSequential() { await PlacesTestUtils.addVisits([{ uri: "http://example1.com/1" }]); await checkDB([["http://", "example1.com", ["http://example1.com/1"]]]); await PlacesTestUtils.addVisits([{ uri: "http://example1.com/2" }]); await checkDB([ [ "http://", "example1.com", ["http://example1.com/1", "http://example1.com/2"], ], ]); await PlacesTestUtils.addVisits([{ uri: "http://example1.com/3" }]); await checkDB([ [ "http://", "example1.com", [ "http://example1.com/1", "http://example1.com/2", "http://example1.com/3", ], ], ]); await PlacesTestUtils.addVisits([{ uri: "http://example2.com/1" }]); await checkDB([ [ "http://", "example1.com", [ "http://example1.com/1", "http://example1.com/2", "http://example1.com/3", ], ], ["http://", "example2.com", ["http://example2.com/1"]], ]); await PlacesTestUtils.addVisits([{ uri: "http://example2.com/2" }]); await checkDB([ [ "http://", "example1.com", [ "http://example1.com/1", "http://example1.com/2", "http://example1.com/3", ], ], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ]); await PlacesTestUtils.addVisits([{ uri: "http://example3.com/1" }]); await checkDB([ [ "http://", "example1.com", [ "http://example1.com/1", "http://example1.com/2", "http://example1.com/3", ], ], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/1"); await checkDB([ [ "http://", "example1.com", ["http://example1.com/2", "http://example1.com/3"], ], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/2"); await checkDB([ ["http://", "example1.com", ["http://example1.com/3"]], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/3"); await checkDB([ [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example2.com/1"); await checkDB([ ["http://", "example2.com", ["http://example2.com/2"]], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example2.com/2"); await checkDB([["http://", "example3.com", ["http://example3.com/1"]]]); await PlacesUtils.history.remove("http://example3.com/1"); await checkDB([]); }); // Repeatedly visiting URLs, some with the same and some with different origins, // should update moz_origins (with the correct frecencies). add_task(async function visitDifferentOriginsDifferentURLsRepeatedly() { await PlacesTestUtils.addVisits([ { uri: "http://example1.com/1" }, { uri: "http://example1.com/1" }, { uri: "http://example1.com/1" }, { uri: "http://example1.com/2" }, { uri: "http://example1.com/2" }, { uri: "http://example1.com/3" }, { uri: "http://example2.com/1" }, { uri: "http://example2.com/1" }, { uri: "http://example2.com/1" }, { uri: "http://example2.com/2" }, { uri: "http://example2.com/2" }, { uri: "http://example3.com/1" }, { uri: "http://example3.com/1" }, ]); await checkDB([ [ "http://", "example1.com", [ "http://example1.com/1", "http://example1.com/2", "http://example1.com/3", ], ], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/1"); await checkDB([ [ "http://", "example1.com", ["http://example1.com/2", "http://example1.com/3"], ], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/2"); await checkDB([ ["http://", "example1.com", ["http://example1.com/3"]], [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example1.com/3"); await checkDB([ [ "http://", "example2.com", ["http://example2.com/1", "http://example2.com/2"], ], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example2.com/1"); await checkDB([ ["http://", "example2.com", ["http://example2.com/2"]], ["http://", "example3.com", ["http://example3.com/1"]], ]); await PlacesUtils.history.remove("http://example2.com/2"); await checkDB([["http://", "example3.com", ["http://example3.com/1"]]]); await PlacesUtils.history.remove("http://example3.com/1"); await checkDB([]); }); // Makes sure URIs with the same TLD but different www subdomains are recognized // as different origins. Makes sure removing one doesn't remove the others. add_task(async function www1() { await PlacesTestUtils.addVisits([ { uri: "http://example.com/" }, { uri: "http://www.example.com/" }, { uri: "http://www.www.example.com/" }, ]); await checkDB([ ["http://", "example.com", ["http://example.com/"]], ["http://", "www.example.com", ["http://www.example.com/"]], ["http://", "www.www.example.com", ["http://www.www.example.com/"]], ]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([ ["http://", "www.example.com", ["http://www.example.com/"]], ["http://", "www.www.example.com", ["http://www.www.example.com/"]], ]); await PlacesUtils.history.remove("http://www.example.com/"); await checkDB([ ["http://", "www.www.example.com", ["http://www.www.example.com/"]], ]); await PlacesUtils.history.remove("http://www.www.example.com/"); await checkDB([]); await cleanUp(); }); // Same as www1, but removes URIs in a different order. add_task(async function www2() { await PlacesTestUtils.addVisits([ { uri: "http://example.com/" }, { uri: "http://www.example.com/" }, { uri: "http://www.www.example.com/" }, ]); await checkDB([ ["http://", "example.com", ["http://example.com/"]], ["http://", "www.example.com", ["http://www.example.com/"]], ["http://", "www.www.example.com", ["http://www.www.example.com/"]], ]); await PlacesUtils.history.remove("http://www.www.example.com/"); await checkDB([ ["http://", "example.com", ["http://example.com/"]], ["http://", "www.example.com", ["http://www.example.com/"]], ]); await PlacesUtils.history.remove("http://www.example.com/"); await checkDB([["http://", "example.com", ["http://example.com/"]]]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([]); await cleanUp(); }); // Makes sure removing an origin without a port doesn't remove the same host // with a port. add_task(async function ports1() { await PlacesTestUtils.addVisits([ { uri: "http://example.com/" }, { uri: "http://example.com:8888/" }, ]); await checkDB([ ["http://", "example.com", ["http://example.com/"]], ["http://", "example.com:8888", ["http://example.com:8888/"]], ]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([ ["http://", "example.com:8888", ["http://example.com:8888/"]], ]); await PlacesUtils.history.remove("http://example.com:8888/"); await checkDB([]); await cleanUp(); }); // Makes sure removing an origin with a port doesn't remove the same host // without a port. add_task(async function ports2() { await PlacesTestUtils.addVisits([ { uri: "http://example.com/" }, { uri: "http://example.com:8888/" }, ]); await checkDB([ ["http://", "example.com", ["http://example.com/"]], ["http://", "example.com:8888", ["http://example.com:8888/"]], ]); await PlacesUtils.history.remove("http://example.com:8888/"); await checkDB([["http://", "example.com", ["http://example.com/"]]]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([]); await cleanUp(); }); // Makes sure multiple URIs with the same origin don't create duplicate origins. add_task(async function duplicates() { await PlacesTestUtils.addVisits([ { uri: "http://example.com/" }, { uri: "http://www.example.com/" }, { uri: "http://www.www.example.com/" }, { uri: "https://example.com/" }, { uri: "ftp://example.com/" }, { uri: "foo://example.com/" }, { uri: "bar:example.com/" }, { uri: "http://example.com:8888/" }, { uri: "http://example.com/dupe" }, { uri: "http://www.example.com/dupe" }, { uri: "http://www.www.example.com/dupe" }, { uri: "https://example.com/dupe" }, { uri: "ftp://example.com/dupe" }, { uri: "foo://example.com/dupe" }, { uri: "bar:example.com/dupe" }, { uri: "http://example.com:8888/dupe" }, ]); await checkDB([ [ "http://", "example.com", ["http://example.com/", "http://example.com/dupe"], ], [ "http://", "www.example.com", ["http://www.example.com/", "http://www.example.com/dupe"], ], [ "http://", "www.www.example.com", ["http://www.www.example.com/", "http://www.www.example.com/dupe"], ], [ "https://", "example.com", ["https://example.com/", "https://example.com/dupe"], ], ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("http://example.com/"); await checkDB([ ["http://", "example.com", ["http://example.com/dupe"]], [ "http://", "www.example.com", ["http://www.example.com/", "http://www.example.com/dupe"], ], [ "http://", "www.www.example.com", ["http://www.www.example.com/", "http://www.www.example.com/dupe"], ], [ "https://", "example.com", ["https://example.com/", "https://example.com/dupe"], ], ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("http://example.com/dupe"); await checkDB([ [ "http://", "www.example.com", ["http://www.example.com/", "http://www.example.com/dupe"], ], [ "http://", "www.www.example.com", ["http://www.www.example.com/", "http://www.www.example.com/dupe"], ], [ "https://", "example.com", ["https://example.com/", "https://example.com/dupe"], ], ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("http://www.example.com/"); await checkDB([ ["http://", "www.example.com", ["http://www.example.com/dupe"]], [ "http://", "www.www.example.com", ["http://www.www.example.com/", "http://www.www.example.com/dupe"], ], [ "https://", "example.com", ["https://example.com/", "https://example.com/dupe"], ], ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("http://www.example.com/dupe"); await checkDB([ [ "http://", "www.www.example.com", ["http://www.www.example.com/", "http://www.www.example.com/dupe"], ], [ "https://", "example.com", ["https://example.com/", "https://example.com/dupe"], ], ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("http://www.www.example.com/"); await checkDB([ ["http://", "www.www.example.com", ["http://www.www.example.com/dupe"]], [ "https://", "example.com", ["https://example.com/", "https://example.com/dupe"], ], ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("http://www.www.example.com/dupe"); await checkDB([ [ "https://", "example.com", ["https://example.com/", "https://example.com/dupe"], ], ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("https://example.com/"); await checkDB([ ["https://", "example.com", ["https://example.com/dupe"]], ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("https://example.com/dupe"); await checkDB([ ["ftp://", "example.com", ["ftp://example.com/", "ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("ftp://example.com/"); await checkDB([ ["ftp://", "example.com", ["ftp://example.com/dupe"]], ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("ftp://example.com/dupe"); await checkDB([ ["foo://", "example.com", ["foo://example.com/", "foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("foo://example.com/"); await checkDB([ ["foo://", "example.com", ["foo://example.com/dupe"]], ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("foo://example.com/dupe"); await checkDB([ ["bar:", "example.com", ["bar:example.com/", "bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("bar:example.com/"); await checkDB([ ["bar:", "example.com", ["bar:example.com/dupe"]], [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("bar:example.com/dupe"); await checkDB([ [ "http://", "example.com:8888", ["http://example.com:8888/", "http://example.com:8888/dupe"], ], ]); await PlacesUtils.history.remove("http://example.com:8888/"); await checkDB([ ["http://", "example.com:8888", ["http://example.com:8888/dupe"]], ]); await PlacesUtils.history.remove("http://example.com:8888/dupe"); await checkDB([]); await cleanUp(); }); // Makes sure adding and removing bookmarks creates origins. add_task(async function addRemoveBookmarks() { let bookmarks = []; let urls = ["http://example.com/", "http://www.example.com/"]; for (let url of urls) { bookmarks.push( await PlacesUtils.bookmarks.insert({ url, parentGuid: PlacesUtils.bookmarks.unfiledGuid, }) ); } await checkDB([ ["http://", "example.com", ["http://example.com/"]], ["http://", "www.example.com", ["http://www.example.com/"]], ]); await PlacesUtils.bookmarks.remove(bookmarks[0]); await PlacesUtils.history.clear(); await checkDB([["http://", "www.example.com", ["http://www.example.com/"]]]); await PlacesUtils.bookmarks.remove(bookmarks[1]); await PlacesUtils.history.clear(); await checkDB([]); await cleanUp(); }); // Makes sure changing bookmarks also changes the corresponding origins. add_task(async function changeBookmarks() { let bookmarks = []; let urls = ["http://example.com/", "http://www.example.com/"]; for (let url of urls) { bookmarks.push( await PlacesUtils.bookmarks.insert({ url, parentGuid: PlacesUtils.bookmarks.unfiledGuid, }) ); } await checkDB([ ["http://", "example.com", ["http://example.com/"]], ["http://", "www.example.com", ["http://www.example.com/"]], ]); await PlacesUtils.bookmarks.update({ url: "http://www.example.com/", guid: bookmarks[0].guid, }); await PlacesUtils.history.clear(); await checkDB([["http://", "www.example.com", ["http://www.example.com/"]]]); await cleanUp(); }); // A slightly more complex test to make sure origin frecency stats are updated // when visits and bookmarks are added and removed. add_task(async function moreOriginFrecencyStats() { await checkDB([]); // Add a URL 0 visit. await PlacesTestUtils.addVisits([{ uri: "http://example.com/0" }]); await checkDB([["http://", "example.com", ["http://example.com/0"]]]); // Add a URL 1 visit. await PlacesTestUtils.addVisits([{ uri: "http://example.com/1" }]); await checkDB([ [ "http://", "example.com", ["http://example.com/0", "http://example.com/1"], ], ]); // Add a URL 2 visit. await PlacesTestUtils.addVisits([{ uri: "http://example.com/2" }]); await checkDB([ [ "http://", "example.com", ["http://example.com/0", "http://example.com/1", "http://example.com/2"], ], ]); // Add another URL 2 visit. await PlacesTestUtils.addVisits([{ uri: "http://example.com/2" }]); await checkDB([ [ "http://", "example.com", ["http://example.com/0", "http://example.com/1", "http://example.com/2"], ], ]); // Remove URL 2's visits. await PlacesUtils.history.remove(["http://example.com/2"]); await checkDB([ [ "http://", "example.com", ["http://example.com/0", "http://example.com/1"], ], ]); // Bookmark URL 1. let bookmark = await PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid, title: "A bookmark", url: NetUtil.newURI("http://example.com/1"), }); await checkDB([ [ "http://", "example.com", ["http://example.com/0", "http://example.com/1"], ], ]); // Remove URL 1's visit. await PlacesUtils.history.remove(["http://example.com/1"]); await checkDB([ [ "http://", "example.com", ["http://example.com/0", "http://example.com/1"], ], ]); // Remove URL 1's bookmark. Also need to call history.remove() again to // remove the URL from moz_places. Otherwise it sticks around and keeps // contributing to the frecency stats. await PlacesUtils.bookmarks.remove(bookmark); await PlacesUtils.history.remove("http://example.com/1"); await checkDB([["http://", "example.com", ["http://example.com/0"]]]); // Remove URL 0. await PlacesUtils.history.remove(["http://example.com/0"]); await checkDB([]); await cleanUp(); }); add_task(async function test_cutoff() { // Add first page with visit. await PlacesTestUtils.addVisits([{ uri: "http://example.com/0" }]); // Add a second page last visited before the cutoff, it should be ignored. let visitDate = PlacesUtils.toPRTime( new Date( new Date().setDate( -Services.prefs.getIntPref("places.frecency.originsCutOffDays", 90) ) ) ); await PlacesTestUtils.addVisits([{ uri: "http://example.com/1", visitDate }]); // Add a third page with visit both before and after the cutoff, should count. await PlacesTestUtils.addVisits([ { uri: "http://example.com/2" }, { uri: "http://example.com/2", visitDate }, ]); await checkDB([ [ "http://", "example.com", ["http://example.com/0", "http://example.com/2"], ], ]); await cleanUp(); }); /** * Returns the expected frecency of the origin of the given URLs, i.e., the sum * of their frecencies. Each URL is expected to have the same origin. * * @param urls * An array of URL strings. * @return The expected origin frecency. */ async function expectedOriginFrecency(urls) { let value = 0; for (let url of urls) { let v = Math.max( (await PlacesTestUtils.getDatabaseValue("moz_places", "frecency", { url, last_visit_date: [">", 0], })) ?? 0, 0 ); value += v; } return value || 1.0; } /** * Asserts that the moz_origins table and the origin frecency stats are correct. * * @param expectedOrigins * An array of expected origins. Each origin in the array is itself an * array that looks like this: * [prefix, host, [url1, url2, ..., urln]] * The element at index 2 is an array of all the URLs with the origin. * If you don't care about checking frecencies and origin frecency stats, * this element can be `undefined`. */ async function checkDB(expectedOrigins) { await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); let db = await PlacesUtils.promiseDBConnection(); let rows = await db.execute(` SELECT prefix, host, frecency FROM moz_origins ORDER BY id ASC `); let checkFrecencies = !expectedOrigins.length || expectedOrigins[0][2] !== undefined; let actualOrigins = rows.map(row => { let o = []; for (let c = 0; c < (checkFrecencies ? 3 : 2); c++) { o.push(row.getResultByIndex(c)); } return o; }); let expected = []; for (let origin of expectedOrigins) { expected.push( origin .slice(0, 2) .concat(checkFrecencies ? await expectedOriginFrecency(origin[2]) : []) ); } Assert.deepEqual(actualOrigins, expected); if (checkFrecencies) { info("Checking threshold"); await PlacesTestUtils.dumpTable({ db, table: "moz_origins" }); await checkThreshold(expected.map(o => o[2])); } } /** * Asserts that the origin frecency threshold is correct. * * @param expectedOriginFrecencies * An array of expected origin frecencies. */ async function checkThreshold(expectedOriginFrecencies) { const DEFAULT_THRESHOLD = 2.0; let threshold = await PlacesUtils.metadata.get( "origin_frecency_threshold", DEFAULT_THRESHOLD ); Assert.equal( threshold, expectedOriginFrecencies.length ? expectedOriginFrecencies.reduce((a, b) => a + b, 0) / expectedOriginFrecencies.length : DEFAULT_THRESHOLD ); } async function cleanUp() { await PlacesUtils.bookmarks.eraseEverything(); await PlacesUtils.history.clear(); }