toolkit/components/contentprefs/tests/unit/test_contentPrefs.js

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 function run_test() {
     6   //**************************************************************************//
     7   // Database Creation, Schema Migration, and Backup
     9   // Note: in these tests we use createInstance instead of getService
    10   // so we can instantiate the service multiple times and make it run
    11   // its database initialization code each time.
    13   // Create a new database.
    14   {
    15     ContentPrefTest.deleteDatabase();
    17     // Get the service and make sure it has a ready database connection.
    18     let cps = Cc["@mozilla.org/content-pref/service;1"].
    19               createInstance(Ci.nsIContentPrefService);
    20     do_check_true(cps.DBConnection.connectionReady);
    21     cps.DBConnection.close();
    22   }
    24   // Open an existing database.
    25   {
    26     let dbFile = ContentPrefTest.deleteDatabase();
    28     let cps = Cc["@mozilla.org/content-pref/service;1"].
    29                createInstance(Ci.nsIContentPrefService);
    30     cps.DBConnection.close();
    31     do_check_true(dbFile.exists());
    33     // Get the service and make sure it has a ready database connection.
    34     cps = Cc["@mozilla.org/content-pref/service;1"].
    35           createInstance(Ci.nsIContentPrefService);
    36     do_check_true(cps.DBConnection.connectionReady);
    37     cps.DBConnection.close();
    38   }
    40   // Open an empty database.
    41   {
    42     let dbFile = ContentPrefTest.deleteDatabase();
    44     // Create an empty database.
    45     let dbService = Cc["@mozilla.org/storage/service;1"].
    46                     getService(Ci.mozIStorageService);
    47     let dbConnection = dbService.openDatabase(dbFile);
    48     do_check_eq(dbConnection.schemaVersion, 0);
    49     dbConnection.close();
    50     do_check_true(dbFile.exists());
    52     // Get the service and make sure it has created the schema.
    53     let cps = Cc["@mozilla.org/content-pref/service;1"].
    54               createInstance(Ci.nsIContentPrefService);
    55     do_check_neq(cps.DBConnection.schemaVersion, 0);
    56     cps.DBConnection.close();
    57   }
    59   // Open a corrupted database.
    60   {
    61     let dbFile = ContentPrefTest.deleteDatabase();
    62     let backupDBFile = ContentPrefTest.deleteBackupDatabase();
    64     // Create a corrupted database.
    65     let foStream = Cc["@mozilla.org/network/file-output-stream;1"].
    66                    createInstance(Ci.nsIFileOutputStream);
    67     foStream.init(dbFile, 0x02 | 0x08 | 0x20, 0666, 0);
    68     let garbageData = "garbage that makes SQLite think the file is corrupted";
    69     foStream.write(garbageData, garbageData.length);
    70     foStream.close();
    72     // Get the service and make sure it backs up and recreates the database.
    73     let cps = Cc["@mozilla.org/content-pref/service;1"].
    74               createInstance(Ci.nsIContentPrefService);
    75     do_check_true(backupDBFile.exists());
    76     do_check_true(cps.DBConnection.connectionReady);
    78     cps.DBConnection.close();
    79   }
    81   // Open a database with a corrupted schema.
    82   {
    83     let dbFile = ContentPrefTest.deleteDatabase();
    84     let backupDBFile = ContentPrefTest.deleteBackupDatabase();
    86     // Create an empty database and set the schema version to a number
    87     // that will trigger a schema migration that will fail.
    88     let dbService = Cc["@mozilla.org/storage/service;1"].
    89                     getService(Ci.mozIStorageService);
    90     let dbConnection = dbService.openDatabase(dbFile);
    91     dbConnection.schemaVersion = -1;
    92     dbConnection.close();
    93     do_check_true(dbFile.exists());
    95     // Get the service and make sure it backs up and recreates the database.
    96     let cps = Cc["@mozilla.org/content-pref/service;1"].
    97               createInstance(Ci.nsIContentPrefService);
    98     do_check_true(backupDBFile.exists());
    99     do_check_true(cps.DBConnection.connectionReady);
   101     cps.DBConnection.close();
   102   }
   105   // Now get the content pref service for real for use by the rest of the tests.
   106   let cps = new ContentPrefInstance(null);
   108   var uri = ContentPrefTest.getURI("http://www.example.com/");
   110   // Make sure disk synchronization checking is turned off by default.
   111   var statement = cps.DBConnection.createStatement("PRAGMA synchronous");
   112   statement.executeStep();
   113   do_check_eq(0, statement.getInt32(0));
   115   //**************************************************************************//
   116   // Nonexistent Pref
   118   do_check_eq(cps.getPref(uri, "test.nonexistent.getPref"), undefined);
   119   do_check_eq(cps.setPref(uri, "test.nonexistent.setPref", 5), undefined);
   120   do_check_false(cps.hasPref(uri, "test.nonexistent.hasPref"));
   121   do_check_eq(cps.removePref(uri, "test.nonexistent.removePref"), undefined);
   124   //**************************************************************************//
   125   // Existing Pref
   127   cps.setPref(uri, "test.existing", 5);
   129   // getPref should return the pref value
   130   do_check_eq(cps.getPref(uri, "test.existing"), 5);
   132   // setPref should return undefined and change the value of the pref
   133   do_check_eq(cps.setPref(uri, "test.existing", 6), undefined);
   134   do_check_eq(cps.getPref(uri, "test.existing"), 6);
   136   // hasPref should return true
   137   do_check_true(cps.hasPref(uri, "test.existing"));
   139   // removePref should return undefined and remove the pref
   140   do_check_eq(cps.removePref(uri, "test.existing"), undefined);
   141   do_check_false(cps.hasPref(uri, "test.existing"));
   144   //**************************************************************************//
   145   // Round-Trip Data Integrity
   147   // Make sure pref values remain the same from setPref to getPref.
   149   cps.setPref(uri, "test.data-integrity.integer", 5);
   150   do_check_eq(cps.getPref(uri, "test.data-integrity.integer"), 5);
   152   cps.setPref(uri, "test.data-integrity.float", 5.5);
   153   do_check_eq(cps.getPref(uri, "test.data-integrity.float"), 5.5);
   155   cps.setPref(uri, "test.data-integrity.boolean", true);
   156   do_check_eq(cps.getPref(uri, "test.data-integrity.boolean"), true);
   158   cps.setPref(uri, "test.data-integrity.string", "test");
   159   do_check_eq(cps.getPref(uri, "test.data-integrity.string"), "test");
   161   cps.setPref(uri, "test.data-integrity.null", null);
   162   do_check_eq(cps.getPref(uri, "test.data-integrity.null"), null);
   164   // XXX Test arbitrary binary data.
   166   // Make sure hasPref and removePref work on all data types.
   168   do_check_true(cps.hasPref(uri, "test.data-integrity.integer"));
   169   do_check_true(cps.hasPref(uri, "test.data-integrity.float"));
   170   do_check_true(cps.hasPref(uri, "test.data-integrity.boolean"));
   171   do_check_true(cps.hasPref(uri, "test.data-integrity.string"));
   172   do_check_true(cps.hasPref(uri, "test.data-integrity.null"));
   174   do_check_eq(cps.removePref(uri, "test.data-integrity.integer"), undefined);
   175   do_check_eq(cps.removePref(uri, "test.data-integrity.float"), undefined);
   176   do_check_eq(cps.removePref(uri, "test.data-integrity.boolean"), undefined);
   177   do_check_eq(cps.removePref(uri, "test.data-integrity.string"), undefined);
   178   do_check_eq(cps.removePref(uri, "test.data-integrity.null"), undefined);
   180   do_check_false(cps.hasPref(uri, "test.data-integrity.integer"));
   181   do_check_false(cps.hasPref(uri, "test.data-integrity.float"));
   182   do_check_false(cps.hasPref(uri, "test.data-integrity.boolean"));
   183   do_check_false(cps.hasPref(uri, "test.data-integrity.string"));
   184   do_check_false(cps.hasPref(uri, "test.data-integrity.null"));
   187   //**************************************************************************//
   188   // getPrefs
   190   cps.setPref(uri, "test.getPrefs.a", 1);
   191   cps.setPref(uri, "test.getPrefs.b", 2);
   192   cps.setPref(uri, "test.getPrefs.c", 3);
   194   var prefs = cps.getPrefs(uri);
   195   do_check_true(prefs.hasKey("test.getPrefs.a"));
   196   do_check_eq(prefs.get("test.getPrefs.a"), 1);
   197   do_check_true(prefs.hasKey("test.getPrefs.b"));
   198   do_check_eq(prefs.get("test.getPrefs.b"), 2);
   199   do_check_true(prefs.hasKey("test.getPrefs.c"));
   200   do_check_eq(prefs.get("test.getPrefs.c"), 3);
   203   //**************************************************************************//
   204   // Site-Specificity
   206   // These are all different sites, and setting a pref for one of them
   207   // shouldn't set it for the others.
   208   var uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
   209   var uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
   210   var uri3 = ContentPrefTest.getURI("http://domain1.com/");
   211   var uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
   213   cps.setPref(uri1, "test.site-specificity.uri1", 5);
   214   do_check_false(cps.hasPref(uri2, "test.site-specificity.uri1"));
   215   do_check_false(cps.hasPref(uri3, "test.site-specificity.uri1"));
   216   do_check_false(cps.hasPref(uri4, "test.site-specificity.uri1"));
   218   cps.setPref(uri2, "test.site-specificity.uri2", 5);
   219   do_check_false(cps.hasPref(uri1, "test.site-specificity.uri2"));
   220   do_check_false(cps.hasPref(uri3, "test.site-specificity.uri2"));
   221   do_check_false(cps.hasPref(uri4, "test.site-specificity.uri2"));
   223   cps.setPref(uri3, "test.site-specificity.uri3", 5);
   224   do_check_false(cps.hasPref(uri1, "test.site-specificity.uri3"));
   225   do_check_false(cps.hasPref(uri2, "test.site-specificity.uri3"));
   226   do_check_false(cps.hasPref(uri4, "test.site-specificity.uri3"));
   228   cps.setPref(uri4, "test.site-specificity.uri4", 5);
   229   do_check_false(cps.hasPref(uri1, "test.site-specificity.uri4"));
   230   do_check_false(cps.hasPref(uri2, "test.site-specificity.uri4"));
   231   do_check_false(cps.hasPref(uri3, "test.site-specificity.uri4"));
   234   //**************************************************************************//
   235   // Observers
   237   var specificObserver = {
   238     interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
   240     QueryInterface: function ContentPrefTest_QueryInterface(iid) {
   241       if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
   242         throw Cr.NS_ERROR_NO_INTERFACE;
   243       return this;
   244     },
   246     numTimesSetCalled: 0,
   247     onContentPrefSet: function specificObserver_onContentPrefSet(group, name, value) {
   248       ++this.numTimesSetCalled;
   249       do_check_eq(group, "www.example.com");
   250       do_check_eq(name, "test.observer.1");
   251       do_check_eq(value, "test value");
   252     },
   254     numTimesRemovedCalled: 0,
   255     onContentPrefRemoved: function specificObserver_onContentPrefRemoved(group, name) {
   256       ++this.numTimesRemovedCalled;
   257       do_check_eq(group, "www.example.com");
   258       do_check_eq(name, "test.observer.1");
   259     }
   261   };
   263   var genericObserver = {
   264     interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
   266     QueryInterface: function ContentPrefTest_QueryInterface(iid) {
   267       if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
   268         throw Cr.NS_ERROR_NO_INTERFACE;
   269       return this;
   270     },
   272     numTimesSetCalled: 0,
   273     onContentPrefSet: function genericObserver_onContentPrefSet(group, name, value) {
   274       ++this.numTimesSetCalled;
   275       do_check_eq(group, "www.example.com");
   276       if (name != "test.observer.1" && name != "test.observer.2")
   277         do_throw("genericObserver.onContentPrefSet: " +
   278                  "name not in (test.observer.1, test.observer.2)");
   279       do_check_eq(value, "test value");
   280     },
   282     numTimesRemovedCalled: 0,
   283     onContentPrefRemoved: function genericObserver_onContentPrefRemoved(group, name) {
   284       ++this.numTimesRemovedCalled;
   285       do_check_eq(group, "www.example.com");
   286       if (name != "test.observer.1" && name != "test.observer.2")
   287         do_throw("genericObserver.onContentPrefSet: " +
   288                  "name not in (test.observer.1, test.observer.2)");
   289     }
   291   };
   293   // Make sure we can add observers, observers get notified about changes,
   294   // specific observers only get notified about changes to the specific setting,
   295   // and generic observers get notified about changes to all settings.
   296   cps.addObserver("test.observer.1", specificObserver);
   297   cps.addObserver(null, genericObserver);
   298   cps.setPref(uri, "test.observer.1", "test value");
   299   cps.setPref(uri, "test.observer.2", "test value");
   300   cps.removePref(uri, "test.observer.1");
   301   cps.removePref(uri, "test.observer.2");
   302   do_check_eq(specificObserver.numTimesSetCalled, 1);
   303   do_check_eq(genericObserver.numTimesSetCalled, 2);
   304   do_check_eq(specificObserver.numTimesRemovedCalled, 1);
   305   do_check_eq(genericObserver.numTimesRemovedCalled, 2);
   307   // Make sure we can remove observers and they don't get notified
   308   // about changes anymore.
   309   cps.removeObserver("test.observer.1", specificObserver);
   310   cps.removeObserver(null, genericObserver);
   311   cps.setPref(uri, "test.observer.1", "test value");
   312   cps.removePref(uri, "test.observer.1", "test value");
   313   do_check_eq(specificObserver.numTimesSetCalled, 1);
   314   do_check_eq(genericObserver.numTimesSetCalled, 2);
   315   do_check_eq(specificObserver.numTimesRemovedCalled, 1);
   316   do_check_eq(genericObserver.numTimesRemovedCalled, 2);
   319   //**************************************************************************//
   320   // Get/Remove Prefs By Name
   322   {
   323     var anObserver = {
   324       interfaces: [Ci.nsIContentPrefObserver, Ci.nsISupports],
   326       QueryInterface: function ContentPrefTest_QueryInterface(iid) {
   327         if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
   328           throw Cr.NS_ERROR_NO_INTERFACE;
   329         return this;
   330       },
   332       onContentPrefSet: function anObserver_onContentPrefSet(group, name, value) {
   333       },
   335       expectedDomains: [],
   336       numTimesRemovedCalled: 0,
   337       onContentPrefRemoved: function anObserver_onContentPrefRemoved(group, name) {
   338         ++this.numTimesRemovedCalled;
   340         // remove the domain from the list of expected domains
   341         var index = this.expectedDomains.indexOf(group);
   342         do_check_true(index >= 0);
   343         this.expectedDomains.splice(index, 1);
   344       }
   345     };
   347     var uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
   348     var uri2 = ContentPrefTest.getURI("http://foo.domain1.com/");
   349     var uri3 = ContentPrefTest.getURI("http://domain1.com/");
   350     var uri4 = ContentPrefTest.getURI("http://www.domain2.com/");
   352     cps.setPref(uri1, "test.byname.1", 1);
   353     cps.setPref(uri1, "test.byname.2", 2);
   354     cps.setPref(uri2, "test.byname.1", 4);
   355     cps.setPref(uri3, "test.byname.3", 8);
   356     cps.setPref(uri4, "test.byname.1", 16);
   357     cps.setPref(null, "test.byname.1", 32);
   358     cps.setPref(null, "test.byname.2", false);
   360     function enumerateAndCheck(testName, expectedSum, expectedDomains) {
   361       var prefsByName = cps.getPrefsByName(testName);
   362       var enumerator = prefsByName.enumerator;
   363       var sum = 0;
   364       while (enumerator.hasMoreElements()) {
   365         var property = enumerator.getNext().QueryInterface(Components.interfaces.nsIProperty);
   366         sum += parseInt(property.value);
   368         // remove the domain from the list of expected domains
   369         var index = expectedDomains.indexOf(property.name);
   370         do_check_true(index >= 0);
   371         expectedDomains.splice(index, 1);
   372       }
   373       do_check_eq(sum, expectedSum);
   374       // check all domains have been removed from the array
   375       do_check_eq(expectedDomains.length, 0);
   376     }
   378     enumerateAndCheck("test.byname.1", 53,
   379       ["foo.domain1.com", null, "www.domain1.com", "www.domain2.com"]);
   380     enumerateAndCheck("test.byname.2", 2, ["www.domain1.com", null]);
   381     enumerateAndCheck("test.byname.3", 8, ["domain1.com"]);
   383     cps.addObserver("test.byname.1", anObserver);
   384     anObserver.expectedDomains = ["foo.domain1.com", null, "www.domain1.com", "www.domain2.com"];
   386     cps.removePrefsByName("test.byname.1");
   387     do_check_false(cps.hasPref(uri1, "test.byname.1"));
   388     do_check_false(cps.hasPref(uri2, "test.byname.1"));
   389     do_check_false(cps.hasPref(uri3, "test.byname.1"));
   390     do_check_false(cps.hasPref(uri4, "test.byname.1"));
   391     do_check_false(cps.hasPref(null, "test.byname.1"));
   392     do_check_true(cps.hasPref(uri1, "test.byname.2"));
   393     do_check_true(cps.hasPref(uri3, "test.byname.3"));
   395     do_check_eq(anObserver.numTimesRemovedCalled, 4);
   396     do_check_eq(anObserver.expectedDomains.length, 0);
   398     cps.removeObserver("test.byname.1", anObserver);
   400     // Clean up after ourselves
   401     cps.removePref(uri1, "test.byname.2");
   402     cps.removePref(uri3, "test.byname.3");
   403     cps.removePref(null, "test.byname.2");
   404   }
   407   //**************************************************************************//
   408   // Clear Private Data Pref Removal
   410   {
   411     let uri1 = ContentPrefTest.getURI("http://www.domain1.com/");
   412     let uri2 = ContentPrefTest.getURI("http://www.domain2.com/");
   413     let uri3 = ContentPrefTest.getURI("http://www.domain3.com/");
   415     let dbConnection = cps.DBConnection;
   417     let prefCount = dbConnection.createStatement("SELECT COUNT(*) AS count FROM prefs");
   419     let groupCount = dbConnection.createStatement("SELECT COUNT(*) AS count FROM groups");
   421     // Add some prefs for multiple domains.
   422     cps.setPref(uri1, "test.removeAllGroups", 1);
   423     cps.setPref(uri2, "test.removeAllGroups", 2);
   424     cps.setPref(uri3, "test.removeAllGroups", 3);
   426     // Add a global pref.
   427     cps.setPref(null, "test.removeAllGroups", 1);
   429     // Make sure there are some prefs and groups in the database.
   430     prefCount.executeStep();
   431     do_check_true(prefCount.row.count > 0);
   432     prefCount.reset();
   433     groupCount.executeStep();
   434     do_check_true(groupCount.row.count > 0);
   435     groupCount.reset();
   437     // Remove all prefs and groups from the database using the same routine
   438     // the Clear Private Data dialog uses.
   439     cps.removeGroupedPrefs();
   441     // Make sure there are no longer any groups in the database and the only pref
   442     // is the global one.
   443     prefCount.executeStep();
   444     do_check_true(prefCount.row.count == 1);
   445     prefCount.reset();
   446     groupCount.executeStep();
   447     do_check_true(groupCount.row.count == 0);
   448     groupCount.reset();
   449     let globalPref = dbConnection.createStatement("SELECT groupID FROM prefs");
   450     globalPref.executeStep();
   451     do_check_true(globalPref.row.groupID == null);
   452     globalPref.reset();
   453   }
   454 }

mercurial