1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/services/sync/tests/unit/test_addons_reconciler.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,195 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +"use strict"; 1.8 + 1.9 +Cu.import("resource://gre/modules/AddonManager.jsm"); 1.10 +Cu.import("resource://services-sync/addonsreconciler.js"); 1.11 +Cu.import("resource://services-sync/engines/addons.js"); 1.12 +Cu.import("resource://services-sync/service.js"); 1.13 +Cu.import("resource://services-sync/util.js"); 1.14 + 1.15 +loadAddonTestFunctions(); 1.16 +startupManager(); 1.17 + 1.18 +function run_test() { 1.19 + initTestLogging("Trace"); 1.20 + Log.repository.getLogger("Sync.AddonsReconciler").level = Log.Level.Trace; 1.21 + Log.repository.getLogger("Sync.AddonsReconciler").level = 1.22 + Log.Level.Trace; 1.23 + 1.24 + Svc.Prefs.set("engine.addons", true); 1.25 + Service.engineManager.register(AddonsEngine); 1.26 + 1.27 + run_next_test(); 1.28 +} 1.29 + 1.30 +add_test(function test_defaults() { 1.31 + _("Ensure new objects have reasonable defaults."); 1.32 + 1.33 + let reconciler = new AddonsReconciler(); 1.34 + 1.35 + do_check_false(reconciler._listening); 1.36 + do_check_eq("object", typeof(reconciler.addons)); 1.37 + do_check_eq(0, Object.keys(reconciler.addons).length); 1.38 + do_check_eq(0, reconciler._changes.length); 1.39 + do_check_eq(0, reconciler._listeners.length); 1.40 + 1.41 + run_next_test(); 1.42 +}); 1.43 + 1.44 +add_test(function test_load_state_empty_file() { 1.45 + _("Ensure loading from a missing file results in defaults being set."); 1.46 + 1.47 + let reconciler = new AddonsReconciler(); 1.48 + 1.49 + reconciler.loadState(null, function(error, loaded) { 1.50 + do_check_eq(null, error); 1.51 + do_check_false(loaded); 1.52 + 1.53 + do_check_eq("object", typeof(reconciler.addons)); 1.54 + do_check_eq(0, Object.keys(reconciler.addons).length); 1.55 + do_check_eq(0, reconciler._changes.length); 1.56 + 1.57 + run_next_test(); 1.58 + }); 1.59 +}); 1.60 + 1.61 +add_test(function test_install_detection() { 1.62 + _("Ensure that add-on installation results in appropriate side-effects."); 1.63 + 1.64 + let reconciler = new AddonsReconciler(); 1.65 + reconciler.startListening(); 1.66 + 1.67 + let before = new Date(); 1.68 + let addon = installAddon("test_bootstrap1_1"); 1.69 + let after = new Date(); 1.70 + 1.71 + do_check_eq(1, Object.keys(reconciler.addons).length); 1.72 + do_check_true(addon.id in reconciler.addons); 1.73 + let record = reconciler.addons[addon.id]; 1.74 + 1.75 + const KEYS = ["id", "guid", "enabled", "installed", "modified", "type", 1.76 + "scope", "foreignInstall"]; 1.77 + for each (let key in KEYS) { 1.78 + do_check_true(key in record); 1.79 + do_check_neq(null, record[key]); 1.80 + } 1.81 + 1.82 + do_check_eq(addon.id, record.id); 1.83 + do_check_eq(addon.syncGUID, record.guid); 1.84 + do_check_true(record.enabled); 1.85 + do_check_true(record.installed); 1.86 + do_check_true(record.modified >= before && record.modified <= after); 1.87 + do_check_eq("extension", record.type); 1.88 + do_check_false(record.foreignInstall); 1.89 + 1.90 + do_check_eq(1, reconciler._changes.length); 1.91 + let change = reconciler._changes[0]; 1.92 + do_check_true(change[0] >= before && change[1] <= after); 1.93 + do_check_eq(CHANGE_INSTALLED, change[1]); 1.94 + do_check_eq(addon.id, change[2]); 1.95 + 1.96 + uninstallAddon(addon); 1.97 + 1.98 + run_next_test(); 1.99 +}); 1.100 + 1.101 +add_test(function test_uninstall_detection() { 1.102 + _("Ensure that add-on uninstallation results in appropriate side-effects."); 1.103 + 1.104 + let reconciler = new AddonsReconciler(); 1.105 + reconciler.startListening(); 1.106 + 1.107 + reconciler._addons = {}; 1.108 + reconciler._changes = []; 1.109 + 1.110 + let addon = installAddon("test_bootstrap1_1"); 1.111 + let id = addon.id; 1.112 + let guid = addon.syncGUID; 1.113 + 1.114 + reconciler._changes = []; 1.115 + uninstallAddon(addon); 1.116 + 1.117 + do_check_eq(1, Object.keys(reconciler.addons).length); 1.118 + do_check_true(id in reconciler.addons); 1.119 + 1.120 + let record = reconciler.addons[id]; 1.121 + do_check_false(record.installed); 1.122 + 1.123 + do_check_eq(1, reconciler._changes.length); 1.124 + let change = reconciler._changes[0]; 1.125 + do_check_eq(CHANGE_UNINSTALLED, change[1]); 1.126 + do_check_eq(id, change[2]); 1.127 + 1.128 + run_next_test(); 1.129 +}); 1.130 + 1.131 +add_test(function test_load_state_future_version() { 1.132 + _("Ensure loading a file from a future version results in no data loaded."); 1.133 + 1.134 + const FILENAME = "TEST_LOAD_STATE_FUTURE_VERSION"; 1.135 + 1.136 + let reconciler = new AddonsReconciler(); 1.137 + 1.138 + // First we populate our new file. 1.139 + let state = {version: 100, addons: {foo: {}}, changes: [[1, 1, "foo"]]}; 1.140 + let cb = Async.makeSyncCallback(); 1.141 + 1.142 + // jsonSave() expects an object with ._log, so we give it a reconciler 1.143 + // instance. 1.144 + Utils.jsonSave(FILENAME, reconciler, state, cb); 1.145 + Async.waitForSyncCallback(cb); 1.146 + 1.147 + reconciler.loadState(FILENAME, function(error, loaded) { 1.148 + do_check_eq(null, error); 1.149 + do_check_false(loaded); 1.150 + 1.151 + do_check_eq("object", typeof(reconciler.addons)); 1.152 + do_check_eq(1, Object.keys(reconciler.addons).length); 1.153 + do_check_eq(1, reconciler._changes.length); 1.154 + 1.155 + run_next_test(); 1.156 + }); 1.157 +}); 1.158 + 1.159 +add_test(function test_prune_changes_before_date() { 1.160 + _("Ensure that old changes are pruned properly."); 1.161 + 1.162 + let reconciler = new AddonsReconciler(); 1.163 + reconciler._ensureStateLoaded(); 1.164 + reconciler._changes = []; 1.165 + 1.166 + let now = new Date(); 1.167 + const HOUR_MS = 1000 * 60 * 60; 1.168 + 1.169 + _("Ensure pruning an empty changes array works."); 1.170 + reconciler.pruneChangesBeforeDate(now); 1.171 + do_check_eq(0, reconciler._changes.length); 1.172 + 1.173 + let old = new Date(now.getTime() - HOUR_MS); 1.174 + let young = new Date(now.getTime() - 1000); 1.175 + reconciler._changes.push([old, CHANGE_INSTALLED, "foo"]); 1.176 + reconciler._changes.push([young, CHANGE_INSTALLED, "bar"]); 1.177 + do_check_eq(2, reconciler._changes.length); 1.178 + 1.179 + _("Ensure pruning with an old time won't delete anything."); 1.180 + let threshold = new Date(old.getTime() - 1); 1.181 + reconciler.pruneChangesBeforeDate(threshold); 1.182 + do_check_eq(2, reconciler._changes.length); 1.183 + 1.184 + _("Ensure pruning a single item works."); 1.185 + let threshold = new Date(young.getTime() - 1000); 1.186 + reconciler.pruneChangesBeforeDate(threshold); 1.187 + do_check_eq(1, reconciler._changes.length); 1.188 + do_check_neq(undefined, reconciler._changes[0]); 1.189 + do_check_eq(young, reconciler._changes[0][0]); 1.190 + do_check_eq("bar", reconciler._changes[0][2]); 1.191 + 1.192 + _("Ensure pruning all changes works."); 1.193 + reconciler._changes.push([old, CHANGE_INSTALLED, "foo"]); 1.194 + reconciler.pruneChangesBeforeDate(now); 1.195 + do_check_eq(0, reconciler._changes.length); 1.196 + 1.197 + run_next_test(); 1.198 +});