#!/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 mozfile
import mozunit
import pytest
from mozprofile.cli
import MozProfileCLI
from mozprofile.prefs
import Preferences, PreferencesReadError
from mozprofile.profile
import Profile
from wptserve
import server
here = os.path.dirname(os.path.abspath(__file__))
# 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",
}
@pytest.fixture
def run_command():
"""
invokes mozprofile command line via the CLI factory
- args : command line arguments (equivalent of sys.argv[1:])
"""
def inner(*args):
# instantiate the factory
cli = MozProfileCLI(list(args))
# create the profile
profile = cli.profile()
# return path to profile
return profile.profile
return inner
@pytest.fixture
def compare_generated(run_command):
"""
writes out to a new profile
with mozprofile command line
reads the generated preferences
with prefs.py
compares the results
cleans up
"""
def inner(prefs, commandline):
profile = run_command(*commandline)
prefs_file = os.path.join(profile,
"user.js")
assert os.path.exists(prefs_file)
read = Preferences.read_prefs(prefs_file)
if isinstance(prefs, dict):
read = dict(read)
assert prefs == read
shutil.rmtree(profile)
return inner
def test_basic_prefs(compare_generated):
"""test setting a pref from the command line entry point"""
_prefs = {
"browser.startup.homepage":
"http://planet.mozilla.org/"}
commandline = []
for pref, value
in _prefs.items():
commandline += [
"--pref",
"%s:%s" % (pref, value)]
compare_generated(_prefs, commandline)
def test_ordered_prefs(compare_generated):
"""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]
compare_generated(_prefs, commandline)
def test_ini(compare_generated):
# 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", text=
True)
os.write(fd, _ini.encode())
os.close(fd)
commandline = [
"--preferences", name]
# test the [DEFAULT] section
_prefs = {
"browser.startup.homepage":
"http://planet.mozilla.org/"}
compare_generated(_prefs, commandline)
# test a specific section
_prefs = {
"browser.startup.homepage":
"http://github.com/"}
commandline[-1] = commandline[-1] +
":foo"
compare_generated(_prefs, commandline)
finally:
# cleanup
os.remove(name)
def test_ini_keep_case(compare_generated):
"""
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]
network.dns.disableIPv6 =
True
"""
try:
fd, name = tempfile.mkstemp(suffix=
".ini", text=
True)
os.write(fd, _ini.encode())
os.close(fd)
commandline = [
"--preferences", name]
# test the [DEFAULT] section
_prefs = {
"network.dns.disableIPv6":
"True"}
compare_generated(_prefs, commandline)
finally:
# cleanup
os.remove(name)
def test_reset_should_remove_added_prefs():
"""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)
assert not initial_prefs
initial_prefs = open(prefs_file).read().strip()
assert not initial_prefs
# add some preferences
prefs1 = [(
"mr.t.quotes",
"i aint getting on no plane!")]
profile.set_preferences(prefs1)
assert prefs1 == Preferences.read_prefs(prefs_file)
lines = open(prefs_file).read().strip().splitlines()
assert any(line.startswith(
"#MozRunner Prefs Start") for line in lines)
assert any(line.startswith(
"#MozRunner Prefs End") for line in lines)
profile.reset()
assert prefs1 != Preferences.read_prefs(os.path.join(profile.profile,
"user.js"))
def test_reset_should_keep_user_added_prefs():
"""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)
assert not initial_prefs
initial_prefs = open(prefs_file).read().strip()
assert not initial_prefs
# add some preferences
prefs1 = [(
"mr.t.quotes",
"i aint getting on no plane!")]
profile.set_persistent_preferences(prefs1)
assert prefs1 == Preferences.read_prefs(prefs_file)
lines = open(prefs_file).read().strip().splitlines()
assert any(line.startswith(
"#MozRunner Prefs Start") for line in lines)
assert any(line.startswith(
"#MozRunner Prefs End") for line in lines)
profile.reset()
assert prefs1 == Preferences.read_prefs(os.path.join(profile.profile,
"user.js"))
def test_magic_markers():
"""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)
assert not initial_prefs
initial_prefs = open(prefs_file).read().strip()
assert not initial_prefs
# add some preferences
prefs1 = [
(
"browser.startup.homepage",
"http://planet.mozilla.org/"),
(
"zoom.minPercent", 30),
]
profile.set_preferences(prefs1)
assert prefs1 == Preferences.read_prefs(prefs_file)
lines = open(prefs_file).read().strip().splitlines()
assert bool([line
for line
in lines
if line.startswith(
"#MozRunner Prefs Start")])
assert 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)
assert prefs1 + prefs2 == Preferences.read_prefs(prefs_file)
lines = open(prefs_file).read().strip().splitlines()
assert (
len([line
for line
in lines
if line.startswith(
"#MozRunner Prefs Start")]) == 2
)
assert 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)
assert not final_prefs
lines = open(prefs_file).read().strip().splitlines()
assert "#MozRunner Prefs Start" not in lines
assert "#MozRunner Prefs End" not in lines
def test_preexisting_preferences():
"""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 = open(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),
]
assert 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)
assert 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)
assert prefs == original_prefs
finally:
shutil.rmtree(tempdir)
def test_can_read_prefs_with_multiline_comments():
"""
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)
try:
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);
""".encode()
)
assert Preferences.read_prefs(user_js.name) == [
(
"webgl.enabled_for_all_sites",
True),
(
"webgl.force-enabled",
True),
]
finally:
mozfile.remove(user_js.name)
def test_json(compare_generated):
_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.encode())
f.flush()
commandline = [
"--preferences", f.name]
compare_generated(_prefs, commandline)
def test_json_datatypes():
# minPercent is at 30.1 to test if non-integer data raises an exception
json =
"""{"zoom.minPercent
": 30.1, "zoom.maxPercent
": 300}"""
with mozfile.NamedTemporaryFile(suffix=
".json")
as f:
f.write(json.encode())
f.flush()
with pytest.raises(PreferencesReadError):
Preferences.read_json(f._path)
def test_prefs_write():
"""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, mode=
"w+t")
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)
assert read_prefs == _prefs
def test_read_prefs_with_comments():
"""test reading preferences from a prefs.js file that contains comments"""
path = os.path.join(here,
"files",
"prefs_with_comments.js")
assert dict(Preferences.read_prefs(path)) == _prefs_with_comments
def test_read_prefs_with_interpolation():
"""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)
assert dict(read_prefs) == expected_prefs
def test_read_prefs_with_multiline():
"""test reading preferences from a prefs.js file that contains multiline prefs"""
path = os.path.join(here,
"files",
"prefs_with_multiline.js")
assert dict(Preferences.read_prefs(path)) == {
"browser.long.preference.name.that.causes.the.line.to.wrap":
"itislong"
}
def test_read_prefs_ttw():
"""test reading preferences through the web via wptserve"""
# create a WebTestHttpd instance
docroot = os.path.join(here,
"files")
host =
"127.0.0.1"
port = 8888
httpd = server.WebTestHttpd(host=host, port=port, doc_root=docroot)
# create a preferences instance
prefs = Preferences()
try:
# start server
httpd.start()
# read preferences through the web
read = prefs.read_prefs(
"http://%s:%d/prefs_with_comments.js" % (host, port))
assert dict(read) == _prefs_with_comments
finally:
httpd.stop()
if __name__ ==
"__main__":
mozunit.main()