Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test runs only with pattern: os != 'android'
- Manifest: services/sync/tests/unit/xpcshell.toml
/* Any copyright is dedicated to the Public Domain.
const { Service } = ChromeUtils.importESModule(
);
const { FakeGUIDService } = ChromeUtils.importESModule(
);
add_task(async function test_urls() {
_("URL related Service properties correspond to preference settings.");
try {
Assert.equal(Service.clusterURL, "");
Assert.ok(!Service.userBaseURL);
Assert.equal(Service.infoURL, undefined);
Assert.equal(Service.storageURL, undefined);
Assert.equal(Service.metaURL, undefined);
_("The 'clusterURL' attribute updates preferences and cached URLs.");
// Since we don't have a cluster URL yet, these will still not be defined.
Assert.equal(Service.infoURL, undefined);
Assert.ok(!Service.userBaseURL);
Assert.equal(Service.storageURL, undefined);
Assert.equal(Service.metaURL, undefined);
Service.clusterURL = "http://weave.cluster/1.1/johndoe/";
Assert.equal(Service.userBaseURL, "http://weave.cluster/1.1/johndoe/");
Assert.equal(
Service.infoURL,
);
Assert.equal(
Service.storageURL,
);
Assert.equal(
Service.metaURL,
);
} finally {
for (const pref of Svc.PrefBranch.getChildList("")) {
Svc.PrefBranch.clearUserPref(pref);
}
}
});
add_test(function test_syncID() {
_("Service.syncID is auto-generated, corresponds to preference.");
new FakeGUIDService();
try {
// Ensure pristine environment
Assert.equal(
Svc.PrefBranch.getPrefType("client.syncID"),
Ci.nsIPrefBranch.PREF_INVALID
);
// Performing the first get on the attribute will generate a new GUID.
Assert.equal(Service.syncID, "fake-guid-00");
Assert.equal(Svc.PrefBranch.getStringPref("client.syncID"), "fake-guid-00");
Svc.PrefBranch.setStringPref("client.syncID", Utils.makeGUID());
Assert.equal(Svc.PrefBranch.getStringPref("client.syncID"), "fake-guid-01");
Assert.equal(Service.syncID, "fake-guid-01");
} finally {
for (const pref of Svc.PrefBranch.getChildList("")) {
Svc.PrefBranch.clearUserPref(pref);
}
new FakeGUIDService();
run_next_test();
}
});
add_test(function test_locked() {
_("The 'locked' attribute can be toggled with lock() and unlock()");
// Defaults to false
Assert.equal(Service.locked, false);
Assert.equal(Service.lock(), true);
Assert.equal(Service.locked, true);
// Locking again will return false
Assert.equal(Service.lock(), false);
Service.unlock();
Assert.equal(Service.locked, false);
run_next_test();
});
add_task(async function test_configure_throws_no_user() {
_("configure() throws when no user is signed in");
const { getFxAccountsSingleton } = ChromeUtils.importESModule(
"resource://gre/modules/FxAccounts.sys.mjs"
);
const fxAccounts = getFxAccountsSingleton();
const originalGetSignedInUser = fxAccounts.getSignedInUser;
fxAccounts.getSignedInUser = () => Promise.resolve(null);
try {
await Assert.rejects(
Service.configure(),
/No FxA user is signed in/,
"configure() should throw when no user is signed in"
);
} finally {
fxAccounts.getSignedInUser = originalGetSignedInUser;
}
});
add_task(async function test_configure_throws_without_keys() {
_("configure() throws when user has no sync keys");
const { getFxAccountsSingleton } = ChromeUtils.importESModule(
"resource://gre/modules/FxAccounts.sys.mjs"
);
const fxAccounts = getFxAccountsSingleton();
// Mock getSignedInUser to return a user
const originalGetSignedInUser = fxAccounts.getSignedInUser;
fxAccounts.getSignedInUser = () =>
Promise.resolve({ email: "test@example.com", uid: "12345" });
// Mock hasKeysForScope to return false (no keys)
const originalHasKeysForScope = fxAccounts.keys.hasKeysForScope;
fxAccounts.keys.hasKeysForScope = () => Promise.resolve(false);
try {
await Assert.rejects(
Service.configure(),
/User does not have sync keys/,
"configure() should throw when no sync keys"
);
} finally {
fxAccounts.getSignedInUser = originalGetSignedInUser;
fxAccounts.keys.hasKeysForScope = originalHasKeysForScope;
}
});
add_task(async function test_configure_succeeds_with_keys() {
_("configure() succeeds when user has sync keys");
const { getFxAccountsSingleton } = ChromeUtils.importESModule(
"resource://gre/modules/FxAccounts.sys.mjs"
);
const fxAccounts = getFxAccountsSingleton();
// Mock getSignedInUser to return a user
const originalGetSignedInUser = fxAccounts.getSignedInUser;
fxAccounts.getSignedInUser = () =>
Promise.resolve({ email: "test@example.com", uid: "12345" });
// Mock hasKeysForScope to return true (has keys)
const originalHasKeysForScope = fxAccounts.keys.hasKeysForScope;
fxAccounts.keys.hasKeysForScope = () => Promise.resolve(true);
try {
await Service.configure();
// Should set the username pref
Assert.equal(Svc.PrefBranch.getStringPref("username"), "test@example.com");
} finally {
fxAccounts.getSignedInUser = originalGetSignedInUser;
fxAccounts.keys.hasKeysForScope = originalHasKeysForScope;
Svc.PrefBranch.clearUserPref("username");
}
});
add_task(async function test_third_party_to_sync_complete_flow() {
_("End-to-end: third-party auth (no keys) -> receive keys -> configure sync");
const { getFxAccountsSingleton } = ChromeUtils.importESModule(
"resource://gre/modules/FxAccounts.sys.mjs"
);
const fxAccounts = getFxAccountsSingleton();
const originalGetSignedInUser = fxAccounts.getSignedInUser;
const originalHasKeysForScope = fxAccounts.keys.hasKeysForScope;
// 1. User signs in without keys (third-party)
const user = { email: "foo@example.com", uid: "uid12345" };
fxAccounts.getSignedInUser = () => Promise.resolve(user);
// 2. Initially no keys - hasKeysForScope returns false
fxAccounts.keys.hasKeysForScope = () => Promise.resolve(false);
try {
await Assert.rejects(
Service.configure(),
/User does not have sync keys/,
"configure() should throw when no sync keys"
);
fxAccounts.keys.hasKeysForScope = () => Promise.resolve(true);
await Service.configure();
Assert.equal(Svc.PrefBranch.getStringPref("username"), "foo@example.com");
} finally {
fxAccounts.getSignedInUser = originalGetSignedInUser;
fxAccounts.keys.hasKeysForScope = originalHasKeysForScope;
Svc.PrefBranch.clearUserPref("username");
}
});