|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 "use strict"; |
|
5 |
|
6 Cu.import("resource://gre/modules/AddonManager.jsm"); |
|
7 Cu.import("resource://services-sync/addonsreconciler.js"); |
|
8 Cu.import("resource://services-sync/engines/addons.js"); |
|
9 Cu.import("resource://services-sync/service.js"); |
|
10 Cu.import("resource://services-sync/util.js"); |
|
11 |
|
12 loadAddonTestFunctions(); |
|
13 startupManager(); |
|
14 |
|
15 function run_test() { |
|
16 initTestLogging("Trace"); |
|
17 Log.repository.getLogger("Sync.AddonsReconciler").level = Log.Level.Trace; |
|
18 Log.repository.getLogger("Sync.AddonsReconciler").level = |
|
19 Log.Level.Trace; |
|
20 |
|
21 Svc.Prefs.set("engine.addons", true); |
|
22 Service.engineManager.register(AddonsEngine); |
|
23 |
|
24 run_next_test(); |
|
25 } |
|
26 |
|
27 add_test(function test_defaults() { |
|
28 _("Ensure new objects have reasonable defaults."); |
|
29 |
|
30 let reconciler = new AddonsReconciler(); |
|
31 |
|
32 do_check_false(reconciler._listening); |
|
33 do_check_eq("object", typeof(reconciler.addons)); |
|
34 do_check_eq(0, Object.keys(reconciler.addons).length); |
|
35 do_check_eq(0, reconciler._changes.length); |
|
36 do_check_eq(0, reconciler._listeners.length); |
|
37 |
|
38 run_next_test(); |
|
39 }); |
|
40 |
|
41 add_test(function test_load_state_empty_file() { |
|
42 _("Ensure loading from a missing file results in defaults being set."); |
|
43 |
|
44 let reconciler = new AddonsReconciler(); |
|
45 |
|
46 reconciler.loadState(null, function(error, loaded) { |
|
47 do_check_eq(null, error); |
|
48 do_check_false(loaded); |
|
49 |
|
50 do_check_eq("object", typeof(reconciler.addons)); |
|
51 do_check_eq(0, Object.keys(reconciler.addons).length); |
|
52 do_check_eq(0, reconciler._changes.length); |
|
53 |
|
54 run_next_test(); |
|
55 }); |
|
56 }); |
|
57 |
|
58 add_test(function test_install_detection() { |
|
59 _("Ensure that add-on installation results in appropriate side-effects."); |
|
60 |
|
61 let reconciler = new AddonsReconciler(); |
|
62 reconciler.startListening(); |
|
63 |
|
64 let before = new Date(); |
|
65 let addon = installAddon("test_bootstrap1_1"); |
|
66 let after = new Date(); |
|
67 |
|
68 do_check_eq(1, Object.keys(reconciler.addons).length); |
|
69 do_check_true(addon.id in reconciler.addons); |
|
70 let record = reconciler.addons[addon.id]; |
|
71 |
|
72 const KEYS = ["id", "guid", "enabled", "installed", "modified", "type", |
|
73 "scope", "foreignInstall"]; |
|
74 for each (let key in KEYS) { |
|
75 do_check_true(key in record); |
|
76 do_check_neq(null, record[key]); |
|
77 } |
|
78 |
|
79 do_check_eq(addon.id, record.id); |
|
80 do_check_eq(addon.syncGUID, record.guid); |
|
81 do_check_true(record.enabled); |
|
82 do_check_true(record.installed); |
|
83 do_check_true(record.modified >= before && record.modified <= after); |
|
84 do_check_eq("extension", record.type); |
|
85 do_check_false(record.foreignInstall); |
|
86 |
|
87 do_check_eq(1, reconciler._changes.length); |
|
88 let change = reconciler._changes[0]; |
|
89 do_check_true(change[0] >= before && change[1] <= after); |
|
90 do_check_eq(CHANGE_INSTALLED, change[1]); |
|
91 do_check_eq(addon.id, change[2]); |
|
92 |
|
93 uninstallAddon(addon); |
|
94 |
|
95 run_next_test(); |
|
96 }); |
|
97 |
|
98 add_test(function test_uninstall_detection() { |
|
99 _("Ensure that add-on uninstallation results in appropriate side-effects."); |
|
100 |
|
101 let reconciler = new AddonsReconciler(); |
|
102 reconciler.startListening(); |
|
103 |
|
104 reconciler._addons = {}; |
|
105 reconciler._changes = []; |
|
106 |
|
107 let addon = installAddon("test_bootstrap1_1"); |
|
108 let id = addon.id; |
|
109 let guid = addon.syncGUID; |
|
110 |
|
111 reconciler._changes = []; |
|
112 uninstallAddon(addon); |
|
113 |
|
114 do_check_eq(1, Object.keys(reconciler.addons).length); |
|
115 do_check_true(id in reconciler.addons); |
|
116 |
|
117 let record = reconciler.addons[id]; |
|
118 do_check_false(record.installed); |
|
119 |
|
120 do_check_eq(1, reconciler._changes.length); |
|
121 let change = reconciler._changes[0]; |
|
122 do_check_eq(CHANGE_UNINSTALLED, change[1]); |
|
123 do_check_eq(id, change[2]); |
|
124 |
|
125 run_next_test(); |
|
126 }); |
|
127 |
|
128 add_test(function test_load_state_future_version() { |
|
129 _("Ensure loading a file from a future version results in no data loaded."); |
|
130 |
|
131 const FILENAME = "TEST_LOAD_STATE_FUTURE_VERSION"; |
|
132 |
|
133 let reconciler = new AddonsReconciler(); |
|
134 |
|
135 // First we populate our new file. |
|
136 let state = {version: 100, addons: {foo: {}}, changes: [[1, 1, "foo"]]}; |
|
137 let cb = Async.makeSyncCallback(); |
|
138 |
|
139 // jsonSave() expects an object with ._log, so we give it a reconciler |
|
140 // instance. |
|
141 Utils.jsonSave(FILENAME, reconciler, state, cb); |
|
142 Async.waitForSyncCallback(cb); |
|
143 |
|
144 reconciler.loadState(FILENAME, function(error, loaded) { |
|
145 do_check_eq(null, error); |
|
146 do_check_false(loaded); |
|
147 |
|
148 do_check_eq("object", typeof(reconciler.addons)); |
|
149 do_check_eq(1, Object.keys(reconciler.addons).length); |
|
150 do_check_eq(1, reconciler._changes.length); |
|
151 |
|
152 run_next_test(); |
|
153 }); |
|
154 }); |
|
155 |
|
156 add_test(function test_prune_changes_before_date() { |
|
157 _("Ensure that old changes are pruned properly."); |
|
158 |
|
159 let reconciler = new AddonsReconciler(); |
|
160 reconciler._ensureStateLoaded(); |
|
161 reconciler._changes = []; |
|
162 |
|
163 let now = new Date(); |
|
164 const HOUR_MS = 1000 * 60 * 60; |
|
165 |
|
166 _("Ensure pruning an empty changes array works."); |
|
167 reconciler.pruneChangesBeforeDate(now); |
|
168 do_check_eq(0, reconciler._changes.length); |
|
169 |
|
170 let old = new Date(now.getTime() - HOUR_MS); |
|
171 let young = new Date(now.getTime() - 1000); |
|
172 reconciler._changes.push([old, CHANGE_INSTALLED, "foo"]); |
|
173 reconciler._changes.push([young, CHANGE_INSTALLED, "bar"]); |
|
174 do_check_eq(2, reconciler._changes.length); |
|
175 |
|
176 _("Ensure pruning with an old time won't delete anything."); |
|
177 let threshold = new Date(old.getTime() - 1); |
|
178 reconciler.pruneChangesBeforeDate(threshold); |
|
179 do_check_eq(2, reconciler._changes.length); |
|
180 |
|
181 _("Ensure pruning a single item works."); |
|
182 let threshold = new Date(young.getTime() - 1000); |
|
183 reconciler.pruneChangesBeforeDate(threshold); |
|
184 do_check_eq(1, reconciler._changes.length); |
|
185 do_check_neq(undefined, reconciler._changes[0]); |
|
186 do_check_eq(young, reconciler._changes[0][0]); |
|
187 do_check_eq("bar", reconciler._changes[0][2]); |
|
188 |
|
189 _("Ensure pruning all changes works."); |
|
190 reconciler._changes.push([old, CHANGE_INSTALLED, "foo"]); |
|
191 reconciler.pruneChangesBeforeDate(now); |
|
192 do_check_eq(0, reconciler._changes.length); |
|
193 |
|
194 run_next_test(); |
|
195 }); |