def test_filtering_by_name(self, api_client, storage): matching_extension = ExtensionFactory() ExtensionFactory() # Generate another extension that will not match res = api_client.get(f"/api/v3/extension/?text={matching_extension.name}") assert res.status_code == 200 assert [ext["name"] for ext in res.data["results"]] == [matching_extension.name]
def test_can_update_without_xpi(self, api_client, storage): xpi = WebExtensionFileFactory() e = ExtensionFactory(xpi__from_func=xpi.open) res = api_client.patch(f"/api/v3/extension/{e.id}/", {"name": "new name"}) assert res.status_code == 200 e.refresh_from_db() assert e.name == "new name"
def test_it_works_for_multiple_extensions(self, storage): extension1 = ExtensionFactory(name="1.xpi") extension2 = ExtensionFactory(name="2.xpi") fake_old_url1 = extension1.xpi.url.replace("/media/", "/media-old/") fake_old_url2 = extension2.xpi.url.replace("/media/", "/media-old/") action = ActionFactory(name="opt-out-study") recipe1 = RecipeFactory(action=action, arguments={ "name": "1", addonUrl: fake_old_url1 }) recipe2 = RecipeFactory(action=action, arguments={ "name": "2", addonUrl: fake_old_url2 }) call_command("update_addon_urls") # For reasons that I don't understand, recipe.update_from_db() doesn't work here. recipe1 = Recipe.objects.get(id=recipe1.id) recipe2 = Recipe.objects.get(id=recipe2.id) assert recipe1.arguments[addonUrl] == extension1.xpi.url assert recipe2.arguments[addonUrl] == extension2.xpi.url
def test_can_update_without_xpi(self, api_client, storage): e = ExtensionFactory( xpi__from_path=self.data_path("webext-signed.xpi")) res = api_client.patch(f"/api/v3/extension/{e.id}/", {"name": "new name"}) assert res.status_code == 200 e.refresh_from_db() assert e.name == "new name"
def test_can_update_xpi(self, api_client, storage): e = ExtensionFactory( xpi__from_path=self.data_path("legacy-signed.xpi")) path = self.data_path("webext-signed.xpi") res = self._update_extension(api_client, e.id, path) assert res.status_code == 200 e.refresh_from_db() assert e.xpi.name.endswith("webext-signed.xpi")
def test_filtering_by_xpi(self, api_client, storage): matching_extension = ExtensionFactory() ExtensionFactory() # Generate another extension that will not match res = api_client.get(f"/api/v3/extension/?text={matching_extension.xpi}") assert res.status_code == 200 expected_path = matching_extension.xpi.url assert [urlparse(ext["xpi"]).path for ext in res.data["results"]] == [expected_path]
def test_filtering_by_name(self, api_client): matching_extension = ExtensionFactory() ExtensionFactory() # Generate another extension that will not match res = api_client.get( f'/api/v2/extension/?text={matching_extension.name}') assert res.status_code == 200 assert [ext['name'] for ext in res.data['results']] == [matching_extension.name]
def test_can_update_xpi(self, api_client, storage): legacy = LegacyAddonFileFactory() e = ExtensionFactory(xpi__from_func=legacy.open) webext = WebExtensionFileFactory() _, filename = os.path.split(webext.path) res = self._update_extension(api_client, e.id, webext.path) assert res.status_code == 200 e.refresh_from_db() assert e.xpi.name.endswith(filename)
def test_cannot_update_in_use_extension(self, api_client, storage): xpi = WebExtensionFileFactory() e = ExtensionFactory(xpi__from_func=xpi.open) a = ActionFactory(name="opt-out-study") RecipeFactory(action=a, arguments={"extensionId": e.id}) res = api_client.patch(f"/api/v3/extension/{e.id}/", {"name": "new name"}) assert res.status_code == 400 assert res.data == ["Extension cannot be updated while in use by a recipe."] e.refresh_from_db() assert e.name != "new name"
def test_cannot_update_extension_duplicate_filename(self, api_client, storage): xpi1 = WebExtensionFileFactory() ExtensionFactory(xpi__from_func=xpi1.open) xpi2 = WebExtensionFileFactory() e = ExtensionFactory(xpi__from_func=xpi2.open) with transaction.atomic(): res = self._update_extension(api_client, e.id, xpi1.path) assert res.status_code == 400 assert res.data == {"xpi": "An extension with this filename already exists."}
def test_order_name(self, api_client): e1 = ExtensionFactory(name="a") e2 = ExtensionFactory(name="b") res = api_client.get(f'/api/v2/extension/?ordering=name') assert res.status_code == 200 assert [r['id'] for r in res.data['results']] == [e1.id, e2.id] res = api_client.get(f'/api/v2/extension/?ordering=-name') assert res.status_code == 200 assert [r['id'] for r in res.data['results']] == [e2.id, e1.id]
def test_order_name(self, api_client, storage): e1 = ExtensionFactory(name="a") e2 = ExtensionFactory(name="b") res = api_client.get(f"/api/v3/extension/?ordering=name") assert res.status_code == 200 assert [r["id"] for r in res.data["results"]] == [e1.id, e2.id] res = api_client.get(f"/api/v3/extension/?ordering=-name") assert res.status_code == 200 assert [r["id"] for r in res.data["results"]] == [e2.id, e1.id]
def test_order_id(self, api_client, storage): e1 = ExtensionFactory() e2 = ExtensionFactory() assert e1.id < e2.id res = api_client.get(f"/api/v3/extension/?ordering=id") assert res.status_code == 200 assert [r["id"] for r in res.data["results"]] == [e1.id, e2.id] res = api_client.get(f"/api/v3/extension/?ordering=-id") assert res.status_code == 200 assert [r["id"] for r in res.data["results"]] == [e2.id, e1.id]
def test_order_id(self, api_client): e1 = ExtensionFactory() e2 = ExtensionFactory() assert e1.id < e2.id res = api_client.get(f'/api/v2/extension/?ordering=id') assert res.status_code == 200 assert [r['id'] for r in res.data['results']] == [e1.id, e2.id] res = api_client.get(f'/api/v2/extension/?ordering=-id') assert res.status_code == 200 assert [r['id'] for r in res.data['results']] == [e2.id, e1.id]
def test_order_bogus(self, api_client): """Test that filtering by an unknown key doesn't change the sort order""" ExtensionFactory() ExtensionFactory() res = api_client.get(f'/api/v2/extension/?ordering=bogus') assert res.status_code == 200 first_ordering = [r['id'] for r in res.data['results']] res = api_client.get(f'/api/v2/extension/?ordering=-bogus') assert res.status_code == 200 assert [r['id'] for r in res.data['results']] == first_ordering
def test_xpi_must_be_signed(self): with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_path=data_path("webext-unsigned.xpi")) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == "Extension file must be signed." with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_path=data_path("legacy-unsigned.xpi")) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == "Extension file must be signed."
def test_order_bogus(self, api_client, storage): """Test that filtering by an unknown key doesn't change the sort order""" ExtensionFactory() ExtensionFactory() res = api_client.get(f"/api/v3/extension/?ordering=bogus") assert res.status_code == 200 first_ordering = [r["id"] for r in res.data["results"]] res = api_client.get(f"/api/v3/extension/?ordering=-bogus") assert res.status_code == 200 assert [r["id"] for r in res.data["results"]] == first_ordering
def test_xpi_must_be_signed(self): xpi = WebExtensionFileFactory(signed=False) with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_func=xpi.open) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == "Extension file must be signed." xpi = LegacyAddonFileFactory(signed=False) with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_func=xpi.open) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == "Extension file must be signed."
def test_webext_no_version(self): with pytest.raises(ValidationError) as exc: ExtensionFactory( xpi__from_path=data_path("webext-no-version-unsigned.xpi")) assert len(exc.value.error_dict["xpi"]) == 1 assert (exc.value.error_dict["xpi"][0].message == 'Web extensions must have a manifest key "version".')
def test_legacy_no_version(self): with pytest.raises(ValidationError) as exc: ExtensionFactory( xpi__from_path=data_path("legacy-no-version-unsigned.xpi")) assert len(exc.value.error_dict["xpi"]) == 1 assert (exc.value.error_dict["xpi"][0].message == 'Legacy addons "install.rdf" must specify a version.')
def test_legacy_no_id(self): xpi = LegacyAddonFileFactory(overwrite_data={"id": ""}, signed=False) with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_func=xpi.open) assert len(exc.value.error_dict["xpi"]) == 1 assert (exc.value.error_dict["xpi"][0].message == 'Legacy addons "install.rdf" must specify an id.')
def test_detail_view_includes_cache_headers(self, api_client): extension = ExtensionFactory() res = api_client.get('/api/v2/extension/{id}/'.format(id=extension.id)) assert res.status_code == 200 # It isn't important to assert a particular value for max-age assert 'max-age=' in res['Cache-Control'] assert 'public' in res['Cache-Control']
def test_hash(self, storage): xpi = WebExtensionFileFactory() f = xpi.open() hashed = hashlib.sha256(f.read()).hexdigest() f.close() extension = ExtensionFactory(xpi__from_func=xpi.open) assert extension.hash == hashed
def test_webext_bad_manifest(self): with pytest.raises(ValidationError) as exc: ExtensionFactory( xpi__from_path=data_path("webext-bad-manifest-unsigned.xpi")) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == "Web extension manifest is corrupt."
def test_detail_view_includes_cache_headers(self, api_client, storage): extension = ExtensionFactory() res = api_client.get("/api/v3/extension/{id}/".format(id=extension.id)) assert res.status_code == 200 # It isn't important to assert a particular value for max-age assert "max-age=" in res["Cache-Control"] assert "public" in res["Cache-Control"]
def test_legacy_bad_install_rdf(self): with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_path=data_path( "legacy-bad-install-rdf-unsigned.xpi")) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == 'Legacy addon "install.rdf" is corrupt.'
def test_legacy_bad_install_rdf(self): xpi = LegacyAddonFileFactory(signed=False) xpi.add_file("install.rdf", b"{}") with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_func=xpi.open) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == 'Legacy addon "install.rdf" is corrupt.'
def test_cannot_create_extension_duplicate_filename(self, api_client, storage): xpi = WebExtensionFileFactory() ExtensionFactory(xpi__from_func=xpi.open) with transaction.atomic(): res = self._upload_extension(api_client, xpi.path) assert res.status_code == 400 assert res.data == {"xpi": "An extension with this filename already exists."} assert Extension.objects.count() == 1
def test_xpi_not_a_zip(self): tmp = tempfile.NamedTemporaryFile(suffix=".txt") tmp.write(b"not an addon") with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_func=lambda: tmp) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == "Extension file must be zip-formatted."
def test_webext_bad_manifest(self): xpi = WebExtensionFileFactory(signed=False) xpi.add_file("manifest.json", b"") with pytest.raises(ValidationError) as exc: ExtensionFactory(xpi__from_func=xpi.open) assert len(exc.value.error_dict["xpi"]) == 1 assert exc.value.error_dict["xpi"][ 0].message == "Web extension manifest is corrupt."