diff --git a/anitya_schema/__init__.py b/anitya_schema/__init__.py index cc09cb6..a5100a0 100644 --- a/anitya_schema/__init__.py +++ b/anitya_schema/__init__.py @@ -25,6 +25,7 @@ ProjectMapDeleted, ProjectMapEdited, ProjectVersionDeleted, + ProjectVersionDeletedV2, ProjectVersionUpdated, ProjectVersionUpdatedV2, ) diff --git a/anitya_schema/project_messages.py b/anitya_schema/project_messages.py index c2eda0d..784e623 100644 --- a/anitya_schema/project_messages.py +++ b/anitya_schema/project_messages.py @@ -863,6 +863,19 @@ class ProjectVersionDeleted(ProjectMessage): }, } + def __init__( + self, body=None, headers=None, topic=None, properties=None, severity=None + ): + """ + Message constructor. + """ + super().__init__(body, headers, topic, properties, severity) + warnings.warn( + "ProjectVersionDeleted class is deprecated, please use ProjectVersionDeletedV2 instead", + DeprecationWarning, + stacklevel=2, + ) + def __str__(self): """ Return a complete human-readable representation of the message, which @@ -886,3 +899,68 @@ def agent(self): def version(self): """The version that was deleted.""" return self.body["message"]["version"] + + +class ProjectVersionDeletedV2(ProjectMessage): + """ + Sent when version is deleted in Anitya. + + Attributes: + topic (str): Message topic + "org.release-monitoring.prod.anitya.project.version.remove.v2" + body_schema (dict): Message schema definition + """ + + topic = "org.release-monitoring.prod.anitya.project.version.remove.v2" + body_schema = { + "id": "https://fedoraproject.org/jsonschema/anitya_project_version_remove_v2.json", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "required": ["project", "message", "distro"], + "properties": { + "distro": {"type": "null"}, + "message": { + "type": "object", + "properties": { + "agent": {"type": "string"}, + "project": {"type": "string"}, + "versions": {"type": "array", "items": {"type": "string"}}, + }, + "required": ["agent", "project", "versions"], + }, + "project": ProjectMessage.project_schema, + }, + } + + def __str__(self): + """ + Return a complete human-readable representation of the message, which + in this case is equivalent to the summary. + """ + return self.summary + + @property + def summary(self): + """Return a summary of the message.""" + if len(self.versions) == 1: + return "A version '{}' was deleted in project {} in release-monitoring.".format( + self.versions[0], self.project_name + ) + elif len(self.versions) <= 5: + return "A versions '{}' were deleted in project {} in release-monitoring.".format( + ", ".join(self.versions), self.project_name + ) + else: + return "{} versions entries were deleted in project {} in release-monitoring.".format( + len(self.versions), self.project_name + ) + + @property + def agent(self): + """User that did the action.""" + return self.body["message"]["agent"] + + @property + def versions(self): + """The versions that were deleted.""" + return self.body["message"]["versions"] diff --git a/anitya_schema/tests/fixtures/org.release-monitoring.prod.anitya.project.version.remove.v2.json b/anitya_schema/tests/fixtures/org.release-monitoring.prod.anitya.project.version.remove.v2.json new file mode 100644 index 0000000..eb05349 --- /dev/null +++ b/anitya_schema/tests/fixtures/org.release-monitoring.prod.anitya.project.version.remove.v2.json @@ -0,0 +1,92 @@ +[ + { + "distro": null, + "message": { + "agent": "tibbs", + "project": "gbrainy", + "versions": ["GBRAINY_2_2_7"] + }, + "project": { + "backend": "custom", + "created_on": 1453077751.0, + "ecosystem": "https://gent.softcatala.org/jmas/gbrainy/", + "homepage": "https://gent.softcatala.org/jmas/gbrainy/", + "id": 8936, + "name": "gbrainy", + "regex": "(?<=gbrainy-)[0-9]+\\.[0-9]+\\.[0-9]+(?=\\.tar\\.gz)", + "updated_on": 1539016658.0, + "version": "2.3.7", + "version_url": "https://gent.softcatala.org/jmas/gbrainy/", + "versions": [ + "2.3.7", + "GBRAINY_2_2_7" + ] + } + }, + { + "distro": null, + "message": { + "agent": "tibbs", + "project": "gbrainy", + "versions": [ + "GBRAINY_2_2_7", + "GBRAINY_2_3_0" + ] + }, + "project": { + "backend": "custom", + "created_on": 1453077751.0, + "ecosystem": "https://gent.softcatala.org/jmas/gbrainy/", + "homepage": "https://gent.softcatala.org/jmas/gbrainy/", + "id": 8936, + "name": "gbrainy", + "regex": "(?<=gbrainy-)[0-9]+\\.[0-9]+\\.[0-9]+(?=\\.tar\\.gz)", + "updated_on": 1539016658.0, + "version": "2.3.7", + "version_url": "https://gent.softcatala.org/jmas/gbrainy/", + "versions": [ + "2.3.7", + "GBRAINY_2_3_0", + "GBRAINY_2_2_7" + ] + } + }, + { + "distro": null, + "message": { + "agent": "http://zlopez.id.fedoraproject.org/", + "project": "tint2", + "versions": [ + "0.14.4", + "0.13.3", + "0.13.2", + "0.13.1", + "v0.13", + "0.12.12", + "0.12.11", + "0.11" + ] + }, + "project": { + "backend": "GitHub", + "created_on": 1412175120.0, + "homepage": "https://github.com/o9000/", + "id": 4973, + "name": "tint2", + "regex": null, + "updated_on": 1537276371.0, + "version": null, + "version_url": null, + "versions": [ + "0.14.4", + "0.13.3", + "0.13.2", + "0.13.1", + "v0.13", + "0.12.12", + "0.12.11", + "0.11" + ] + } + } +] diff --git a/anitya_schema/tests/test_project_messages.py b/anitya_schema/tests/test_project_messages.py index 0f3096f..9e11c68 100644 --- a/anitya_schema/tests/test_project_messages.py +++ b/anitya_schema/tests/test_project_messages.py @@ -18,6 +18,8 @@ import unittest import mock +import pytest + from anitya_schema import ( ProjectCreated, ProjectDeleted, @@ -28,6 +30,7 @@ ProjectMapDeleted, ProjectMapEdited, ProjectVersionDeleted, + ProjectVersionDeletedV2, ProjectVersionUpdated, ProjectVersionUpdatedV2, ) @@ -698,3 +701,69 @@ def test_version(self): self.message.body = {"message": {"version": "1.0.0"}} self.assertEqual(self.message.version, "1.0.0") + + +class TestProjectVersionDeletedV2: + """Tests for anitya_schema.project_messages.ProjectVersionDeletedV2 class.""" + + def setup(self): + """Set up the tests.""" + self.message = ProjectVersionDeletedV2() + + @mock.patch( + "anitya_schema.project_messages.ProjectVersionDeletedV2.summary", + new_callable=mock.PropertyMock, + ) + def test__str__(self, mock_property): + """Assert that correct string is returned.""" + mock_property.return_value = "Dummy" + + assert self.message.__str__() == "Dummy" + + @pytest.mark.parametrize( + "test_input,expected", + [ + ( + ["1.0.0"], + "A version '1.0.0' was deleted in project Dummy in release-monitoring.", + ), + ( + ["1.0.0", "1.0.1"], + "A versions '1.0.0, 1.0.1' were deleted in project Dummy in release-monitoring.", + ), + ( + ["1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4"], + "A versions '1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4' were deleted in project Dummy in release-monitoring.", # noqa: E501 + ), + ( + ["1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", "1.0.5"], + "6 versions entries were deleted in project Dummy in release-monitoring.", + ), + ], + ) + @mock.patch( + "anitya_schema.project_messages.ProjectVersionDeletedV2.project_name", + new_callable=mock.PropertyMock, + ) + @mock.patch( + "anitya_schema.project_messages.ProjectVersionDeletedV2.versions", + new_callable=mock.PropertyMock, + ) + def test_summary(self, mock_versions, mock_name, test_input, expected): + """Assert that correct summary string is returned.""" + mock_name.return_value = "Dummy" + mock_versions.return_value = test_input + + assert self.message.summary == expected + + def test_agent(self): + """Assert that agent is returned.""" + self.message.body = {"message": {"agent": "Dummy"}} + + assert self.message.agent == "Dummy" + + def test_versions(self): + """Assert that version string is returned.""" + self.message.body = {"message": {"versions": ["1.0.0"]}} + + assert self.message.versions == ["1.0.0"] diff --git a/news/31.feature b/news/31.feature new file mode 100644 index 0000000..08e1fe2 --- /dev/null +++ b/news/31.feature @@ -0,0 +1 @@ +Add `anitya.project.version.remove.v2` topic diff --git a/pyproject.toml b/pyproject.toml index ce5917d..f223956 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,8 +94,9 @@ exclude = [ "anitya.project.map.update" = "anitya_schema:ProjectMapEdited" "anitya.project.map.remove" = "anitya_schema:ProjectMapDeleted" "anitya.project.version.update" = "anitya_schema:ProjectVersionUpdated" -"anitya.project.version.remove" = "anitya_schema:ProjectVersionDeleted" "anitya.project.version.update.v2" = "anitya_schema:ProjectVersionUpdatedV2" +"anitya.project.version.remove" = "anitya_schema:ProjectVersionDeleted" +"anitya.project.version.remove.v2" = "anitya_schema:ProjectVersionDeletedV2" [tool.poetry.dependencies] python = "^3.8"