diff options
Diffstat (limited to 'testing/mozbase/mozprofile/tests/test_addons.py')
-rw-r--r-- | testing/mozbase/mozprofile/tests/test_addons.py | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/testing/mozbase/mozprofile/tests/test_addons.py b/testing/mozbase/mozprofile/tests/test_addons.py new file mode 100644 index 0000000000..f6b79ce498 --- /dev/null +++ b/testing/mozbase/mozprofile/tests/test_addons.py @@ -0,0 +1,373 @@ +#!/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() |