tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test-case.sub.js (3854B)


      1 function TestCase(scenarios, sanityChecker) {
      2  function runTest(scenario) {
      3    sanityChecker.checkScenario(scenario, subresourceMap);
      4 
      5    const urls = getRequestURLs(scenario.subresource,
      6                                scenario.origin,
      7                                scenario.redirection);
      8 
      9    /** @type {Subresource} */
     10    const subresource = {
     11      subresourceType: scenario.subresource,
     12      url: urls.testUrl,
     13      policyDeliveries: scenario.subresource_policy_deliveries,
     14    };
     15 
     16    let violationEventResolve;
     17    // Resolved with an array of securitypolicyviolation events.
     18    const violationEventPromise = new Promise(resolve => {
     19        violationEventResolve = resolve;
     20      });
     21 
     22    promise_test(async t => {
     23      await xhrRequest(urls.announceUrl);
     24 
     25      // Currently only requests from top-level Documents are tested
     26      // (specified by `spec.src.json`) and thus securitypolicyviolation
     27      // events are assumed to be fired on the top-level Document here.
     28      // When adding non-top-level Document tests, securitypolicyviolation
     29      // events should be caught in appropriate contexts.
     30      const violationEvents = [];
     31      const listener = e => { violationEvents.push(e); };
     32      document.addEventListener('securitypolicyviolation', listener);
     33 
     34      try {
     35        // Send out the real resource request.
     36        // This should tear down the key if it's not blocked.
     37        const mainPromise = invokeRequest(subresource, scenario.source_context_list);
     38        if (scenario.expectation === 'allowed') {
     39          await mainPromise;
     40        } else {
     41          await mainPromise
     42              .then(t.unreached_func('main promise resolved unexpectedly'))
     43              .catch(_ => {});
     44        }
     45      } finally {
     46        // Always perform post-processing/clean up for
     47        // 'securitypolicyviolation' events and resolve
     48        // `violationEventPromise`, to prevent timeout of the
     49        // promise_test() below.
     50 
     51        // securitypolicyviolation events are fired in a queued task in
     52        // https://w3c.github.io/webappsec-csp/#report-violation
     53        // so wait for queued tasks to run using setTimeout().
     54        let timeout = 0;
     55        if (scenario.subresource.startsWith('worklet-') &&
     56            navigator.userAgent.includes("Firefox/")) {
     57          // https://bugzilla.mozilla.org/show_bug.cgi?id=1808911
     58          // In Firefox sometimes violations from Worklets are delayed.
     59          timeout = 10;
     60        }
     61        await new Promise(resolve => setTimeout(resolve, timeout));
     62 
     63        // Pass violation events to `violationEventPromise` (which will be tested
     64        // in the subsequent promise_test()) and clean up the listener.
     65        violationEventResolve(violationEvents);
     66        document.removeEventListener('securitypolicyviolation', listener);
     67      }
     68 
     69      // Send request to check if the key has been torn down.
     70      const assertResult = await xhrRequest(urls.assertUrl);
     71 
     72      // Now check if the value has been torn down. If it's still there,
     73      // we have blocked the request by content security policy.
     74      assert_equals(assertResult.status, scenario.expectation,
     75        "The resource request should be '" + scenario.expectation + "'.");
     76 
     77    }, scenario.test_description);
     78 
     79    promise_test(async _ => {
     80        const violationEvents = await violationEventPromise;
     81        if (scenario.expectation === 'allowed') {
     82          assert_array_equals(violationEvents, [],
     83              'no violation events should be fired');
     84        } else {
     85          assert_equals(violationEvents.length, 1,
     86              'One violation event should be fired');
     87        }
     88      }, scenario.test_description + ": securitypolicyviolation");
     89  }  // runTest
     90 
     91  function runTests() {
     92    for (const scenario of scenarios) {
     93      runTest(scenario);
     94    }
     95  }
     96 
     97  return {start: runTests};
     98 }