/* 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();
});