chromium/chrome/test/data/extensions/api_test/declarative_net_request/dynamic_rules_limits/background.js

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var updateDynamicRules = chrome.declarativeNetRequest.updateDynamicRules;
var getDynamicRules = chrome.declarativeNetRequest.getDynamicRules;

// Rule limits are actually set after the browser replies to the extension's
// "ready" message.
var ruleLimit = -1;
var unsafeRuleLimit = -1;
var regexRuleLimit = -1;

var nextId = 1;

var createRuleWithID = function(id) {
  return {
    id: id,
    priority: 1,
    condition: {urlFilter: id.toString()},
    action: {type: 'block'},
  };
};

var createRedirectRuleWithID = function(id) {
  return {
    id: id,
    priority: 1,
    condition: {urlFilter: id.toString()},
    action: {type: 'redirect', redirect: {url: 'https://example.com'}},
  };
};

var createRegexRuleWithID = function(id) {
  return {
    id: id,
    priority: 1,
    condition: {regexFilter: id.toString()},
    action: {type: 'block'},
  };
};

// Verifies the current set of rules. Ensures no error is signalled and proceeds
// to the next test.
var verifyCurrentRulesCallback = function() {
  chrome.test.assertNoLastError();

  getDynamicRules(function(rules) {
    chrome.test.assertNoLastError();

    var comparator = function(rule1, rule2) {
      return rule1.id - rule2.id;
    };

    // Sort by ID first since assertEq respects order of arrays.
    rules.sort(comparator)
    currentRules.sort(comparator);
    chrome.test.assertEq(currentRules, rules);

    chrome.test.succeed();
  });
};
var currentRules = [];

const testCases = [
  // Sanity check that rule limits received from the browser have been set.
  function checkRuleLimits() {
    chrome.test.assertTrue(ruleLimit > 0);
    chrome.test.assertTrue(unsafeRuleLimit > 0);
    chrome.test.assertTrue(regexRuleLimit > 0);
    chrome.test.succeed();
  },

  // Ensure that an extension can add up to `regexRuleLimit` number of regex
  // rules.
  function regexRuleLimitReached() {
    var newRules = [];
    while (newRules.length < regexRuleLimit) {
      newRules.push(createRegexRuleWithID(nextId++));
    }

    currentRules = newRules.concat(currentRules);
    chrome.test.assertEq(regexRuleLimit, currentRules.length);
    updateDynamicRules({addRules: newRules}, verifyCurrentRulesCallback);
  },

  // Ensure that adding more regex rules than `regexRuleLimit` causes an error.
  function regexRuleLimitError() {
    updateDynamicRules(
        {addRules: [createRegexRuleWithID(nextId++)]},
        chrome.test.callbackFail(
            'Dynamic rule count for regex rules exceeded.'));
  },

  // Ensure that an extension can add up to `unsafeRuleLimit` number of "unsafe"
  // rules.
  function unsafeRuleLimitReached() {
    var newRules = [];
    while (newRules.length < unsafeRuleLimit) {
      newRules.push(createRedirectRuleWithID(nextId++));
    }

    currentRules = newRules.concat(currentRules);
    chrome.test.assertEq(regexRuleLimit + unsafeRuleLimit, currentRules.length);
    updateDynamicRules({addRules: newRules}, verifyCurrentRulesCallback);
  },

  // Ensure that adding more "unsafe" rules than `unsafeRuleLimit` causes an
  // error.
  function unsafeRuleLimitError() {
    updateDynamicRules(
        {addRules: [createRedirectRuleWithID(nextId++)]},
        chrome.test.callbackFail('Dynamic unsafe rule count exceeded.'));
  },

  // Ensure we can add up to `ruleLimit` no. of rules.
  function ruleLimitReached() {
    var numRulesToAdd = ruleLimit - currentRules.length;
    var newRules = [];
    while (newRules.length < numRulesToAdd)
      newRules.push(createRuleWithID(nextId++));

    currentRules = newRules.concat(currentRules);
    chrome.test.assertEq(ruleLimit, currentRules.length);
    updateDynamicRules(
        {addRules: newRules, removeRuleIds: []}, verifyCurrentRulesCallback);
  },

  // Ensure we can't add more than `ruleLimit` rules.
  function ruleLimitError() {
    updateDynamicRules(
        {addRules: [createRuleWithID(nextId++)]},
        chrome.test.callbackFail('Dynamic rule count exceeded.'));
  },
];

chrome.test.sendMessage('ready', ruleLimitsStr => {
  const ruleLimits = JSON.parse(ruleLimitsStr);
  ruleLimit = ruleLimits.ruleLimit;
  unsafeRuleLimit = ruleLimits.unsafeRuleLimit;
  regexRuleLimit = ruleLimits.regexRuleLimit;

  chrome.test.runTests(testCases);
});