diff --git a/requirements.txt b/requirements.txt index 4205973..3a5e8e6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,5 @@ SQLAlchemy >=0.7.2 zope.sqlalchemy alembic arrow +fedora_messaging +tahrir-messages diff --git a/tahrir_api/dbapi.py b/tahrir_api/dbapi.py index 849a1e8..10fc3f0 100644 --- a/tahrir_api/dbapi.py +++ b/tahrir_api/dbapi.py @@ -10,6 +10,7 @@ from sqlalchemy.orm import sessionmaker, scoped_session from datetime import datetime, timedelta from collections import OrderedDict +from tahrir_messages import PersonLoginFirstV1, BadgeAwardV1, PersonRankAdvanceV1 class TahrirDatabase(object): @@ -163,8 +164,7 @@ def create_series(self, name, desc, team_id, tags=None, series_id=None): if not self.series_exists(series_id): new_series = Series( - id=series_id, name=name, description=desc, - tags=tags, team_id=team_id + id=series_id, name=name, description=desc, tags=tags, team_id=team_id ) self.session.add(new_series) @@ -495,7 +495,7 @@ def person_exists(self, email=None, id=None, nickname=None): return False def person_opted_out(self, email=None, id=None, nickname=None): - """ Returns true if a given person has opted out of tahrir. """ + """Returns true if a given person has opted out of tahrir.""" person = self.get_person(email, id, nickname) @@ -604,7 +604,6 @@ def add_person(self, email, nickname=None, website=None, bio=None): """ if not self.person_exists(email=email): - # If no nickname is specified, just use the first bit of their # email as a convenient default. if not nickname: @@ -621,17 +620,15 @@ def add_person(self, email, nickname=None, website=None, bio=None): @autocommit def note_login(self, person_email=None, id=None, nickname=None): - """ Make a note that a person has logged in. """ + """Make a note that a person has logged in.""" person = self.get_person(person_email, id, nickname) # If this is the first time they have ever logged in, optionally # publish a notification about the event. if not person.last_login and self.notification_callback: - self.notification_callback( - topic="person.login.first", - msg=dict(user=dict(username=person.nickname, badges_user_id=person.id)), - ) + body = dict(user=dict(username=person.nickname, badges_user_id=person.id)) + self.notification_callback(PersonLoginFirstV1(body=body)) # Finally, update the field. person.last_login = datetime.utcnow() @@ -891,7 +888,6 @@ def add_authorization(self, badge_id, person_email): """ if self.person_exists(email=person_email) and self.badge_exists(badge_id): - person = self.get_person(person_email) new_authz = Authorization(badge_id=badge_id, person_id=person.id) @@ -925,7 +921,6 @@ def add_assertion(self, badge_id, person_email, issued_on, issued_for=None): issued_on = datetime.utcnow() if self.person_exists(email=person_email) and self.badge_exists(badge_id): - badge = self.get_badge(badge_id) person = self.get_person(person_email) old_rank = person.rank @@ -940,18 +935,16 @@ def add_assertion(self, badge_id, person_email, issued_on, issued_for=None): self.session.flush() if self.notification_callback: - self.notification_callback( - topic="badge.award", - msg=dict( - badge=dict( - name=badge.name, - description=badge.description, - image_url=badge.image, - badge_id=badge_id, - ), - user=dict(username=person.nickname, badges_user_id=person.id), + body = dict( + badge=dict( + name=badge.name, + description=badge.description, + image_url=badge.image, + badge_id=badge_id, ), + user=dict(username=person.nickname, badges_user_id=person.id), ) + self.notification_callback(BadgeAwardV1(body=body)) self._adjust_ranks(person, old_rank) @@ -960,7 +953,7 @@ def add_assertion(self, badge_id, person_email, issued_on, issued_for=None): return False def _adjust_ranks(self, person, old_rank): - """ Given a person model object and the 'old' rank of that person, + """Given a person model object and the 'old' rank of that person, adjust the ranks of all persons between the 'old' rank and the present rank of the given person. @@ -983,15 +976,12 @@ def _adjust_ranks(self, person, old_rank): self.session.flush() + body = dict(person=person.__json__(), old_rank=old_rank) if self.notification_callback: - self.notification_callback( - topic="person.rank.advance", msg=dict( - person=person.__json__(), old_rank=old_rank - ) - ) + self.notification_callback(PersonRankAdvanceV1(body=body)) def _make_leaderboard(self, start=None, stop=None): - """ Produce a dict mapping persons to information about + """Produce a dict mapping persons to information about the number of badges they have been awarded and their rank, freshly calculated. This is relatively expensive. diff --git a/tests/test_dbai.py b/tests/test_dbai.py index 8590ad7..fdeaa69 100644 --- a/tests/test_dbai.py +++ b/tests/test_dbai.py @@ -12,7 +12,6 @@ def check_output(cmd): except: return None - except: import subprocess @@ -119,6 +118,12 @@ def test_last_login(self): self.api.note_login(nickname=person.nickname) assert person.last_login + assert len(self.callback_calls) == 1 + message = self.callback_calls[0][0][0] + assert message.body == {"user": {"username": "test", "badges_user_id": 1}} + assert message.agent_name == "test" + assert message.summary == "test logged into badges for the first time" + def test_add_assertion(self): issuer_id = self.api.add_issuer( "TestOrigin", "TestName", "TestOrg", "TestContact" @@ -145,8 +150,36 @@ def test_add_assertion(self): # Ensure that we would have published two fedmsg messages for that. assert len(self.callback_calls) == 2 - # Ensure that the first message had a 'badge_id' in the message. - assert "badge_id" in self.callback_calls[0][1]["msg"]["badge"] + award_message = self.callback_calls[0][0][0] + rank_advance_message = self.callback_calls[1][0][0] + + assert award_message.body == { + "badge": { + "name": "TestBadge", + "description": "A test badge for doing unit tests", + "image_url": "TestImage", + "badge_id": "testbadge", + }, + "user": {"username": "test", "badges_user_id": 1}, + } + assert award_message.agent_name == "test" + assert award_message.summary == "test was awarded the badge `TestBadge`" + + assert rank_advance_message.body == { + "person": { + "email": "test@tester.com", + "id": 1, + "nickname": "test", + "website": None, + "bio": None, + "rank": 1, + }, + "old_rank": None, + } + assert rank_advance_message.agent_name == "test" + assert ( + rank_advance_message.summary == "test's Badges rank changed from None to 1" + ) def test_get_badges_from_tags(self): issuer_id = self.api.add_issuer( diff --git a/tox.ini b/tox.ini index 7a0bb7b..7c0ab84 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,7 @@ [tox] -envlist = py35,py36,py37 +# not ideal, but nose doesnt work on > 3.9, so keep this +# until we change the test infra +envlist = py3{8,9} # If the user is missing an interpreter, don't fail skip_missing_interpreters = True