summaryrefslogtreecommitdiff
path: root/testing/mozbase/mozprofile/tests
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commitad18d877ddd2a44d98fa12ccd3dbbcf4d0ac4299 (patch)
tree10027f336435511475e392454359edea8e25895d /testing/mozbase/mozprofile/tests
parent15477ed9af4859dacb069040b5d4de600803d3bc (diff)
downloaduxp-ad18d877ddd2a44d98fa12ccd3dbbcf4d0ac4299.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'testing/mozbase/mozprofile/tests')
-rw-r--r--testing/mozbase/mozprofile/tests/addon_stubs.py78
-rwxr-xr-xtesting/mozbase/mozprofile/tests/addonid.py184
-rw-r--r--testing/mozbase/mozprofile/tests/addons/empty.xpibin0 -> 530 bytes
-rw-r--r--testing/mozbase/mozprofile/tests/addons/empty/install.rdf20
-rw-r--r--testing/mozbase/mozprofile/tests/addons/invalid.xpibin0 -> 564 bytes
-rwxr-xr-xtesting/mozbase/mozprofile/tests/bug758250.py53
-rwxr-xr-xtesting/mozbase/mozprofile/tests/bug785146.py51
-rw-r--r--testing/mozbase/mozprofile/tests/files/not_an_addon.txt0
-rw-r--r--testing/mozbase/mozprofile/tests/files/prefs_with_comments.js6
-rw-r--r--testing/mozbase/mozprofile/tests/files/prefs_with_interpolation.js4
-rw-r--r--testing/mozbase/mozprofile/tests/files/webapps1.json50
-rw-r--r--testing/mozbase/mozprofile/tests/files/webapps2.json37
-rw-r--r--testing/mozbase/mozprofile/tests/install_manifests/test_addon_1.rdf21
-rw-r--r--testing/mozbase/mozprofile/tests/install_manifests/test_addon_2.rdf21
-rw-r--r--testing/mozbase/mozprofile/tests/install_manifests/test_addon_3.rdf22
-rw-r--r--testing/mozbase/mozprofile/tests/install_manifests/test_addon_4.rdf22
-rw-r--r--testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_no_id.rdf22
-rw-r--r--testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_not_wellformed.rdf23
-rw-r--r--testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_version.rdf23
-rw-r--r--testing/mozbase/mozprofile/tests/install_manifests/test_addon_unpack.rdf22
-rw-r--r--testing/mozbase/mozprofile/tests/manifest.ini12
-rwxr-xr-xtesting/mozbase/mozprofile/tests/permissions.py199
-rw-r--r--testing/mozbase/mozprofile/tests/server_locations.py151
-rw-r--r--testing/mozbase/mozprofile/tests/test_addons.py415
-rw-r--r--testing/mozbase/mozprofile/tests/test_clone_cleanup.py63
-rwxr-xr-xtesting/mozbase/mozprofile/tests/test_nonce.py49
-rwxr-xr-xtesting/mozbase/mozprofile/tests/test_preferences.py378
-rw-r--r--testing/mozbase/mozprofile/tests/test_profile.py30
-rw-r--r--testing/mozbase/mozprofile/tests/test_profile_view.py75
-rwxr-xr-xtesting/mozbase/mozprofile/tests/test_webapps.py202
30 files changed, 2233 insertions, 0 deletions
diff --git a/testing/mozbase/mozprofile/tests/addon_stubs.py b/testing/mozbase/mozprofile/tests/addon_stubs.py
new file mode 100644
index 0000000000..f9602de462
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/addon_stubs.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+
+import os
+import tempfile
+import zipfile
+
+import mozfile
+
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+# stubs is a dict of the form {'addon id': 'install manifest content'}
+stubs = {
+ 'test-addon-1@mozilla.org': 'test_addon_1.rdf',
+ 'test-addon-2@mozilla.org': 'test_addon_2.rdf',
+ 'test-addon-3@mozilla.org': 'test_addon_3.rdf',
+ 'test-addon-4@mozilla.org': 'test_addon_4.rdf',
+ 'test-addon-invalid-no-id@mozilla.org': 'test_addon_invalid_no_id.rdf',
+ 'test-addon-invalid-version@mozilla.org': 'test_addon_invalid_version.rdf',
+ 'test-addon-invalid-no-manifest@mozilla.org': None,
+ 'test-addon-invalid-not-wellformed@mozilla.org': 'test_addon_invalid_not_wellformed.rdf',
+ 'test-addon-unpack@mozilla.org': 'test_addon_unpack.rdf'}
+
+
+def generate_addon(addon_id, path=None, name=None, xpi=True):
+ """
+ Method to generate a single addon.
+
+ :param addon_id: id of an addon to generate from the stubs dictionary
+ :param path: path where addon and .xpi should be generated
+ :param name: name for the addon folder or .xpi file
+ :param xpi: Flag if an XPI or folder should be generated
+
+ Returns the file-path of the addon's .xpi file
+ """
+
+ if addon_id not in stubs.keys():
+ raise IOError('Requested addon stub "%s" does not exist' % addon_id)
+
+ # Generate directory structure for addon
+ try:
+ tmpdir = path or tempfile.mkdtemp()
+ addon_dir = os.path.join(tmpdir, name or addon_id)
+ os.mkdir(addon_dir)
+ except IOError:
+ raise IOError('Could not generate directory structure for addon stub.')
+
+ # Write install.rdf for addon
+ if stubs[addon_id]:
+ install_rdf = os.path.join(addon_dir, 'install.rdf')
+ with open(install_rdf, 'w') as f:
+ manifest = os.path.join(here, 'install_manifests', stubs[addon_id])
+ f.write(open(manifest, 'r').read())
+
+ if not xpi:
+ return addon_dir
+
+ # Generate the .xpi for the addon
+ xpi_file = os.path.join(tmpdir, (name or addon_id) + '.xpi')
+ with zipfile.ZipFile(xpi_file, 'w') as x:
+ x.write(install_rdf, install_rdf[len(addon_dir):])
+
+ # Ensure we remove the temporary folder to not install the addon twice
+ mozfile.rmtree(addon_dir)
+
+ return xpi_file
+
+
+def generate_manifest(addon_list, path=None):
+ tmpdir = path or tempfile.mkdtemp()
+ addons = [generate_addon(addon, path=tmpdir) for addon in addon_list]
+
+ manifest = os.path.join(tmpdir, 'manifest.ini')
+ with open(manifest, 'w') as f:
+ for addon in addons:
+ f.write('[' + addon + ']\n')
+
+ return manifest
diff --git a/testing/mozbase/mozprofile/tests/addonid.py b/testing/mozbase/mozprofile/tests/addonid.py
new file mode 100755
index 0000000000..f76c5a913c
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/addonid.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+
+import os
+import tempfile
+import unittest
+import shutil
+from mozprofile import addons
+
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+class AddonIDTest(unittest.TestCase):
+ """ Test finding the addon id in a variety of install.rdf styles """
+
+ def make_install_rdf(self, filecontents):
+ path = tempfile.mkdtemp()
+ f = open(os.path.join(path, "install.rdf"), "w")
+ f.write(filecontents)
+ f.close()
+ return path
+
+ def test_addonID(self):
+ testlist = self.get_test_list()
+ for t in testlist:
+ try:
+ p = self.make_install_rdf(t)
+ a = addons.AddonManager(os.path.join(p, "profile"))
+ addon_id = a.addon_details(p)['id']
+ self.assertEqual(addon_id, "winning", "We got the addon id")
+ finally:
+ shutil.rmtree(p)
+
+ def test_addonID_xpi(self):
+ a = addons.AddonManager("profile")
+ addon = a.addon_details(os.path.join(here, "addons", "empty.xpi"))
+ self.assertEqual(addon['id'], "test-empty@quality.mozilla.org", "We got the addon id")
+
+ def get_test_list(self):
+ """ This just returns a hardcoded list of install.rdf snippets for testing.
+ When adding snippets for testing, remember that the id we're looking for
+ is "winning" (no quotes). So, make sure you have that id in your snippet
+ if you want it to pass.
+ """
+ tests = [
+ """<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>winning</em:id>
+ <em:name>MozMill</em:name>
+ <em:version>2.0a</em:version>
+ <em:creator>Adam Christian</em:creator>
+ <em:description>A testing extension based on the
+ Windmill Testing Framework client source</em:description>
+ <em:unpack>true</em:unpack>
+ <em:targetApplication>
+ <!-- Firefox -->
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5</em:minVersion>
+ <em:maxVersion>8.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <!-- Thunderbird -->
+ <Description>
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
+ <em:minVersion>3.0a1pre</em:minVersion>
+ <em:maxVersion>3.2*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <!-- Sunbird -->
+ <Description>
+ <em:id>{718e30fb-e89b-41dd-9da7-e25a45638b28}</em:id>
+ <em:minVersion>0.6a1</em:minVersion>
+ <em:maxVersion>1.0pre</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <!-- SeaMonkey -->
+ <Description>
+ <em:id>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</em:id>
+ <em:minVersion>2.0a1</em:minVersion>
+ <em:maxVersion>2.1*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <!-- Songbird -->
+ <Description>
+ <em:id>songbird@songbirdnest.com</em:id>
+ <em:minVersion>0.3pre</em:minVersion>
+ <em:maxVersion>1.3.0a</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <em:id>toolkit@mozilla.org</em:id>
+ <em:minVersion>1.9.1</em:minVersion>
+ <em:maxVersion>2.0*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>""",
+ """<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:targetApplication>
+ <!-- Firefox -->
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5</em:minVersion>
+ <em:maxVersion>8.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:id>winning</em:id>
+ <em:name>MozMill</em:name>
+ <em:version>2.0a</em:version>
+ <em:creator>Adam Christian</em:creator>
+ <em:description>A testing extension based on the
+ Windmill Testing Framework client source</em:description>
+ <em:unpack>true</em:unpack>
+ </Description>
+ </RDF>""",
+ """<RDF xmlns="http://www.mozilla.org/2004/em-rdf#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description about="urn:mozilla:install-manifest">
+ <id>winning</id>
+ <name>foo</name>
+ <version>42</version>
+ <description>A testing extension based on the
+ Windmill Testing Framework client source</description>
+ </rdf:Description>
+</RDF>""",
+ """<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:foobar="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <foobar:targetApplication>
+ <!-- Firefox -->
+ <Description>
+ <foobar:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</foobar:id>
+ <foobar:minVersion>3.5</foobar:minVersion>
+ <foobar:maxVersion>8.*</foobar:maxVersion>
+ </Description>
+ </foobar:targetApplication>
+ <foobar:id>winning</foobar:id>
+ <foobar:name>MozMill</foobar:name>
+ <foobar:version>2.0a</foobar:version>
+ <foobar:creator>Adam Christian</foobar:creator>
+ <foobar:description>A testing extension based on the
+ Windmill Testing Framework client source</foobar:description>
+ <foobar:unpack>true</foobar:unpack>
+ </Description>
+ </RDF>""",
+ """<?xml version="1.0"?>
+<!--
+
+-->
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest"
+ em:id="winning"
+ em:name="Language Pack"
+ em:version="42.0a2"
+ em:type="8"
+ em:creator="Some Contributor">
+ <em:contributor></em:contributor>
+
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>42.0a2</em:minVersion>
+ <em:maxVersion>42.0a2</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
+"""]
+ return tests
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/addons/empty.xpi b/testing/mozbase/mozprofile/tests/addons/empty.xpi
new file mode 100644
index 0000000000..26f28f099d
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/addons/empty.xpi
Binary files differ
diff --git a/testing/mozbase/mozprofile/tests/addons/empty/install.rdf b/testing/mozbase/mozprofile/tests/addons/empty/install.rdf
new file mode 100644
index 0000000000..70b9e13e44
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/addons/empty/install.rdf
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>test-empty@quality.mozilla.org</em:id>
+ <em:version>0.1</em:version>
+ <em:name>Test Extension (empty)</em:name>
+ <em:creator>Mozilla QA</em:creator>
+ <em:homepageURL>http://quality.mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
diff --git a/testing/mozbase/mozprofile/tests/addons/invalid.xpi b/testing/mozbase/mozprofile/tests/addons/invalid.xpi
new file mode 100644
index 0000000000..2f222c7637
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/addons/invalid.xpi
Binary files differ
diff --git a/testing/mozbase/mozprofile/tests/bug758250.py b/testing/mozbase/mozprofile/tests/bug758250.py
new file mode 100755
index 0000000000..f25901a199
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/bug758250.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+import mozprofile
+import os
+import shutil
+import tempfile
+import unittest
+
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+class Bug758250(unittest.TestCase):
+ """
+ use of --profile in mozrunner just blows away addon sources:
+ https://bugzilla.mozilla.org/show_bug.cgi?id=758250
+ """
+
+ def setUp(self):
+ self.tmpdir = tempfile.mkdtemp()
+ self.addon = os.path.join(here, 'addons', 'empty')
+
+ def tearDown(self):
+ # remove vestiges
+ shutil.rmtree(self.tmpdir)
+
+ def test_profile_addon_cleanup(self):
+
+ # sanity check: the empty addon should be here
+ self.assertTrue(os.path.exists(self.addon))
+ self.assertTrue(os.path.isdir(self.addon))
+ self.assertTrue(os.path.exists(os.path.join(self.addon, 'install.rdf')))
+
+ # because we are testing data loss, let's make sure we make a copy
+ shutil.rmtree(self.tmpdir)
+ shutil.copytree(self.addon, self.tmpdir)
+ self.assertTrue(os.path.exists(os.path.join(self.tmpdir, 'install.rdf')))
+
+ # make a starter profile
+ profile = mozprofile.FirefoxProfile()
+ path = profile.profile
+
+ # make a new profile based on the old
+ newprofile = mozprofile.FirefoxProfile(profile=path, addons=[self.tmpdir])
+ newprofile.cleanup()
+
+ # the source addon *should* still exist
+ self.assertTrue(os.path.exists(self.tmpdir))
+ self.assertTrue(os.path.exists(os.path.join(self.tmpdir, 'install.rdf')))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/bug785146.py b/testing/mozbase/mozprofile/tests/bug785146.py
new file mode 100755
index 0000000000..2bbf4fb050
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/bug785146.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import mozfile
+import os
+import shutil
+import sqlite3
+import tempfile
+import unittest
+from mozprofile.permissions import Permissions
+
+
+class PermissionsTest(unittest.TestCase):
+
+ locations = """http://mochi.test:8888 primary,privileged
+http://127.0.0.1:80 noxul
+http://127.0.0.1:8888 privileged
+"""
+
+ def setUp(self):
+ self.profile_dir = tempfile.mkdtemp()
+ self.locations_file = mozfile.NamedTemporaryFile()
+ self.locations_file.write(self.locations)
+ self.locations_file.flush()
+
+ def tearDown(self):
+ if self.profile_dir:
+ shutil.rmtree(self.profile_dir)
+ if self.locations_file:
+ self.locations_file.close()
+
+ def test_schema_version(self):
+ perms = Permissions(self.profile_dir, self.locations_file.name)
+ perms_db_filename = os.path.join(self.profile_dir, 'permissions.sqlite')
+ perms.write_db(self.locations_file)
+
+ stmt = 'PRAGMA user_version;'
+
+ con = sqlite3.connect(perms_db_filename)
+ cur = con.cursor()
+ cur.execute(stmt)
+ entries = cur.fetchall()
+
+ schema_version = entries[0][0]
+ self.assertEqual(schema_version, 5)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/files/not_an_addon.txt b/testing/mozbase/mozprofile/tests/files/not_an_addon.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/files/not_an_addon.txt
diff --git a/testing/mozbase/mozprofile/tests/files/prefs_with_comments.js b/testing/mozbase/mozprofile/tests/files/prefs_with_comments.js
new file mode 100644
index 0000000000..06a56f2138
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/files/prefs_with_comments.js
@@ -0,0 +1,6 @@
+# A leading comment
+user_pref("browser.startup.homepage", "http://planet.mozilla.org"); # A trailing comment
+user_pref("zoom.minPercent", 30);
+// Another leading comment
+user_pref("zoom.maxPercent", 300); // Another trailing comment
+user_pref("webgl.verbose", "false");
diff --git a/testing/mozbase/mozprofile/tests/files/prefs_with_interpolation.js b/testing/mozbase/mozprofile/tests/files/prefs_with_interpolation.js
new file mode 100644
index 0000000000..d0b30bf7bb
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/files/prefs_with_interpolation.js
@@ -0,0 +1,4 @@
+user_pref("browser.foo", "http://{server}");
+user_pref("zoom.minPercent", 30);
+user_pref("webgl.verbose", "false");
+user_pref("browser.bar", "{abc}xyz");
diff --git a/testing/mozbase/mozprofile/tests/files/webapps1.json b/testing/mozbase/mozprofile/tests/files/webapps1.json
new file mode 100644
index 0000000000..00220a3d13
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/files/webapps1.json
@@ -0,0 +1,50 @@
+[{ "name": "http_example_org",
+ "csp": "",
+ "origin": "http://example.org",
+ "manifestURL": "http://example.org/manifest.webapp",
+ "description": "http://example.org App",
+ "appStatus": 1
+ },
+ { "name": "https_example_com",
+ "csp": "",
+ "origin": "https://example.com",
+ "manifestURL": "https://example.com/manifest.webapp",
+ "description": "https://example.com App",
+ "appStatus": 1
+ },
+ { "name": "http_test1_example_org",
+ "csp": "",
+ "origin": "http://test1.example.org",
+ "manifestURL": "http://test1.example.org/manifest.webapp",
+ "description": "http://test1.example.org App",
+ "appStatus": 1
+ },
+ { "name": "http_test1_example_org_8000",
+ "csp": "",
+ "origin": "http://test1.example.org:8000",
+ "manifestURL": "http://test1.example.org:8000/manifest.webapp",
+ "description": "http://test1.example.org:8000 App",
+ "appStatus": 1
+ },
+ { "name": "http_sub1_test1_example_org",
+ "csp": "",
+ "origin": "http://sub1.test1.example.org",
+ "manifestURL": "http://sub1.test1.example.org/manifest.webapp",
+ "description": "http://sub1.test1.example.org App",
+ "appStatus": 1
+ },
+ { "name": "https_example_com_privileged",
+ "csp": "",
+ "origin": "https://example.com",
+ "manifestURL": "https://example.com/manifest_priv.webapp",
+ "description": "https://example.com Privileged App",
+ "appStatus": 2
+ },
+ { "name": "https_example_com_certified",
+ "csp": "",
+ "origin": "https://example.com",
+ "manifestURL": "https://example.com/manifest_cert.webapp",
+ "description": "https://example.com Certified App",
+ "appStatus": 3
+ }
+]
diff --git a/testing/mozbase/mozprofile/tests/files/webapps2.json b/testing/mozbase/mozprofile/tests/files/webapps2.json
new file mode 100644
index 0000000000..03e84a0419
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/files/webapps2.json
@@ -0,0 +1,37 @@
+{
+ "https_example_csp_certified": {
+ "csp": "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'",
+ "origin": "https://example.com",
+ "manifestURL": "https://example.com/manifest_csp_cert.webapp",
+ "description": "https://example.com certified app with manifest policy",
+ "appStatus": 3
+ },
+ "https_example_csp_installed": {
+ "csp": "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'",
+ "origin": "https://example.com",
+ "manifestURL": "https://example.com/manifest_csp_inst.webapp",
+ "description": "https://example.com installed app with manifest policy",
+ "appStatus": 1
+ },
+ "https_example_csp_privileged": {
+ "csp": "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'",
+ "origin": "https://example.com",
+ "manifestURL": "https://example.com/manifest_csp_priv.webapp",
+ "description": "https://example.com privileged app with manifest policy",
+ "appStatus": 2
+ },
+ "https_a_domain_certified": {
+ "csp": "",
+ "origin": "https://acertified.com",
+ "manifestURL": "https://acertified.com/manifest.webapp",
+ "description": "https://acertified.com certified app",
+ "appStatus": 3
+ },
+ "https_a_domain_privileged": {
+ "csp": "",
+ "origin": "https://aprivileged.com",
+ "manifestURL": "https://aprivileged.com/manifest.webapp",
+ "description": "https://aprivileged.com privileged app ",
+ "appStatus": 2
+ }
+}
diff --git a/testing/mozbase/mozprofile/tests/install_manifests/test_addon_1.rdf b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_1.rdf
new file mode 100644
index 0000000000..839ea9fbd5
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_1.rdf
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>test-addon-1@mozilla.org</em:id>
+ <em:version>0.1</em:version>
+ <em:name>Test Add-on 1</em:name>
+ <em:creator>Mozilla</em:creator>
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
diff --git a/testing/mozbase/mozprofile/tests/install_manifests/test_addon_2.rdf b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_2.rdf
new file mode 100644
index 0000000000..8303e862fc
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_2.rdf
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>test-addon-2@mozilla.org</em:id>
+ <em:version>0.2</em:version>
+ <em:name>Test Add-on 2</em:name>
+ <em:creator>Mozilla</em:creator>
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
diff --git a/testing/mozbase/mozprofile/tests/install_manifests/test_addon_3.rdf b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_3.rdf
new file mode 100644
index 0000000000..5bd6d38043
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_3.rdf
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>test-addon-3@mozilla.org</em:id>
+ <em:version>0.1</em:version>
+ <em:name>Test Add-on 3</em:name>
+ <em:creator>Mozilla</em:creator>
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
+
diff --git a/testing/mozbase/mozprofile/tests/install_manifests/test_addon_4.rdf b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_4.rdf
new file mode 100644
index 0000000000..e0f99d3133
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_4.rdf
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>test-addon-4@mozilla.org</em:id>
+ <em:version>0.1</em:version>
+ <em:name>Test Add-on 4</em:name>
+ <em:creator>Mozilla</em:creator>
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
+
diff --git a/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_no_id.rdf b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_no_id.rdf
new file mode 100644
index 0000000000..23f60fece1
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_no_id.rdf
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <!-- Invalid because of a missing add-on id -->
+ <em:version>0.1</em:version>
+ <em:name>Test Invalid Extension (no id)</em:name>
+ <em:creator>Mozilla</em:creator>
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <!-- Invalid target application string -->
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
diff --git a/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_not_wellformed.rdf b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_not_wellformed.rdf
new file mode 100644
index 0000000000..690ec406cc
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_not_wellformed.rdf
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <!-- Invalid because it's not well-formed -->
+ <em:id>test-addon-invalid-not-wellformed@mozilla.org</em:id
+ <em:version>0.1</em:version>
+ <em:name>Test Invalid Extension (no id)</em:name>
+ <em:creator>Mozilla</em:creator>
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <!-- Invalid target application string -->
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
diff --git a/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_version.rdf b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_version.rdf
new file mode 100644
index 0000000000..c854bfcdb5
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_invalid_version.rdf
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>test-addon-invalid-version@mozilla.org</em:id>
+ <!-- Invalid addon version -->
+ <em:version>0.NOPE</em:version>
+ <em:name>Test Invalid Extension (invalid version)</em:name>
+ <em:creator>Mozilla</em:creator>
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <!-- Invalid target application string -->
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
diff --git a/testing/mozbase/mozprofile/tests/install_manifests/test_addon_unpack.rdf b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_unpack.rdf
new file mode 100644
index 0000000000..cc85ea560f
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/install_manifests/test_addon_unpack.rdf
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>test-addon-unpack@mozilla.org</em:id>
+ <em:version>0.1</em:version>
+ <em:name>Test Add-on (unpack)</em:name>
+ <em:creator>Mozilla</em:creator>
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+ <em:type>2</em:type>
+ <em:unpack>true</em:unpack>
+
+ <!-- Firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.*</em:minVersion>
+ <em:maxVersion>*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
diff --git a/testing/mozbase/mozprofile/tests/manifest.ini b/testing/mozbase/mozprofile/tests/manifest.ini
new file mode 100644
index 0000000000..3e5ea50d67
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/manifest.ini
@@ -0,0 +1,12 @@
+[addonid.py]
+[server_locations.py]
+[test_preferences.py]
+[permissions.py]
+[bug758250.py]
+[test_nonce.py]
+[bug785146.py]
+[test_clone_cleanup.py]
+[test_webapps.py]
+[test_profile.py]
+[test_profile_view.py]
+[test_addons.py]
diff --git a/testing/mozbase/mozprofile/tests/permissions.py b/testing/mozbase/mozprofile/tests/permissions.py
new file mode 100755
index 0000000000..8889277afb
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/permissions.py
@@ -0,0 +1,199 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import mozfile
+import os
+import shutil
+import sqlite3
+import tempfile
+import unittest
+from mozprofile.permissions import Permissions
+
+
+class PermissionsTest(unittest.TestCase):
+
+ locations = """http://mochi.test:8888 primary,privileged
+http://127.0.0.1:80 noxul
+http://127.0.0.1:8888 privileged
+"""
+
+ profile_dir = None
+ locations_file = None
+
+ def setUp(self):
+ self.profile_dir = tempfile.mkdtemp()
+ self.locations_file = mozfile.NamedTemporaryFile()
+ self.locations_file.write(self.locations)
+ self.locations_file.flush()
+
+ def tearDown(self):
+ if self.profile_dir:
+ shutil.rmtree(self.profile_dir)
+ if self.locations_file:
+ self.locations_file.close()
+
+ def write_perm_db(self, version=3):
+ permDB = sqlite3.connect(os.path.join(self.profile_dir, "permissions.sqlite"))
+ cursor = permDB.cursor()
+
+ cursor.execute("PRAGMA user_version=%d;" % version)
+
+ if version == 5:
+ cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
+ id INTEGER PRIMARY KEY,
+ origin TEXT,
+ type TEXT,
+ permission INTEGER,
+ expireType INTEGER,
+ expireTime INTEGER,
+ modificationTime INTEGER)""")
+ elif version == 4:
+ cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
+ id INTEGER PRIMARY KEY,
+ host TEXT,
+ type TEXT,
+ permission INTEGER,
+ expireType INTEGER,
+ expireTime INTEGER,
+ modificationTime INTEGER,
+ appId INTEGER,
+ isInBrowserElement INTEGER)""")
+ elif version == 3:
+ cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
+ id INTEGER PRIMARY KEY,
+ host TEXT,
+ type TEXT,
+ permission INTEGER,
+ expireType INTEGER,
+ expireTime INTEGER,
+ appId INTEGER,
+ isInBrowserElement INTEGER)""")
+ elif version == 2:
+ cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
+ id INTEGER PRIMARY KEY,
+ host TEXT,
+ type TEXT,
+ permission INTEGER,
+ expireType INTEGER,
+ expireTime INTEGER)""")
+ else:
+ raise Exception("version must be 2, 3, 4 or 5")
+
+ permDB.commit()
+ cursor.close()
+
+ def test_create_permissions_db(self):
+ perms = Permissions(self.profile_dir, self.locations_file.name)
+ perms_db_filename = os.path.join(self.profile_dir, 'permissions.sqlite')
+
+ select_stmt = 'select origin, type, permission from moz_hosts'
+
+ con = sqlite3.connect(perms_db_filename)
+ cur = con.cursor()
+ cur.execute(select_stmt)
+ entries = cur.fetchall()
+
+ self.assertEqual(len(entries), 3)
+
+ self.assertEqual(entries[0][0], 'http://mochi.test:8888')
+ self.assertEqual(entries[0][1], 'allowXULXBL')
+ self.assertEqual(entries[0][2], 1)
+
+ self.assertEqual(entries[1][0], 'http://127.0.0.1')
+ self.assertEqual(entries[1][1], 'allowXULXBL')
+ self.assertEqual(entries[1][2], 2)
+
+ self.assertEqual(entries[2][0], 'http://127.0.0.1:8888')
+ self.assertEqual(entries[2][1], 'allowXULXBL')
+ self.assertEqual(entries[2][2], 1)
+
+ perms._locations.add_host('a.b.c', port='8081', scheme='https', options='noxul')
+
+ cur.execute(select_stmt)
+ entries = cur.fetchall()
+
+ self.assertEqual(len(entries), 4)
+ self.assertEqual(entries[3][0], 'https://a.b.c:8081')
+ self.assertEqual(entries[3][1], 'allowXULXBL')
+ self.assertEqual(entries[3][2], 2)
+
+ # when creating a DB we should default to user_version==5
+ cur.execute('PRAGMA user_version')
+ entries = cur.fetchall()
+ self.assertEqual(entries[0][0], 5)
+
+ perms.clean_db()
+ # table should be removed
+ cur.execute("select * from sqlite_master where type='table'")
+ entries = cur.fetchall()
+ self.assertEqual(len(entries), 0)
+
+ def test_nw_prefs(self):
+ perms = Permissions(self.profile_dir, self.locations_file.name)
+
+ prefs, user_prefs = perms.network_prefs(False)
+
+ self.assertEqual(len(user_prefs), 0)
+ self.assertEqual(len(prefs), 0)
+
+ prefs, user_prefs = perms.network_prefs(True)
+ self.assertEqual(len(user_prefs), 2)
+ self.assertEqual(user_prefs[0], ('network.proxy.type', 2))
+ self.assertEqual(user_prefs[1][0], 'network.proxy.autoconfig_url')
+
+ origins_decl = "var knownOrigins = (function () { return ['http://mochi.test:8888', " \
+ "'http://127.0.0.1:80', 'http://127.0.0.1:8888'].reduce"
+ self.assertTrue(origins_decl in user_prefs[1][1])
+
+ proxy_check = ("'http': 'PROXY mochi.test:8888'",
+ "'https': 'PROXY mochi.test:4443'",
+ "'ws': 'PROXY mochi.test:4443'",
+ "'wss': 'PROXY mochi.test:4443'")
+ self.assertTrue(all(c in user_prefs[1][1] for c in proxy_check))
+
+ def verify_user_version(self, version):
+ """Verifies that we call INSERT statements using the correct number
+ of columns for existing databases.
+ """
+ self.write_perm_db(version=version)
+ Permissions(self.profile_dir, self.locations_file.name)
+ perms_db_filename = os.path.join(self.profile_dir, 'permissions.sqlite')
+
+ select_stmt = 'select * from moz_hosts'
+
+ con = sqlite3.connect(perms_db_filename)
+ cur = con.cursor()
+ cur.execute(select_stmt)
+ entries = cur.fetchall()
+
+ self.assertEqual(len(entries), 3)
+
+ columns = {
+ 1: 6,
+ 2: 6,
+ 3: 8,
+ 4: 9,
+ 5: 7,
+ }[version]
+
+ self.assertEqual(len(entries[0]), columns)
+ for x in range(4, columns):
+ self.assertEqual(entries[0][x], 0)
+
+ def test_existing_permissions_db_v2(self):
+ self.verify_user_version(2)
+
+ def test_existing_permissions_db_v3(self):
+ self.verify_user_version(3)
+
+ def test_existing_permissions_db_v4(self):
+ self.verify_user_version(4)
+
+ def test_existing_permissions_db_v5(self):
+ self.verify_user_version(5)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/server_locations.py b/testing/mozbase/mozprofile/tests/server_locations.py
new file mode 100644
index 0000000000..5aa5c0f5eb
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/server_locations.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import mozfile
+import unittest
+from mozprofile.permissions import ServerLocations, \
+ MissingPrimaryLocationError, MultiplePrimaryLocationsError, \
+ DuplicateLocationError, BadPortLocationError, LocationsSyntaxError
+
+
+class ServerLocationsTest(unittest.TestCase):
+ """test server locations"""
+
+ locations = """# This is the primary location from which tests run.
+#
+http://mochi.test:8888 primary,privileged
+
+# a few test locations
+http://127.0.0.1:80 privileged
+http://127.0.0.1:8888 privileged
+https://test:80 privileged
+http://example.org:80 privileged
+http://test1.example.org privileged
+
+ """
+
+ locations_no_primary = """http://secondary.test:80 privileged
+http://tertiary.test:8888 privileged
+"""
+
+ locations_bad_port = """http://mochi.test:8888 primary,privileged
+http://127.0.0.1:80 privileged
+http://127.0.0.1:8888 privileged
+http://test:badport privileged
+http://example.org:80 privileged
+"""
+
+ def compare_location(self, location, scheme, host, port, options):
+ self.assertEqual(location.scheme, scheme)
+ self.assertEqual(location.host, host)
+ self.assertEqual(location.port, port)
+ self.assertEqual(location.options, options)
+
+ def create_temp_file(self, contents):
+ f = mozfile.NamedTemporaryFile()
+ f.write(contents)
+ f.flush()
+ return f
+
+ def test_server_locations(self):
+ # write a permissions file
+ f = self.create_temp_file(self.locations)
+
+ # read the locations
+ locations = ServerLocations(f.name)
+
+ # ensure that they're what we expect
+ self.assertEqual(len(locations), 6)
+ i = iter(locations)
+ self.compare_location(i.next(), 'http', 'mochi.test', '8888',
+ ['primary', 'privileged'])
+ self.compare_location(i.next(), 'http', '127.0.0.1', '80',
+ ['privileged'])
+ self.compare_location(i.next(), 'http', '127.0.0.1', '8888',
+ ['privileged'])
+ self.compare_location(i.next(), 'https', 'test', '80', ['privileged'])
+ self.compare_location(i.next(), 'http', 'example.org', '80',
+ ['privileged'])
+ self.compare_location(i.next(), 'http', 'test1.example.org', '8888',
+ ['privileged'])
+
+ locations.add_host('mozilla.org')
+ self.assertEqual(len(locations), 7)
+ self.compare_location(i.next(), 'http', 'mozilla.org', '80',
+ ['privileged'])
+
+ # test some errors
+ self.assertRaises(MultiplePrimaryLocationsError, locations.add_host,
+ 'primary.test', options='primary')
+
+ # We no longer throw these DuplicateLocation Error
+ try:
+ locations.add_host('127.0.0.1')
+ except DuplicateLocationError:
+ self.assertTrue(False, "Should no longer throw DuplicateLocationError")
+
+ self.assertRaises(BadPortLocationError, locations.add_host, '127.0.0.1',
+ port='abc')
+
+ # test some errors in locations file
+ f = self.create_temp_file(self.locations_no_primary)
+
+ exc = None
+ try:
+ ServerLocations(f.name)
+ except LocationsSyntaxError as e:
+ exc = e
+ self.assertNotEqual(exc, None)
+ self.assertEqual(exc.err.__class__, MissingPrimaryLocationError)
+ self.assertEqual(exc.lineno, 3)
+
+ # test bad port in a locations file to ensure lineno calculated
+ # properly.
+ f = self.create_temp_file(self.locations_bad_port)
+
+ exc = None
+ try:
+ ServerLocations(f.name)
+ except LocationsSyntaxError as e:
+ exc = e
+ self.assertNotEqual(exc, None)
+ self.assertEqual(exc.err.__class__, BadPortLocationError)
+ self.assertEqual(exc.lineno, 4)
+
+ def test_server_locations_callback(self):
+ class CallbackTest(object):
+ last_locations = None
+
+ def callback(self, locations):
+ self.last_locations = locations
+
+ c = CallbackTest()
+ f = self.create_temp_file(self.locations)
+ locations = ServerLocations(f.name, c.callback)
+
+ # callback should be for all locations in file
+ self.assertEqual(len(c.last_locations), 6)
+
+ # validate arbitrary one
+ self.compare_location(c.last_locations[2], 'http', '127.0.0.1', '8888',
+ ['privileged'])
+
+ locations.add_host('a.b.c')
+
+ # callback should be just for one location
+ self.assertEqual(len(c.last_locations), 1)
+ self.compare_location(c.last_locations[0], 'http', 'a.b.c', '80',
+ ['privileged'])
+
+ # read a second file, which should generate a callback with both
+ # locations.
+ f = self.create_temp_file(self.locations_no_primary)
+ locations.read(f.name)
+ self.assertEqual(len(c.last_locations), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/test_addons.py b/testing/mozbase/mozprofile/tests/test_addons.py
new file mode 100644
index 0000000000..93b930feac
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/test_addons.py
@@ -0,0 +1,415 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import shutil
+import tempfile
+import unittest
+import urllib2
+
+from manifestparser import ManifestParser
+import mozfile
+import mozhttpd
+import mozlog.unstructured as mozlog
+import mozprofile
+
+from addon_stubs import generate_addon, generate_manifest
+
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+class TestAddonsManager(unittest.TestCase):
+ """ Class to test mozprofile.addons.AddonManager """
+
+ def setUp(self):
+ self.logger = mozlog.getLogger('mozprofile.addons')
+ self.logger.setLevel(mozlog.ERROR)
+
+ self.profile = mozprofile.profile.Profile()
+ self.am = self.profile.addon_manager
+
+ self.profile_path = self.profile.profile
+ self.tmpdir = tempfile.mkdtemp()
+ self.addCleanup(mozfile.remove, self.tmpdir)
+
+ def test_install_addons_multiple_same_source(self):
+ # Generate installer stubs for all possible types of addons
+ addon_xpi = generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir)
+ addon_folder = generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir,
+ xpi=False)
+
+ # The same folder should not be installed twice
+ self.am.install_addons([addon_folder, addon_folder])
+ self.assertEqual(self.am.installed_addons, [addon_folder])
+ self.am.clean()
+
+ # The same XPI file should not be installed twice
+ self.am.install_addons([addon_xpi, addon_xpi])
+ self.assertEqual(self.am.installed_addons, [addon_xpi])
+ self.am.clean()
+
+ # Even if it is the same id the add-on should be installed twice, if
+ # specified via XPI and folder
+ self.am.install_addons([addon_folder, addon_xpi])
+ self.assertEqual(len(self.am.installed_addons), 2)
+ self.assertIn(addon_folder, self.am.installed_addons)
+ self.assertIn(addon_xpi, self.am.installed_addons)
+ self.am.clean()
+
+ def test_download(self):
+ server = mozhttpd.MozHttpd(docroot=os.path.join(here, 'addons'))
+ server.start()
+
+ # Download a valid add-on without a class instance to the general
+ # tmp folder and clean-up
+ try:
+ addon = server.get_url() + 'empty.xpi'
+ xpi_file = mozprofile.addons.AddonManager.download(addon)
+ self.assertTrue(os.path.isfile(xpi_file))
+ self.assertIn('test-empty@quality.mozilla.org.xpi',
+ os.path.basename(xpi_file))
+ self.assertNotIn(self.tmpdir, os.path.dirname(xpi_file))
+ finally:
+ # Given that the file is stored outside of the created tmp dir
+ # we have to ensure to explicitely remove it
+ if os.path.isfile(xpi_file):
+ os.remove(xpi_file)
+
+ # Download an valid add-on to a special folder
+ addon = server.get_url() + 'empty.xpi'
+ xpi_file = self.am.download(addon, self.tmpdir)
+ self.assertTrue(os.path.isfile(xpi_file))
+ self.assertIn('test-empty@quality.mozilla.org.xpi',
+ os.path.basename(xpi_file))
+ self.assertIn(self.tmpdir, os.path.dirname(xpi_file))
+ self.assertEqual(self.am.downloaded_addons, [])
+ os.remove(xpi_file)
+
+ # Download an invalid add-on to a special folder
+ addon = server.get_url() + 'invalid.xpi'
+ self.assertRaises(mozprofile.addons.AddonFormatError,
+ self.am.download, addon, self.tmpdir)
+ self.assertEqual(os.listdir(self.tmpdir), [])
+
+ # Download from an invalid URL
+ addon = server.get_url() + 'not_existent.xpi'
+ self.assertRaises(urllib2.HTTPError,
+ self.am.download, addon, self.tmpdir)
+ self.assertEqual(os.listdir(self.tmpdir), [])
+
+ # Download from an invalid URL
+ addon = 'not_existent.xpi'
+ self.assertRaises(ValueError,
+ self.am.download, addon, self.tmpdir)
+ self.assertEqual(os.listdir(self.tmpdir), [])
+
+ server.stop()
+
+ def test_install_from_path_xpi(self):
+ addons_to_install = []
+ addons_installed = []
+
+ # Generate installer stubs and install them
+ for ext in ['test-addon-1@mozilla.org', 'test-addon-2@mozilla.org']:
+ temp_addon = generate_addon(ext, path=self.tmpdir)
+ addons_to_install.append(self.am.addon_details(temp_addon)['id'])
+ self.am.install_from_path(temp_addon)
+
+ # Generate a list of addons installed in the profile
+ addons_installed = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+ self.profile.profile, 'extensions', 'staged'))]
+ self.assertEqual(addons_to_install.sort(), addons_installed.sort())
+
+ def test_install_from_path_folder(self):
+ # Generate installer stubs for all possible types of addons
+ addons = []
+ addons.append(generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir))
+ addons.append(generate_addon('test-addon-2@mozilla.org',
+ path=self.tmpdir,
+ xpi=False))
+ addons.append(generate_addon('test-addon-3@mozilla.org',
+ path=self.tmpdir,
+ name='addon-3'))
+ addons.append(generate_addon('test-addon-4@mozilla.org',
+ path=self.tmpdir,
+ name='addon-4',
+ xpi=False))
+ addons.sort()
+
+ self.am.install_from_path(self.tmpdir)
+
+ self.assertEqual(self.am.installed_addons, addons)
+
+ def test_install_from_path_unpack(self):
+ # Generate installer stubs for all possible types of addons
+ addon_xpi = generate_addon('test-addon-unpack@mozilla.org',
+ path=self.tmpdir)
+ addon_folder = generate_addon('test-addon-unpack@mozilla.org',
+ path=self.tmpdir,
+ xpi=False)
+ addon_no_unpack = generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir)
+
+ # Test unpack flag for add-on as XPI
+ self.am.install_from_path(addon_xpi)
+ self.assertEqual(self.am.installed_addons, [addon_xpi])
+ self.am.clean()
+
+ # Test unpack flag for add-on as folder
+ self.am.install_from_path(addon_folder)
+ self.assertEqual(self.am.installed_addons, [addon_folder])
+ self.am.clean()
+
+ # Test forcing unpack an add-on
+ self.am.install_from_path(addon_no_unpack, unpack=True)
+ self.assertEqual(self.am.installed_addons, [addon_no_unpack])
+ self.am.clean()
+
+ def test_install_from_path_url(self):
+ server = mozhttpd.MozHttpd(docroot=os.path.join(here, 'addons'))
+ server.start()
+
+ addon = server.get_url() + 'empty.xpi'
+ self.am.install_from_path(addon)
+
+ server.stop()
+
+ self.assertEqual(len(self.am.downloaded_addons), 1)
+ self.assertTrue(os.path.isfile(self.am.downloaded_addons[0]))
+ self.assertIn('test-empty@quality.mozilla.org.xpi',
+ os.path.basename(self.am.downloaded_addons[0]))
+
+ def test_install_from_path_after_reset(self):
+ # Installing the same add-on after a reset should not cause a failure
+ addon = generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir, xpi=False)
+
+ # We cannot use self.am because profile.reset() creates a new instance
+ self.profile.addon_manager.install_from_path(addon)
+
+ self.profile.reset()
+
+ self.profile.addon_manager.install_from_path(addon)
+ self.assertEqual(self.profile.addon_manager.installed_addons, [addon])
+
+ def test_install_from_path_backup(self):
+ staged_path = os.path.join(self.profile_path, 'extensions', 'staged')
+
+ # Generate installer stubs for all possible types of addons
+ addon_xpi = generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir)
+ addon_folder = generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir,
+ xpi=False)
+ addon_name = generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir,
+ name='test-addon-1-dupe@mozilla.org')
+
+ # Test backup of xpi files
+ self.am.install_from_path(addon_xpi)
+ self.assertIsNone(self.am.backup_dir)
+
+ self.am.install_from_path(addon_xpi)
+ self.assertIsNotNone(self.am.backup_dir)
+ self.assertEqual(os.listdir(self.am.backup_dir),
+ ['test-addon-1@mozilla.org.xpi'])
+
+ self.am.clean()
+ self.assertEqual(os.listdir(staged_path),
+ ['test-addon-1@mozilla.org.xpi'])
+ self.am.clean()
+
+ # Test backup of folders
+ self.am.install_from_path(addon_folder)
+ self.assertIsNone(self.am.backup_dir)
+
+ self.am.install_from_path(addon_folder)
+ self.assertIsNotNone(self.am.backup_dir)
+ self.assertEqual(os.listdir(self.am.backup_dir),
+ ['test-addon-1@mozilla.org'])
+
+ self.am.clean()
+ self.assertEqual(os.listdir(staged_path),
+ ['test-addon-1@mozilla.org'])
+ self.am.clean()
+
+ # Test backup of xpi files with another file name
+ self.am.install_from_path(addon_name)
+ self.assertIsNone(self.am.backup_dir)
+
+ self.am.install_from_path(addon_xpi)
+ self.assertIsNotNone(self.am.backup_dir)
+ self.assertEqual(os.listdir(self.am.backup_dir),
+ ['test-addon-1@mozilla.org.xpi'])
+
+ self.am.clean()
+ self.assertEqual(os.listdir(staged_path),
+ ['test-addon-1@mozilla.org.xpi'])
+ self.am.clean()
+
+ def test_install_from_path_invalid_addons(self):
+ # Generate installer stubs for all possible types of addons
+ addons = []
+ addons.append(generate_addon('test-addon-invalid-no-manifest@mozilla.org',
+ path=self.tmpdir,
+ xpi=False))
+ addons.append(generate_addon('test-addon-invalid-no-id@mozilla.org',
+ path=self.tmpdir))
+
+ self.am.install_from_path(self.tmpdir)
+
+ self.assertEqual(self.am.installed_addons, [])
+
+ @unittest.skip("Feature not implemented as part of AddonManger")
+ def test_install_from_path_error(self):
+ """ Check install_from_path raises an error with an invalid addon"""
+
+ temp_addon = generate_addon('test-addon-invalid-version@mozilla.org')
+ # This should raise an error here
+ self.am.install_from_path(temp_addon)
+
+ def test_install_from_manifest(self):
+ temp_manifest = generate_manifest(['test-addon-1@mozilla.org',
+ 'test-addon-2@mozilla.org'])
+ m = ManifestParser()
+ m.read(temp_manifest)
+ addons = m.get()
+
+ # Obtain details of addons to install from the manifest
+ addons_to_install = [self.am.addon_details(x['path']).get('id') for x in addons]
+
+ self.am.install_from_manifest(temp_manifest)
+ # Generate a list of addons installed in the profile
+ addons_installed = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+ self.profile.profile, 'extensions', 'staged'))]
+ self.assertEqual(addons_installed.sort(), addons_to_install.sort())
+
+ # Cleanup the temporary addon and manifest directories
+ mozfile.rmtree(os.path.dirname(temp_manifest))
+
+ def test_addon_details(self):
+ # Generate installer stubs for a valid and invalid add-on manifest
+ valid_addon = generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir)
+ invalid_addon = generate_addon('test-addon-invalid-not-wellformed@mozilla.org',
+ path=self.tmpdir)
+
+ # Check valid add-on
+ details = self.am.addon_details(valid_addon)
+ self.assertEqual(details['id'], 'test-addon-1@mozilla.org')
+ self.assertEqual(details['name'], 'Test Add-on 1')
+ self.assertEqual(details['unpack'], False)
+ self.assertEqual(details['version'], '0.1')
+
+ # Check invalid add-on
+ self.assertRaises(mozprofile.addons.AddonFormatError,
+ self.am.addon_details, invalid_addon)
+
+ # Check invalid path
+ self.assertRaises(IOError,
+ self.am.addon_details, '')
+
+ # Check invalid add-on format
+ addon_path = os.path.join(os.path.join(here, 'files'), 'not_an_addon.txt')
+ self.assertRaises(mozprofile.addons.AddonFormatError,
+ self.am.addon_details, addon_path)
+
+ @unittest.skip("Bug 900154")
+ def test_clean_addons(self):
+ addon_one = generate_addon('test-addon-1@mozilla.org')
+ addon_two = generate_addon('test-addon-2@mozilla.org')
+
+ self.am.install_addons(addon_one)
+ installed_addons = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+ self.profile.profile, 'extensions', 'staged'))]
+
+ # Create a new profile based on an existing profile
+ # Install an extra addon in the new profile
+ # Cleanup addons
+ duplicate_profile = mozprofile.profile.Profile(profile=self.profile.profile,
+ addons=addon_two)
+ duplicate_profile.addon_manager.clean()
+
+ addons_after_cleanup = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+ duplicate_profile.profile, 'extensions', 'staged'))]
+ # New addons installed should be removed by clean_addons()
+ self.assertEqual(installed_addons, addons_after_cleanup)
+
+ def test_noclean(self):
+ """test `restore=True/False` functionality"""
+
+ server = mozhttpd.MozHttpd(docroot=os.path.join(here, 'addons'))
+ server.start()
+
+ profile = tempfile.mkdtemp()
+ tmpdir = tempfile.mkdtemp()
+
+ try:
+ # empty initially
+ self.assertFalse(bool(os.listdir(profile)))
+
+ # make an addon
+ addons = []
+ addons.append(generate_addon('test-addon-1@mozilla.org',
+ path=tmpdir))
+ addons.append(server.get_url() + 'empty.xpi')
+
+ # install it with a restore=True AddonManager
+ am = mozprofile.addons.AddonManager(profile, restore=True)
+
+ for addon in addons:
+ am.install_from_path(addon)
+
+ # now its there
+ self.assertEqual(os.listdir(profile), ['extensions'])
+ staging_folder = os.path.join(profile, 'extensions', 'staged')
+ self.assertTrue(os.path.exists(staging_folder))
+ self.assertEqual(len(os.listdir(staging_folder)), 2)
+
+ # del addons; now its gone though the directory tree exists
+ downloaded_addons = am.downloaded_addons
+ del am
+
+ self.assertEqual(os.listdir(profile), ['extensions'])
+ self.assertTrue(os.path.exists(staging_folder))
+ self.assertEqual(os.listdir(staging_folder), [])
+
+ for addon in downloaded_addons:
+ self.assertFalse(os.path.isfile(addon))
+
+ finally:
+ mozfile.rmtree(tmpdir)
+ mozfile.rmtree(profile)
+
+ def test_remove_addon(self):
+ addons = []
+ addons.append(generate_addon('test-addon-1@mozilla.org',
+ path=self.tmpdir))
+ addons.append(generate_addon('test-addon-2@mozilla.org',
+ path=self.tmpdir))
+
+ self.am.install_from_path(self.tmpdir)
+
+ extensions_path = os.path.join(self.profile_path, 'extensions')
+ staging_path = os.path.join(extensions_path, 'staged')
+
+ # Fake a run by virtually installing one of the staged add-ons
+ shutil.move(os.path.join(staging_path, 'test-addon-1@mozilla.org.xpi'),
+ extensions_path)
+
+ for addon in self.am._addons:
+ self.am.remove_addon(addon)
+
+ self.assertEqual(os.listdir(staging_path), [])
+ self.assertEqual(os.listdir(extensions_path), ['staged'])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/test_clone_cleanup.py b/testing/mozbase/mozprofile/tests/test_clone_cleanup.py
new file mode 100644
index 0000000000..51c7ba03e8
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/test_clone_cleanup.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+import os
+import tempfile
+import unittest
+import mozfile
+
+from mozprofile.profile import Profile
+
+
+class CloneCleanupTest(unittest.TestCase):
+ """
+ test cleanup logic for the clone functionality
+ see https://bugzilla.mozilla.org/show_bug.cgi?id=642843
+ """
+
+ def setUp(self):
+ # make a profile with one preference
+ path = tempfile.mktemp()
+ self.addCleanup(mozfile.remove, path)
+ self.profile = Profile(path,
+ preferences={'foo': 'bar'},
+ restore=False)
+ user_js = os.path.join(self.profile.profile, 'user.js')
+ self.assertTrue(os.path.exists(user_js))
+
+ def test_restore_true(self):
+ # make a clone of this profile with restore=True
+ clone = Profile.clone(self.profile.profile, restore=True)
+ self.addCleanup(mozfile.remove, clone.profile)
+
+ clone.cleanup()
+
+ # clone should be deleted
+ self.assertFalse(os.path.exists(clone.profile))
+
+ def test_restore_false(self):
+ # make a clone of this profile with restore=False
+ clone = Profile.clone(self.profile.profile, restore=False)
+ self.addCleanup(mozfile.remove, clone.profile)
+
+ clone.cleanup()
+
+ # clone should still be around on the filesystem
+ self.assertTrue(os.path.exists(clone.profile))
+
+ def test_cleanup_on_garbage_collected(self):
+ clone = Profile.clone(self.profile.profile)
+ self.addCleanup(mozfile.remove, clone.profile)
+ profile_dir = clone.profile
+ self.assertTrue(os.path.exists(profile_dir))
+ del clone
+ # clone should be deleted
+ self.assertFalse(os.path.exists(profile_dir))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/test_nonce.py b/testing/mozbase/mozprofile/tests/test_nonce.py
new file mode 100755
index 0000000000..fef2622725
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/test_nonce.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+"""
+test nonce in prefs delimeters
+see https://bugzilla.mozilla.org/show_bug.cgi?id=722804
+"""
+
+import os
+import tempfile
+import unittest
+import mozfile
+from mozprofile.prefs import Preferences
+from mozprofile.profile import Profile
+
+
+class PreferencesNonceTest(unittest.TestCase):
+
+ def test_nonce(self):
+
+ # make a profile with one preference
+ path = tempfile.mktemp()
+ self.addCleanup(mozfile.remove, path)
+ profile = Profile(path,
+ preferences={'foo': 'bar'},
+ restore=False)
+ user_js = os.path.join(profile.profile, 'user.js')
+ self.assertTrue(os.path.exists(user_js))
+
+ # ensure the preference is correct
+ prefs = Preferences.read_prefs(user_js)
+ self.assertEqual(dict(prefs), {'foo': 'bar'})
+
+ del profile
+
+ # augment the profile with a second preference
+ profile = Profile(path,
+ preferences={'fleem': 'baz'},
+ restore=True)
+ prefs = Preferences.read_prefs(user_js)
+ self.assertEqual(dict(prefs), {'foo': 'bar', 'fleem': 'baz'})
+
+ # cleanup the profile;
+ # this should remove the new preferences but not the old
+ profile.cleanup()
+ prefs = Preferences.read_prefs(user_js)
+ self.assertEqual(dict(prefs), {'foo': 'bar'})
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/test_preferences.py b/testing/mozbase/mozprofile/tests/test_preferences.py
new file mode 100755
index 0000000000..45d99c2e27
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/test_preferences.py
@@ -0,0 +1,378 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import mozfile
+import mozhttpd
+import os
+import shutil
+import tempfile
+import unittest
+from mozprofile.cli import MozProfileCLI
+from mozprofile.prefs import Preferences
+from mozprofile.profile import Profile
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+class PreferencesTest(unittest.TestCase):
+ """test mozprofile preference handling"""
+
+ # preferences from files/prefs_with_comments.js
+ _prefs_with_comments = {'browser.startup.homepage': 'http://planet.mozilla.org',
+ 'zoom.minPercent': 30,
+ 'zoom.maxPercent': 300,
+ 'webgl.verbose': 'false'}
+
+ def run_command(self, *args):
+ """
+ invokes mozprofile command line via the CLI factory
+ - args : command line arguments (equivalent of sys.argv[1:])
+ """
+
+ # instantiate the factory
+ cli = MozProfileCLI(list(args))
+
+ # create the profile
+ profile = cli.profile()
+
+ # return path to profile
+ return profile.profile
+
+ def compare_generated(self, _prefs, commandline):
+ """
+ writes out to a new profile with mozprofile command line
+ reads the generated preferences with prefs.py
+ compares the results
+ cleans up
+ """
+ profile = self.run_command(*commandline)
+ prefs_file = os.path.join(profile, 'user.js')
+ self.assertTrue(os.path.exists(prefs_file))
+ read = Preferences.read_prefs(prefs_file)
+ if isinstance(_prefs, dict):
+ read = dict(read)
+ self.assertEqual(_prefs, read)
+ shutil.rmtree(profile)
+
+ def test_basic_prefs(self):
+ """test setting a pref from the command line entry point"""
+
+ _prefs = {"browser.startup.homepage": "http://planet.mozilla.org/"}
+ commandline = []
+ _prefs = _prefs.items()
+ for pref, value in _prefs:
+ commandline += ["--pref", "%s:%s" % (pref, value)]
+ self.compare_generated(_prefs, commandline)
+
+ def test_ordered_prefs(self):
+ """ensure the prefs stay in the right order"""
+ _prefs = [("browser.startup.homepage", "http://planet.mozilla.org/"),
+ ("zoom.minPercent", 30),
+ ("zoom.maxPercent", 300),
+ ("webgl.verbose", 'false')]
+ commandline = []
+ for pref, value in _prefs:
+ commandline += ["--pref", "%s:%s" % (pref, value)]
+ _prefs = [(i, Preferences.cast(j)) for i, j in _prefs]
+ self.compare_generated(_prefs, commandline)
+
+ def test_ini(self):
+
+ # write the .ini file
+ _ini = """[DEFAULT]
+browser.startup.homepage = http://planet.mozilla.org/
+
+[foo]
+browser.startup.homepage = http://github.com/
+"""
+ try:
+ fd, name = tempfile.mkstemp(suffix='.ini')
+ os.write(fd, _ini)
+ os.close(fd)
+ commandline = ["--preferences", name]
+
+ # test the [DEFAULT] section
+ _prefs = {'browser.startup.homepage': 'http://planet.mozilla.org/'}
+ self.compare_generated(_prefs, commandline)
+
+ # test a specific section
+ _prefs = {'browser.startup.homepage': 'http://github.com/'}
+ commandline[-1] = commandline[-1] + ':foo'
+ self.compare_generated(_prefs, commandline)
+
+ finally:
+ # cleanup
+ os.remove(name)
+
+ def test_ini_keep_case(self):
+ """
+ Read a preferences config file with a preference in camel-case style.
+ Check that the read preference name has not been lower-cased
+ """
+ # write the .ini file
+ _ini = """[DEFAULT]
+general.warnOnAboutConfig = False
+"""
+ try:
+ fd, name = tempfile.mkstemp(suffix='.ini')
+ os.write(fd, _ini)
+ os.close(fd)
+ commandline = ["--preferences", name]
+
+ # test the [DEFAULT] section
+ _prefs = {'general.warnOnAboutConfig': 'False'}
+ self.compare_generated(_prefs, commandline)
+
+ finally:
+ # cleanup
+ os.remove(name)
+
+ def test_reset_should_remove_added_prefs(self):
+ """Check that when we call reset the items we expect are updated"""
+ profile = Profile()
+ prefs_file = os.path.join(profile.profile, 'user.js')
+
+ # we shouldn't have any initial preferences
+ initial_prefs = Preferences.read_prefs(prefs_file)
+ self.assertFalse(initial_prefs)
+ initial_prefs = file(prefs_file).read().strip()
+ self.assertFalse(initial_prefs)
+
+ # add some preferences
+ prefs1 = [("mr.t.quotes", "i aint getting on no plane!")]
+ profile.set_preferences(prefs1)
+ self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
+ lines = file(prefs_file).read().strip().splitlines()
+ self.assertTrue(any(line.startswith('#MozRunner Prefs Start') for line in lines))
+ self.assertTrue(any(line.startswith('#MozRunner Prefs End') for line in lines))
+
+ profile.reset()
+ self.assertNotEqual(prefs1,
+ Preferences.read_prefs(os.path.join(profile.profile, 'user.js')),
+ "I pity the fool who left my pref")
+
+ def test_reset_should_keep_user_added_prefs(self):
+ """Check that when we call reset the items we expect are updated"""
+ profile = Profile()
+ prefs_file = os.path.join(profile.profile, 'user.js')
+
+ # we shouldn't have any initial preferences
+ initial_prefs = Preferences.read_prefs(prefs_file)
+ self.assertFalse(initial_prefs)
+ initial_prefs = file(prefs_file).read().strip()
+ self.assertFalse(initial_prefs)
+
+ # add some preferences
+ prefs1 = [("mr.t.quotes", "i aint getting on no plane!")]
+ profile.set_persistent_preferences(prefs1)
+ self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
+ lines = file(prefs_file).read().strip().splitlines()
+ self.assertTrue(any(line.startswith('#MozRunner Prefs Start') for line in lines))
+ self.assertTrue(any(line.startswith('#MozRunner Prefs End') for line in lines))
+
+ profile.reset()
+ self.assertEqual(prefs1,
+ Preferences.read_prefs(os.path.join(profile.profile, 'user.js')),
+ "I pity the fool who left my pref")
+
+ def test_magic_markers(self):
+ """ensure our magic markers are working"""
+
+ profile = Profile()
+ prefs_file = os.path.join(profile.profile, 'user.js')
+
+ # we shouldn't have any initial preferences
+ initial_prefs = Preferences.read_prefs(prefs_file)
+ self.assertFalse(initial_prefs)
+ initial_prefs = file(prefs_file).read().strip()
+ self.assertFalse(initial_prefs)
+
+ # add some preferences
+ prefs1 = [("browser.startup.homepage", "http://planet.mozilla.org/"),
+ ("zoom.minPercent", 30)]
+ profile.set_preferences(prefs1)
+ self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
+ lines = file(prefs_file).read().strip().splitlines()
+ self.assertTrue(bool([line for line in lines
+ if line.startswith('#MozRunner Prefs Start')]))
+ self.assertTrue(bool([line for line in lines
+ if line.startswith('#MozRunner Prefs End')]))
+
+ # add some more preferences
+ prefs2 = [("zoom.maxPercent", 300),
+ ("webgl.verbose", 'false')]
+ profile.set_preferences(prefs2)
+ self.assertEqual(prefs1 + prefs2, Preferences.read_prefs(prefs_file))
+ lines = file(prefs_file).read().strip().splitlines()
+ self.assertTrue(len([line for line in lines
+ if line.startswith('#MozRunner Prefs Start')]) == 2)
+ self.assertTrue(len([line for line in lines
+ if line.startswith('#MozRunner Prefs End')]) == 2)
+
+ # now clean it up
+ profile.clean_preferences()
+ final_prefs = Preferences.read_prefs(prefs_file)
+ self.assertFalse(final_prefs)
+ lines = file(prefs_file).read().strip().splitlines()
+ self.assertTrue('#MozRunner Prefs Start' not in lines)
+ self.assertTrue('#MozRunner Prefs End' not in lines)
+
+ def test_preexisting_preferences(self):
+ """ensure you don't clobber preexisting preferences"""
+
+ # make a pretend profile
+ tempdir = tempfile.mkdtemp()
+
+ try:
+ # make a user.js
+ contents = """
+user_pref("webgl.enabled_for_all_sites", true);
+user_pref("webgl.force-enabled", true);
+"""
+ user_js = os.path.join(tempdir, 'user.js')
+ f = file(user_js, 'w')
+ f.write(contents)
+ f.close()
+
+ # make sure you can read it
+ prefs = Preferences.read_prefs(user_js)
+ original_prefs = [('webgl.enabled_for_all_sites', True), ('webgl.force-enabled', True)]
+ self.assertTrue(prefs == original_prefs)
+
+ # now read this as a profile
+ profile = Profile(tempdir, preferences={"browser.download.dir": "/home/jhammel"})
+
+ # make sure the new pref is now there
+ new_prefs = original_prefs[:] + [("browser.download.dir", "/home/jhammel")]
+ prefs = Preferences.read_prefs(user_js)
+ self.assertTrue(prefs == new_prefs)
+
+ # clean up the added preferences
+ profile.cleanup()
+ del profile
+
+ # make sure you have the original preferences
+ prefs = Preferences.read_prefs(user_js)
+ self.assertTrue(prefs == original_prefs)
+ finally:
+ shutil.rmtree(tempdir)
+
+ def test_can_read_prefs_with_multiline_comments(self):
+ """
+ Ensure that multiple comments in the file header do not break reading
+ the prefs (https://bugzilla.mozilla.org/show_bug.cgi?id=1233534).
+ """
+ user_js = tempfile.NamedTemporaryFile(suffix='.js', delete=False)
+ self.addCleanup(mozfile.remove, user_js.name)
+ with user_js:
+ user_js.write("""
+# Mozilla User Preferences
+
+/* Do not edit this file.
+ *
+ * If you make changes to this file while the application is running,
+ * the changes will be overwritten when the application exits.
+ *
+ * To make a manual change to preferences, you can visit the URL about:config
+ */
+
+user_pref("webgl.enabled_for_all_sites", true);
+user_pref("webgl.force-enabled", true);
+""")
+ self.assertEqual(
+ Preferences.read_prefs(user_js.name),
+ [('webgl.enabled_for_all_sites', True),
+ ('webgl.force-enabled', True)]
+ )
+
+ def test_json(self):
+ _prefs = {"browser.startup.homepage": "http://planet.mozilla.org/"}
+ json = '{"browser.startup.homepage": "http://planet.mozilla.org/"}'
+
+ # just repr it...could use the json module but we don't need it here
+ with mozfile.NamedTemporaryFile(suffix='.json') as f:
+ f.write(json)
+ f.flush()
+
+ commandline = ["--preferences", f.name]
+ self.compare_generated(_prefs, commandline)
+
+ def test_prefs_write(self):
+ """test that the Preferences.write() method correctly serializes preferences"""
+
+ _prefs = {'browser.startup.homepage': "http://planet.mozilla.org",
+ 'zoom.minPercent': 30,
+ 'zoom.maxPercent': 300}
+
+ # make a Preferences manager with the testing preferences
+ preferences = Preferences(_prefs)
+
+ # write them to a temporary location
+ path = None
+ read_prefs = None
+ try:
+ with mozfile.NamedTemporaryFile(suffix='.js', delete=False) as f:
+ path = f.name
+ preferences.write(f, _prefs)
+
+ # read them back and ensure we get what we put in
+ read_prefs = dict(Preferences.read_prefs(path))
+
+ finally:
+ # cleanup
+ if path and os.path.exists(path):
+ os.remove(path)
+
+ self.assertEqual(read_prefs, _prefs)
+
+ def test_read_prefs_with_comments(self):
+ """test reading preferences from a prefs.js file that contains comments"""
+
+ path = os.path.join(here, 'files', 'prefs_with_comments.js')
+ self.assertEqual(dict(Preferences.read_prefs(path)), self._prefs_with_comments)
+
+ def test_read_prefs_with_interpolation(self):
+ """test reading preferences from a prefs.js file whose values
+ require interpolation"""
+
+ expected_prefs = {
+ "browser.foo": "http://server-name",
+ "zoom.minPercent": 30,
+ "webgl.verbose": "false",
+ "browser.bar": "somethingxyz"
+ }
+ values = {
+ "server": "server-name",
+ "abc": "something"
+ }
+ path = os.path.join(here, 'files', 'prefs_with_interpolation.js')
+ read_prefs = Preferences.read_prefs(path, interpolation=values)
+ self.assertEqual(dict(read_prefs), expected_prefs)
+
+ def test_read_prefs_ttw(self):
+ """test reading preferences through the web via mozhttpd"""
+
+ # create a MozHttpd instance
+ docroot = os.path.join(here, 'files')
+ host = '127.0.0.1'
+ port = 8888
+ httpd = mozhttpd.MozHttpd(host=host, port=port, docroot=docroot)
+
+ # create a preferences instance
+ prefs = Preferences()
+
+ try:
+ # start server
+ httpd.start(block=False)
+
+ # read preferences through the web
+ read = prefs.read_prefs('http://%s:%d/prefs_with_comments.js' % (host, port))
+ self.assertEqual(dict(read), self._prefs_with_comments)
+ finally:
+ httpd.stop()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/test_profile.py b/testing/mozbase/mozprofile/tests/test_profile.py
new file mode 100644
index 0000000000..e24de1904c
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/test_profile.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import unittest
+import os
+from mozprofile import Profile
+
+
+class TestProfile(unittest.TestCase):
+
+ def test_with_profile_should_cleanup(self):
+ with Profile() as profile:
+ self.assertTrue(os.path.exists(profile.profile))
+ # profile is cleaned
+ self.assertFalse(os.path.exists(profile.profile))
+
+ def test_with_profile_should_cleanup_even_on_exception(self):
+ with self.assertRaises(ZeroDivisionError):
+ with Profile() as profile:
+ self.assertTrue(os.path.exists(profile.profile))
+ 1 / 0 # will raise ZeroDivisionError
+ # profile is cleaned
+ self.assertFalse(os.path.exists(profile.profile))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/test_profile_view.py b/testing/mozbase/mozprofile/tests/test_profile_view.py
new file mode 100644
index 0000000000..2e10a913bd
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/test_profile_view.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import mozfile
+import mozprofile
+import os
+import tempfile
+import unittest
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+class TestProfilePrint(unittest.TestCase):
+
+ def test_profileprint(self):
+ """
+ test the summary function
+ """
+
+ keys = set(['Files', 'Path', 'user.js'])
+ ff_prefs = mozprofile.FirefoxProfile.preferences # shorthand
+ pref_string = '\n'.join(['%s: %s' % (key, ff_prefs[key])
+ for key in sorted(ff_prefs.keys())])
+
+ tempdir = tempfile.mkdtemp()
+ try:
+ profile = mozprofile.FirefoxProfile(tempdir)
+ parts = profile.summary(return_parts=True)
+ parts = dict(parts)
+
+ self.assertEqual(parts['Path'], tempdir)
+ self.assertEqual(set(parts.keys()), keys)
+ self.assertEqual(pref_string, parts['user.js'].strip())
+
+ except:
+ raise
+ finally:
+ mozfile.rmtree(tempdir)
+
+ def test_strcast(self):
+ """
+ test casting to a string
+ """
+
+ profile = mozprofile.Profile()
+ self.assertEqual(str(profile), profile.summary())
+
+ def test_profile_diff(self):
+ profile1 = mozprofile.Profile()
+ profile2 = mozprofile.Profile(preferences=dict(foo='bar'))
+
+ # diff a profile against itself; no difference
+ self.assertEqual([], mozprofile.diff(profile1, profile1))
+
+ # diff two profiles
+ diff = dict(mozprofile.diff(profile1, profile2))
+ self.assertEqual(diff.keys(), ['user.js'])
+ lines = [line.strip() for line in diff['user.js'].splitlines()]
+ self.assertTrue('+foo: bar' in lines)
+
+ # diff a blank vs FirefoxProfile
+ ff_profile = mozprofile.FirefoxProfile()
+ diff = dict(mozprofile.diff(profile2, ff_profile))
+ self.assertEqual(diff.keys(), ['user.js'])
+ lines = [line.strip() for line in diff['user.js'].splitlines()]
+ self.assertTrue('-foo: bar' in lines)
+ ff_pref_lines = ['+%s: %s' % (key, value)
+ for key, value in mozprofile.FirefoxProfile.preferences.items()]
+ self.assertTrue(set(ff_pref_lines).issubset(lines))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/mozbase/mozprofile/tests/test_webapps.py b/testing/mozbase/mozprofile/tests/test_webapps.py
new file mode 100755
index 0000000000..4db992d696
--- /dev/null
+++ b/testing/mozbase/mozprofile/tests/test_webapps.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python
+
+"""
+test installing and managing webapps in a profile
+"""
+
+import os
+import shutil
+import unittest
+from tempfile import mkdtemp
+
+from mozprofile.webapps import WebappCollection, Webapp, WebappFormatException
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+class WebappTest(unittest.TestCase):
+ """Tests reading, installing and cleaning webapps
+ from a profile.
+ """
+ manifest_path_1 = os.path.join(here, 'files', 'webapps1.json')
+ manifest_path_2 = os.path.join(here, 'files', 'webapps2.json')
+
+ def setUp(self):
+ self.profile = mkdtemp(prefix='test_webapp')
+ self.webapps_dir = os.path.join(self.profile, 'webapps')
+ self.webapps_json_path = os.path.join(self.webapps_dir, 'webapps.json')
+
+ def tearDown(self):
+ shutil.rmtree(self.profile)
+
+ def test_read_json_manifest(self):
+ """Tests WebappCollection.read_json"""
+ # Parse a list of webapp objects and verify it worked
+ manifest_json_1 = WebappCollection.read_json(self.manifest_path_1)
+ self.assertEqual(len(manifest_json_1), 7)
+ for app in manifest_json_1:
+ self.assertIsInstance(app, Webapp)
+ for key in Webapp.required_keys:
+ self.assertIn(key, app)
+
+ # Parse a dictionary of webapp objects and verify it worked
+ manifest_json_2 = WebappCollection.read_json(self.manifest_path_2)
+ self.assertEqual(len(manifest_json_2), 5)
+ for app in manifest_json_2:
+ self.assertIsInstance(app, Webapp)
+ for key in Webapp.required_keys:
+ self.assertIn(key, app)
+
+ def test_invalid_webapp(self):
+ """Tests a webapp with a missing required key"""
+ webapps = WebappCollection(self.profile)
+ # Missing the required key "description", exception should be raised
+ self.assertRaises(WebappFormatException, webapps.append, {'name': 'foo'})
+
+ def test_webapp_collection(self):
+ """Tests the methods of the WebappCollection object"""
+ webapp_1 = {'name': 'test_app_1',
+ 'description': 'a description',
+ 'manifestURL': 'http://example.com/1/manifest.webapp',
+ 'appStatus': 1}
+
+ webapp_2 = {'name': 'test_app_2',
+ 'description': 'another description',
+ 'manifestURL': 'http://example.com/2/manifest.webapp',
+ 'appStatus': 2}
+
+ webapp_3 = {'name': 'test_app_2',
+ 'description': 'a third description',
+ 'manifestURL': 'http://example.com/3/manifest.webapp',
+ 'appStatus': 3}
+
+ webapps = WebappCollection(self.profile)
+ self.assertEqual(len(webapps), 0)
+
+ # WebappCollection should behave like a list
+ def invalid_index():
+ webapps[0]
+ self.assertRaises(IndexError, invalid_index)
+
+ # Append a webapp object
+ webapps.append(webapp_1)
+ self.assertTrue(len(webapps), 1)
+ self.assertIsInstance(webapps[0], Webapp)
+ self.assertEqual(len(webapps[0]), len(webapp_1))
+ self.assertEqual(len(set(webapps[0].items()) & set(webapp_1.items())), len(webapp_1))
+
+ # Remove a webapp object
+ webapps.remove(webapp_1)
+ self.assertEqual(len(webapps), 0)
+
+ # Extend a list of webapp objects
+ webapps.extend([webapp_1, webapp_2])
+ self.assertEqual(len(webapps), 2)
+ self.assertTrue(webapp_1 in webapps)
+ self.assertTrue(webapp_2 in webapps)
+ self.assertNotEquals(webapps[0], webapps[1])
+
+ # Insert a webapp object
+ webapps.insert(1, webapp_3)
+ self.assertEqual(len(webapps), 3)
+ self.assertEqual(webapps[1], webapps[2])
+ for app in webapps:
+ self.assertIsInstance(app, Webapp)
+
+ # Assigning an invalid type (must be accepted by the dict() constructor) should throw
+ def invalid_type():
+ webapps[2] = 1
+ self.assertRaises(WebappFormatException, invalid_type)
+
+ def test_install_webapps(self):
+ """Test installing webapps into a profile that has no prior webapps"""
+ webapps = WebappCollection(self.profile, apps=self.manifest_path_1)
+ self.assertFalse(os.path.exists(self.webapps_dir))
+
+ # update the webapp manifests for the first time
+ webapps.update_manifests()
+ self.assertFalse(os.path.isdir(os.path.join(self.profile, webapps.backup_dir)))
+ self.assertTrue(os.path.isfile(self.webapps_json_path))
+
+ webapps_json = webapps.read_json(self.webapps_json_path, description="fake description")
+ self.assertEqual(len(webapps_json), 7)
+ for app in webapps_json:
+ self.assertIsInstance(app, Webapp)
+
+ manifest_json_1 = webapps.read_json(self.manifest_path_1)
+ manifest_json_2 = webapps.read_json(self.manifest_path_2)
+ self.assertEqual(len(webapps_json), len(manifest_json_1))
+ for app in webapps_json:
+ self.assertTrue(app in manifest_json_1)
+
+ # Remove one of the webapps from WebappCollection after it got installed
+ removed_app = manifest_json_1[2]
+ webapps.remove(removed_app)
+ # Add new webapps to the collection
+ webapps.extend(manifest_json_2)
+
+ # update the webapp manifests a second time
+ webapps.update_manifests()
+ self.assertFalse(os.path.isdir(os.path.join(self.profile, webapps.backup_dir)))
+ self.assertTrue(os.path.isfile(self.webapps_json_path))
+
+ webapps_json = webapps.read_json(self.webapps_json_path, description="a description")
+ self.assertEqual(len(webapps_json), 11)
+
+ # The new apps should be added
+ for app in webapps_json:
+ self.assertIsInstance(app, Webapp)
+ self.assertTrue(os.path.isfile(os.path.join(self.webapps_dir, app['name'],
+ 'manifest.webapp')))
+ # The removed app should not exist in the manifest
+ self.assertNotIn(removed_app, webapps_json)
+ self.assertFalse(os.path.exists(os.path.join(self.webapps_dir, removed_app['name'])))
+
+ # Cleaning should delete the webapps directory entirely
+ # since there was nothing there before
+ webapps.clean()
+ self.assertFalse(os.path.isdir(self.webapps_dir))
+
+ def test_install_webapps_preexisting(self):
+ """Tests installing webapps when the webapps directory already exists"""
+ manifest_json_2 = WebappCollection.read_json(self.manifest_path_2)
+
+ # Synthesize a pre-existing webapps directory
+ os.mkdir(self.webapps_dir)
+ shutil.copyfile(self.manifest_path_2, self.webapps_json_path)
+ for app in manifest_json_2:
+ app_path = os.path.join(self.webapps_dir, app['name'])
+ os.mkdir(app_path)
+ f = open(os.path.join(app_path, 'manifest.webapp'), 'w')
+ f.close()
+
+ webapps = WebappCollection(self.profile, apps=self.manifest_path_1)
+ self.assertTrue(os.path.exists(self.webapps_dir))
+
+ # update webapp manifests for the first time
+ webapps.update_manifests()
+ # A backup should be created
+ self.assertTrue(os.path.isdir(os.path.join(self.profile, webapps.backup_dir)))
+
+ # Both manifests should remain installed
+ webapps_json = webapps.read_json(self.webapps_json_path, description='a fake description')
+ self.assertEqual(len(webapps_json), 12)
+ for app in webapps_json:
+ self.assertIsInstance(app, Webapp)
+ self.assertTrue(os.path.isfile(os.path.join(self.webapps_dir, app['name'],
+ 'manifest.webapp')))
+
+ # Upon cleaning the backup should be restored
+ webapps.clean()
+ self.assertFalse(os.path.isdir(os.path.join(self.profile, webapps.backup_dir)))
+
+ # The original webapps should still be installed
+ webapps_json = webapps.read_json(self.webapps_json_path)
+ for app in webapps_json:
+ self.assertIsInstance(app, Webapp)
+ self.assertTrue(os.path.isfile(os.path.join(self.webapps_dir, app['name'],
+ 'manifest.webapp')))
+ self.assertEqual(webapps_json, manifest_json_2)
+
+if __name__ == '__main__':
+ unittest.main()