diff --git a/fedbadges/rules.py b/fedbadges/rules.py index 9df0e40..785674a 100644 --- a/fedbadges/rules.py +++ b/fedbadges/rules.py @@ -176,6 +176,22 @@ def matches(self, msg): if isinstance(obj, (basestring, int, float)): obj = [obj] + # It is possible to recieve a list of dictionary containing the name + # of the recipient, this is the case in the pagure's fedmsg. + # In that case we create a new list containing the names taken from the + # dictionnary. + # If the "name" was not available in the dictionary we raise an exception. + new_obj = [] + for item in obj: + if isinstance(item, dict): + try: + new_obj.append(item["name"]) + except KeyError: + raise Exception("Multiple recipients : name not found in the message") + if new_obj: + obj = new_obj + + # On the way, it is possible for the fedmsg message to contain None # for "agent". A problem here though is that None is not iterable, # so let's replace it with an equivalently empty iterable so code diff --git a/tests/test_badges/pagure-long-live.yaml b/tests/test_badges/pagure-long-live.yaml new file mode 100644 index 0000000..57c79a4 --- /dev/null +++ b/tests/test_badges/pagure-long-live.yaml @@ -0,0 +1,33 @@ +%YAML 1.2 +--- +# This is some metadata about the badge +name: Long Life to Pagure (Pagure I) +description: Pushed 1 commit to a Pagure repository. +creator: robyduck + +# This is a link to the discussion about adopting this as a for-real badge. +discussion: https://pagure.io/design/issue/434 + +# A link to the image for the badge +image_url: https://badges.fedoraproject.org/pngs/pagure-long-life-01.png +# That's us! +issuer_id: fedora-project + +# We'll perform our more costly check (defined below) only when +# we receive messages that match this 'trigger' +trigger: + topic: pagure.git.receive + +# Once the check has been triggered, this defines what we actually check. +criteria: + datanommer: + filter: + topics: + - "%(topic)s" # The topic of the message that triggered us. + users: + - "%(msg.authors)s" + operation: count + condition: + greater than or equal to: 1 + +recipient: "%(msg.authors)s" diff --git a/tests/test_complicated_recipient.py b/tests/test_complicated_recipient.py index 24342a9..7f263ed 100644 --- a/tests/test_complicated_recipient.py +++ b/tests/test_complicated_recipient.py @@ -21,9 +21,6 @@ class TestComplicatedRecipient(unittest.TestCase): def setUp(self, fedmsg_init, add_issuer, add_badge): hub = utils.MockHub() self.consumer = fedbadges.consumers.FedoraBadgesConsumer(hub) - for rule in self.consumer.badge_rules: - if rule['name'] == 'Speak Up!': - self.rule = rule @patch('datanommer.models.Message.grep') @patch('tahrir_api.dbapi.TahrirDatabase.get_person') @@ -33,6 +30,10 @@ def test_complicated_recipient_real(self, get_person, grep, ): + + for rule in self.consumer.badge_rules: + if rule['name'] == 'Speak Up!': + self.rule = rule msg = { u'username': u'daemon', u'i': 236, @@ -65,3 +66,102 @@ class MockPerson(object): with patch("fedbadges.rules.user_exists_in_fas") as g: g.return_value = True eq_(self.rule.matches(msg), set(['zodbot', 'threebean'])) + + + @patch('datanommer.models.Message.grep') + @patch('tahrir_api.dbapi.TahrirDatabase.get_person') + @patch('tahrir_api.dbapi.TahrirDatabase.assertion_exists') + def test_complicated_recipient_pagure(self, + assertion_exists, + get_person, + grep, + ): + + for rule in self.consumer.badge_rules: + if rule['name'] == 'Long Life to Pagure (Pagure I)': + self.rule = rule + msg = { + "username": "git", + "source_name": "datanommer", + "i": 1, + "timestamp": 1528825180.0, + "topic": "io.pagure.prod.pagure.git.receive", + "msg": { + "authors": [ + { + "fullname": "Pierre-YvesChibon", + "name": "pingou" + }, + { + "fullname": "Lubom\u00edr Sedl\u00e1\u0159", + "name": "lsedlar" + } + ], + "total_commits": 2, + "start_commit": "da090b8449237e3878d4d1fe56f7f8fcfd13a248" + } + } + + # Set up some mock stuff + class MockQuery(object): + def count(self): + return float("inf") # Master tagger + + class MockPerson(object): + opt_out = False + + grep.return_value = float("inf"), 1, MockQuery() + get_person.return_value = MockPerson() + assertion_exists.return_value = False + + with patch("fedbadges.rules.user_exists_in_fas") as g: + g.return_value = True + eq_(self.rule.matches(msg), set(['pingou', 'lsedlar'])) + + @patch('datanommer.models.Message.grep') + @patch('tahrir_api.dbapi.TahrirDatabase.get_person') + @patch('tahrir_api.dbapi.TahrirDatabase.assertion_exists') + def test_complicated_recipient_pagure_bad(self, + assertion_exists, + get_person, + grep, + ): + + for rule in self.consumer.badge_rules: + if rule['name'] == 'Long Life to Pagure (Pagure I)': + self.rule = rule + msg = { + "username": "git", + "source_name": "datanommer", + "i": 1, + "timestamp": 1528825180.0, + "topic": "io.pagure.prod.pagure.git.receive", + "msg": { + "authors": [ + { + "fullname": "Pierre-YvesChibon", + }, + { + "fullname": "Lubom\u00edr Sedl\u00e1\u0159", + } + ], + "total_commits": 2, + "start_commit": "da090b8449237e3878d4d1fe56f7f8fcfd13a248" + } + } + + # Set up some mock stuff + class MockQuery(object): + def count(self): + return float("inf") # Master tagger + + class MockPerson(object): + opt_out = False + + grep.return_value = float("inf"), 1, MockQuery() + get_person.return_value = MockPerson() + assertion_exists.return_value = False + + with patch("fedbadges.rules.user_exists_in_fas") as g: + g.return_value = True + self.assertRaises(Exception("Multiple recipients : name not found in the message")) diff --git a/tests/test_yaml_collector.py b/tests/test_yaml_collector.py index ea146d3..7a1fa15 100644 --- a/tests/test_yaml_collector.py +++ b/tests/test_yaml_collector.py @@ -21,7 +21,7 @@ def setUp(self, fedmsg_init, add_issuer, add_badge): def test_load_badges_number(self): """ Determine that we can load badges from file. """ - eq_(len(self.consumer.badge_rules), 4) + eq_(len(self.consumer.badge_rules), 5) def test_load_badges_contents(self): """ Determine that we can load badges from file. """ @@ -31,4 +31,5 @@ def test_load_badges_contents(self): 'The Zen of Foo Bar Baz', 'Junior Tagger (Tagger I)', 'Speak Up!', + 'Long Life to Pagure (Pagure I)', ]))