summaryrefslogtreecommitdiffstats
path: root/toolkit/components/featuregates/test/unit/test_FeatureGateImplementation.js
blob: ac844b488029ee86b6e9dc817f19a74470002ef6 (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
137
138
139
140
141
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const { FeatureGateImplementation } = ChromeUtils.importESModule(
  "resource://featuregates/FeatureGateImplementation.sys.mjs"
);

const kDefinitionDefaults = {
  id: "test-feature",
  title: "Test Feature",
  description: "A feature for testing",
  restartRequired: false,
  type: "boolean",
  preference: "test.feature",
  defaultValue: false,
  isPublic: false,
};

function definitionFactory(override = {}) {
  return Object.assign({}, kDefinitionDefaults, override);
}

// getValue should work
add_task(async function testGetValue() {
  const preference = "test.pref";
  equal(
    Services.prefs.getPrefType(preference),
    Services.prefs.PREF_INVALID,
    "Before creating the feature gate, the preference should not exist"
  );
  const feature = new FeatureGateImplementation(
    definitionFactory({ preference, defaultValue: false })
  );
  equal(
    Services.prefs.getPrefType(preference),
    Services.prefs.PREF_INVALID,
    "Instantiating a feature gate should not set its default value"
  );
  equal(
    await feature.getValue(),
    false,
    "getValue() should return the feature gate's default"
  );

  Services.prefs.setBoolPref(preference, true);
  equal(
    await feature.getValue(),
    true,
    "getValue() should return the new value"
  );

  Services.prefs.setBoolPref(preference, false);
  equal(
    await feature.getValue(),
    false,
    "getValue() should return the third value"
  );

  // cleanup
  Services.prefs.getDefaultBranch("").deleteBranch(preference);
});

// event observers should work
add_task(async function testGetValue() {
  const preference = "test.pref";
  const feature = new FeatureGateImplementation(
    definitionFactory({ preference, defaultValue: false })
  );
  const observer = {
    onChange: sinon.stub(),
    onEnable: sinon.stub(),
    onDisable: sinon.stub(),
  };

  let rv = await feature.addObserver(observer);
  equal(rv, false, "addObserver returns the current value");

  Assert.deepEqual(observer.onChange.args, [], "onChange should not be called");
  Assert.deepEqual(observer.onEnable.args, [], "onEnable should not be called");
  Assert.deepEqual(
    observer.onDisable.args,
    [],
    "onDisable should not be called"
  );

  Services.prefs.setBoolPref(preference, true);
  await Promise.resolve(); // Allow events to be called async
  Assert.deepEqual(
    observer.onChange.args,
    [[true]],
    "onChange should be called with the new value"
  );
  Assert.deepEqual(observer.onEnable.args, [[]], "onEnable should be called");
  Assert.deepEqual(
    observer.onDisable.args,
    [],
    "onDisable should not be called"
  );

  Services.prefs.setBoolPref(preference, false);
  await Promise.resolve(); // Allow events to be called async
  Assert.deepEqual(
    observer.onChange.args,
    [[true], [false]],
    "onChange should be called again with the new value"
  );
  Assert.deepEqual(
    observer.onEnable.args,
    [[]],
    "onEnable should not be called a second time"
  );
  Assert.deepEqual(
    observer.onDisable.args,
    [[]],
    "onDisable should be called for the first time"
  );

  Services.prefs.setBoolPref(preference, false);
  await Promise.resolve(); // Allow events to be called async
  Assert.deepEqual(
    observer.onChange.args,
    [[true], [false]],
    "onChange should not be called if the value did not change"
  );
  Assert.deepEqual(
    observer.onEnable.args,
    [[]],
    "onEnable should not be called again if the value did not change"
  );
  Assert.deepEqual(
    observer.onDisable.args,
    [[]],
    "onDisable should not be called if the value did not change"
  );

  // cleanup
  feature.removeAllObservers();
  Services.prefs.getDefaultBranch("").deleteBranch(preference);
});