Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/dom/push/test/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  test_utils.js   Sprache: JAVA

 
"use strict";

const url = SimpleTest.getTestFileURL("mockpushserviceparent.js");
const chromeScript = SpecialPowers.loadChromeScript(url);

/**
 * Replaces `PushService.sys.mjs` with a mock implementation that handles requests
 * from the DOM API. This allows tests to simulate local errors and error
 * reporting, bypassing the `PushService.sys.mjs` machinery.
 */

async function replacePushService(mockService) {
  chromeScript.addMessageListener("service-delivery-error"function (msg) {
    mockService.reportDeliveryError(msg.messageId, msg.reason);
  });
  chromeScript.addMessageListener("service-request"function (msg) {
    let promise;
    try {
      let handler = mockService[msg.name];
      promise = Promise.resolve(handler(msg.params));
    } catch (error) {
      promise = Promise.reject(error);
    }
    promise.then(
      result => {
        chromeScript.sendAsyncMessage("service-response", {
          id: msg.id,
          result,
        });
      },
      error => {
        chromeScript.sendAsyncMessage("service-response", {
          id: msg.id,
          error,
        });
      }
    );
  });
  await new Promise(resolve => {
    chromeScript.addMessageListener("service-replaced"function onReplaced() {
      chromeScript.removeMessageListener("service-replaced", onReplaced);
      resolve();
    });
    chromeScript.sendAsyncMessage("service-replace");
  });
}

async function restorePushService() {
  await new Promise(resolve => {
    chromeScript.addMessageListener("service-restored"function onRestored() {
      chromeScript.removeMessageListener("service-restored", onRestored);
      resolve();
    });
    chromeScript.sendAsyncMessage("service-restore");
  });
}

let currentMockSocket = null;

/**
 * Sets up a mock connection for the WebSocket backend. This only replaces
 * the transport layer; `PushService.sys.mjs` still handles DOM API requests,
 * observes permission changes, writes to IndexedDB, and notifies service
 * workers of incoming push messages.
 */

function setupMockPushSocket(mockWebSocket) {
  currentMockSocket = mockWebSocket;
  currentMockSocket._isActive = true;
  chromeScript.sendAsyncMessage("socket-setup");
  chromeScript.addMessageListener("socket-client-msg"function (msg) {
    mockWebSocket.handleMessage(msg);
  });
}

function teardownMockPushSocket() {
  if (currentMockSocket) {
    return new Promise(resolve => {
      currentMockSocket._isActive = false;
      chromeScript.addMessageListener("socket-server-teardown", resolve);
      chromeScript.sendAsyncMessage("socket-teardown");
    });
  }
  return Promise.resolve();
}

/**
 * Minimal implementation of web sockets for use in testing. Forwards
 * messages to a mock web socket in the parent process that is used
 * by the push service.
 */

class MockWebSocket {
  // Default implementation to make the push server work minimally.
  // Override methods to implement custom functionality.
  constructor() {
    this.userAgentID = "8e1c93a9-139b-419c-b200-e715bb1e8ce8";
    this.registerCount = 0;
    // We only allow one active mock web socket to talk to the parent.
    // This flag is used to keep track of which mock web socket is active.
    this._isActive = false;
  }

  onHello() {
    this.serverSendMsg(
      JSON.stringify({
        messageType: "hello",
        uaid: this.userAgentID,
        status: 200,
        use_webpush: true,
      })
    );
  }

  onRegister(request) {
    this.serverSendMsg(
      JSON.stringify({
        messageType: "register",
        uaid: this.userAgentID,
        channelID: request.channelID,
        status: 200,
        pushEndpoint: "https://example.com/endpoint/" + this.registerCount++,
      })
    );
  }

  onUnregister(request) {
    this.serverSendMsg(
      JSON.stringify({
        messageType: "unregister",
        channelID: request.channelID,
        status: 200,
      })
    );
  }

  onAck() {
    // Do nothing.
  }

  handleMessage(msg) {
    let request = JSON.parse(msg);
    let messageType = request.messageType;
    switch (messageType) {
      case "hello":
        this.onHello(request);
        break;
      case "register":
        this.onRegister(request);
        break;
      case "unregister":
        this.onUnregister(request);
        break;
      case "ack":
        this.onAck(request);
        break;
      default:
        throw new Error("Unexpected message: " + messageType);
    }
  }

  serverSendMsg(msg) {
    if (this._isActive) {
      chromeScript.sendAsyncMessage("socket-server-msg", msg);
    }
  }
}

// Remove permissions and prefs when the test finishes.
SimpleTest.registerCleanupFunction(async function () {
  await new Promise(resolve => SpecialPowers.flushPermissions(resolve));
  await SpecialPowers.flushPrefEnv();
  await restorePushService();
  await teardownMockPushSocket();
});

function setPushPermission(allow) {
  let permissions = [
    { type: "desktop-notification", allow, context: document },
  ];

  if (isXOrigin) {
    // We need to add permission for the xorigin tests. In xorigin tests, the
    // test page will be run under third-party context, so we need to use
    // partitioned principal to add the permission.
    let partitionedPrincipal =
      SpecialPowers.wrap(document).partitionedPrincipal;

    permissions.push({
      type: "desktop-notification",
      allow,
      context: {
        url: partitionedPrincipal.originNoSuffix,
        originAttributes: {
          partitionKey: partitionedPrincipal.originAttributes.partitionKey,
        },
      },
    });
  }

  return SpecialPowers.pushPermissions(permissions);
}

function setupPrefs() {
  return SpecialPowers.pushPrefEnv({
    set: [
      ["dom.push.enabled"true],
      ["dom.push.connection.enabled"true],
      ["dom.push.maxRecentMessageIDsPerSubscription", 0],
      ["dom.serviceWorkers.exemptFromPerDomainMax"true],
      ["dom.serviceWorkers.enabled"true],
      ["dom.serviceWorkers.testing.enabled"true],
    ],
  });
}

async function setupPrefsAndReplaceService(mockService) {
  await replacePushService(mockService);
  await setupPrefs();
}

function setupPrefsAndMockSocket(mockSocket) {
  setupMockPushSocket(mockSocket);
  return setupPrefs();
}

function injectControlledFrame(target = document.body) {
  return new Promise(function (res) {
    var iframe = document.createElement("iframe");
    iframe.src = "/tests/dom/push/test/frame.html";

    var controlledFrame = {
      remove() {
        target.removeChild(iframe);
        iframe = null;
      },
      waitOnWorkerMessage(type) {
        return iframe
          ? iframe.contentWindow.waitOnWorkerMessage(type)
          : Promise.reject(new Error("Frame removed from document"));
      },
      innerWindowId() {
        return SpecialPowers.wrap(iframe).browsingContext.currentWindowContext
          .innerWindowId;
      },
    };

    iframe.onload = () => res(controlledFrame);
    target.appendChild(iframe);
  });
}

function sendRequestToWorker(request) {
  return navigator.serviceWorker.ready.then(registration => {
    return new Promise((resolve, reject) => {
      var channel = new MessageChannel();
      channel.port1.onmessage = e => {
        (e.data.error ? reject : resolve)(e.data);
      };
      registration.active.postMessage(request, [channel.port2]);
    });
  });
}

function waitForActive(swr) {
  let sw = swr.installing || swr.waiting || swr.active;
  return new Promise(resolve => {
    if (sw.state === "activated") {
      resolve(swr);
      return;
    }
    sw.addEventListener("statechange"function onStateChange() {
      if (sw.state === "activated") {
        sw.removeEventListener("statechange", onStateChange);
        resolve(swr);
      }
    });
  });
}

function base64UrlDecode(s) {
  s = s.replace(/-/g, "+").replace(/_/g, "/");

  // Replace padding if it was stripped by the sender.
  // See http://tools.ietf.org/html/rfc4648#section-4
  switch (s.length % 4) {
    case 0:
      break// No pad chars in this case
    case 2:
      s += "==";
      break// Two pad chars
    case 3:
      s += "=";
      break// One pad char
    default:
      throw new Error("Illegal base64url string!");
  }

  // With correct padding restored, apply the standard base64 decoder
  var decoded = atob(s);

  var array = new Uint8Array(new ArrayBuffer(decoded.length));
  for (var i = 0; i < decoded.length; i++) {
    array[i] = decoded.charCodeAt(i);
  }
  return array;
}

Messung V0.5
C=94 H=86 G=89

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.