910e62b5创建于 1月15日历史提交
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// META script=resources/controlled_frame_helpers.js
// META script=resources/event_handler_helpers.js

// This file contains authrequired event related tests.
//
// Successful authentications are cached and can mess with subsequent tests.
// To get around this, the test uses separate partitions for tests that
// successfully authenticate, but a shared partition for others to speed up the
// tests because partition creation is expensive.

async function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

promise_test(async (test) => {
  const controlledframe = await createControlledFrame('/simple.html', 'auth1');
  controlledframe.stop();

  const targetUrl = new URL(controlledframe.src);
  targetUrl.pathname = '/auth-basic';
  targetUrl.search = '*';
  addWebRequestListeners(controlledframe, targetUrl.toString());

  controlledframe.request.createWebRequestInterceptor({
    urlPatterns: [targetUrl.toString()],
    blocking: true,
  }).addEventListener('authrequired', (e) => {
    e.setCredentials(new Promise((resolve) => {
      // Sleep to ensure the network request is paused until the
      // promise resolves.
      sleep(1);
      resolve({
        username: '',
        password: 'PASS',
      });
    }));
  });

  targetUrl.search = 'password=PASS&realm=REALM';
  await navigateControlledFrame(controlledframe, targetUrl.toString());

  verifyWebRequestEvents([
    'beforerequest',
    'beforesendheaders',
    'sendheaders',
    'headersreceived',
    'authrequired',
    'responsestarted',
    'completed',
  ]);
}, 'WebRequest Auth Async');

promise_test(async (test) => {
  const controlledframe = await createControlledFrame('/simple.html', 'auth2');
  controlledframe.stop();

  const targetUrl = new URL(controlledframe.src);
  targetUrl.pathname = '/auth-basic';
  targetUrl.search = '*';
  addWebRequestListeners(controlledframe, targetUrl.toString());

  controlledframe.request.createWebRequestInterceptor({
    urlPatterns: [targetUrl.toString()],
    blocking: true,
  }).addEventListener('authrequired', (e) => {
    e.setCredentials({
      username: '',
      password: 'PASS',
    });
  });

  targetUrl.search = 'password=PASS&realm=REALM';
  await navigateControlledFrame(controlledframe, targetUrl.toString());

  verifyWebRequestEvents([
    'beforerequest',
    'beforesendheaders',
    'sendheaders',
    'headersreceived',
    'authrequired',
    'responsestarted',
    'completed',
  ]);
}, 'WebRequest Auth Sync');

promise_test(async (test) => {
  const controlledframe = await createControlledFrame('/simple.html', 'noauth');
  controlledframe.stop();

  const targetUrl = new URL(controlledframe.src);
  targetUrl.pathname = '/auth-basic';
  targetUrl.search = '*';
  addWebRequestListeners(controlledframe, targetUrl.toString());

  controlledframe.request.createWebRequestInterceptor({
    urlPatterns: [targetUrl.toString()],
    blocking: true,
  }).addEventListener('authrequired', (e) => {
    e.setCredentials({
      username: '',
      password: 'WRONG_PASSWORD',
    });
  });

  targetUrl.search = 'password=PASS&realm=REALM';
  try {
    await navigateControlledFrame(controlledframe, targetUrl.toString());
  } catch (e) {}

  assert_false(window.events.includes('completed'), 'completed fired');
  assert_true(window.events.includes('authrequired'), 'authrequired fired');
  assert_equals(
      window.events.slice(-1)[0], 'erroroccurred', 'erroroccurred fired');
  assert_equals(
      window.occurredErrors[0], 'net::ERR_TOO_MANY_RETRIES', 'error code');
}, 'WebRequest Auth Fail');

promise_test(async (test) => {
  const controlledframe = await createControlledFrame('/simple.html', 'noauth');
  controlledframe.stop();

  const targetUrl = new URL(controlledframe.src);
  targetUrl.pathname = '/auth-basic';
  targetUrl.search = '*';
  addWebRequestListeners(controlledframe, targetUrl.toString());

  const interceptor = controlledframe.request.createWebRequestInterceptor({
    urlPatterns: [targetUrl.toString()],
    blocking: true,
  });
  interceptor.addEventListener('authrequired', (e) => {
    e.preventDefault();
  });

  let statusCode = -1;
  interceptor.addEventListener('completed', (e) => {
    statusCode = e.response.statusCode;
  });

  targetUrl.search = 'password=PASS&realm=REALM';
  await navigateControlledFrame(controlledframe, targetUrl.toString());

  verifyWebRequestEvents([
    'beforerequest',
    'beforesendheaders',
    'sendheaders',
    'headersreceived',
    'authrequired',
    'responsestarted',
    'completed',
  ]);
  assert_equals(statusCode, 401);
}, 'WebRequest Auth Cancel Sync');

promise_test(async (test) => {
  const controlledframe = await createControlledFrame('/simple.html', 'noauth');
  controlledframe.stop();

  const targetUrl = new URL(controlledframe.src);
  targetUrl.pathname = '/auth-basic';
  targetUrl.search = '*';
  addWebRequestListeners(controlledframe, targetUrl.toString());

  const interceptor = controlledframe.request.createWebRequestInterceptor({
    urlPatterns: [targetUrl.toString()],
    blocking: true,
  });
  interceptor.addEventListener('authrequired', (e) => {
    const controller = new AbortController();
    e.setCredentials(new Promise(() => {}), {signal: controller.signal});
    sleep(1).then(() => {
      controller.abort();
    });
  });

  let statusCode = -1;
  interceptor.addEventListener('completed', (e) => {
    statusCode = e.response.statusCode;
  });

  targetUrl.search = 'password=PASS&realm=REALM';
  await navigateControlledFrame(controlledframe, targetUrl.toString());

  verifyWebRequestEvents([
    'beforerequest',
    'beforesendheaders',
    'sendheaders',
    'headersreceived',
    'authrequired',
    'responsestarted',
    'completed',
  ]);
  assert_equals(statusCode, 401);
}, 'WebRequest Auth Cancel AbortSignal');

promise_test(async (test) => {
  const controlledframe = await createControlledFrame('/simple.html', 'noauth');
  controlledframe.stop();

  const targetUrl = new URL(controlledframe.src);
  targetUrl.pathname = '/auth-basic';
  targetUrl.search = '*';
  addWebRequestListeners(controlledframe, targetUrl.toString());

  const interceptor = controlledframe.request.createWebRequestInterceptor({
    urlPatterns: [targetUrl.toString()],
    blocking: true,
  });
  interceptor.addEventListener('authrequired', (e) => {
    const controller = new AbortController();
    controller.abort();
    e.setCredentials(new Promise(() => {}), {signal: controller.signal});
  });

  let statusCode = -1;
  interceptor.addEventListener('completed', (e) => {
    statusCode = e.response.statusCode;
  });

  targetUrl.search = 'password=PASS&realm=REALM';
  await navigateControlledFrame(controlledframe, targetUrl.toString());

  verifyWebRequestEvents([
    'beforerequest',
    'beforesendheaders',
    'sendheaders',
    'headersreceived',
    'authrequired',
    'responsestarted',
    'completed',
  ]);
  assert_equals(statusCode, 401);
}, 'WebRequest Auth Cancel Preaborted AbortSignal');

promise_test(async (test) => {
  const controlledframe = await createControlledFrame('/simple.html', 'noauth');
  controlledframe.stop();

  const targetUrl = new URL(controlledframe.src);
  targetUrl.pathname = '/auth-basic';
  targetUrl.search = '*';
  addWebRequestListeners(controlledframe, targetUrl.toString());

  const interceptor = controlledframe.request.createWebRequestInterceptor({
    urlPatterns: [targetUrl.toString()],
    blocking: true,
  });
  interceptor.addEventListener('authrequired', (e) => {
    // Ignore the event
  });

  let statusCode = -1;
  interceptor.addEventListener('completed', (e) => {
    statusCode = e.response.statusCode;
  });

  targetUrl.search = 'password=PASS&realm=REALM';
  await navigateControlledFrame(
      controlledframe, targetUrl.toString(), /*expectFailure=*/true);

  verifyWebRequestEvents([
    'beforerequest',
    'beforesendheaders',
    'sendheaders',
    'headersreceived',
    'authrequired',
    'responsestarted',
    'completed',
  ]);
  assert_equals(statusCode, 401);
}, 'WebRequest Auth Noop');