1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { getFxAccountsSingleton } = ChromeUtils.importESModule(
"resource://gre/modules/FxAccounts.sys.mjs"
);
const fxAccounts = getFxAccountsSingleton();
const { ON_NEW_DEVICE_ID, PREF_ACCOUNT_ROOT } = ChromeUtils.import(
"resource://gre/modules/FxAccountsCommon.js"
);
function promiseObserved(topic) {
return new Promise(res => {
Services.obs.addObserver(res, topic);
});
}
_("Misc tests for FxAccounts.device");
fxAccounts.device._checkRemoteCommandsUpdateNeeded = async () => false;
add_test(function test_default_device_name() {
// Note that head_helpers overrides getDefaultLocalName - this test is
// really just to ensure the actual implementation is sane - we can't
// really check the value it uses is correct.
// We are just hoping to avoid a repeat of bug 1369285.
let def = fxAccounts.device.getDefaultLocalName(); // make sure it doesn't throw.
_("default value is " + def);
ok(!!def.length);
// This is obviously tied to the implementation, but we want early warning
// if any of these things fail.
// We really want one of these 2 to provide a value.
let hostname = Services.sysinfo.get("device") || Services.dns.myHostName;
_("hostname is " + hostname);
ok(!!hostname.length);
// the hostname should be in the default.
ok(def.includes(hostname));
// We expect the following to work as a fallback to the above.
let fallback = Cc["@mozilla.org/network/protocol;1?name=http"].getService(
Ci.nsIHttpProtocolHandler
).oscpu;
_("UA fallback is " + fallback);
ok(!!fallback.length);
// the fallback should not be in the default
ok(!def.includes(fallback));
run_next_test();
});
add_test(function test_migration() {
Services.prefs.clearUserPref("identity.fxaccounts.account.device.name");
Services.prefs.setStringPref("services.sync.client.name", "my client name");
// calling getLocalName() should move the name to the new pref and reset the old.
equal(fxAccounts.device.getLocalName(), "my client name");
equal(
Services.prefs.getStringPref("identity.fxaccounts.account.device.name"),
"my client name"
);
ok(!Services.prefs.prefHasUserValue("services.sync.client.name"));
run_next_test();
});
add_test(function test_migration_set_before_get() {
Services.prefs.setStringPref("services.sync.client.name", "old client name");
fxAccounts.device.setLocalName("new client name");
equal(fxAccounts.device.getLocalName(), "new client name");
run_next_test();
});
add_task(async function test_reset() {
// We don't test the client name specifically here because the client name
// is set as part of signing the user in via the attempt to register the
// device.
const testPref = PREF_ACCOUNT_ROOT + "test-pref";
Services.prefs.setStringPref(testPref, "whatever");
let credentials = {
email: "foo@example.com",
uid: "1234@lcip.org",
sessionToken: "dead",
verified: true,
...MOCK_ACCOUNT_KEYS,
};
// FxA will try to register its device record in the background after signin.
const registerDevice = sinon
.stub(fxAccounts._internal.fxAccountsClient, "registerDevice")
.callsFake(async () => {
return { id: "foo" };
});
await fxAccounts._internal.setSignedInUser(credentials);
// wait for device registration to complete.
await promiseObserved(ON_NEW_DEVICE_ID);
ok(!Services.prefs.prefHasUserValue(testPref));
// signing the user out should reset the name pref.
const namePref = PREF_ACCOUNT_ROOT + "device.name";
ok(Services.prefs.prefHasUserValue(namePref));
await fxAccounts.signOut(/* localOnly = */ true);
ok(!Services.prefs.prefHasUserValue(namePref));
registerDevice.restore();
});
add_task(async function test_name_sanitization() {
fxAccounts.device.setLocalName("emoji is valid \u2665");
Assert.equal(fxAccounts.device.getLocalName(), "emoji is valid \u2665");
let invalid = "x\uFFFD\n\r\t" + "x".repeat(255);
let sanitized = "x\uFFFD\uFFFD\uFFFD\uFFFD" + "x".repeat(250); // 255 total.
// If the pref already has the invalid value we still get the valid one back.
Services.prefs.setStringPref(
"identity.fxaccounts.account.device.name",
invalid
);
Assert.equal(fxAccounts.device.getLocalName(), sanitized);
// But if we explicitly set it to an invalid name, the sanitized value ends
// up in the pref.
fxAccounts.device.setLocalName(invalid);
Assert.equal(fxAccounts.device.getLocalName(), sanitized);
Assert.equal(
Services.prefs.getStringPref("identity.fxaccounts.account.device.name"),
sanitized
);
});
|