blob: dd0b6c6b697b4287c912daa6f2b1ea14fe424610 [file]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const declarative = chrome.declarative;
const RequestMatcher = chrome.declarativeWebRequest.RequestMatcher;
const CancelRequest = chrome.declarativeWebRequest.CancelRequest;
const RedirectRequest = chrome.declarativeWebRequest.RedirectRequest;
const SetRequestHeader = chrome.declarativeWebRequest.SetRequestHeader;
const inputRule0 = {
// No 'id', this should be filled by the API.
conditions: [
new RequestMatcher({url: {hostPrefix: 'test1'}}),
new RequestMatcher({url: {hostPrefix: 'test2'}}),
],
actions: [
new CancelRequest(),
new RedirectRequest({redirectUrl: 'http://foobar.com'}),
],
// No 'priority', this should be filled by the API.
};
const outputRule0 = {
id: '_0_',
conditions: [
new RequestMatcher({url: {hostPrefix: 'test1'}}),
new RequestMatcher({url: {hostPrefix: 'test2'}}),
],
actions: [
new CancelRequest(),
new RedirectRequest({redirectUrl: 'http://foobar.com'}),
],
priority: 100,
};
const inputRule1 = {
id: 'my_rule_id',
conditions: [],
actions: [],
priority: 10,
};
const outputRule1 = inputRule1;
const inputRule2 = {
// No 'id', this should be filled by the API.
conditions: [new RequestMatcher({url: {hostPrefix: 'test3'}})],
actions: [new CancelRequest()],
// No 'priority', this should be filled by the API.
};
const outputRule2 = {
id: '_1_',
conditions: [new RequestMatcher({url: {hostPrefix: 'test3'}})],
actions: [new CancelRequest()],
priority: 100,
};
const invalidRule0 = {
conditions: [new RequestMatcher({url: {hostPrefix: 'test1'}})],
// 'actions' is missing but not optional.
};
const invalidRule1 = {
conditions: [new RequestMatcher({url: {hostPrefix: 'test1'}})],
// 'actions' contains an invalid action (separate test because this validation
// happens on a different code path).
actions: [{key: 'value'}],
};
const invalidRule2 = {
conditions: [new RequestMatcher({url: {hostPrefix: 'test1'}})],
actions: [new SetRequestHeader({name: '\x00', value: 'whatever'})],
};
const testEvent = chrome.declarativeWebRequest.onRequest;
chrome.test.runTests([
// Test validation
function testInvalidAddRules() {
try {
testEvent.addRules();
chrome.test.fail();
} catch (e) {
chrome.test.succeed();
}
},
function testInvalidGetRules() {
try {
testEvent.getRules(1, function() {});
chrome.test.fail();
} catch (e) {
chrome.test.succeed();
}
},
function testInvalidRemoveRules() {
try {
testEvent.removeRules(1, function() {});
chrome.test.fail();
} catch (e) {
chrome.test.succeed();
}
},
// Add adding two simple rules and check that their optional fields are set
// correctly in the call back function.
function testAddRules() {
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.assertEq(2, rules.length);
// API should have generated id and priority fields.
chrome.test.assertTrue('id' in rules[0]);
chrome.test.assertEq([outputRule0, outputRule1], rules);
chrome.test.succeed();
};
testEvent.addRules([inputRule0, inputRule1], callback);
},
// Check that getRules() returns all rules if no filter is passed.
function testGetRules() {
const callback = function(rules) {
chrome.test.assertNoLastError();
// We are not given any guarantee on the order in which rules are
// returned.
chrome.test.assertTrue(
chrome.test.checkDeepEq([outputRule0, outputRule1], rules) ||
chrome.test.checkDeepEq([outputRule1, outputRule0], rules));
chrome.test.succeed();
};
testEvent.getRules(null, callback);
},
// Check that getRules() returns all rules if no filter is passed.
function testGetRules2() {
const callback = function(rules) {
chrome.test.assertNoLastError();
// We are not given any guarantee on the order in which rules are
// returned.
chrome.test.assertTrue(
chrome.test.checkDeepEq([outputRule0, outputRule1], rules) ||
chrome.test.checkDeepEq([outputRule1, outputRule0], rules));
chrome.test.succeed();
};
testEvent.getRules(undefined, callback);
},
// Check that getRules() returns no rules if empty filter is passed.
function testGetRules3() {
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.assertEq([], rules);
chrome.test.succeed();
};
testEvent.getRules([], callback);
},
// TODO(devlin): The documentation for event.getRules() states that the
// filter parameter is optional. However, with JS bindings, we throw an error
// if it's omitted. This is fixed with native bindings.
// Check that getRules() returns all rules if the filter is omitted.
// function testGetRules4() {
// const callback = function(rules) {
// chrome.test.assertNoLastError();
// // We are not given any guarantee on the order in which rules are
// // returned.
// chrome.test.assertTrue(
// chrome.test.checkDeepEq([outputRule0, outputRule1], rules) ||
// chrome.test.checkDeepEq([outputRule1, outputRule0], rules));
// chrome.test.succeed();
// }
// testEvent.getRules(callback);
// },
// Check that getRules() returns matching rules if rules are filtered by ID.
function testSelectiveGetRules() {
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.assertEq([outputRule1], rules);
chrome.test.succeed();
};
testEvent.getRules(['my_rule_id'], callback);
},
// Check that we can remove individual rules.
function testSelectiveRemoveRules() {
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.succeed();
};
testEvent.removeRules(['my_rule_id'], callback);
},
// Check that after removal, the rules are really gone.
function testGetRemainingRules() {
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.assertEq([outputRule0], rules);
chrome.test.succeed();
};
testEvent.getRules(null, callback);
},
// Check that rules are assigned unique IDs.
function testIdGeneration() {
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.assertEq(1, rules.length);
// API should have generated id and priority fields.
chrome.test.assertTrue('id' in rules[0]);
// The IDs should be distinct.
chrome.test.assertNe(rules[0].id, outputRule0.id);
chrome.test.succeed();
};
testEvent.addRules([inputRule2], callback);
},
// Check that we can remove all rules at once.
function testRemovingAllRules() {
const callback = function() {
chrome.test.assertNoLastError();
chrome.test.succeed();
};
testEvent.removeRules(null, callback);
},
// Check that the rules are actually gone.
function testAllRulesRemoved() {
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.assertEq(0, rules.length);
chrome.test.succeed();
};
testEvent.getRules(null, callback);
},
// Check that validation is performed.
function testValidation() {
const fail = function() {
chrome.test.fail('An exception was expected');
};
try {
testEvent.addRules([invalidRule0], fail);
fail();
} catch (e) {
}
try {
testEvent.addRules([invalidRule1], fail);
fail();
} catch (e) {
}
// None of these rules should have been registered.
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.assertEq(0, rules.length);
chrome.test.succeed();
};
testEvent.getRules(null, callback);
},
// Check that errors are propagated
function testValidationAsync() {
const callback = function() {
chrome.test.assertLastError('Invalid header name.');
chrome.test.succeed();
};
testEvent.addRules([invalidRule2], callback);
},
// Finally we add one additional rule, to check that is is removed
// on page unload.
function testAddRules() {
const callback = function(rules) {
chrome.test.assertNoLastError();
chrome.test.assertEq(1, rules.length);
chrome.test.succeed();
};
testEvent.addRules([inputRule0], callback);
},
]);