Index: test/synchronizer.js |
=================================================================== |
--- a/test/synchronizer.js |
+++ b/test/synchronizer.js |
@@ -12,527 +12,539 @@ |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
*/ |
"use strict"; |
+const assert = require("assert"); |
let { |
- createSandbox, setupTimerAndXMLHttp, setupRandomResult, unexpectedError, Cr, |
+ createSandbox, setupTimerAndXMLHttp, setupRandomResult, Cr, |
MILLIS_IN_SECOND, MILLIS_IN_HOUR |
} = require("./_common"); |
let filterStorage = null; |
let Prefs = null; |
let Subscription = null; |
-exports.setUp = function(callback) |
-{ |
- let globals = Object.assign({}, setupTimerAndXMLHttp.call(this), |
- setupRandomResult.call(this)); |
- |
- let sandboxedRequire = createSandbox({globals}); |
- ( |
- {filterStorage} = sandboxedRequire("../lib/filterStorage"), |
- {Prefs} = sandboxedRequire("./stub-modules/prefs"), |
- {Subscription} = sandboxedRequire("../lib/subscriptionClasses"), |
- sandboxedRequire("../lib/synchronizer") |
- ); |
- |
- callback(); |
-}; |
- |
-function resetSubscription(subscription) |
+describe("Synchronizer", () => |
{ |
- filterStorage.updateSubscriptionFilters(subscription, []); |
- subscription.lastCheck = subscription.lastDownload = |
- subscription.version = subscription.lastSuccess = |
- subscription.expires = subscription.softExpiration = 0; |
- subscription.title = ""; |
- subscription.homepage = null; |
- subscription.errors = 0; |
- subscription.downloadStatus = null; |
- subscription.requiredVersion = null; |
-} |
+ let runner = {}; |
+ |
+ beforeEach(() => |
+ { |
+ runner = {}; |
+ let globals = Object.assign({}, setupTimerAndXMLHttp.call(runner), |
+ setupRandomResult.call(runner)); |
-let initialDelay = 1 / 60; |
- |
-exports.testOneSubscriptionDownloads = function(test) |
-{ |
- let subscription = Subscription.fromURL("http://example.com/subscription"); |
- filterStorage.addSubscription(subscription); |
- |
- let requests = []; |
- this.registerHandler("/subscription", metadata => |
- { |
- requests.push([this.getTimeOffset(), metadata.method, metadata.path]); |
- return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; |
+ let sandboxedRequire = createSandbox({globals}); |
+ ( |
+ {filterStorage} = sandboxedRequire("../lib/filterStorage"), |
+ {Prefs} = sandboxedRequire("./stub-modules/prefs"), |
+ {Subscription} = sandboxedRequire("../lib/subscriptionClasses"), |
+ sandboxedRequire("../lib/synchronizer") |
+ ); |
}); |
- this.runScheduledTasks(50).then(() => |
+ function resetSubscription(subscription) |
{ |
- test.deepEqual(requests, [ |
- [0 + initialDelay, "GET", "/subscription"], |
- [24 + initialDelay, "GET", "/subscription"], |
- [48 + initialDelay, "GET", "/subscription"] |
- ], "Requests after 50 hours"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
-}; |
+ filterStorage.updateSubscriptionFilters(subscription, []); |
+ subscription.lastCheck = subscription.lastDownload = |
+ subscription.version = subscription.lastSuccess = |
+ subscription.expires = subscription.softExpiration = 0; |
+ subscription.title = ""; |
+ subscription.homepage = null; |
+ subscription.errors = 0; |
+ subscription.downloadStatus = null; |
+ subscription.requiredVersion = null; |
+ } |
+ |
+ let initialDelay = 1 / 60; |
+ |
+ describe("Downloads", () => |
+ { |
+ it("One Subscription", () => |
+ { |
+ let subscription = Subscription.fromURL("http://example.com/subscription"); |
+ filterStorage.addSubscription(subscription); |
-exports.testTwoSubscriptionsDownloads = function(test) |
-{ |
- let subscription1 = Subscription.fromURL("http://example.com/subscription1"); |
- filterStorage.addSubscription(subscription1); |
+ let requests = []; |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ requests.push([runner.getTimeOffset(), metadata.method, metadata.path]); |
+ return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; |
+ }); |
+ |
+ return runner.runScheduledTasks(50).then(() => |
+ { |
+ assert.deepEqual(requests, [ |
+ [0 + initialDelay, "GET", "/subscription"], |
+ [24 + initialDelay, "GET", "/subscription"], |
+ [48 + initialDelay, "GET", "/subscription"] |
+ ], "Requests after 50 hours"); |
+ }); |
+ }); |
- let subscription2 = Subscription.fromURL("http://example.com/subscription2"); |
- subscription2.expires = |
- subscription2.softExpiration = |
- (this.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND; |
- filterStorage.addSubscription(subscription2); |
+ it("Two Subscriptions", () => |
+ { |
+ let subscription1 = Subscription.fromURL("http://example.com/subscription1"); |
+ filterStorage.addSubscription(subscription1); |
- let requests = []; |
- let handler = metadata => |
- { |
- requests.push([this.getTimeOffset(), metadata.method, metadata.path]); |
- return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; |
- }; |
+ let subscription2 = Subscription.fromURL("http://example.com/subscription2"); |
+ subscription2.expires = |
+ subscription2.softExpiration = |
+ (runner.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND; |
+ filterStorage.addSubscription(subscription2); |
+ |
+ let requests = []; |
+ let handler = metadata => |
+ { |
+ requests.push([runner.getTimeOffset(), metadata.method, metadata.path]); |
+ return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"]; |
+ }; |
- this.registerHandler("/subscription1", handler); |
- this.registerHandler("/subscription2", handler); |
+ runner.registerHandler("/subscription1", handler); |
+ runner.registerHandler("/subscription2", handler); |
- this.runScheduledTasks(55).then(() => |
+ return runner.runScheduledTasks(55).then(() => |
+ { |
+ assert.deepEqual(requests, [ |
+ [0 + initialDelay, "GET", "/subscription1"], |
+ [2 + initialDelay, "GET", "/subscription2"], |
+ [24 + initialDelay, "GET", "/subscription1"], |
+ [26 + initialDelay, "GET", "/subscription2"], |
+ [48 + initialDelay, "GET", "/subscription1"], |
+ [50 + initialDelay, "GET", "/subscription2"] |
+ ], "Requests after 55 hours"); |
+ }); |
+ }); |
+ }); |
+ |
+ describe("Subscription Headers", () => |
{ |
- test.deepEqual(requests, [ |
- [0 + initialDelay, "GET", "/subscription1"], |
- [2 + initialDelay, "GET", "/subscription2"], |
- [24 + initialDelay, "GET", "/subscription1"], |
- [26 + initialDelay, "GET", "/subscription2"], |
- [48 + initialDelay, "GET", "/subscription1"], |
- [50 + initialDelay, "GET", "/subscription2"] |
- ], "Requests after 55 hours"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
-}; |
+ for (let currentTest of [ |
+ {header: "[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: null}, |
+ {header: "[Adblock Plus]", downloadStatus: "synchronize_ok", requiredVersion: null}, |
+ {header: "(something)[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: null}, |
+ {header: "[Adblock Plus 0.0.1]", downloadStatus: "synchronize_ok", requiredVersion: "0.0.1"}, |
+ {header: "[Adblock Plus 99.9]", downloadStatus: "synchronize_ok", requiredVersion: "99.9"}, |
+ {header: "[Foo]", downloadStatus: "synchronize_invalid_data", requiredVersion: null} |
+ ]) |
+ { |
+ it(currentTest.header, () => |
+ { |
+ let subscription = Subscription.fromURL("http://example.com/subscription"); |
+ filterStorage.addSubscription(subscription); |
+ |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ return [Cr.NS_OK, 200, currentTest.header + "\n!Expires: 8 hours\nfoo\n!bar\n\n@@bas\n#bam"]; |
+ }); |
-exports.testSubscriptionHeaders = {}; |
+ return runner.runScheduledTasks(2).then(() => |
+ { |
+ assert.equal(subscription.downloadStatus, currentTest.downloadStatus, "Download status"); |
+ assert.equal(subscription.requiredVersion, currentTest.requiredVersion, "Required version"); |
-for (let currentTest of [ |
- {header: "[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: null}, |
- {header: "[Adblock Plus]", downloadStatus: "synchronize_ok", requiredVersion: null}, |
- {header: "(something)[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: null}, |
- {header: "[Adblock Plus 0.0.1]", downloadStatus: "synchronize_ok", requiredVersion: "0.0.1"}, |
- {header: "[Adblock Plus 99.9]", downloadStatus: "synchronize_ok", requiredVersion: "99.9"}, |
- {header: "[Foo]", downloadStatus: "synchronize_invalid_data", requiredVersion: null} |
-]) |
-{ |
- exports.testSubscriptionHeaders[currentTest.header] = function(test) |
+ if (currentTest.downloadStatus == "synchronize_ok") |
+ { |
+ assert.deepEqual([...subscription.filterText()], ["foo", "!bar", "@@bas", "#bam"], "Resulting subscription filters"); |
+ } |
+ else |
+ { |
+ assert.deepEqual([...subscription.filterText()], [ |
+ ], "Resulting subscription filters"); |
+ } |
+ }); |
+ }); |
+ } |
+ }); |
+ |
+ it("Disable Updates", () => |
{ |
+ Prefs.subscriptions_autoupdate = false; |
+ |
let subscription = Subscription.fromURL("http://example.com/subscription"); |
filterStorage.addSubscription(subscription); |
- this.registerHandler("/subscription", metadata => |
+ let requests = 0; |
+ runner.registerHandler("/subscription", metadata => |
{ |
- return [Cr.NS_OK, 200, currentTest.header + "\n!Expires: 8 hours\nfoo\n!bar\n\n@@bas\n#bam"]; |
+ requests++; |
+ throw new Error("Unexpected request"); |
}); |
- this.runScheduledTasks(2).then(() => |
+ return runner.runScheduledTasks(50).then(() => |
{ |
- test.equal(subscription.downloadStatus, currentTest.downloadStatus, "Download status"); |
- test.equal(subscription.requiredVersion, currentTest.requiredVersion, "Required version"); |
- |
- if (currentTest.downloadStatus == "synchronize_ok") |
- { |
- test.deepEqual([...subscription.filterText()], ["foo", "!bar", "@@bas", "#bam"], "Resulting subscription filters"); |
- } |
- else |
- { |
- test.deepEqual([...subscription.filterText()], [ |
- ], "Resulting subscription filters"); |
- } |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
- }; |
-} |
- |
-exports.testsDisabledUpdates = function(test) |
-{ |
- Prefs.subscriptions_autoupdate = false; |
- |
- let subscription = Subscription.fromURL("http://example.com/subscription"); |
- filterStorage.addSubscription(subscription); |
- |
- let requests = 0; |
- this.registerHandler("/subscription", metadata => |
- { |
- requests++; |
- throw new Error("Unexpected request"); |
+ assert.equal(requests, 0, "Request count"); |
+ }); |
}); |
- this.runScheduledTasks(50).then(() => |
- { |
- test.equal(requests, 0, "Request count"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
-}; |
- |
-exports.testExpirationTime = {}; |
- |
-for (let currentTest of [ |
- { |
- expiration: "default", |
- randomResult: 0.5, |
- requests: [0 + initialDelay, 5 * 24 + initialDelay] |
- }, |
- { |
- expiration: "1 hours", // Minimal expiration interval |
- randomResult: 0.5, |
- requests: [0 + initialDelay, 1 + initialDelay, 2 + initialDelay, 3 + initialDelay] |
- }, |
- { |
- expiration: "26 hours", |
- randomResult: 0.5, |
- requests: [0 + initialDelay, 26 + initialDelay] |
- }, |
- { |
- expiration: "2 days", |
- randomResult: 0.5, |
- requests: [0 + initialDelay, 48 + initialDelay] |
- }, |
- { |
- expiration: "20 days", // Too large, will be corrected |
- randomResult: 0.5, |
- requests: [0 + initialDelay, 14 * 24 + initialDelay] |
- }, |
+ describe("Expiration time", () => |
{ |
- expiration: "35 hours", |
- randomResult: 0, // Changes interval by factor 0.8 |
- requests: [0 + initialDelay, 28 + initialDelay] |
- }, |
- { |
- expiration: "35 hours", |
- randomResult: 1, // Changes interval by factor 1.2 |
- requests: [0 + initialDelay, 42 + initialDelay] |
- }, |
- { |
- expiration: "35 hours", |
- randomResult: 0.25, // Changes interval by factor 0.9 |
- requests: [0 + initialDelay, 32 + initialDelay] |
- }, |
- { |
- expiration: "40 hours", |
- randomResult: 0.5, |
- skipAfter: 5 + initialDelay, |
- skip: 10, // Short break should not increase soft expiration |
- requests: [0 + initialDelay, 40 + initialDelay] |
- }, |
+ for (let currentTest of [ |
+ { |
+ expiration: "default", |
+ randomResult: 0.5, |
+ requests: [0 + initialDelay, 5 * 24 + initialDelay] |
+ }, |
+ { |
+ expiration: "1 hours", // Minimal expiration interval |
+ randomResult: 0.5, |
+ requests: [0 + initialDelay, 1 + initialDelay, 2 + initialDelay, 3 + initialDelay] |
+ }, |
+ { |
+ expiration: "26 hours", |
+ randomResult: 0.5, |
+ requests: [0 + initialDelay, 26 + initialDelay] |
+ }, |
+ { |
+ expiration: "2 days", |
+ randomResult: 0.5, |
+ requests: [0 + initialDelay, 48 + initialDelay] |
+ }, |
+ { |
+ expiration: "20 days", // Too large, will be corrected |
+ randomResult: 0.5, |
+ requests: [0 + initialDelay, 14 * 24 + initialDelay] |
+ }, |
+ { |
+ expiration: "35 hours", |
+ randomResult: 0, // Changes interval by factor 0.8 |
+ requests: [0 + initialDelay, 28 + initialDelay] |
+ }, |
+ { |
+ expiration: "35 hours", |
+ randomResult: 1, // Changes interval by factor 1.2 |
+ requests: [0 + initialDelay, 42 + initialDelay] |
+ }, |
+ { |
+ expiration: "35 hours", |
+ randomResult: 0.25, // Changes interval by factor 0.9 |
+ requests: [0 + initialDelay, 32 + initialDelay] |
+ }, |
+ { |
+ expiration: "40 hours", |
+ randomResult: 0.5, |
+ skipAfter: 5 + initialDelay, |
+ skip: 10, // Short break should not increase soft expiration |
+ requests: [0 + initialDelay, 40 + initialDelay] |
+ }, |
+ { |
+ expiration: "40 hours", |
+ randomResult: 0.5, |
+ skipAfter: 5 + initialDelay, |
+ skip: 30, // Long break should increase soft expiration |
+ requests: [0 + initialDelay, 70 + initialDelay] |
+ }, |
+ { |
+ expiration: "40 hours", |
+ randomResult: 0.5, |
+ skipAfter: 5 + initialDelay, |
+ skip: 80, // Hitting hard expiration, immediate download |
+ requests: [0 + initialDelay, 85 + initialDelay] |
+ } |
+ ]) |
+ { |
+ let testId = `"${currentTest.expiration}"`; |
+ if (currentTest.randomResult != 0.5) |
+ testId += ` with Math.random() returning ${currentTest.randomResult}`; |
+ if (currentTest.skip) |
+ testId += ` skipping ${currentTest.skip} hours after ${currentTest.skipAfter} hours`; |
+ |
+ it(testId, () => |
+ { |
+ let subscription = Subscription.fromURL("http://example.com/subscription"); |
+ filterStorage.addSubscription(subscription); |
+ |
+ let requests = []; |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ requests.push(runner.getTimeOffset()); |
+ return [Cr.NS_OK, 200, "[Adblock]\n!Expires: " + currentTest.expiration + "\nbar"]; |
+ }); |
+ |
+ runner.randomResult = currentTest.randomResult; |
+ |
+ let maxHours = Math.round(Math.max.apply(null, currentTest.requests)) + 1; |
+ return runner.runScheduledTasks(maxHours, currentTest.skipAfter, currentTest.skip).then(() => |
+ { |
+ assert.deepEqual(requests, currentTest.requests, "Requests"); |
+ }); |
+ }); |
+ } |
+ }); |
+ |
+ describe("Special Comments", () => |
{ |
- expiration: "40 hours", |
- randomResult: 0.5, |
- skipAfter: 5 + initialDelay, |
- skip: 30, // Long break should increase soft expiration |
- requests: [0 + initialDelay, 70 + initialDelay] |
- }, |
- { |
- expiration: "40 hours", |
- randomResult: 0.5, |
- skipAfter: 5 + initialDelay, |
- skip: 80, // Hitting hard expiration, immediate download |
- requests: [0 + initialDelay, 85 + initialDelay] |
- } |
-]) |
-{ |
- let testId = `"${currentTest.expiration}"`; |
- if (currentTest.randomResult != 0.5) |
- testId += " with Math.random() returning " + currentTest.randomResult; |
- if (currentTest.skip) |
- testId += " skipping " + currentTest.skip + " hours after " + currentTest.skipAfter + " hours"; |
- exports.testExpirationTime[testId] = function(test) |
+ for (let [comment, check] of [ |
+ ["! Homepage: http://example.com/", subscription => |
+ { |
+ assert.equal(subscription.homepage, "http://example.com/", "Valid homepage comment"); |
+ }], |
+ ["! Homepage: ssh://example.com/", subscription => |
+ { |
+ assert.equal(subscription.homepage, null, "Invalid homepage comment"); |
+ }], |
+ ["! Title: foo", subscription => |
+ { |
+ assert.equal(subscription.title, "foo", "Title comment"); |
+ assert.equal(subscription.fixedTitle, true, "Fixed title"); |
+ }], |
+ ["! Version: 1234", subscription => |
+ { |
+ assert.equal(subscription.version, 1234, "Version comment"); |
+ }] |
+ ]) |
+ { |
+ it(comment, () => |
+ { |
+ let subscription = Subscription.fromURL("http://example.com/subscription"); |
+ filterStorage.addSubscription(subscription); |
+ |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ return [Cr.NS_OK, 200, "[Adblock]\n" + comment + "\nfoo\nbar"]; |
+ }); |
+ |
+ return runner.runScheduledTasks(2).then(() => |
+ { |
+ check(subscription); |
+ assert.deepEqual([...subscription.filterText()], ["foo", "bar"], "Special comment not added to filters"); |
+ }); |
+ }); |
+ } |
+ }); |
+ |
+ it("Redirects", () => |
{ |
let subscription = Subscription.fromURL("http://example.com/subscription"); |
filterStorage.addSubscription(subscription); |
- let requests = []; |
- this.registerHandler("/subscription", metadata => |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ return [Cr.NS_OK, 200, "[Adblock]\n!Redirect: http://example.com/redirected\nbar"]; |
+ }); |
+ |
+ let requests; |
+ |
+ return runner.runScheduledTasks(30).then(() => |
+ { |
+ assert.equal([...filterStorage.subscriptions()][0], subscription, "Invalid redirect ignored"); |
+ assert.equal(subscription.downloadStatus, "synchronize_connection_error", "Connection error recorded"); |
+ assert.equal(subscription.errors, 2, "Number of download errors"); |
+ |
+ requests = []; |
+ |
+ runner.registerHandler("/redirected", metadata => |
+ { |
+ requests.push(runner.getTimeOffset()); |
+ return [Cr.NS_OK, 200, "[Adblock]\n! Expires: 8 hours\nbar"]; |
+ }); |
+ |
+ resetSubscription(subscription); |
+ return runner.runScheduledTasks(15); |
+ }).then(() => |
{ |
- requests.push(this.getTimeOffset()); |
- return [Cr.NS_OK, 200, "[Adblock]\n!Expires: " + currentTest.expiration + "\nbar"]; |
+ assert.equal([...filterStorage.subscriptions()][0].url, "http://example.com/redirected", "Redirect followed"); |
+ assert.deepEqual(requests, [0 + initialDelay, 8 + initialDelay], "Resulting requests"); |
+ |
+ runner.registerHandler("/redirected", metadata => |
+ { |
+ return [Cr.NS_OK, 200, "[Adblock]\n!Redirect: http://example.com/subscription\nbar"]; |
+ }); |
+ |
+ subscription = Subscription.fromURL("http://example.com/subscription"); |
+ resetSubscription(subscription); |
+ filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
+ filterStorage.addSubscription(subscription); |
+ |
+ return runner.runScheduledTasks(2); |
+ }).then(() => |
+ { |
+ assert.equal([...filterStorage.subscriptions()][0], subscription, "Redirect not followed on redirect loop"); |
+ assert.equal(subscription.downloadStatus, "synchronize_connection_error", "Download status after redirect loop"); |
+ }); |
+ }); |
+ |
+ it("Fallback", () => |
+ { |
+ Prefs.subscriptions_fallbackerrors = 3; |
+ Prefs.subscriptions_fallbackurl = "http://example.com/fallback?%SUBSCRIPTION%&%CHANNELSTATUS%&%RESPONSESTATUS%"; |
+ |
+ let subscription = Subscription.fromURL("http://example.com/subscription"); |
+ filterStorage.addSubscription(subscription); |
+ |
+ // No valid response from fallback |
+ |
+ let requests = []; |
+ let fallbackParams; |
+ let redirectedRequests; |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ requests.push(runner.getTimeOffset()); |
+ return [Cr.NS_OK, 404, ""]; |
}); |
- this.randomResult = currentTest.randomResult; |
+ return runner.runScheduledTasks(100).then(() => |
+ { |
+ assert.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Continue trying if the fallback doesn't respond"); |
+ |
+ // Fallback giving "Gone" response |
- let maxHours = Math.round(Math.max.apply(null, currentTest.requests)) + 1; |
- this.runScheduledTasks(maxHours, currentTest.skipAfter, currentTest.skip).then(() => |
+ resetSubscription(subscription); |
+ requests = []; |
+ fallbackParams = null; |
+ runner.registerHandler("/fallback", metadata => |
+ { |
+ fallbackParams = decodeURIComponent(metadata.queryString); |
+ return [Cr.NS_OK, 200, "410 Gone"]; |
+ }); |
+ |
+ return runner.runScheduledTasks(100); |
+ }).then(() => |
{ |
- test.deepEqual(requests, currentTest.requests, "Requests"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
- }; |
-} |
+ assert.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay], "Stop trying if the fallback responds with Gone"); |
+ assert.equal(fallbackParams, "http://example.com/subscription&0&404", "Fallback arguments"); |
+ |
+ // Fallback redirecting to a missing file |
+ |
+ subscription = Subscription.fromURL("http://example.com/subscription"); |
+ resetSubscription(subscription); |
+ filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
+ filterStorage.addSubscription(subscription); |
+ requests = []; |
-exports.testSpecialComments = {}; |
+ runner.registerHandler("/fallback", metadata => |
+ { |
+ return [Cr.NS_OK, 200, "301 http://example.com/redirected"]; |
+ }); |
+ return runner.runScheduledTasks(100); |
+ }).then(() => |
+ { |
+ assert.equal([...filterStorage.subscriptions()][0].url, "http://example.com/subscription", "Ignore invalid redirect from fallback"); |
+ assert.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Requests not affected by invalid redirect"); |
+ |
+ // Fallback redirecting to an existing file |
-for (let [comment, check] of [ |
- ["! Homepage: http://example.com/", (test, subscription) => |
- { |
- test.equal(subscription.homepage, "http://example.com/", "Valid homepage comment"); |
- }], |
- ["! Homepage: ssh://example.com/", (test, subscription) => |
- { |
- test.equal(subscription.homepage, null, "Invalid homepage comment"); |
- }], |
- ["! Title: foo", (test, subscription) => |
- { |
- test.equal(subscription.title, "foo", "Title comment"); |
- test.equal(subscription.fixedTitle, true, "Fixed title"); |
- }], |
- ["! Version: 1234", (test, subscription) => |
- { |
- test.equal(subscription.version, 1234, "Version comment"); |
- }] |
-]) |
-{ |
- exports.testSpecialComments[comment] = function(test) |
+ resetSubscription(subscription); |
+ requests = []; |
+ redirectedRequests = []; |
+ runner.registerHandler("/redirected", metadata => |
+ { |
+ redirectedRequests.push(runner.getTimeOffset()); |
+ return [Cr.NS_OK, 200, "[Adblock]\n!Expires: 1day\nfoo\nbar"]; |
+ }); |
+ |
+ return runner.runScheduledTasks(100); |
+ }).then(() => |
+ { |
+ assert.equal([...filterStorage.subscriptions()][0].url, "http://example.com/redirected", "Valid redirect from fallback is followed"); |
+ assert.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay], "Stop polling original URL after a valid redirect from fallback"); |
+ assert.deepEqual(redirectedRequests, [48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Request new URL after a valid redirect from fallback"); |
+ |
+ // Redirect loop |
+ |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscription2"]; |
+ }); |
+ runner.registerHandler("/subscription2", metadata => |
+ { |
+ return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscription"]; |
+ }); |
+ |
+ subscription = Subscription.fromURL("http://example.com/subscription"); |
+ resetSubscription(subscription); |
+ filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
+ filterStorage.addSubscription(subscription); |
+ |
+ return runner.runScheduledTasks(100); |
+ }).then(() => |
+ { |
+ assert.equal([...filterStorage.subscriptions()][0].url, "http://example.com/redirected", "Fallback can still redirect even after a redirect loop"); |
+ }); |
+ }); |
+ |
+ it("State Fields", () => |
{ |
let subscription = Subscription.fromURL("http://example.com/subscription"); |
filterStorage.addSubscription(subscription); |
- this.registerHandler("/subscription", metadata => |
- { |
- return [Cr.NS_OK, 200, "[Adblock]\n" + comment + "\nfoo\nbar"]; |
- }); |
- |
- this.runScheduledTasks(2).then(() => |
- { |
- check(test, subscription); |
- test.deepEqual([...subscription.filterText()], ["foo", "bar"], "Special comment not added to filters"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
- }; |
-} |
- |
-exports.testRedirects = function(test) |
-{ |
- let subscription = Subscription.fromURL("http://example.com/subscription"); |
- filterStorage.addSubscription(subscription); |
- |
- this.registerHandler("/subscription", metadata => |
- { |
- return [Cr.NS_OK, 200, "[Adblock]\n!Redirect: http://example.com/redirected\nbar"]; |
- }); |
- |
- let requests; |
- |
- this.runScheduledTasks(30).then(() => |
- { |
- test.equal([...filterStorage.subscriptions()][0], subscription, "Invalid redirect ignored"); |
- test.equal(subscription.downloadStatus, "synchronize_connection_error", "Connection error recorded"); |
- test.equal(subscription.errors, 2, "Number of download errors"); |
- |
- requests = []; |
- |
- this.registerHandler("/redirected", metadata => |
- { |
- requests.push(this.getTimeOffset()); |
- return [Cr.NS_OK, 200, "[Adblock]\n! Expires: 8 hours\nbar"]; |
- }); |
- |
- resetSubscription(subscription); |
- return this.runScheduledTasks(15); |
- }).then(() => |
- { |
- test.equal([...filterStorage.subscriptions()][0].url, "http://example.com/redirected", "Redirect followed"); |
- test.deepEqual(requests, [0 + initialDelay, 8 + initialDelay], "Resulting requests"); |
- |
- this.registerHandler("/redirected", metadata => |
+ runner.registerHandler("/subscription", metadata => |
{ |
- return [Cr.NS_OK, 200, "[Adblock]\n!Redirect: http://example.com/subscription\nbar"]; |
- }); |
- |
- subscription = Subscription.fromURL("http://example.com/subscription"); |
- resetSubscription(subscription); |
- filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
- filterStorage.addSubscription(subscription); |
- |
- return this.runScheduledTasks(2); |
- }).then(() => |
- { |
- test.equal([...filterStorage.subscriptions()][0], subscription, "Redirect not followed on redirect loop"); |
- test.equal(subscription.downloadStatus, "synchronize_connection_error", "Download status after redirect loop"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
-}; |
- |
-exports.testFallback = function(test) |
-{ |
- Prefs.subscriptions_fallbackerrors = 3; |
- Prefs.subscriptions_fallbackurl = "http://example.com/fallback?%SUBSCRIPTION%&%CHANNELSTATUS%&%RESPONSESTATUS%"; |
- |
- let subscription = Subscription.fromURL("http://example.com/subscription"); |
- filterStorage.addSubscription(subscription); |
- |
- // No valid response from fallback |
- |
- let requests = []; |
- let fallbackParams; |
- let redirectedRequests; |
- this.registerHandler("/subscription", metadata => |
- { |
- requests.push(this.getTimeOffset()); |
- return [Cr.NS_OK, 404, ""]; |
- }); |
- |
- this.runScheduledTasks(100).then(() => |
- { |
- test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Continue trying if the fallback doesn't respond"); |
- |
- // Fallback giving "Gone" response |
- |
- resetSubscription(subscription); |
- requests = []; |
- fallbackParams = null; |
- this.registerHandler("/fallback", metadata => |
- { |
- fallbackParams = decodeURIComponent(metadata.queryString); |
- return [Cr.NS_OK, 200, "410 Gone"]; |
+ return [Cr.NS_OK, 200, "[Adblock]\n! Expires: 2 hours\nfoo\nbar"]; |
}); |
- return this.runScheduledTasks(100); |
- }).then(() => |
- { |
- test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay], "Stop trying if the fallback responds with Gone"); |
- test.equal(fallbackParams, "http://example.com/subscription&0&404", "Fallback arguments"); |
- |
- // Fallback redirecting to a missing file |
+ let startTime = runner.currentTime; |
+ return runner.runScheduledTasks(2).then(() => |
+ { |
+ assert.equal(subscription.downloadStatus, "synchronize_ok", "downloadStatus after successful download"); |
+ assert.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastDownload after successful download"); |
+ assert.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after successful download"); |
+ assert.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (1 + initialDelay) * MILLIS_IN_HOUR, "lastCheck after successful download"); |
+ assert.equal(subscription.errors, 0, "errors after successful download"); |
- subscription = Subscription.fromURL("http://example.com/subscription"); |
- resetSubscription(subscription); |
- filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
- filterStorage.addSubscription(subscription); |
- requests = []; |
- |
- this.registerHandler("/fallback", metadata => |
- { |
- return [Cr.NS_OK, 200, "301 http://example.com/redirected"]; |
- }); |
- return this.runScheduledTasks(100); |
- }).then(() => |
- { |
- test.equal([...filterStorage.subscriptions()][0].url, "http://example.com/subscription", "Ignore invalid redirect from fallback"); |
- test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Requests not affected by invalid redirect"); |
- |
- // Fallback redirecting to an existing file |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ return [Cr.NS_ERROR_FAILURE, 0, ""]; |
+ }); |
- resetSubscription(subscription); |
- requests = []; |
- redirectedRequests = []; |
- this.registerHandler("/redirected", metadata => |
+ return runner.runScheduledTasks(2); |
+ }).then(() => |
{ |
- redirectedRequests.push(this.getTimeOffset()); |
- return [Cr.NS_OK, 200, "[Adblock]\n!Expires: 1day\nfoo\nbar"]; |
+ assert.equal(subscription.downloadStatus, "synchronize_connection_error", "downloadStatus after connection error"); |
+ assert.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (2 + initialDelay) * MILLIS_IN_HOUR, "lastDownload after connection error"); |
+ assert.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after connection error"); |
+ assert.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (3 + initialDelay) * MILLIS_IN_HOUR, "lastCheck after connection error"); |
+ assert.equal(subscription.errors, 1, "errors after connection error"); |
+ |
+ runner.registerHandler("/subscription", metadata => |
+ { |
+ return [Cr.NS_OK, 404, ""]; |
+ }); |
+ |
+ return runner.runScheduledTasks(24); |
+ }).then(() => |
+ { |
+ assert.equal(subscription.downloadStatus, "synchronize_connection_error", "downloadStatus after download error"); |
+ assert.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (26 + initialDelay) * MILLIS_IN_HOUR, "lastDownload after download error"); |
+ assert.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after download error"); |
+ assert.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (27 + initialDelay) * MILLIS_IN_HOUR, "lastCheck after download error"); |
+ assert.equal(subscription.errors, 2, "errors after download error"); |
}); |
+ }); |
- return this.runScheduledTasks(100); |
- }).then(() => |
+ it("Special Comment Ordering", () => |
{ |
- test.equal([...filterStorage.subscriptions()][0].url, "http://example.com/redirected", "Valid redirect from fallback is followed"); |
- test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialDelay], "Stop polling original URL after a valid redirect from fallback"); |
- test.deepEqual(redirectedRequests, [48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Request new URL after a valid redirect from fallback"); |
- |
- // Redirect loop |
- |
- this.registerHandler("/subscription", metadata => |
- { |
- return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscription2"]; |
- }); |
- this.registerHandler("/subscription2", metadata => |
- { |
- return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscription"]; |
- }); |
- |
- subscription = Subscription.fromURL("http://example.com/subscription"); |
- resetSubscription(subscription); |
- filterStorage.removeSubscription([...filterStorage.subscriptions()][0]); |
+ let subscription = Subscription.fromURL("http://example.com/subscription"); |
filterStorage.addSubscription(subscription); |
- return this.runScheduledTasks(100); |
- }).then(() => |
- { |
- test.equal([...filterStorage.subscriptions()][0].url, "http://example.com/redirected", "Fallback can still redirect even after a redirect loop"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
-}; |
- |
-exports.testStateFields = function(test) |
-{ |
- let subscription = Subscription.fromURL("http://example.com/subscription"); |
- filterStorage.addSubscription(subscription); |
- |
- this.registerHandler("/subscription", metadata => |
- { |
- return [Cr.NS_OK, 200, "[Adblock]\n! Expires: 2 hours\nfoo\nbar"]; |
- }); |
- |
- let startTime = this.currentTime; |
- this.runScheduledTasks(2).then(() => |
- { |
- test.equal(subscription.downloadStatus, "synchronize_ok", "downloadStatus after successful download"); |
- test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastDownload after successful download"); |
- test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after successful download"); |
- test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (1 + initialDelay) * MILLIS_IN_HOUR, "lastCheck after successful download"); |
- test.equal(subscription.errors, 0, "errors after successful download"); |
- |
- this.registerHandler("/subscription", metadata => |
+ runner.registerHandler("/subscription", metadata => |
{ |
- return [Cr.NS_ERROR_FAILURE, 0, ""]; |
+ return [Cr.NS_OK, 200, "[Adblock]\n! Special Comment: x\n!foo\n! Title: foobar\nfoo\nbar"]; |
}); |
- return this.runScheduledTasks(2); |
- }).then(() => |
+ return runner.runScheduledTasks(1).then(() => |
+ { |
+ assert.equal(subscription.title, "http://example.com/subscription", "make sure title was not found"); |
+ }); |
+ }); |
+ |
+ it("Unkown Special Comments", () => |
{ |
- test.equal(subscription.downloadStatus, "synchronize_connection_error", "downloadStatus after connection error"); |
- test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (2 + initialDelay) * MILLIS_IN_HOUR, "lastDownload after connection error"); |
- test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after connection error"); |
- test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (3 + initialDelay) * MILLIS_IN_HOUR, "lastCheck after connection error"); |
- test.equal(subscription.errors, 1, "errors after connection error"); |
+ let subscription = Subscription.fromURL("http://example.com/subscription"); |
+ filterStorage.addSubscription(subscription); |
- this.registerHandler("/subscription", metadata => |
+ runner.registerHandler("/subscription", metadata => |
{ |
- return [Cr.NS_OK, 404, ""]; |
+ // To test allowing unknown special comments like `! :`, `!!@#$%^&*() : `, and `! Some Unknown Comment : ` |
+ return [Cr.NS_OK, 200, "[Adblock]\n! :\n! !@#$%^&*() :\n! Some Unknown Comment :\n! Title: foobar\nfoo\nbar"]; |
}); |
- return this.runScheduledTasks(24); |
- }).then(() => |
- { |
- test.equal(subscription.downloadStatus, "synchronize_connection_error", "downloadStatus after download error"); |
- test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (26 + initialDelay) * MILLIS_IN_HOUR, "lastDownload after download error"); |
- test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialDelay * MILLIS_IN_HOUR, "lastSuccess after download error"); |
- test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (27 + initialDelay) * MILLIS_IN_HOUR, "lastCheck after download error"); |
- test.equal(subscription.errors, 2, "errors after download error"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
-}; |
- |
-exports.testSpecialCommentOrdering = function(test) |
-{ |
- let subscription = Subscription.fromURL("http://example.com/subscription"); |
- filterStorage.addSubscription(subscription); |
- |
- this.registerHandler("/subscription", metadata => |
- { |
- return [Cr.NS_OK, 200, "[Adblock]\n! Special Comment: x\n!foo\n! Title: foobar\nfoo\nbar"]; |
+ return runner.runScheduledTasks(1).then(() => |
+ { |
+ assert.equal(subscription.title, "foobar", "make sure title was found"); |
+ }); |
}); |
- |
- this.runScheduledTasks(1).then(() => |
- { |
- test.equal(subscription.title, "http://example.com/subscription", "make sure title was not found"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
-}; |
- |
-exports.testUnknownSpecialComments = function(test) |
-{ |
- let subscription = Subscription.fromURL("http://example.com/subscription"); |
- filterStorage.addSubscription(subscription); |
- |
- this.registerHandler("/subscription", metadata => |
- { |
- // To test allowing unknown special comments like `! :`, `!!@#$%^&*() : `, and `! Some Unknown Comment : ` |
- return [Cr.NS_OK, 200, "[Adblock]\n! :\n! !@#$%^&*() :\n! Some Unknown Comment :\n! Title: foobar\nfoo\nbar"]; |
- }); |
- |
- this.runScheduledTasks(1).then(() => |
- { |
- test.equal(subscription.title, "foobar", "make sure title was found"); |
- }).catch(unexpectedError.bind(test)).then(() => test.done()); |
-}; |
+}); |