summaryrefslogtreecommitdiffstats
path: root/services/sync/tests/unit/test_extension_storage_engine_kinto.js
blob: b074fe376cb3197d1adee259fc6781b73db276d0 (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
135
136
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

Services.prefs.setBoolPref("webextensions.storage.sync.kinto", true);

const { ExtensionStorageEngineKinto: ExtensionStorageEngine } =
  ChromeUtils.importESModule(
    "resource://services-sync/engines/extension-storage.sys.mjs"
  );
const { Service } = ChromeUtils.importESModule(
  "resource://services-sync/service.sys.mjs"
);
const { extensionStorageSyncKinto: extensionStorageSync } =
  ChromeUtils.importESModule(
    "resource://gre/modules/ExtensionStorageSyncKinto.sys.mjs"
  );

let engine;

function mock(options) {
  let calls = [];
  let ret = function () {
    calls.push(arguments);
    return options.returns;
  };
  let proto = {
    get calls() {
      return calls;
    },
  };
  Object.setPrototypeOf(proto, Function.prototype);
  Object.setPrototypeOf(ret, proto);
  return ret;
}

function setSkipChance(v) {
  Services.prefs.setIntPref(
    "services.sync.extension-storage.skipPercentageChance",
    v
  );
}

add_task(async function setup() {
  await Service.engineManager.register(ExtensionStorageEngine);
  engine = Service.engineManager.get("extension-storage");
  do_get_profile(); // so we can use FxAccounts
  loadWebExtensionTestFunctions();
  setSkipChance(0);
});

add_task(async function test_calling_sync_calls__sync() {
  let oldSync = ExtensionStorageEngine.prototype._sync;
  let syncMock = (ExtensionStorageEngine.prototype._sync = mock({
    returns: true,
  }));
  try {
    // I wanted to call the main sync entry point for the entire
    // package, but that fails because it tries to sync ClientEngine
    // first, which fails.
    await engine.sync();
  } finally {
    ExtensionStorageEngine.prototype._sync = oldSync;
  }
  equal(syncMock.calls.length, 1);
});

add_task(async function test_sync_skip() {
  try {
    // Do a few times to ensure we aren't getting "lucky" WRT Math.random()
    for (let i = 0; i < 10; ++i) {
      setSkipChance(100);
      engine._tracker._score = 0;
      ok(
        !engine.shouldSkipSync("user"),
        "Should allow explicitly requested syncs"
      );
      ok(!engine.shouldSkipSync("startup"), "Should allow startup syncs");
      ok(
        engine.shouldSkipSync("schedule"),
        "Should skip scheduled syncs if skipProbability is 100"
      );
      engine._tracker._score = MULTI_DEVICE_THRESHOLD;
      ok(
        !engine.shouldSkipSync("schedule"),
        "should allow scheduled syncs if tracker score is high"
      );
      engine._tracker._score = 0;
      setSkipChance(0);
      ok(
        !engine.shouldSkipSync("schedule"),
        "Should allow scheduled syncs if probability is 0"
      );
    }
  } finally {
    engine._tracker._score = 0;
    setSkipChance(0);
  }
});

add_task(async function test_calling_wipeClient_calls_clearAll() {
  let oldClearAll = extensionStorageSync.clearAll;
  let clearMock = (extensionStorageSync.clearAll = mock({
    returns: Promise.resolve(),
  }));
  try {
    await engine.wipeClient();
  } finally {
    extensionStorageSync.clearAll = oldClearAll;
  }
  equal(clearMock.calls.length, 1);
});

add_task(async function test_calling_sync_calls_ext_storage_sync() {
  const extension = { id: "my-extension" };
  let oldSync = extensionStorageSync.syncAll;
  let syncMock = (extensionStorageSync.syncAll = mock({
    returns: Promise.resolve(),
  }));
  try {
    await withSyncContext(async function (context) {
      // Set something so that everyone knows that we're using storage.sync
      await extensionStorageSync.set(extension, { a: "b" }, context);
      let ping = await sync_engine_and_validate_telem(engine, false);
      Assert.ok(ping.engines.find(e => e.name == "extension-storage"));
      Assert.equal(
        ping.engines.find(e => e.name == "rust-webext-storage"),
        null
      );
    });
  } finally {
    extensionStorageSync.syncAll = oldSync;
  }
  Assert.ok(syncMock.calls.length >= 1);
});