From 25e67a6787237e97fef12e6428089cf75ae852c3 Mon Sep 17 00:00:00 2001
From: Eric Barbour <ebarbour@redhat.com>
Date: Jun 14 2016 16:16:43 +0000
Subject: [PATCH 1/3] Add fedmsg/markup route, and api tests


---

diff --git a/hubs/app.py b/hubs/app.py
index fe661ab..df33459 100755
--- a/hubs/app.py
+++ b/hubs/app.py
@@ -1,11 +1,15 @@
 import datetime
 import functools
+import json
 import logging
 import os
+import uuid
 
 import flask
 import flask.json
+import fmn.lib
 import munch
+import pygments.formatters
 import six
 
 from flask.ext.openid import OpenID
@@ -16,6 +20,10 @@ import hubs.widgets
 import datanommer.models
 
 from hubs.utils import username2avatar
+from hubs.widgets.feed import (
+    apply_markup, rehydrate_preference,
+    get_remote_preference
+)
 
 app = flask.Flask(__name__)
 
@@ -43,6 +51,7 @@ import fedmsg.config
 import fedmsg.meta
 fedmsg_config = fedmsg.config.load_config()
 fedmsg.meta.make_processors(**fedmsg_config)
+PATHS = fmn.lib.load_rules(root='fmn.rules')
 
 session = hubs.models.init(fedmsg_config['hubs.sqlalchemy.uri'])
 datanommer.models.init(fedmsg_config['datanommer.sqlalchemy.uri'])
@@ -628,3 +637,50 @@ def hub_leave(hub):
         return flask.abort(400)
     session.commit()
     return flask.redirect(flask.url_for('hub', name=hub.name))
+
+
+@app.route('/api/fedmsg/markup', methods=['GET'])
+def markup_fedmsg():
+    try:
+        data = flask.request.args['message']
+        plugin = flask.request.args['plugin']
+    except KeyError:
+        return flask.abort(400)
+    widget = hubs.models.Widget.by_plugin(session, plugin)
+    if not widget:
+        return flask.abort(400)
+    context = widget.config.get('fmn_context')
+    messages = []
+    message = json.loads(data)
+    try:
+        nickname = flask.g.auth.nickname
+    except AttributeError:      # Not logged in
+        return flask.abort(403)
+    preference = get_remote_preference(nickname, context)
+    if preference:
+        try:
+            preference = rehydrate_preference(preference)
+        except ImportError:
+            pass
+    recipients = fmn.lib.recipients(
+        [preference], message, PATHS, fedmsg_config)
+    if recipients:
+        messages.append(message)
+    matches = fedmsg.meta.conglomerate(messages, lexers=True, **fedmsg_config)
+    for match in matches:
+        match['markup'] = apply_markup(match)
+        for _, constituent in match['msg_ids'].items():
+            constituent['markup'] = apply_markup(constituent)
+            if constituent['long_form'] != constituent['subtitle']:
+                if constituent.get('lexer'):
+                    constituent['long_form'] = pygments.highlight(
+                        constituent['long_form'],
+                        constituent['lexer'],
+                        pygments.formatters.HtmlFormatter(style='monokai'),
+                    )
+                else:
+                    markup = u"<h5>{long_form}</h5>".format(**constituent)
+                    constituent['long_form'] = markup
+        # And tack on a unique identifier for each top level entry.
+        match['dom_id'] = six.text_type(uuid.uuid4())
+    return flask.jsonify(matches)
diff --git a/hubs/models.py b/hubs/models.py
index 1731076..32580a6 100755
--- a/hubs/models.py
+++ b/hubs/models.py
@@ -303,6 +303,10 @@ class Widget(BASE):
     def by_idx(cls, session, idx):
         return session.query(cls).filter_by(idx=idx).first()
 
+    @classmethod
+    def by_plugin(cls, session, plugin):
+        return session.query(cls).filter_by(plugin=plugin).first()
+
     get = by_idx
 
     @property
diff --git a/hubs/tests/__init__.py b/hubs/tests/__init__.py
index 8dbca6c..7c9da28 100644
--- a/hubs/tests/__init__.py
+++ b/hubs/tests/__init__.py
@@ -88,6 +88,22 @@ class APPTest(unittest.TestCase):
 
 
 @contextmanager
+def user_set(APP, user):
+    """ Set the provided user as fas_user in the provided application."""
+    # Hack used to remove the before_request function set by
+    # flask.ext.fas_openid.FAS which otherwise kills our effort to set a
+    # flask.g.fas_user.
+    from flask import appcontext_pushed, g
+
+    def handler(sender, **kwargs):
+        g.fas_user = user
+        g.fas_session_id = b'123'
+
+    with appcontext_pushed.connected_to(handler, APP):
+        yield
+
+
+@contextmanager
 def auth_set(APP, auth):
     """ Set the provided user as fas_user in the provided application."""
 
@@ -105,6 +121,7 @@ def auth_set(APP, auth):
     with appcontext_pushed.connected_to(handler, APP):
         yield
 
+
 class FakeUser(object):
     """ Fake user used to test the fedocallib library. """
 
diff --git a/hubs/tests/test_api/test_fedmsg.py b/hubs/tests/test_api/test_fedmsg.py
new file mode 100644
index 0000000..c708073
--- /dev/null
+++ b/hubs/tests/test_api/test_fedmsg.py
@@ -0,0 +1,330 @@
+import json
+
+import hubs.tests
+import hubs.models
+
+
+class TestFeed(hubs.tests.APPTest):
+    # TODO this test relies on a specific filter for the atelic user
+    # It would be better to fake preferences on FAS
+    user = hubs.tests.FakeAuthorization('atelic')
+    message_involved = {
+        'timestamp': 1465567413.0,
+        'topic': 'io.pagure.prod.pagure.issue.new',
+        'msg_id': '2016-0490127f-473f-4d01-ASDF-a864a56dc302',
+        'msg': {
+            'action': 'created',
+            'comment': {
+                'body':
+                'hm, there is something odd, the stackage page is being inconsistent, one time the version number for LTS is linked, one time it isn\'t.\r\n\r\nIt\'s as if there are 2 servers running 2 different versions of the application',
+                'created_at': '2016-06-10T14:03:31Z',
+                'html_url':
+                'https://github.com/fedora-infra/anitya/issues/283#issuecomment-225190438',
+                'id': 225190438,
+                'updated_at': '2016-06-10T14:03:31Z',
+                'url':
+                'https://api.github.com/repos/fedora-infra/anitya/issues/comments/225190438',
+                'user': {
+                    'gravatar_id': '',
+                    'html_url': 'https://github.com/pypingou',
+                    'id': 1240038,
+                    'login': 'pypingou',
+                    'site_admin': False,
+                    'type': 'User',
+                    'url': 'https://api.github.com/users/pypingou'
+                }
+            },
+            'fas_usernames': {
+                'fedora-infra': 'github_org_fedora-infra',
+                'pypingou': 'pingou'
+            },
+            'issue': {
+                'assignee': None,
+                'body':
+                '@juhp it seems that the stackage backend is broken: https://release-monitoring.org/projects/updates/failed?name=&log=stackage want to look at it?',
+                'closed_at': '2016-04-29T14:53:10Z',
+                'comments': 8,
+                'created_at': '2016-04-15T16:15:57Z',
+                'html_url':
+                'https://github.com/fedora-infra/anitya/issues/283',
+                'id': 148703615,
+                'labels': [],
+                'locked': False,
+                'milestone': None,
+                'number': 283,
+                'state': 'closed',
+                'title': 'stackage backend broken',
+                'updated_at': '2016-06-10T14:03:31Z',
+                'url':
+                'https://api.github.com/repos/fedora-infra/anitya/issues/283',
+                'user': {
+                    'gravatar_id': '',
+                    'html_url': 'https://github.com/pypingou',
+                    'id': 1240038,
+                    'login': 'pypingou',
+                    'site_admin': False,
+                    'type': 'User',
+                    'url': 'https://api.github.com/users/pypingou'
+                }
+            },
+            'organization': {
+                'description': 'Fedora Infrastructure Team',
+                'id': 3316637,
+                'login': 'fedora-infra',
+                'url': 'https://api.github.com/orgs/fedora-infra'
+            },
+            'repository': {
+                'created_at': '2013-11-29T10:17:26Z',
+                'default_branch': 'master',
+                'description': 'A cross-distribution upstream release project',
+                'fork': False,
+                'forks': 33,
+                'forks_count': 33,
+                'full_name': 'fedora-infra/anitya',
+                'has_downloads': True,
+                'has_issues': True,
+                'has_pages': False,
+                'has_wiki': False,
+                'homepage': 'https://release-monitoring.org',
+                'html_url': 'https://github.com/fedora-infra/anitya',
+                'id': 14798348,
+                'language': 'Python',
+                'name': 'anitya',
+                'open_issues': 25,
+                'open_issues_count': 25,
+                'owner': {
+                    'gravatar_id': '',
+                    'html_url': 'https://github.com/fedora-infra',
+                    'id': 3316637,
+                    'login': 'fedora-infra',
+                    'site_admin': False,
+                    'type': 'Organization',
+                    'url': 'https://api.github.com/users/fedora-infra'
+                },
+                'private': False,
+                'pushed_at': '2016-06-05T18:16:15Z',
+                'size': 4364,
+                'stargazers_count': 56,
+                'updated_at': '2016-06-10T09:43:58Z',
+                'url': 'https://api.github.com/repos/fedora-infra/anitya',
+                'watchers': 56,
+                'watchers_count': 56
+            },
+            'sender': {
+                'gravatar_id': '',
+                'html_url': 'https://github.com/pypingou',
+                'id': 1240038,
+                'login': 'pypingou',
+                'site_admin': False,
+                'type': 'User',
+                'url': 'https://api.github.com/users/pypingou'
+            }
+        },
+        'arguments': {
+            'categories': [
+                'pagure'
+            ],
+            'contains': [],
+            'delta': 172800.0,
+            'end': 1465839365.0,
+            'grouped': False,
+            'meta': [],
+            'not_categories': [],
+            'not_packages': [],
+            'not_topics': [],
+            'not_users': [],
+            'order': 'desc',
+            'packages': [],
+            'page': 1,
+            'rows_per_page': 1,
+            'start': 1465666565.0,
+            'topics': [],
+            'users': []
+        },
+        'count': 1,
+        'pages': 225,
+        'total': 225
+    }
+    message_not_involved = {
+        'topic': 'org.fedoraproject.prod.github.issue.comment',
+        'i': 1,
+        'msg': {
+            'action': 'created',
+            'comment': {
+                'body':
+                'hm, there is something odd, the stackage page is being inconsistent, one time the version number for LTS is linked, one time it isn\'t.\r\n\r\nIt\'s as if there are 2 servers running 2 different versions of the application',
+                'created_at': '2016-06-10T14:03:31Z',
+                'html_url':
+                'https://github.com/fedora-infra/anitya/issues/283#issuecomment-225190438',
+                'id': 225190438,
+                'updated_at': '2016-06-10T14:03:31Z',
+                'url':
+                'https://api.github.com/repos/fedora-infra/anitya/issues/comments/225190438',
+                'user': {
+                    'gravatar_id': '',
+                    'html_url': 'https://github.com/pypingou',
+                    'id': 1240038,
+                    'login': 'pypingou',
+                    'site_admin': False,
+                    'type': 'User',
+                    'url': 'https://api.github.com/users/pypingou'
+                }
+            },
+            'fas_usernames': {
+                'fedora-infra': 'github_org_fedora-infra',
+                'pypingou': 'pingou'
+            },
+            'issue': {
+                'assignee': None,
+                'body':
+                '@juhp it seems that the stackage backend is broken: https://release-monitoring.org/projects/updates/failed?name=&log=stackage want to look at it?',
+                'closed_at': '2016-04-29T14:53:10Z',
+                'comments': 8,
+                'created_at': '2016-04-15T16:15:57Z',
+                'html_url':
+                'https://github.com/fedora-infra/anitya/issues/283',
+                'id': 148703615,
+                'labels': [],
+                'locked': False,
+                'milestone': None,
+                'number': 283,
+                'state': 'closed',
+                'title': 'stackage backend broken',
+                'updated_at': '2016-06-10T14:03:31Z',
+                'url':
+                'https://api.github.com/repos/fedora-infra/anitya/issues/283',
+                'user': {
+                    'gravatar_id': '',
+                    'html_url': 'https://github.com/pypingou',
+                    'id': 1240038,
+                    'login': 'pypingou',
+                    'site_admin': False,
+                    'type': 'User',
+                    'url': 'https://api.github.com/users/pypingou'
+                }
+            },
+            'organization': {
+                'description': 'Fedora Infrastructure Team',
+                'id': 3316637,
+                'login': 'fedora-infra',
+                'url': 'https://api.github.com/orgs/fedora-infra'
+            },
+            'repository': {
+                'created_at': '2013-11-29T10:17:26Z',
+                'default_branch': 'master',
+                'description':
+                'A cross-distribution upstream release monitoring project',
+                'fork': False,
+                'forks': 33,
+                'forks_count': 33,
+                'full_name': 'fedora-infra/anitya',
+                'has_downloads': True,
+                'has_issues': True,
+                'has_pages': False,
+                'has_wiki': False,
+                'homepage': 'https://release-monitoring.org',
+                'html_url': 'https://github.com/fedora-infra/anitya',
+                'id': 14798348,
+                'language': 'Python',
+                'name': 'anitya',
+                'open_issues': 25,
+                'open_issues_count': 25,
+                'owner': {
+                    'gravatar_id': '',
+                    'html_url': 'https://github.com/fedora-infra',
+                    'id': 3316637,
+                    'login': 'fedora-infra',
+                    'site_admin': False,
+                    'type': 'Organization',
+                    'url': 'https://api.github.com/users/fedora-infra'
+                },
+                'private': False,
+                'pushed_at': '2016-06-05T18:16:15Z',
+                'size': 4364,
+                'stargazers_count': 56,
+                'updated_at': '2016-06-10T09:43:58Z',
+                'url': 'https://api.github.com/repos/fedora-infra/anitya',
+                'watchers': 56,
+                'watchers_count': 56
+            },
+            'sender': {
+                'gravatar_id': '',
+                'html_url': 'https://github.com/pypingou',
+                'id': 1240038,
+                'login': 'pypingou',
+                'site_admin': False,
+                'type': 'User',
+                'url': 'https://api.github.com/users/pypingou'
+            }
+        },
+        'msg_id': '2016-0490127f-473f-4d01-8e3a-a864a56dc302',
+        'signature':
+        'MNpAVdrPW78dcSe94FOS+/6QFBYo/LkrV5ee9tQedkhurHY1BGpaFHlU5l8cNVEpB7rr/zhHgQ+V\nmE3zYPmW/aREgvUoQgz74TR5F6/nK4Q1cD97VkFgHCadxZC6kjXd4H3BahEYnD+erj1iaArcdZaI\nXyKLZUBJLYL4JiXlmec=\n',
+        'source_name': 'datanommer',
+        'source_version': '0.6.5',
+        'timestamp': 1465567413.0,
+        'topic': 'org.fedoraproject.prod.github.issue.comment'
+    }
+
+    plugin = 'feed'
+
+    def test_returns_400_when_no_message(self):
+        payload = {'plugin': 'feed'}
+        response = self.app.get('/api/fedmsg/markup', query_string=payload)
+        assert response.status_code == 400
+
+    def test_returns_400_when_no_plugin(self):
+        payload = {'message': json.dumps(self.message_involved)}
+        response = self.app.get('/api/fedmsg/markup', query_string=payload)
+        assert response.status_code == 400
+
+    def test_returns_400_when_bad_plugin_name(self):
+        payload = {
+            'message': json.dumps(self.message_involved),
+            'plugin': 'notarealplugin'
+        }
+        response = self.app.get('/api/fedmsg/markup', query_string=payload)
+        assert response.status_code == 400
+
+    def test_returns_403_when_not_logged_in(self):
+        payload = {
+            'message': json.dumps(self.message_involved),
+            'plugin': 'feed'
+        }
+        with hubs.tests.user_set(self.app, self.user):
+            response = self.app.get('/api/fedmsg/markup', query_string=payload)
+
+            assert response.status_code == 403
+
+    def test_returns_match_if_involved(self):
+        payload = {
+            'message': json.dumps(self.message_involved),
+            'plugin': 'feed'
+        }
+        with self.app.session_transaction() as sess:
+            sess['openid'] = 'atelic@fedoraproject.org'
+            sess['nickname'] = 'atelic'
+
+        with hubs.tests.user_set(self.app, self.user):
+            response = self.app.get('/api/fedmsg/markup', query_string=payload)
+
+            assert response.status_code == 200, response.status_code
+            data = json.loads(response.data)
+            self.assertTrue(data)
+            assert isinstance(data[0], dict)
+
+    def test_returns_no_match_if_not_involved(self):
+        payload = {
+            'message': json.dumps(self.message_not_involved),
+            'plugin': 'feed'
+        }
+        with self.app.session_transaction() as sess:
+            sess['openid'] = 'atelic@fedoraproject.org'
+            sess['nickname'] = 'atelic'
+
+        with hubs.tests.user_set(self.app, self.user):
+            response = self.app.get('/api/fedmsg/markup', query_string=payload)
+
+            assert response.status_code == 200, response.status_code
+            data = json.loads(response.data)
+            self.assertFalse(data)

From d4fcd3f05604b98fe20b20e74b6d3a375f871c76 Mon Sep 17 00:00:00 2001
From: Eric Barbour <ebarbour@redhat.com>
Date: Jun 16 2016 14:42:05 +0000
Subject: [PATCH 2/3] Add tests for /api/hub/*


Still skipping tests that check logged out behavior until issues can be
worked out with testing redirecting

---

diff --git a/hubs/app.py b/hubs/app.py
index df33459..c283490 100755
--- a/hubs/app.py
+++ b/hubs/app.py
@@ -641,6 +641,12 @@ def hub_leave(hub):
 
 @app.route('/api/fedmsg/markup', methods=['GET'])
 def markup_fedmsg():
+    '''
+    This is a temporary endpoint to create a human-readable form of a message.
+    For now it serves as a development tool
+
+    This route will be removed once its functionality is integrated into FMN
+    '''
     try:
         data = flask.request.args['message']
         plugin = flask.request.args['plugin']
diff --git a/hubs/tests/__init__.py b/hubs/tests/__init__.py
index 7c9da28..bafe0a1 100644
--- a/hubs/tests/__init__.py
+++ b/hubs/tests/__init__.py
@@ -88,28 +88,16 @@ class APPTest(unittest.TestCase):
 
 
 @contextmanager
-def user_set(APP, user):
-    """ Set the provided user as fas_user in the provided application."""
-    # Hack used to remove the before_request function set by
-    # flask.ext.fas_openid.FAS which otherwise kills our effort to set a
-    # flask.g.fas_user.
-    from flask import appcontext_pushed, g
-
-    def handler(sender, **kwargs):
-        g.fas_user = user
-        g.fas_session_id = b'123'
-
-    with appcontext_pushed.connected_to(handler, APP):
-        yield
-
-
-@contextmanager
 def auth_set(APP, auth):
-    """ Set the provided user as fas_user in the provided application."""
+    """
+    Set the provided user as g.auth in the provided application.
+    :param APP: A Flask instance. Cannot be a FlaskClient.
+    :param auth: A FakeAuthorization instance to set as g.auth.
+    """
 
     # Hack used to remove the before_request function set by
     # flask.ext.fas_openid.FAS which otherwise kills our effort to set a
-    # flask.g.fas_user.
+    # flask.g.auth.
     from flask import appcontext_pushed, g
     APP.before_request_funcs[None] = []
 
@@ -123,7 +111,7 @@ def auth_set(APP, auth):
 
 
 class FakeUser(object):
-    """ Fake user used to test the fedocallib library. """
+    """ Fake user to be attached to an Authorization. """
 
     def __init__(self, username='username'):
         """ Constructor.
@@ -131,7 +119,7 @@ class FakeUser(object):
             supposed to be.
         """
         self.username = username
-        self.openid = username + 'id.fedoraproject.org'
+        self.openid = username + '.id.fedoraproject.org'
         self.booksmarks = []
 
     def __getitem__(self, key):
@@ -139,7 +127,7 @@ class FakeUser(object):
 
 
 class FakeAuthorization(object):
-    """ Fake user used to test the fedocallib library. """
+    """ Fake Authorization used to set as flask.g.auth. """
 
     def __init__(self, username='username'):
         """ Constructor.
@@ -149,10 +137,11 @@ class FakeAuthorization(object):
         self.logged_in = True
         self.fullname = 'fullname: ' + username
         self.email = 'email: ' + username
-        self.openid = username + 'id.fedoraproject.org'
+        self.openid = username + '.id.fedoraproject.org'
         self.user = FakeUser(username)
         self.avatar = 'avatar_src_url'
         self.nickname = username
+        self.username = username
 
     def __getitem__(self, key):
         return self.dic[key]
diff --git a/hubs/tests/test_api/test_fedmsg.py b/hubs/tests/test_api/test_fedmsg.py
index c708073..ef3b6db 100644
--- a/hubs/tests/test_api/test_fedmsg.py
+++ b/hubs/tests/test_api/test_fedmsg.py
@@ -2,6 +2,7 @@ import json
 
 import hubs.tests
 import hubs.models
+from hubs.app import app
 
 
 class TestFeed(hubs.tests.APPTest):
@@ -271,12 +272,12 @@ class TestFeed(hubs.tests.APPTest):
     def test_returns_400_when_no_message(self):
         payload = {'plugin': 'feed'}
         response = self.app.get('/api/fedmsg/markup', query_string=payload)
-        assert response.status_code == 400
+        self.assertEqual(response.status_code, 400)
 
     def test_returns_400_when_no_plugin(self):
         payload = {'message': json.dumps(self.message_involved)}
         response = self.app.get('/api/fedmsg/markup', query_string=payload)
-        assert response.status_code == 400
+        self.assertEqual(response.status_code, 400)
 
     def test_returns_400_when_bad_plugin_name(self):
         payload = {
@@ -284,17 +285,16 @@ class TestFeed(hubs.tests.APPTest):
             'plugin': 'notarealplugin'
         }
         response = self.app.get('/api/fedmsg/markup', query_string=payload)
-        assert response.status_code == 400
+        self.assertEqual(response.status_code, 400)
 
     def test_returns_403_when_not_logged_in(self):
         payload = {
             'message': json.dumps(self.message_involved),
             'plugin': 'feed'
         }
-        with hubs.tests.user_set(self.app, self.user):
-            response = self.app.get('/api/fedmsg/markup', query_string=payload)
 
-            assert response.status_code == 403
+        response = self.app.get('/api/fedmsg/markup', query_string=payload)
+        self.assertEqual(response.status_code, 403)
 
     def test_returns_match_if_involved(self):
         payload = {
@@ -305,13 +305,13 @@ class TestFeed(hubs.tests.APPTest):
             sess['openid'] = 'atelic@fedoraproject.org'
             sess['nickname'] = 'atelic'
 
-        with hubs.tests.user_set(self.app, self.user):
+        with hubs.tests.auth_set(app, self.user):
             response = self.app.get('/api/fedmsg/markup', query_string=payload)
 
-            assert response.status_code == 200, response.status_code
+            self.assertEqual(response.status_code, 200)
             data = json.loads(response.data)
             self.assertTrue(data)
-            assert isinstance(data[0], dict)
+            self.assertTrue(isinstance(data[0], dict))
 
     def test_returns_no_match_if_not_involved(self):
         payload = {
@@ -322,9 +322,9 @@ class TestFeed(hubs.tests.APPTest):
             sess['openid'] = 'atelic@fedoraproject.org'
             sess['nickname'] = 'atelic'
 
-        with hubs.tests.user_set(self.app, self.user):
+        with hubs.tests.auth_set(app, self.user):
             response = self.app.get('/api/fedmsg/markup', query_string=payload)
 
-            assert response.status_code == 200, response.status_code
+            self.assertEqual(response.status_code, 200)
             data = json.loads(response.data)
             self.assertFalse(data)
diff --git a/hubs/tests/test_api/test_hub.py b/hubs/tests/test_api/test_hub.py
new file mode 100644
index 0000000..ee749d9
--- /dev/null
+++ b/hubs/tests/test_api/test_hub.py
@@ -0,0 +1,150 @@
+import flask
+import unittest
+
+import hubs.tests
+import hubs.models
+from hubs.app import app
+
+
+def usernames(collection): return [u.username for u in collection]
+
+
+class TestHubSubscribe(hubs.tests.APPTest):
+    user = hubs.tests.FakeAuthorization('decause')
+
+    @unittest.skip('Need to handle redirects')
+    def test_subscribe_redirects_when_logged_out(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        resp = self.app.post('/api/hub/{}/subscribe'.format(hub.idx))
+        self.assertEqual(resp.status_code, 302)
+        self.assertEqual(resp.location, flask.url_for('fedora.login'))
+
+    def test_subscribe_when_logged_in(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        with hubs.tests.auth_set(app, self.user):
+            resp = self.app.post('/api/hub/{}/subscribe'.format(hub.name),
+                                 follow_redirects=True)
+            self.assertEqual(resp.status_code, 200)
+            # Need to find the Hub again to avoid DetachedInstanceError
+            h = hubs.models.Hub.by_name(self.session, 'infra')
+            self.assertTrue(self.user.username in usernames(h.subscribers))
+
+
+class TestHubUnsubscribe(hubs.tests.APPTest):
+    user = hubs.tests.FakeAuthorization('decause')
+
+    @unittest.skip('Need to handle redirects')
+    def test_unsubscribe_redirects_when_logged_out(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        resp = self.app.post('/api/hub/{}/unsubscribe'.format(hub.idx))
+        self.assertEqual(resp.status_code, 302)
+        self.assertEqual(resp.location, flask.url_for('fedora.login'))
+
+    def test_unsubscribe_when_logged_in(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        # Need a real user model to subscribe to the hub
+        User = hubs.models.User.by_username(self.session, self.user.username)
+        hub.subscribe(self.session, User)
+
+        self.assertTrue(self.user.username in usernames(hub.subscribers))
+
+        with hubs.tests.auth_set(app, self.user):
+            resp = self.app.post('/api/hub/{}/unsubscribe'.format(hub.name),
+                                 follow_redirects=True)
+            self.assertEqual(resp.status_code, 200)
+            h = hubs.models.Hub.by_name(self.session, 'infra')
+            self.assertTrue(self.user.username not in usernames(h.subscribers))
+
+
+class TestHubStar(hubs.tests.APPTest):
+    user = hubs.tests.FakeAuthorization('decause')
+
+    @unittest.skip('Need to handle redirects')
+    def test_star_redirects_when_logged_out(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        resp = self.app.post('/api/hub/{}/star'.format(hub.idx))
+        self.assertEqual(resp.status_code, 302)
+        self.assertEqual(resp.location, flask.url_for('fedora.login'))
+
+    def test_star_when_logged_in(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        with hubs.tests.auth_set(app, self.user):
+            resp = self.app.post('/api/hub/{}/star'.format(hub.name),
+                                 follow_redirects=True)
+
+            self.assertEqual(resp.status_code, 200)
+            h = hubs.models.Hub.by_name(self.session, 'infra')
+            self.assertTrue(self.user.username in usernames(h.stargazers))
+
+
+class TestHubUnstar(hubs.tests.APPTest):
+    user = hubs.tests.FakeAuthorization('decause')
+
+    @unittest.skip('Need to handle redirects')
+    def test_unstar_redirects_when_logged_out(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        resp = self.app.post('/api/hub/{}/unstar'.format(hub.idx))
+        self.assertEqual(resp.status_code, 302)
+        self.assertEqual(resp.location, flask.url_for('fedora.login'))
+
+    def test_unstar_when_logged_in(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        # Need a real user model to subscribe to the hub
+        User = hubs.models.User.by_username(self.session, self.user.username)
+        hub.subscribe(self.session, User, role='stargazer')
+
+        self.assertTrue(self.user.username in [u.username for
+                                               u in hub.stargazers])
+
+        with hubs.tests.auth_set(app, self.user):
+            resp = self.app.post('/api/hub/{}/unstar'.format(hub.name),
+                                 follow_redirects=True)
+            self.assertEqual(resp.status_code, 200)
+            h = hubs.models.Hub.by_name(self.session, 'infra')
+            self.assertTrue(self.user.username not in usernames(h.stargazers))
+
+
+class TestHubJoin(hubs.tests.APPTest):
+    user = hubs.tests.FakeAuthorization('decause')
+
+    @unittest.skip('Need to handle redirects')
+    def test_join_redirects_when_logged_out(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        resp = self.app.post('/api/hub/{}/join'.format(hub.idx))
+        self.assertEqual(resp.status_code, 302)
+        self.assertEqual(resp.location, flask.url_for('fedora.login'))
+
+    def test_join_when_logged_in(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        with hubs.tests.auth_set(app, self.user):
+            resp = self.app.post('/api/hub/{}/join'.format(hub.name),
+                                 follow_redirects=True)
+
+            self.assertEqual(resp.status_code, 200)
+            h = hubs.models.Hub.by_name(self.session, 'infra')
+            self.assertTrue(self.user.username in usernames(h.members))
+
+
+class TestHubLeave(hubs.tests.APPTest):
+    user = hubs.tests.FakeAuthorization('decause')
+
+    @unittest.skip('Need to handle redirects')
+    def test_leave_redirects_when_logged_out(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        resp = self.app.post('/api/hub/{}/leave'.format(hub.idx))
+        self.assertEqual(resp.status_code, 302)
+        self.assertEqual(resp.location, flask.url_for('fedora.login'))
+
+    def test_star_when_logged_in(self):
+        hub = hubs.models.Hub.by_name(self.session, 'infra')
+        # Need a real user model to subscribe to the hub
+        User = hubs.models.User.by_username(self.session, self.user.username)
+        hub.subscribe(self.session, User, role='member')
+
+        with hubs.tests.auth_set(app, self.user):
+            resp = self.app.post('/api/hub/{}/leave'.format(hub.name),
+                                 follow_redirects=True)
+
+            self.assertEqual(resp.status_code, 200)
+            h = hubs.models.Hub.by_name(self.session, 'infra')
+            self.assertTrue(self.user.username not in usernames(h.members))

From eaa718781c8cbeadd90929820bd07c5871ec4a00 Mon Sep 17 00:00:00 2001
From: Eric Barbour <ebarbour@redhat.com>
Date: Jun 16 2016 15:54:14 +0000
Subject: [PATCH 3/3] Apply pep8 and move json data to their own files


---

diff --git a/hubs/tests/__init__.py b/hubs/tests/__init__.py
index bafe0a1..96379c2 100644
--- a/hubs/tests/__init__.py
+++ b/hubs/tests/__init__.py
@@ -1,6 +1,7 @@
 from contextlib import contextmanager
 import json
 from datetime import datetime, timedelta
+import os
 
 import munch
 from os.path import dirname
@@ -12,6 +13,8 @@ import vcr
 import hubs.models
 
 cassette_dir = dirname(dirname(__file__)) + '/vcr-request-data/'
+json_path = os.path.join(
+    os.path.join(os.path.dirname(os.path.abspath(__file__))), 'data/')
 
 
 class APPTest(unittest.TestCase):
diff --git a/hubs/tests/data/message_involved.json b/hubs/tests/data/message_involved.json
new file mode 100644
index 0000000..fdfd0db
--- /dev/null
+++ b/hubs/tests/data/message_involved.json
@@ -0,0 +1,137 @@
+{
+    "timestamp": 1465567413.0,
+    "topic": "io.pagure.prod.pagure.issue.new",
+    "msg_id": "2016-0490127f-473f-4d01-ASDF-a864a56dc302",
+    "msg": {
+        "action": "created",
+        "comment": {
+            "body":
+            "hm, there is something odd the stackage page is inconsistent",
+            "created_at": "2016-06-10T14:03:31Z",
+            "html_url":
+            "https://github.com/fedora-infra/anitya/issues/283#issuecomment-225190438",
+            "id": 225190438,
+            "updated_at": "2016-06-10T14:03:31Z",
+            "url":
+            "https://api.github.com/repos/fedora-infra/anitya/issues/comments/225190438",
+            "user": {
+                "gravatar_id": "",
+                "html_url": "https://github.com/pypingou",
+                "id": 1240038,
+                "login": "pypingou",
+                "site_admin": false,
+                "type": "User",
+                "url": "https://api.github.com/users/pypingou"
+            }
+        },
+        "fas_usernames": {
+            "fedora-infra": "github_org_fedora-infra",
+            "pypingou": "pingou"
+        },
+        "issue": {
+            "assignee": null,
+            "body":
+            "@juhp it seems that the stackage backend is broken:",
+            "closed_at": "2016-04-29T14:53:10Z",
+            "comments": 8,
+            "created_at": "2016-04-15T16:15:57Z",
+            "html_url":
+            "https://github.com/fedora-infra/anitya/issues/283",
+            "id": 148703615,
+            "labels": [],
+            "locked": false,
+            "milestone": null,
+            "number": 283,
+            "state": "closed",
+            "title": "stackage backend broken",
+            "updated_at": "2016-06-10T14:03:31Z",
+            "url":
+            "https://api.github.com/repos/fedora-infra/anitya/issues/283",
+            "user": {
+                "gravatar_id": "",
+                "html_url": "https://github.com/pypingou",
+                "id": 1240038,
+                "login": "pypingou",
+                "site_admin": false,
+                "type": "User",
+                "url": "https://api.github.com/users/pypingou"
+            }
+        },
+        "organization": {
+            "description": "Fedora Infrastructure Team",
+            "id": 3316637,
+            "login": "fedora-infra",
+            "url": "https://api.github.com/orgs/fedora-infra"
+        },
+        "repository": {
+            "created_at": "2013-11-29T10:17:26Z",
+            "default_branch": "master",
+            "description": "A cross-distribution upstream release project",
+            "fork": false,
+            "forks": 33,
+            "forks_count": 33,
+            "full_name": "fedora-infra/anitya",
+            "has_downloads": true,
+            "has_issues": true,
+            "has_pages": false,
+            "has_wiki": false,
+            "homepage": "https://release-monitoring.org",
+            "html_url": "https://github.com/fedora-infra/anitya",
+            "id": 14798348,
+            "language": "Python",
+            "name": "anitya",
+            "open_issues": 25,
+            "open_issues_count": 25,
+            "owner": {
+                "gravatar_id": "",
+                "html_url": "https://github.com/fedora-infra",
+                "id": 3316637,
+                "login": "fedora-infra",
+                "site_admin": false,
+                "type": "Organization",
+                "url": "https://api.github.com/users/fedora-infra"
+            },
+            "private": false,
+            "pushed_at": "2016-06-05T18:16:15Z",
+            "size": 4364,
+            "stargazers_count": 56,
+            "updated_at": "2016-06-10T09:43:58Z",
+            "url": "https://api.github.com/repos/fedora-infra/anitya",
+            "watchers": 56,
+            "watchers_count": 56
+        },
+        "sender": {
+            "gravatar_id": "",
+            "html_url": "https://github.com/pypingou",
+            "id": 1240038,
+            "login": "pypingou",
+            "site_admin": false,
+            "type": "User",
+            "url": "https://api.github.com/users/pypingou"
+        }
+    },
+    "arguments": {
+        "categories": [
+            "pagure"
+        ],
+        "contains": [],
+        "delta": 172800.0,
+        "end": 1465839365.0,
+        "grouped": false,
+        "meta": [],
+        "not_categories": [],
+        "not_packages": [],
+        "not_topics": [],
+        "not_users": [],
+        "order": "desc",
+        "packages": [],
+        "page": 1,
+        "rows_per_page": 1,
+        "start": 1465666565.0,
+        "topics": [],
+        "users": []
+    },
+    "count": 1,
+    "pages": 225,
+    "total": 225
+}
diff --git a/hubs/tests/data/message_not_involved.json b/hubs/tests/data/message_not_involved.json
new file mode 100644
index 0000000..e72439a
--- /dev/null
+++ b/hubs/tests/data/message_not_involved.json
@@ -0,0 +1,120 @@
+{
+    "topic": "org.fedoraproject.prod.github.issue.comment",
+    "i": 1,
+    "msg": {
+        "action": "created",
+        "comment": {
+            "body":
+            "hm, there is something odd the stackage page is inconsistent",
+            "created_at": "2016-06-10T14:03:31Z",
+            "html_url":
+            "https://github.com/fedora-infra/anitya/issues/283#issuecomment-225190438",
+            "id": 225190438,
+            "updated_at": "2016-06-10T14:03:31Z",
+            "url":
+            "https://api.github.com/repos/fedora-infra/anitya/issues/comments/225190438",
+            "user": {
+                "gravatar_id": "",
+                "html_url": "https://github.com/pypingou",
+                "id": 1240038,
+                "login": "pypingou",
+                "site_admin": false,
+                "type": "User",
+                "url": "https://api.github.com/users/pypingou"
+            }
+        },
+        "fas_usernames": {
+            "fedora-infra": "github_org_fedora-infra",
+            "pypingou": "pingou"
+        },
+        "issue": {
+            "assignee": null,
+            "body":
+            "@juhp it seems that the stackage backend is broken",
+            "closed_at": "2016-04-29T14:53:10Z",
+            "comments": 8,
+            "created_at": "2016-04-15T16:15:57Z",
+            "html_url":
+            "https://github.com/fedora-infra/anitya/issues/283",
+            "id": 148703615,
+            "labels": [],
+            "locked": false,
+            "milestone": null,
+            "number": 283,
+            "state": "closed",
+            "title": "stackage backend broken",
+            "updated_at": "2016-06-10T14:03:31Z",
+            "url":
+            "https://api.github.com/repos/fedora-infra/anitya/issues/283",
+            "user": {
+                "gravatar_id": "",
+                "html_url": "https://github.com/pypingou",
+                "id": 1240038,
+                "login": "pypingou",
+                "site_admin": false,
+                "type": "User",
+                "url": "https://api.github.com/users/pypingou"
+            }
+        },
+        "organization": {
+            "description": "Fedora Infrastructure Team",
+            "id": 3316637,
+            "login": "fedora-infra",
+            "url": "https://api.github.com/orgs/fedora-infra"
+        },
+        "repository": {
+            "created_at": "2013-11-29T10:17:26Z",
+            "default_branch": "master",
+            "description":
+            "A cross-distribution upstream release monitoring project",
+            "fork": false,
+            "forks": 33,
+            "forks_count": 33,
+            "full_name": "fedora-infra/anitya",
+            "has_downloads": true,
+            "has_issues": true,
+            "has_pages": false,
+            "has_wiki": false,
+            "homepage": "https://release-monitoring.org",
+            "html_url": "https://github.com/fedora-infra/anitya",
+            "id": 14798348,
+            "language": "Python",
+            "name": "anitya",
+            "open_issues": 25,
+            "open_issues_count": 25,
+            "owner": {
+                "gravatar_id": "",
+                "html_url": "https://github.com/fedora-infra",
+                "id": 3316637,
+                "login": "fedora-infra",
+                "site_admin": false,
+                "type": "Organization",
+                "url": "https://api.github.com/users/fedora-infra"
+            },
+            "private": false,
+            "pushed_at": "2016-06-05T18:16:15Z",
+            "size": 4364,
+            "stargazers_count": 56,
+            "updated_at": "2016-06-10T09:43:58Z",
+            "url": "https://api.github.com/repos/fedora-infra/anitya",
+            "watchers": 56,
+            "watchers_count": 56
+        },
+        "sender": {
+            "gravatar_id": "",
+            "html_url": "https://github.com/pypingou",
+            "id": 1240038,
+            "login": "pypingou",
+            "site_admin": false,
+            "type": "User",
+            "url": "https://api.github.com/users/pypingou"
+        }
+    },
+    "msg_id": "2016-0490127f-473f-4d01-8e3a-a864a56dc302",
+    "signature":
+    "MNpAVdrPW78dcSe94FOS+/6QFBYo/LkrV5ee9tQedkhurHY1BGpaFHlU5l8cNVEpB7rr",
+    "source_name": "datanommer",
+    "source_version": "0.6.5",
+    "timestamp": 1465567413.0,
+    "topic": "org.fedoraproject.prod.github.issue.comment"
+}
diff --git a/hubs/tests/test_api/test_fedmsg.py b/hubs/tests/test_api/test_fedmsg.py
index ef3b6db..d6e67ef 100644
--- a/hubs/tests/test_api/test_fedmsg.py
+++ b/hubs/tests/test_api/test_fedmsg.py
@@ -1,271 +1,23 @@
 import json
+import os
 
 import hubs.tests
 import hubs.models
 from hubs.app import app
+from hubs.tests import json_path
 
 
 class TestFeed(hubs.tests.APPTest):
+
+    with open(json_path + 'message_involved.json', 'r') as fp:
+        message_involved = json.loads(fp.read())
+
+    with open(json_path + 'message_not_involved.json', 'r') as fp:
+        message_not_involved = json.loads(fp.read())
+
     # TODO this test relies on a specific filter for the atelic user
     # It would be better to fake preferences on FAS
     user = hubs.tests.FakeAuthorization('atelic')
-    message_involved = {
-        'timestamp': 1465567413.0,
-        'topic': 'io.pagure.prod.pagure.issue.new',
-        'msg_id': '2016-0490127f-473f-4d01-ASDF-a864a56dc302',
-        'msg': {
-            'action': 'created',
-            'comment': {
-                'body':
-                'hm, there is something odd, the stackage page is being inconsistent, one time the version number for LTS is linked, one time it isn\'t.\r\n\r\nIt\'s as if there are 2 servers running 2 different versions of the application',
-                'created_at': '2016-06-10T14:03:31Z',
-                'html_url':
-                'https://github.com/fedora-infra/anitya/issues/283#issuecomment-225190438',
-                'id': 225190438,
-                'updated_at': '2016-06-10T14:03:31Z',
-                'url':
-                'https://api.github.com/repos/fedora-infra/anitya/issues/comments/225190438',
-                'user': {
-                    'gravatar_id': '',
-                    'html_url': 'https://github.com/pypingou',
-                    'id': 1240038,
-                    'login': 'pypingou',
-                    'site_admin': False,
-                    'type': 'User',
-                    'url': 'https://api.github.com/users/pypingou'
-                }
-            },
-            'fas_usernames': {
-                'fedora-infra': 'github_org_fedora-infra',
-                'pypingou': 'pingou'
-            },
-            'issue': {
-                'assignee': None,
-                'body':
-                '@juhp it seems that the stackage backend is broken: https://release-monitoring.org/projects/updates/failed?name=&log=stackage want to look at it?',
-                'closed_at': '2016-04-29T14:53:10Z',
-                'comments': 8,
-                'created_at': '2016-04-15T16:15:57Z',
-                'html_url':
-                'https://github.com/fedora-infra/anitya/issues/283',
-                'id': 148703615,
-                'labels': [],
-                'locked': False,
-                'milestone': None,
-                'number': 283,
-                'state': 'closed',
-                'title': 'stackage backend broken',
-                'updated_at': '2016-06-10T14:03:31Z',
-                'url':
-                'https://api.github.com/repos/fedora-infra/anitya/issues/283',
-                'user': {
-                    'gravatar_id': '',
-                    'html_url': 'https://github.com/pypingou',
-                    'id': 1240038,
-                    'login': 'pypingou',
-                    'site_admin': False,
-                    'type': 'User',
-                    'url': 'https://api.github.com/users/pypingou'
-                }
-            },
-            'organization': {
-                'description': 'Fedora Infrastructure Team',
-                'id': 3316637,
-                'login': 'fedora-infra',
-                'url': 'https://api.github.com/orgs/fedora-infra'
-            },
-            'repository': {
-                'created_at': '2013-11-29T10:17:26Z',
-                'default_branch': 'master',
-                'description': 'A cross-distribution upstream release project',
-                'fork': False,
-                'forks': 33,
-                'forks_count': 33,
-                'full_name': 'fedora-infra/anitya',
-                'has_downloads': True,
-                'has_issues': True,
-                'has_pages': False,
-                'has_wiki': False,
-                'homepage': 'https://release-monitoring.org',
-                'html_url': 'https://github.com/fedora-infra/anitya',
-                'id': 14798348,
-                'language': 'Python',
-                'name': 'anitya',
-                'open_issues': 25,
-                'open_issues_count': 25,
-                'owner': {
-                    'gravatar_id': '',
-                    'html_url': 'https://github.com/fedora-infra',
-                    'id': 3316637,
-                    'login': 'fedora-infra',
-                    'site_admin': False,
-                    'type': 'Organization',
-                    'url': 'https://api.github.com/users/fedora-infra'
-                },
-                'private': False,
-                'pushed_at': '2016-06-05T18:16:15Z',
-                'size': 4364,
-                'stargazers_count': 56,
-                'updated_at': '2016-06-10T09:43:58Z',
-                'url': 'https://api.github.com/repos/fedora-infra/anitya',
-                'watchers': 56,
-                'watchers_count': 56
-            },
-            'sender': {
-                'gravatar_id': '',
-                'html_url': 'https://github.com/pypingou',
-                'id': 1240038,
-                'login': 'pypingou',
-                'site_admin': False,
-                'type': 'User',
-                'url': 'https://api.github.com/users/pypingou'
-            }
-        },
-        'arguments': {
-            'categories': [
-                'pagure'
-            ],
-            'contains': [],
-            'delta': 172800.0,
-            'end': 1465839365.0,
-            'grouped': False,
-            'meta': [],
-            'not_categories': [],
-            'not_packages': [],
-            'not_topics': [],
-            'not_users': [],
-            'order': 'desc',
-            'packages': [],
-            'page': 1,
-            'rows_per_page': 1,
-            'start': 1465666565.0,
-            'topics': [],
-            'users': []
-        },
-        'count': 1,
-        'pages': 225,
-        'total': 225
-    }
-    message_not_involved = {
-        'topic': 'org.fedoraproject.prod.github.issue.comment',
-        'i': 1,
-        'msg': {
-            'action': 'created',
-            'comment': {
-                'body':
-                'hm, there is something odd, the stackage page is being inconsistent, one time the version number for LTS is linked, one time it isn\'t.\r\n\r\nIt\'s as if there are 2 servers running 2 different versions of the application',
-                'created_at': '2016-06-10T14:03:31Z',
-                'html_url':
-                'https://github.com/fedora-infra/anitya/issues/283#issuecomment-225190438',
-                'id': 225190438,
-                'updated_at': '2016-06-10T14:03:31Z',
-                'url':
-                'https://api.github.com/repos/fedora-infra/anitya/issues/comments/225190438',
-                'user': {
-                    'gravatar_id': '',
-                    'html_url': 'https://github.com/pypingou',
-                    'id': 1240038,
-                    'login': 'pypingou',
-                    'site_admin': False,
-                    'type': 'User',
-                    'url': 'https://api.github.com/users/pypingou'
-                }
-            },
-            'fas_usernames': {
-                'fedora-infra': 'github_org_fedora-infra',
-                'pypingou': 'pingou'
-            },
-            'issue': {
-                'assignee': None,
-                'body':
-                '@juhp it seems that the stackage backend is broken: https://release-monitoring.org/projects/updates/failed?name=&log=stackage want to look at it?',
-                'closed_at': '2016-04-29T14:53:10Z',
-                'comments': 8,
-                'created_at': '2016-04-15T16:15:57Z',
-                'html_url':
-                'https://github.com/fedora-infra/anitya/issues/283',
-                'id': 148703615,
-                'labels': [],
-                'locked': False,
-                'milestone': None,
-                'number': 283,
-                'state': 'closed',
-                'title': 'stackage backend broken',
-                'updated_at': '2016-06-10T14:03:31Z',
-                'url':
-                'https://api.github.com/repos/fedora-infra/anitya/issues/283',
-                'user': {
-                    'gravatar_id': '',
-                    'html_url': 'https://github.com/pypingou',
-                    'id': 1240038,
-                    'login': 'pypingou',
-                    'site_admin': False,
-                    'type': 'User',
-                    'url': 'https://api.github.com/users/pypingou'
-                }
-            },
-            'organization': {
-                'description': 'Fedora Infrastructure Team',
-                'id': 3316637,
-                'login': 'fedora-infra',
-                'url': 'https://api.github.com/orgs/fedora-infra'
-            },
-            'repository': {
-                'created_at': '2013-11-29T10:17:26Z',
-                'default_branch': 'master',
-                'description':
-                'A cross-distribution upstream release monitoring project',
-                'fork': False,
-                'forks': 33,
-                'forks_count': 33,
-                'full_name': 'fedora-infra/anitya',
-                'has_downloads': True,
-                'has_issues': True,
-                'has_pages': False,
-                'has_wiki': False,
-                'homepage': 'https://release-monitoring.org',
-                'html_url': 'https://github.com/fedora-infra/anitya',
-                'id': 14798348,
-                'language': 'Python',
-                'name': 'anitya',
-                'open_issues': 25,
-                'open_issues_count': 25,
-                'owner': {
-                    'gravatar_id': '',
-                    'html_url': 'https://github.com/fedora-infra',
-                    'id': 3316637,
-                    'login': 'fedora-infra',
-                    'site_admin': False,
-                    'type': 'Organization',
-                    'url': 'https://api.github.com/users/fedora-infra'
-                },
-                'private': False,
-                'pushed_at': '2016-06-05T18:16:15Z',
-                'size': 4364,
-                'stargazers_count': 56,
-                'updated_at': '2016-06-10T09:43:58Z',
-                'url': 'https://api.github.com/repos/fedora-infra/anitya',
-                'watchers': 56,
-                'watchers_count': 56
-            },
-            'sender': {
-                'gravatar_id': '',
-                'html_url': 'https://github.com/pypingou',
-                'id': 1240038,
-                'login': 'pypingou',
-                'site_admin': False,
-                'type': 'User',
-                'url': 'https://api.github.com/users/pypingou'
-            }
-        },
-        'msg_id': '2016-0490127f-473f-4d01-8e3a-a864a56dc302',
-        'signature':
-        'MNpAVdrPW78dcSe94FOS+/6QFBYo/LkrV5ee9tQedkhurHY1BGpaFHlU5l8cNVEpB7rr/zhHgQ+V\nmE3zYPmW/aREgvUoQgz74TR5F6/nK4Q1cD97VkFgHCadxZC6kjXd4H3BahEYnD+erj1iaArcdZaI\nXyKLZUBJLYL4JiXlmec=\n',
-        'source_name': 'datanommer',
-        'source_version': '0.6.5',
-        'timestamp': 1465567413.0,
-        'topic': 'org.fedoraproject.prod.github.issue.comment'
-    }
 
     plugin = 'feed'
 

