summaryrefslogtreecommitdiffstats
path: root/services/sync/tests/unit/test_prefs_engine.js
blob: 77a4474cb411229c03fb41103865ce878afce814 (plain)
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
128
129
130
131
132
133
134
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

const { getPrefsGUIDForTest } = ChromeUtils.importESModule(
  "resource://services-sync/engines/prefs.sys.mjs"
);
const PREFS_GUID = getPrefsGUIDForTest();
const { Service } = ChromeUtils.importESModule(
  "resource://services-sync/service.sys.mjs"
);

async function cleanup(engine, server) {
  await engine._tracker.stop();
  await engine.wipeClient();
  for (const pref of Svc.PrefBranch.getChildList("")) {
    Svc.PrefBranch.clearUserPref(pref);
  }
  Service.recordManager.clearCache();
  await promiseStopServer(server);
}

add_task(async function test_modified_after_fail() {
  let engine = Service.engineManager.get("prefs");

  let server = await serverForFoo(engine);
  await SyncTestingInfrastructure(server);

  try {
    // The homepage pref is synced by default.
    _("Set homepage before first sync");
    Services.prefs.setStringPref("browser.startup.homepage", "about:welcome");

    _("First sync; create collection and pref record on server");
    await sync_engine_and_validate_telem(engine, false);

    let collection = server.user("foo").collection("prefs");
    equal(
      collection.cleartext(PREFS_GUID).value["browser.startup.homepage"],
      "about:welcome",
      "Should upload homepage in pref record"
    );
    ok(
      !engine._tracker.modified,
      "Tracker shouldn't be modified after first sync"
    );

    // Our tracker only has a `modified` flag that's reset after a
    // successful upload. Force it to remain set by failing the
    // upload.
    _("Second sync; flag tracker as modified and throw on upload");
    Services.prefs.setStringPref("browser.startup.homepage", "about:robots");
    engine._tracker.modified = true;
    let oldPost = collection.post;
    collection.post = () => {
      throw new Error("Sync this!");
    };
    await Assert.rejects(
      sync_engine_and_validate_telem(engine, true),
      ex => ex.success === false
    );
    ok(
      engine._tracker.modified,
      "Tracker should remain modified after failed sync"
    );

    _("Third sync");
    collection.post = oldPost;
    await sync_engine_and_validate_telem(engine, false);
    equal(
      collection.cleartext(PREFS_GUID).value["browser.startup.homepage"],
      "about:robots",
      "Should upload new homepage on third sync"
    );
    ok(
      !engine._tracker.modified,
      "Tracker shouldn't be modified again after third sync"
    );
  } finally {
    await cleanup(engine, server);
  }
});

add_task(async function test_allow_arbitrary() {
  let engine = Service.engineManager.get("prefs");

  let server = await serverForFoo(engine);
  await SyncTestingInfrastructure(server);

  try {
    _("Create collection and pref record on server");
    await sync_engine_and_validate_telem(engine, false);

    let collection = server.user("foo").collection("prefs");

    _("Insert arbitrary pref into remote record");
    let cleartext1 = collection.cleartext(PREFS_GUID);
    cleartext1.value.let_viruses_take_over = true;
    collection.insert(
      PREFS_GUID,
      encryptPayload(cleartext1),
      new_timestamp() + 5
    );

    _("Sync again; client shouldn't allow pref");
    await sync_engine_and_validate_telem(engine, false);
    ok(
      !Services.prefs.getBoolPref("let_viruses_take_over", false),
      "Shouldn't allow arbitrary remote prefs without control pref"
    );

    _("Sync with control pref set; client should set new pref");
    Services.prefs.setBoolPref(
      "services.sync.prefs.sync.let_viruses_take_over_take_two",
      true
    );

    let cleartext2 = collection.cleartext(PREFS_GUID);
    cleartext2.value.let_viruses_take_over_take_two = true;
    collection.insert(
      PREFS_GUID,
      encryptPayload(cleartext2),
      new_timestamp() + 5
    );
    // Reset the last sync time so that the engine fetches the record again.
    await engine.setLastSync(0);
    await sync_engine_and_validate_telem(engine, false);
    ok(
      Services.prefs.getBoolPref("let_viruses_take_over_take_two"),
      "Should set arbitrary remote pref with control pref"
    );
  } finally {
    await cleanup(engine, server);
  }
});