/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

/**
 * Tests for the error registry foundation.
 * These tests verify that the error registry provides correct configurations
 * for network and certificate errors.
 */

const REGISTRY_URL = "chrome://global/content/errors/error-registry.mjs";
const LOOKUP_URL = "chrome://global/content/errors/error-lookup.mjs";
const CERT_ERRORS_URL = "chrome://global/content/errors/cert-errors.mjs";
const PKIX_ERRORS_URL = "chrome://global/content/errors/pkix-errors.mjs";
const SSL_ERRORS_URL = "chrome://global/content/errors/ssl-errors.mjs";
const NET_ERRORS_URL = "chrome://global/content/errors/net-errors.mjs";

add_task(async function test_registry_exports() {
  const registry = ChromeUtils.importESModule(REGISTRY_URL);

  Assert.strictEqual(
    typeof registry.getErrorConfig,
    "function",
    "getErrorConfig should be exported"
  );
  Assert.strictEqual(
    typeof registry.registerError,
    "function",
    "registerError should be exported"
  );
  Assert.strictEqual(
    typeof registry.isErrorSupported,
    "function",
    "isErrorSupported should be exported"
  );
});

add_task(async function test_lookup_exports() {
  const lookup = ChromeUtils.importESModule(LOOKUP_URL);

  Assert.strictEqual(
    typeof lookup.errorHasNoUserFix,
    "function",
    "errorHasNoUserFix should be exported"
  );
  Assert.strictEqual(
    typeof lookup.getResolvedErrorConfig,
    "function",
    "getResolvedErrorConfig should be exported"
  );
  Assert.strictEqual(
    typeof lookup.isFeltPrivacySupported,
    "function",
    "isFeltPrivacySupported should be exported"
  );
});

add_task(async function test_unknown_error_returns_default() {
  const { getErrorConfig } = ChromeUtils.importESModule(REGISTRY_URL);

  const config = getErrorConfig("UNKNOWN_ERROR_12345");

  Assert.strictEqual(
    config,
    undefined,
    "Unknown error should return undefined"
  );
});

add_task(async function test_register_and_get_error() {
  const { registerError, getErrorConfig, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();

  const testConfig = {
    id: "TEST_ERROR_123",
    errorCode: "TEST_ERROR_123",
    category: "cert",
    pageTitleL10nId: "test-page-title",
    bodyTitleL10nId: "test-body-title",
    buttons: {
      showTryAgain: false,
      showGoBack: true,
    },
    hasNoUserFix: true,
  };

  registerError(testConfig);

  const retrieved = getErrorConfig("TEST_ERROR_123");
  Assert.equal(retrieved.errorCode, "TEST_ERROR_123");
  Assert.equal(retrieved.category, "cert");
  Assert.equal(retrieved.pageTitleL10nId, "test-page-title");
  Assert.equal(retrieved.hasNoUserFix, true);

  _testOnlyClearRegistry();
});

add_task(async function test_is_error_supported() {
  const { registerError, isErrorSupported, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();

  Assert.ok(
    !isErrorSupported("TEST_ERROR_456"),
    "Unregistered error should not be supported"
  );

  registerError({
    id: "TEST_ERROR_456",
    errorCode: "TEST_ERROR_456",
    category: "net",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    buttons: {},
  });

  Assert.ok(
    isErrorSupported("TEST_ERROR_456"),
    "Registered error should be supported"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_error_has_no_user_fix() {
  const { registerError, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);
  const { errorHasNoUserFix } = ChromeUtils.importESModule(LOOKUP_URL);

  _testOnlyClearRegistry();

  registerError({
    id: "NO_FIX_ERROR",
    errorCode: "NO_FIX_ERROR",
    category: "cert",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    buttons: {},
    hasNoUserFix: true,
  });

  registerError({
    id: "HAS_FIX_ERROR",
    errorCode: "HAS_FIX_ERROR",
    category: "cert",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    buttons: {},
    hasNoUserFix: false,
  });

  Assert.ok(
    errorHasNoUserFix("NO_FIX_ERROR"),
    "Error with hasNoUserFix=true should return true"
  );
  Assert.ok(
    !errorHasNoUserFix("HAS_FIX_ERROR"),
    "Error with hasNoUserFix=false should return false"
  );
  Assert.ok(
    !errorHasNoUserFix("UNKNOWN_ERROR"),
    "Unknown error should return false (default)"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_resolve_l10n_args() {
  const { resolveL10nArgs } = ChromeUtils.importESModule(LOOKUP_URL);

  const config = {
    dataL10nId: "test-l10n-id",
    dataL10nArgs: { hostname: null, otherArg: "static" },
  };

  const context = { hostname: "example.com" };
  const resolved = resolveL10nArgs(config, context);

  Assert.equal(resolved.dataL10nId, "test-l10n-id");
  Assert.equal(resolved.dataL10nArgs.hostname, "example.com");
  Assert.equal(resolved.dataL10nArgs.otherArg, "static");
});

add_task(async function test_resolve_l10n_args_null_input() {
  const { resolveL10nArgs } = ChromeUtils.importESModule(LOOKUP_URL);

  const resolved = resolveL10nArgs(null, { hostname: "example.com" });
  Assert.equal(resolved, null, "Null config should return null");
});

add_task(async function test_get_resolved_error_config() {
  const { registerError, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);
  const { getResolvedErrorConfig } = ChromeUtils.importESModule(LOOKUP_URL);

  _testOnlyClearRegistry();

  registerError({
    id: "RESOLVE_TEST_ERROR",
    errorCode: "RESOLVE_TEST_ERROR",
    category: "cert",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    introContent: {
      dataL10nId: "test-intro",
      dataL10nArgs: { hostname: null },
    },
    shortDescription: {
      dataL10nId: "test-short-desc",
      dataL10nArgs: { hostname: null },
    },
    buttons: {},
    hasNoUserFix: false,
  });

  const context = { hostname: "test.example.com" };
  const resolved = getResolvedErrorConfig("RESOLVE_TEST_ERROR", context);

  Assert.equal(resolved.errorCode, "RESOLVE_TEST_ERROR");
  Assert.equal(resolved.introContent.dataL10nArgs.hostname, "test.example.com");
  Assert.equal(
    resolved.shortDescription.dataL10nArgs.hostname,
    "test.example.com"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_get_errors_by_category() {
  const { registerErrors, getErrorsByCategory, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();

  registerErrors([
    {
      id: "CERT_ERROR_1",
      errorCode: "CERT_ERROR_1",
      category: "cert",
      pageTitleL10nId: "t1",
      bodyTitleL10nId: "b1",
      buttons: {},
    },
    {
      id: "CERT_ERROR_2",
      errorCode: "CERT_ERROR_2",
      category: "cert",
      pageTitleL10nId: "t2",
      bodyTitleL10nId: "b2",
      buttons: {},
    },
    {
      id: "NET_ERROR_1",
      errorCode: "NET_ERROR_1",
      category: "net",
      pageTitleL10nId: "t3",
      bodyTitleL10nId: "b3",
      buttons: {},
    },
  ]);

  const certErrors = getErrorsByCategory("cert");
  const netErrors = getErrorsByCategory("net");

  Assert.equal(certErrors.length, 2, "Should have 2 cert errors");
  Assert.equal(netErrors.length, 1, "Should have 1 net error");

  _testOnlyClearRegistry();
});

add_task(async function test_is_felt_privacy_supported() {
  const { registerError, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);
  const { isFeltPrivacySupported } = ChromeUtils.importESModule(LOOKUP_URL);

  _testOnlyClearRegistry();

  registerError({
    id: "FP_SUPPORTED_ERROR",
    errorCode: "FP_SUPPORTED_ERROR",
    category: "cert",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    introContent: { id: "fp-intro" },
    buttons: {},
  });

  registerError({
    id: "fp-another-supported-error",
    category: "net",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    buttons: {},
  });

  Assert.ok(
    isFeltPrivacySupported("FP_SUPPORTED_ERROR"),
    "Registered error should support Felt Privacy"
  );
  Assert.ok(
    isFeltPrivacySupported("fp-another-supported-error"),
    "All registered errors should support Felt Privacy"
  );
  Assert.ok(
    !isFeltPrivacySupported("NONEXISTENT_ERROR"),
    "Unregistered error should not support Felt Privacy"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_register_error_throws_without_id() {
  const { registerError } = ChromeUtils.importESModule(REGISTRY_URL);

  Assert.throws(
    () => registerError({}),
    /Error configuration must have an id/,
    "registerError should throw when config has no id"
  );
});

add_task(async function test_registered_config_is_frozen() {
  const { registerError, getErrorConfig, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();

  registerError({
    id: "FROZEN_TEST_ERROR",
    errorCode: "FROZEN_TEST_ERROR",
    category: "cert",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    buttons: {},
  });

  const config = getErrorConfig("FROZEN_TEST_ERROR");
  Assert.ok(Object.isFrozen(config), "Registered config should be frozen");

  _testOnlyClearRegistry();
});

add_task(async function test_duplicate_registration_throws() {
  const { registerError, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();

  registerError({
    id: "DUP_TEST_ERROR",
    errorCode: "DUP_TEST_ERROR",
    category: "cert",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    buttons: {},
  });

  Assert.throws(
    () =>
      registerError({
        id: "DUP_TEST_ERROR",
        errorCode: "DUP_TEST_ERROR",
        category: "net",
        pageTitleL10nId: "test-title-2",
        bodyTitleL10nId: "test-body-2",
        buttons: {},
      }),
    /Duplicate error registration/,
    "registerError should throw when a duplicate id is registered"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_initialize_registry_count() {
  const { initializeRegistry, getErrorCount, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);
  const { CERT_ERRORS } = ChromeUtils.importESModule(CERT_ERRORS_URL);
  const { PKIX_ERRORS } = ChromeUtils.importESModule(PKIX_ERRORS_URL);
  const { SSL_ERRORS } = ChromeUtils.importESModule(SSL_ERRORS_URL);
  const { NET_ERRORS } = ChromeUtils.importESModule(NET_ERRORS_URL);

  _testOnlyClearRegistry();
  initializeRegistry();

  const expectedCount =
    CERT_ERRORS.length +
    PKIX_ERRORS.length +
    SSL_ERRORS.length +
    NET_ERRORS.length;
  Assert.equal(
    getErrorCount(),
    expectedCount,
    "initializeRegistry should register all errors from all sources"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_resolve_l10n_args_resolution() {
  const { resolveL10nArgs } = ChromeUtils.importESModule(LOOKUP_URL);

  const config = {
    dataL10nId: "x",
    dataL10nArgs: { hostname: "" },
  };
  const resolved = resolveL10nArgs(config, { hostname: "example.com" });
  Assert.equal(
    resolved.dataL10nArgs.hostname,
    "example.com",
    "Empty string should be replaced with runtime value"
  );
});

add_task(async function test_dataL10nId_configured_as_function() {
  const { resolveL10nArgs } = ChromeUtils.importESModule(LOOKUP_URL);

  const fn = ctx => (ctx.cssClass === "badStsCert" ? "sts-id" : "normal-id");
  const config1 = { dataL10nId: fn, dataL10nArgs: {} };
  const config2 = { dataL10nId: fn, dataL10nArgs: {} };

  const resolved1 = resolveL10nArgs(config1, { cssClass: "badStsCert" });
  Assert.equal(
    resolved1.dataL10nId,
    "sts-id",
    "Function dataL10nId should resolve with badStsCert context"
  );

  const resolved2 = resolveL10nArgs(config2, { cssClass: "other" });
  Assert.equal(
    resolved2.dataL10nId,
    "normal-id",
    "Function dataL10nId should resolve with non-badStsCert context"
  );
});

add_task(async function test_dataL10nArgs_param_as_function() {
  const { resolveL10nArgs } = ChromeUtils.importESModule(LOOKUP_URL);

  const config = {
    dataL10nId: "x",
    dataL10nArgs: { date: ctx => ctx.errorInfo.validNotAfter },
  };
  const resolved = resolveL10nArgs(config, {
    errorInfo: { validNotAfter: 12345 },
  });
  Assert.equal(
    resolved.dataL10nArgs.date,
    12345,
    "Configured function in l10n args should be replaced with its return value"
  );
});

add_task(async function test_resolve_many_l10n_args() {
  const { resolveManyL10nArgs } = ChromeUtils.importESModule(LOOKUP_URL);

  const configs = [
    { dataL10nId: "a", dataL10nArgs: { hostname: null } },
    { dataL10nId: "b", dataL10nArgs: { hostname: null } },
  ];
  const resolved = resolveManyL10nArgs(configs, { hostname: "example.com" });
  Assert.equal(
    resolved[0].dataL10nArgs.hostname,
    "example.com",
    "First config hostname should be resolved"
  );
  Assert.equal(
    resolved[1].dataL10nArgs.hostname,
    "example.com",
    "Second config hostname should be resolved"
  );

  const nullResult = resolveManyL10nArgs(null, { hostname: "example.com" });
  Assert.strictEqual(nullResult, null, "Null input should return null");
});

add_task(async function test_resolve_description_parts_static_array() {
  const { resolveDescriptionParts } = ChromeUtils.importESModule(LOOKUP_URL);

  const parts = [
    { dataL10nId: "part-one", dataL10nArgs: { hostname: null } },
    { dataL10nId: "part-two", dataL10nArgs: { hostname: null } },
  ];
  const resolved = resolveDescriptionParts(parts, { hostname: "example.com" });
  Assert.equal(
    resolved[0].dataL10nArgs.hostname,
    "example.com",
    "First description part hostname should be resolved"
  );
  Assert.equal(
    resolved[1].dataL10nArgs.hostname,
    "example.com",
    "Second description part hostname should be resolved"
  );
});

add_task(async function test_resolve_description_parts_function_online() {
  const { resolveDescriptionParts } = ChromeUtils.importESModule(LOOKUP_URL);
  const { DESCRIPTION_PARTS_MAP } = ChromeUtils.importESModule(NET_ERRORS_URL);

  const result = resolveDescriptionParts(
    DESCRIPTION_PARTS_MAP.dnsNotFoundDescription,
    { noConnectivity: false }
  );
  Assert.ok(
    result.some(p => p.dataL10nId === "neterror-dns-not-found-hint-header"),
    "Online branch should include neterror-dns-not-found-hint-header"
  );
});

add_task(async function test_resolve_description_parts_function_offline() {
  const { resolveDescriptionParts } = ChromeUtils.importESModule(LOOKUP_URL);
  const { DESCRIPTION_PARTS_MAP } = ChromeUtils.importESModule(NET_ERRORS_URL);

  const result = resolveDescriptionParts(
    DESCRIPTION_PARTS_MAP.dnsNotFoundDescription,
    { noConnectivity: true }
  );
  Assert.ok(
    result.some(
      p => p.dataL10nId === "neterror-dns-not-found-offline-hint-header"
    ),
    "Offline branch should include neterror-dns-not-found-offline-hint-header"
  );
});

add_task(async function test_resolve_description_parts_null() {
  const { resolveDescriptionParts } = ChromeUtils.importESModule(LOOKUP_URL);

  const result = resolveDescriptionParts(null, {});
  Assert.deepEqual(
    result,
    [],
    "Null descriptionParts should return empty array"
  );
});

add_task(async function test_resolve_advanced_config() {
  const { registerError, getErrorConfig, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);
  const { resolveAdvancedConfig } = ChromeUtils.importESModule(LOOKUP_URL);

  _testOnlyClearRegistry();

  registerError({
    id: "ADV_TEST_ERROR",
    errorCode: "ADV_TEST_ERROR",
    category: "cert",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    buttons: {},
    advanced: {
      whyDangerous: { dataL10nId: "x", dataL10nArgs: { hostname: null } },
      whatCanYouDo: { dataL10nId: "y", dataL10nArgs: { hostname: null } },
      learnMore: { dataL10nId: "z", dataL10nArgs: { hostname: null } },
    },
  });

  const config = getErrorConfig("ADV_TEST_ERROR");
  const resolved = resolveAdvancedConfig(config.advanced, {
    hostname: "example.com",
  });

  Assert.equal(
    resolved.whyDangerous.dataL10nArgs.hostname,
    "example.com",
    "whyDangerous hostname should be resolved"
  );
  Assert.equal(
    resolved.whatCanYouDo.dataL10nArgs.hostname,
    "example.com",
    "whatCanYouDo hostname should be resolved"
  );
  Assert.equal(
    resolved.learnMore.dataL10nArgs.hostname,
    "example.com",
    "learnMore hostname should be resolved"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_resolve_advanced_config_null() {
  const { resolveAdvancedConfig } = ChromeUtils.importESModule(LOOKUP_URL);

  const result = resolveAdvancedConfig(null, {});
  Assert.strictEqual(result, null, "Null advancedConfig should return null");
});

add_task(async function test_ssl_error_rx_record_too_long_registered() {
  const { initializeRegistry, getErrorConfig, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();
  initializeRegistry();

  const config = getErrorConfig("SSL_ERROR_RX_RECORD_TOO_LONG");
  Assert.ok(config, "SSL_ERROR_RX_RECORD_TOO_LONG should be registered");
  Assert.equal(config.category, "cert", "Should be in the cert category");
  Assert.equal(
    config.bodyTitleL10nId,
    "nssFailure2-title",
    "Should have the nssFailure2 title for consistency with other SSL errors"
  );
  Assert.ok(
    Array.isArray(config.introContent),
    "introContent should be an array"
  );
  Assert.equal(
    config.introContent[0].dataL10nId,
    "cert-error-ssl-connection-error",
    "First intro content should be the SSL connection error message"
  );
  Assert.equal(
    config.introContent[1].dataL10nId,
    "ssl-error-rx-record-too-long",
    "Second intro content should be the specific error message"
  );
  Assert.ok(config.buttons.showTryAgain, "Should show try again button");
  Assert.ok(config.buttons.showAdvanced, "Should show advanced section");
  Assert.equal(config.hasNoUserFix, true, "Should have no user fix");

  _testOnlyClearRegistry();
});

add_task(async function test_denied_port_access_intro_content() {
  const { initializeRegistry, getErrorConfig, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();
  initializeRegistry();

  const config = getErrorConfig("deniedPortAccess");
  Assert.ok(config, "deniedPortAccess should be registered");
  Assert.equal(
    config.introContent.dataL10nId,
    "fp-neterror-denied-port-access",
    "Should use the denied port access l10n id, not the offline intro"
  );
  Assert.strictEqual(
    config.introContent.dataL10nArgs,
    undefined,
    "Should not have l10n args (no hostname needed)"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_clock_skew_errors_have_checkClockSkew() {
  const { initializeRegistry, getErrorConfig, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();
  initializeRegistry();

  const clockSkewErrorIds = [
    "SEC_ERROR_EXPIRED_CERTIFICATE",
    "SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE",
    "MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE",
    "MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE",
  ];

  for (const id of clockSkewErrorIds) {
    const config = getErrorConfig(id);
    Assert.ok(config, `${id} should be registered`);
    Assert.equal(
      config.checkClockSkew,
      true,
      `${id} should have checkClockSkew: true`
    );
  }

  _testOnlyClearRegistry();
});

add_task(async function test_resolve_error_id_nss_fallthrough() {
  const { registerError, isErrorSupported, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);
  const { resolveErrorID } = ChromeUtils.importESModule(LOOKUP_URL);

  _testOnlyClearRegistry();

  registerError({
    id: "nssFailure2",
    errorCode: "nssFailure2",
    category: "cert",
    pageTitleL10nId: "test-title",
    bodyTitleL10nId: "test-body",
    buttons: {},
  });

  Assert.ok(
    isErrorSupported("nssFailure2"),
    "nssFailure2 should be registered"
  );

  Assert.strictEqual(
    resolveErrorID({
      errorCodeString: "SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT",
      gErrorCode: "nssFailure2",
      noConnectivity: false,
      vpnActive: false,
    }),
    "nssFailure2",
    "Unrecognized errorCodeString with gErrorCode=nssFailure2 should fall through to nssFailure2"
  );

  Assert.strictEqual(
    resolveErrorID({
      errorCodeString: "SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT",
      gErrorCode: "dnsNotFound",
      noConnectivity: false,
      vpnActive: false,
    }),
    null,
    "Unrecognized errorCodeString with gErrorCode other than nssFailure2 should return null"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_dns_not_found_what_can_you_do_items() {
  const { initializeRegistry, getErrorConfig, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();
  initializeRegistry();

  const config = getErrorConfig("dnsNotFound");
  Assert.ok(config, "dnsNotFound should be registered");

  const items = config.customNetError?.whatCanYouDoItems;
  Assert.ok(
    Array.isArray(items),
    "dnsNotFound customNetError should have a whatCanYouDoItems array"
  );
  Assert.equal(items.length, 3, "whatCanYouDoItems should have 3 entries");
  Assert.ok(
    items.includes("neterror-http-empty-response"),
    "whatCanYouDoItems should include neterror-http-empty-response"
  );
  Assert.ok(
    items.includes("neterror-dns-not-found-hint-check-network-2"),
    "whatCanYouDoItems should include neterror-dns-not-found-hint-check-network-2"
  );
  Assert.ok(
    items.includes("neterror-dns-not-found-hint-firewall-2"),
    "whatCanYouDoItems should include neterror-dns-not-found-hint-firewall-2"
  );

  _testOnlyClearRegistry();
});

add_task(async function test_sec_error_ca_cert_invalid_registered() {
  const { initializeRegistry, getErrorConfig, _testOnlyClearRegistry } =
    ChromeUtils.importESModule(REGISTRY_URL);

  _testOnlyClearRegistry();
  initializeRegistry();

  const config = getErrorConfig("SEC_ERROR_CA_CERT_INVALID");
  Assert.ok(config, "SEC_ERROR_CA_CERT_INVALID should be registered");
  Assert.equal(config.category, "cert", "Should be in the cert category");
  Assert.ok(
    config.buttons.showAddException,
    "Should show the exception button"
  );
  Assert.ok(config.buttons.showAdvanced, "Should show the advanced section");
  Assert.equal(config.hasNoUserFix, true, "Should have no user fix");
  Assert.equal(
    config.advanced.whyDangerous.dataL10nId,
    "fp-certerror-invalid-cert-why-dangerous",
    "Should use the invalid cert why-dangerous l10n id"
  );
  Assert.equal(
    config.advanced.whatCanYouDo.dataL10nId,
    "fp-certerror-untrusted-issuer-what-can-you-do-body",
    "Should reuse the untrusted issuer what-can-you-do l10n id"
  );

  _testOnlyClearRegistry();
});
