373 lines
11 KiB
Python
373 lines
11 KiB
Python
#!/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 zipfile
|
|
|
|
import mozprofile
|
|
import mozunit
|
|
import pytest
|
|
from addon_stubs import generate_addon
|
|
|
|
here = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
@pytest.fixture
|
|
def profile():
|
|
return mozprofile.Profile()
|
|
|
|
|
|
@pytest.fixture
|
|
def am(profile):
|
|
return profile.addons
|
|
|
|
|
|
def test_install_multiple_same_source(tmpdir, am):
|
|
path = tmpdir.strpath
|
|
|
|
# Generate installer stubs for all possible types of addons
|
|
addon_xpi = generate_addon("test-addon-1@mozilla.org", path=path)
|
|
addon_folder = generate_addon("test-addon-1@mozilla.org", path=path, xpi=False)
|
|
|
|
# The same folder should not be installed twice
|
|
am.install([addon_folder, addon_folder])
|
|
assert am.installed_addons == [addon_folder]
|
|
am.clean()
|
|
|
|
# The same XPI file should not be installed twice
|
|
am.install([addon_xpi, addon_xpi])
|
|
assert am.installed_addons == [addon_xpi]
|
|
am.clean()
|
|
|
|
# Even if it is the same id the add-on should be installed twice, if
|
|
# specified via XPI and folder
|
|
am.install([addon_folder, addon_xpi])
|
|
assert len(am.installed_addons) == 2
|
|
assert addon_folder in am.installed_addons
|
|
assert addon_xpi in am.installed_addons
|
|
am.clean()
|
|
|
|
|
|
def test_install_webextension_from_dir(tmpdir, am):
|
|
tmpdir = tmpdir.strpath
|
|
|
|
addon = os.path.join(here, "addons", "apply-css.xpi")
|
|
zipped = zipfile.ZipFile(addon)
|
|
try:
|
|
zipped.extractall(tmpdir)
|
|
finally:
|
|
zipped.close()
|
|
am.install(tmpdir)
|
|
assert len(am.installed_addons) == 1
|
|
assert os.path.isdir(am.installed_addons[0])
|
|
|
|
|
|
def test_install_webextension(am):
|
|
addon = os.path.join(here, "addons", "apply-css.xpi")
|
|
|
|
am.install(addon)
|
|
assert len(am.installed_addons) == 1
|
|
assert os.path.isfile(am.installed_addons[0])
|
|
assert "apply-css.xpi" == os.path.basename(am.installed_addons[0])
|
|
|
|
details = am.addon_details(am.installed_addons[0])
|
|
assert "test-webext@quality.mozilla.org" == details["id"]
|
|
|
|
|
|
def test_install_webextension_id_via_browser_specific_settings(am):
|
|
# See Bug 1572404
|
|
addon = os.path.join(
|
|
here, "addons", "apply-css-id-via-browser-specific-settings.xpi"
|
|
)
|
|
am.install(addon)
|
|
assert len(am.installed_addons) == 1
|
|
assert os.path.isfile(am.installed_addons[0])
|
|
assert "apply-css-id-via-browser-specific-settings.xpi" == os.path.basename(
|
|
am.installed_addons[0]
|
|
)
|
|
|
|
details = am.addon_details(am.installed_addons[0])
|
|
assert "test-webext@quality.mozilla.org" == details["id"]
|
|
|
|
|
|
def test_install_webextension_sans_id(am):
|
|
addon = os.path.join(here, "addons", "apply-css-sans-id.xpi")
|
|
am.install(addon)
|
|
|
|
assert len(am.installed_addons) == 1
|
|
assert os.path.isfile(am.installed_addons[0])
|
|
assert "apply-css-sans-id.xpi" == os.path.basename(am.installed_addons[0])
|
|
|
|
details = am.addon_details(am.installed_addons[0])
|
|
assert "@temporary-addon" in details["id"]
|
|
|
|
|
|
def test_install_xpi(tmpdir, am):
|
|
tmpdir = tmpdir.strpath
|
|
|
|
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=tmpdir)
|
|
addons_to_install.append(am.addon_details(temp_addon)["id"])
|
|
am.install(temp_addon)
|
|
|
|
# Generate a list of addons installed in the profile
|
|
addons_installed = [
|
|
str(x[: -len(".xpi")])
|
|
for x in os.listdir(os.path.join(am.profile, "extensions"))
|
|
]
|
|
assert addons_to_install.sort() == addons_installed.sort()
|
|
|
|
|
|
def test_install_folder(tmpdir, am):
|
|
tmpdir = tmpdir.strpath
|
|
|
|
# Generate installer stubs for all possible types of addons
|
|
addons = []
|
|
addons.append(generate_addon("test-addon-1@mozilla.org", path=tmpdir))
|
|
addons.append(generate_addon("test-addon-2@mozilla.org", path=tmpdir, xpi=False))
|
|
addons.append(
|
|
generate_addon("test-addon-3@mozilla.org", path=tmpdir, name="addon-3")
|
|
)
|
|
addons.append(
|
|
generate_addon(
|
|
"test-addon-4@mozilla.org", path=tmpdir, name="addon-4", xpi=False
|
|
)
|
|
)
|
|
addons.sort()
|
|
|
|
am.install(tmpdir)
|
|
|
|
assert am.installed_addons == addons
|
|
|
|
|
|
def test_install_unpack(tmpdir, am):
|
|
tmpdir = tmpdir.strpath
|
|
|
|
# Generate installer stubs for all possible types of addons
|
|
addon_xpi = generate_addon("test-addon-unpack@mozilla.org", path=tmpdir)
|
|
addon_folder = generate_addon(
|
|
"test-addon-unpack@mozilla.org", path=tmpdir, xpi=False
|
|
)
|
|
addon_no_unpack = generate_addon("test-addon-1@mozilla.org", path=tmpdir)
|
|
|
|
# Test unpack flag for add-on as XPI
|
|
am.install(addon_xpi)
|
|
assert am.installed_addons == [addon_xpi]
|
|
am.clean()
|
|
|
|
# Test unpack flag for add-on as folder
|
|
am.install(addon_folder)
|
|
assert am.installed_addons == [addon_folder]
|
|
am.clean()
|
|
|
|
# Test forcing unpack an add-on
|
|
am.install(addon_no_unpack, unpack=True)
|
|
assert am.installed_addons == [addon_no_unpack]
|
|
am.clean()
|
|
|
|
|
|
def test_install_after_reset(tmpdir, profile):
|
|
tmpdir = tmpdir.strpath
|
|
am = profile.addons
|
|
|
|
# Installing the same add-on after a reset should not cause a failure
|
|
addon = generate_addon("test-addon-1@mozilla.org", path=tmpdir, xpi=False)
|
|
|
|
# We cannot use am because profile.reset() creates a new instance
|
|
am.install(addon)
|
|
profile.reset()
|
|
|
|
am.install(addon)
|
|
assert am.installed_addons == [addon]
|
|
|
|
|
|
def test_install_backup(tmpdir, am):
|
|
tmpdir = tmpdir.strpath
|
|
|
|
staged_path = os.path.join(am.profile, "extensions")
|
|
|
|
# Generate installer stubs for all possible types of addons
|
|
addon_xpi = generate_addon("test-addon-1@mozilla.org", path=tmpdir)
|
|
addon_folder = generate_addon("test-addon-1@mozilla.org", path=tmpdir, xpi=False)
|
|
addon_name = generate_addon(
|
|
"test-addon-1@mozilla.org", path=tmpdir, name="test-addon-1-dupe@mozilla.org"
|
|
)
|
|
|
|
# Test backup of xpi files
|
|
am.install(addon_xpi)
|
|
assert am.backup_dir is None
|
|
|
|
am.install(addon_xpi)
|
|
assert am.backup_dir is not None
|
|
assert os.listdir(am.backup_dir) == ["test-addon-1@mozilla.org.xpi"]
|
|
|
|
am.clean()
|
|
assert os.listdir(staged_path) == ["test-addon-1@mozilla.org.xpi"]
|
|
am.clean()
|
|
|
|
# Test backup of folders
|
|
am.install(addon_folder)
|
|
assert am.backup_dir is None
|
|
|
|
am.install(addon_folder)
|
|
assert am.backup_dir is not None
|
|
assert os.listdir(am.backup_dir) == ["test-addon-1@mozilla.org"]
|
|
|
|
am.clean()
|
|
assert os.listdir(staged_path) == ["test-addon-1@mozilla.org"]
|
|
am.clean()
|
|
|
|
# Test backup of xpi files with another file name
|
|
am.install(addon_name)
|
|
assert am.backup_dir is None
|
|
|
|
am.install(addon_xpi)
|
|
assert am.backup_dir is not None
|
|
assert os.listdir(am.backup_dir) == ["test-addon-1@mozilla.org.xpi"]
|
|
|
|
am.clean()
|
|
assert os.listdir(staged_path) == ["test-addon-1@mozilla.org.xpi"]
|
|
am.clean()
|
|
|
|
|
|
def test_install_invalid_addons(tmpdir, am):
|
|
tmpdir = tmpdir.strpath
|
|
|
|
# Generate installer stubs for all possible types of addons
|
|
addons = []
|
|
addons.append(
|
|
generate_addon(
|
|
"test-addon-invalid-no-manifest@mozilla.org", path=tmpdir, xpi=False
|
|
)
|
|
)
|
|
addons.append(generate_addon("test-addon-invalid-no-id@mozilla.org", path=tmpdir))
|
|
|
|
am.install(tmpdir)
|
|
|
|
assert am.installed_addons == []
|
|
|
|
|
|
@pytest.mark.xfail(reason="feature not implemented as part of AddonManger")
|
|
def test_install_error(am):
|
|
"""Check install raises an error with an invalid addon"""
|
|
temp_addon = generate_addon("test-addon-invalid-version@mozilla.org")
|
|
# This should raise an error here
|
|
with pytest.raises(Exception):
|
|
am.install(temp_addon)
|
|
|
|
|
|
def test_addon_details(tmpdir, am):
|
|
tmpdir = tmpdir.strpath
|
|
|
|
# Generate installer stubs for a valid and invalid add-on manifest
|
|
valid_addon = generate_addon("test-addon-1@mozilla.org", path=tmpdir)
|
|
invalid_addon = generate_addon(
|
|
"test-addon-invalid-not-wellformed@mozilla.org", path=tmpdir
|
|
)
|
|
|
|
# Check valid add-on
|
|
details = am.addon_details(valid_addon)
|
|
assert details["id"] == "test-addon-1@mozilla.org"
|
|
assert details["name"] == "Test Add-on 1"
|
|
assert not details["unpack"]
|
|
assert details["version"] == "0.1"
|
|
|
|
# Check invalid add-on
|
|
with pytest.raises(mozprofile.addons.AddonFormatError):
|
|
am.addon_details(invalid_addon)
|
|
|
|
# Check invalid path
|
|
with pytest.raises(IOError):
|
|
am.addon_details("")
|
|
|
|
# Check invalid add-on format
|
|
addon_path = os.path.join(os.path.join(here, "files"), "not_an_addon.txt")
|
|
with pytest.raises(mozprofile.addons.AddonFormatError):
|
|
am.addon_details(addon_path)
|
|
|
|
|
|
def test_clean_addons(am):
|
|
addon_one = generate_addon("test-addon-1@mozilla.org")
|
|
addon_two = generate_addon("test-addon-2@mozilla.org")
|
|
|
|
am.install(addon_one)
|
|
installed_addons = [
|
|
str(x[: -len(".xpi")])
|
|
for x in os.listdir(os.path.join(am.profile, "extensions"))
|
|
]
|
|
|
|
# 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=am.profile, addons=addon_two)
|
|
duplicate_profile.addons.clean()
|
|
|
|
addons_after_cleanup = [
|
|
str(x[: -len(".xpi")])
|
|
for x in os.listdir(os.path.join(duplicate_profile.profile, "extensions"))
|
|
]
|
|
# New addons installed should be removed by clean_addons()
|
|
assert installed_addons == addons_after_cleanup
|
|
|
|
|
|
def test_noclean(tmpdir):
|
|
"""test `restore=True/False` functionality"""
|
|
profile = tmpdir.mkdtemp().strpath
|
|
tmpdir = tmpdir.mkdtemp().strpath
|
|
|
|
# empty initially
|
|
assert not bool(os.listdir(profile))
|
|
|
|
# make an addon
|
|
addons = [
|
|
generate_addon("test-addon-1@mozilla.org", path=tmpdir),
|
|
os.path.join(here, "addons", "empty.xpi"),
|
|
]
|
|
|
|
# install it with a restore=True AddonManager
|
|
am = mozprofile.addons.AddonManager(profile, restore=True)
|
|
|
|
for addon in addons:
|
|
am.install(addon)
|
|
|
|
# now its there
|
|
assert os.listdir(profile) == ["extensions"]
|
|
staging_folder = os.path.join(profile, "extensions")
|
|
assert os.path.exists(staging_folder)
|
|
assert len(os.listdir(staging_folder)) == 2
|
|
|
|
del am
|
|
|
|
assert os.listdir(profile) == ["extensions"]
|
|
assert os.path.exists(staging_folder)
|
|
assert os.listdir(staging_folder) == []
|
|
|
|
|
|
def test_remove_addon(tmpdir, am):
|
|
tmpdir = tmpdir.strpath
|
|
|
|
addons = []
|
|
addons.append(generate_addon("test-addon-1@mozilla.org", path=tmpdir))
|
|
addons.append(generate_addon("test-addon-2@mozilla.org", path=tmpdir))
|
|
|
|
am.install(tmpdir)
|
|
|
|
extensions_path = os.path.join(am.profile, "extensions")
|
|
staging_path = os.path.join(extensions_path)
|
|
|
|
for addon in am._addons:
|
|
am.remove_addon(addon)
|
|
|
|
assert os.listdir(staging_path) == []
|
|
assert os.listdir(extensions_path) == []
|
|
|
|
|
|
if __name__ == "__main__":
|
|
mozunit.main()
|