tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_addons.py (11227B)


      1 #!/usr/bin/env python
      2 
      3 # This Source Code Form is subject to the terms of the Mozilla Public
      4 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 # You can obtain one at http://mozilla.org/MPL/2.0/.
      6 
      7 import os
      8 import zipfile
      9 
     10 import mozprofile
     11 import mozunit
     12 import pytest
     13 from addon_stubs import generate_addon
     14 
     15 here = os.path.dirname(os.path.abspath(__file__))
     16 
     17 
     18 @pytest.fixture
     19 def profile():
     20    return mozprofile.Profile()
     21 
     22 
     23 @pytest.fixture
     24 def am(profile):
     25    return profile.addons
     26 
     27 
     28 def test_install_multiple_same_source(tmpdir, am):
     29    path = tmpdir.strpath
     30 
     31    # Generate installer stubs for all possible types of addons
     32    addon_xpi = generate_addon("test-addon-1@mozilla.org", path=path)
     33    addon_folder = generate_addon("test-addon-1@mozilla.org", path=path, xpi=False)
     34 
     35    # The same folder should not be installed twice
     36    am.install([addon_folder, addon_folder])
     37    assert am.installed_addons == [addon_folder]
     38    am.clean()
     39 
     40    # The same XPI file should not be installed twice
     41    am.install([addon_xpi, addon_xpi])
     42    assert am.installed_addons == [addon_xpi]
     43    am.clean()
     44 
     45    # Even if it is the same id the add-on should be installed twice, if
     46    # specified via XPI and folder
     47    am.install([addon_folder, addon_xpi])
     48    assert len(am.installed_addons) == 2
     49    assert addon_folder in am.installed_addons
     50    assert addon_xpi in am.installed_addons
     51    am.clean()
     52 
     53 
     54 def test_install_webextension_from_dir(tmpdir, am):
     55    tmpdir = tmpdir.strpath
     56 
     57    addon = os.path.join(here, "addons", "apply-css.xpi")
     58    zipped = zipfile.ZipFile(addon)
     59    try:
     60        zipped.extractall(tmpdir)
     61    finally:
     62        zipped.close()
     63    am.install(tmpdir)
     64    assert len(am.installed_addons) == 1
     65    assert os.path.isdir(am.installed_addons[0])
     66 
     67 
     68 def test_install_webextension(am):
     69    addon = os.path.join(here, "addons", "apply-css.xpi")
     70 
     71    am.install(addon)
     72    assert len(am.installed_addons) == 1
     73    assert os.path.isfile(am.installed_addons[0])
     74    assert "apply-css.xpi" == os.path.basename(am.installed_addons[0])
     75 
     76    details = am.addon_details(am.installed_addons[0])
     77    assert "test-webext@quality.mozilla.org" == details["id"]
     78 
     79 
     80 def test_install_webextension_id_via_browser_specific_settings(am):
     81    # See Bug 1572404
     82    addon = os.path.join(
     83        here, "addons", "apply-css-id-via-browser-specific-settings.xpi"
     84    )
     85    am.install(addon)
     86    assert len(am.installed_addons) == 1
     87    assert os.path.isfile(am.installed_addons[0])
     88    assert "apply-css-id-via-browser-specific-settings.xpi" == os.path.basename(
     89        am.installed_addons[0]
     90    )
     91 
     92    details = am.addon_details(am.installed_addons[0])
     93    assert "test-webext@quality.mozilla.org" == details["id"]
     94 
     95 
     96 def test_install_webextension_sans_id(am):
     97    addon = os.path.join(here, "addons", "apply-css-sans-id.xpi")
     98    am.install(addon)
     99 
    100    assert len(am.installed_addons) == 1
    101    assert os.path.isfile(am.installed_addons[0])
    102    assert "apply-css-sans-id.xpi" == os.path.basename(am.installed_addons[0])
    103 
    104    details = am.addon_details(am.installed_addons[0])
    105    assert "@temporary-addon" in details["id"]
    106 
    107 
    108 def test_install_xpi(tmpdir, am):
    109    tmpdir = tmpdir.strpath
    110 
    111    addons_to_install = []
    112    addons_installed = []
    113 
    114    # Generate installer stubs and install them
    115    for ext in ["test-addon-1@mozilla.org", "test-addon-2@mozilla.org"]:
    116        temp_addon = generate_addon(ext, path=tmpdir)
    117        addons_to_install.append(am.addon_details(temp_addon)["id"])
    118        am.install(temp_addon)
    119 
    120    # Generate a list of addons installed in the profile
    121    addons_installed = [
    122        str(x[: -len(".xpi")])
    123        for x in os.listdir(os.path.join(am.profile, "extensions"))
    124    ]
    125    assert addons_to_install.sort() == addons_installed.sort()
    126 
    127 
    128 def test_install_folder(tmpdir, am):
    129    tmpdir = tmpdir.strpath
    130 
    131    # Generate installer stubs for all possible types of addons
    132    addons = []
    133    addons.append(generate_addon("test-addon-1@mozilla.org", path=tmpdir))
    134    addons.append(generate_addon("test-addon-2@mozilla.org", path=tmpdir, xpi=False))
    135    addons.append(
    136        generate_addon("test-addon-3@mozilla.org", path=tmpdir, name="addon-3")
    137    )
    138    addons.append(
    139        generate_addon(
    140            "test-addon-4@mozilla.org", path=tmpdir, name="addon-4", xpi=False
    141        )
    142    )
    143    addons.sort()
    144 
    145    am.install(tmpdir)
    146 
    147    assert am.installed_addons == addons
    148 
    149 
    150 def test_install_unpack(tmpdir, am):
    151    tmpdir = tmpdir.strpath
    152 
    153    # Generate installer stubs for all possible types of addons
    154    addon_xpi = generate_addon("test-addon-unpack@mozilla.org", path=tmpdir)
    155    addon_folder = generate_addon(
    156        "test-addon-unpack@mozilla.org", path=tmpdir, xpi=False
    157    )
    158    addon_no_unpack = generate_addon("test-addon-1@mozilla.org", path=tmpdir)
    159 
    160    # Test unpack flag for add-on as XPI
    161    am.install(addon_xpi)
    162    assert am.installed_addons == [addon_xpi]
    163    am.clean()
    164 
    165    # Test unpack flag for add-on as folder
    166    am.install(addon_folder)
    167    assert am.installed_addons == [addon_folder]
    168    am.clean()
    169 
    170    # Test forcing unpack an add-on
    171    am.install(addon_no_unpack, unpack=True)
    172    assert am.installed_addons == [addon_no_unpack]
    173    am.clean()
    174 
    175 
    176 def test_install_after_reset(tmpdir, profile):
    177    tmpdir = tmpdir.strpath
    178    am = profile.addons
    179 
    180    # Installing the same add-on after a reset should not cause a failure
    181    addon = generate_addon("test-addon-1@mozilla.org", path=tmpdir, xpi=False)
    182 
    183    # We cannot use am because profile.reset() creates a new instance
    184    am.install(addon)
    185    profile.reset()
    186 
    187    am.install(addon)
    188    assert am.installed_addons == [addon]
    189 
    190 
    191 def test_install_backup(tmpdir, am):
    192    tmpdir = tmpdir.strpath
    193 
    194    staged_path = os.path.join(am.profile, "extensions")
    195 
    196    # Generate installer stubs for all possible types of addons
    197    addon_xpi = generate_addon("test-addon-1@mozilla.org", path=tmpdir)
    198    addon_folder = generate_addon("test-addon-1@mozilla.org", path=tmpdir, xpi=False)
    199    addon_name = generate_addon(
    200        "test-addon-1@mozilla.org", path=tmpdir, name="test-addon-1-dupe@mozilla.org"
    201    )
    202 
    203    # Test backup of xpi files
    204    am.install(addon_xpi)
    205    assert am.backup_dir is None
    206 
    207    am.install(addon_xpi)
    208    assert am.backup_dir is not None
    209    assert os.listdir(am.backup_dir) == ["test-addon-1@mozilla.org.xpi"]
    210 
    211    am.clean()
    212    assert os.listdir(staged_path) == ["test-addon-1@mozilla.org.xpi"]
    213    am.clean()
    214 
    215    # Test backup of folders
    216    am.install(addon_folder)
    217    assert am.backup_dir is None
    218 
    219    am.install(addon_folder)
    220    assert am.backup_dir is not None
    221    assert os.listdir(am.backup_dir) == ["test-addon-1@mozilla.org"]
    222 
    223    am.clean()
    224    assert os.listdir(staged_path) == ["test-addon-1@mozilla.org"]
    225    am.clean()
    226 
    227    # Test backup of xpi files with another file name
    228    am.install(addon_name)
    229    assert am.backup_dir is None
    230 
    231    am.install(addon_xpi)
    232    assert am.backup_dir is not None
    233    assert os.listdir(am.backup_dir) == ["test-addon-1@mozilla.org.xpi"]
    234 
    235    am.clean()
    236    assert os.listdir(staged_path) == ["test-addon-1@mozilla.org.xpi"]
    237    am.clean()
    238 
    239 
    240 def test_install_invalid_addons(tmpdir, am):
    241    tmpdir = tmpdir.strpath
    242 
    243    # Generate installer stubs for all possible types of addons
    244    addons = []
    245    addons.append(
    246        generate_addon(
    247            "test-addon-invalid-no-manifest@mozilla.org", path=tmpdir, xpi=False
    248        )
    249    )
    250    addons.append(generate_addon("test-addon-invalid-no-id@mozilla.org", path=tmpdir))
    251 
    252    am.install(tmpdir)
    253 
    254    assert am.installed_addons == []
    255 
    256 
    257 @pytest.mark.xfail(reason="feature not implemented as part of AddonManger")
    258 def test_install_error(am):
    259    """Check install raises an error with an invalid addon"""
    260    temp_addon = generate_addon("test-addon-invalid-version@mozilla.org")
    261    # This should raise an error here
    262    with pytest.raises(Exception):
    263        am.install(temp_addon)
    264 
    265 
    266 def test_addon_details(tmpdir, am):
    267    tmpdir = tmpdir.strpath
    268 
    269    # Generate installer stubs for a valid and invalid add-on manifest
    270    valid_addon = generate_addon("test-addon-1@mozilla.org", path=tmpdir)
    271    invalid_addon = generate_addon(
    272        "test-addon-invalid-not-wellformed@mozilla.org", path=tmpdir
    273    )
    274 
    275    # Check valid add-on
    276    details = am.addon_details(valid_addon)
    277    assert details["id"] == "test-addon-1@mozilla.org"
    278    assert details["name"] == "Test Add-on 1"
    279    assert not details["unpack"]
    280    assert details["version"] == "0.1"
    281 
    282    # Check invalid add-on
    283    with pytest.raises(mozprofile.addons.AddonFormatError):
    284        am.addon_details(invalid_addon)
    285 
    286    # Check invalid path
    287    with pytest.raises(IOError):
    288        am.addon_details("")
    289 
    290    # Check invalid add-on format
    291    addon_path = os.path.join(os.path.join(here, "files"), "not_an_addon.txt")
    292    with pytest.raises(mozprofile.addons.AddonFormatError):
    293        am.addon_details(addon_path)
    294 
    295 
    296 def test_clean_addons(am):
    297    addon_one = generate_addon("test-addon-1@mozilla.org")
    298    addon_two = generate_addon("test-addon-2@mozilla.org")
    299 
    300    am.install(addon_one)
    301    installed_addons = [
    302        str(x[: -len(".xpi")])
    303        for x in os.listdir(os.path.join(am.profile, "extensions"))
    304    ]
    305 
    306    # Create a new profile based on an existing profile
    307    # Install an extra addon in the new profile
    308    # Cleanup addons
    309    duplicate_profile = mozprofile.profile.Profile(profile=am.profile, addons=addon_two)
    310    duplicate_profile.addons.clean()
    311 
    312    addons_after_cleanup = [
    313        str(x[: -len(".xpi")])
    314        for x in os.listdir(os.path.join(duplicate_profile.profile, "extensions"))
    315    ]
    316    # New addons installed should be removed by clean_addons()
    317    assert installed_addons == addons_after_cleanup
    318 
    319 
    320 def test_noclean(tmpdir):
    321    """test `restore=True/False` functionality"""
    322    profile = tmpdir.mkdtemp().strpath
    323    tmpdir = tmpdir.mkdtemp().strpath
    324 
    325    # empty initially
    326    assert not bool(os.listdir(profile))
    327 
    328    # make an addon
    329    addons = [
    330        generate_addon("test-addon-1@mozilla.org", path=tmpdir),
    331        os.path.join(here, "addons", "empty.xpi"),
    332    ]
    333 
    334    # install it with a restore=True AddonManager
    335    am = mozprofile.addons.AddonManager(profile, restore=True)
    336 
    337    for addon in addons:
    338        am.install(addon)
    339 
    340    # now its there
    341    assert os.listdir(profile) == ["extensions"]
    342    staging_folder = os.path.join(profile, "extensions")
    343    assert os.path.exists(staging_folder)
    344    assert len(os.listdir(staging_folder)) == 2
    345 
    346    del am
    347 
    348    assert os.listdir(profile) == ["extensions"]
    349    assert os.path.exists(staging_folder)
    350    assert os.listdir(staging_folder) == []
    351 
    352 
    353 def test_remove_addon(tmpdir, am):
    354    tmpdir = tmpdir.strpath
    355 
    356    addons = []
    357    addons.append(generate_addon("test-addon-1@mozilla.org", path=tmpdir))
    358    addons.append(generate_addon("test-addon-2@mozilla.org", path=tmpdir))
    359 
    360    am.install(tmpdir)
    361 
    362    extensions_path = os.path.join(am.profile, "extensions")
    363    staging_path = os.path.join(extensions_path)
    364 
    365    for addon in am._addons:
    366        am.remove_addon(addon)
    367 
    368    assert os.listdir(staging_path) == []
    369    assert os.listdir(extensions_path) == []
    370 
    371 
    372 if __name__ == "__main__":
    373    mozunit.main()