Example #1
0
 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
Example #2
0
 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
Example #3
0
    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."
Example #4
0
    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."
Example #5
0
 def test_webext_no_version(self):
     xpi = WebExtensionFileFactory()
     manifest = xpi.manifest
     del manifest["version"]
     xpi.replace_manifest(manifest)
     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 extensions must have a manifest key "version".')
Example #6
0
 def test_uploaded_webexts_must_have_id(self, api_client, storage):
     # NB: This is a fragile test. It uses a unsigned webext, and
     # so it relies on the ID check happening before the signing
     # check, so that the error comes from the former.
     xpi = WebExtensionFileFactory()
     xpi.update_manifest({"applications": {"gecko": {}}})
     res = self._upload_extension(api_client, xpi.path)
     assert res.status_code == 400  # Client error
     assert res.data == {
         "xpi": 'Web extensions must have a manifest key "applications.gecko.id".'
     }
    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."}
Example #8
0
 def test_uploaded_webexts_must_have_id(self, api_client, storage):
     # NB: This is a fragile test. It uses a unsigned webext, and
     # so it relies on the ID check happening before the signing
     # check, so that the error comes from the former.
     xpi = WebExtensionFileFactory()
     xpi.update_manifest({"applications": {"gecko": {}}})
     res = self._upload_extension(api_client, xpi.path)
     assert res.status_code == 400  # Client error
     assert res.data == {
         "xpi": 'Web extensions must have a manifest key "applications.gecko.id".'
     }
Example #9
0
 def test_webext_no_version(self):
     xpi = WebExtensionFileFactory()
     manifest = xpi.manifest
     del manifest["version"]
     xpi.replace_manifest(manifest)
     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 extensions must have a manifest key "version".'
     )
Example #10
0
 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"
Example #11
0
 def test_uploads_must_be_signed_webext(self, api_client, storage):
     xpi = WebExtensionFileFactory(signed=False)
     res = self._upload_extension(api_client, xpi.path)
     assert res.status_code == 400  # Client error
     assert res.data == {
         "xpi": [ExtensionFileField.default_error_messages["not_signed"]]
     }
 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
Example #13
0
 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)
Example #14
0
 def test_can_delete_extensions_no_longer_in_use(self, api_client, storage):
     xpi = WebExtensionFileFactory()
     e = ExtensionFactory(xpi__from_func=xpi.open)
     a = ActionFactory(name="opt-out-study")
     r = RecipeFactory(action=a, arguments={"extensionId": e.id})
     r.revise(arguments=OptOutStudyArgumentsFactory(extensionId=e.id + 1))
     res = api_client.delete(f"/api/v3/extension/{e.id}/")
     assert res.status_code == 204
     assert Extension.objects.count() == 0
 def test_cannot_delete_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.delete(f"/api/v3/extension/{e.id}/")
     assert res.status_code == 400
     assert res.data == ["Extension cannot be updated while in use by a recipe."]
     assert Extension.objects.count() == 1
 def test_can_update_extensions_no_longer_in_use(self, api_client, storage):
     xpi = WebExtensionFileFactory()
     e = ExtensionFactory(xpi__from_func=xpi.open)
     a = ActionFactory(name="opt-out-study")
     r = RecipeFactory(action=a, arguments={"extensionId": e.id})
     r.revise(arguments={"extensionId": 0})
     res = api_client.patch(f"/api/v3/extension/{e.id}/", {"name": "new name"})
     assert res.status_code == 200
     assert res.data["name"] == "new name"
Example #17
0
 def test_read_only(self, api_client, storage):
     xpi = WebExtensionFileFactory()
     with open(xpi.path, "rb") as f:
         res = api_client.post("/api/v1/extension/", {
             "name": "test extension",
             "xpi": f
         },
                               format="multipart")
     assert res.status_code == 405
 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"
Example #19
0
 def test_webext_no_id(self):
     xpi = WebExtensionFileFactory(
         signed=False, overwrite_data={"applications": {
             "gecko": {}
         }})
     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 extensions must have a manifest key "applications.gecko.id".')
Example #20
0
    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."
Example #21
0
 def test_upload_works_webext(self, api_client, storage):
     xpi = WebExtensionFileFactory()
     res = self._upload_extension(api_client, xpi.path)
     assert res.status_code == 201  # created
     Extension.objects.filter(id=res.data["id"]).exists()
Example #22
0
 def test_uploads_must_be_signed_webext(self, api_client, storage):
     xpi = WebExtensionFileFactory(signed=False)
     res = self._upload_extension(api_client, xpi.path)
     assert res.status_code == 400  # Client error
     assert res.data == {"xpi": "Extension file must be signed."}
Example #23
0
 def test_no_duplicate_files(self, storage):
     xpi = WebExtensionFileFactory()
     ExtensionFactory(xpi__from_func=xpi.open)
     with transaction.atomic(), pytest.raises(FileExistsError):
         ExtensionFactory(xpi__from_func=xpi.open)
     assert Extension.objects.count() == 1
Example #24
0
 def test_extension_id(self, storage):
     xpi = WebExtensionFileFactory(
         gecko_id="*****@*****.**")
     extension = ExtensionFactory(xpi__from_func=xpi.open)
     assert extension.extension_id == "*****@*****.**"
Example #25
0
 def test_version(self, storage):
     xpi = WebExtensionFileFactory(overwrite_data={"version": "0.1"})
     extension = ExtensionFactory(xpi__from_func=xpi.open)
     assert extension.version == "0.1"