#5020 Pagure-messages integration
Merged 2 months ago by pingou. Opened 3 months ago by pingou.

@@ -23,6 +23,8 @@ 

      python-flask \

      python-flake8 \

      python2-pytest-xdist \

+     python2-fedora-messaging \

+     python2-pip \

      redis \

      which \

      git
@@ -30,6 +32,10 @@ 

  #    repoSpanner \

  #    repoSpanner-bridge

  

+ RUN pip install pip --upgrade

+ RUN pip install setuptools --upgrade

+ RUN pip install pagure-messages

+ 

  RUN cd / \

      && GIT_TRACE=1 GIT_CURL_VERBOSE=1 git clone -b $BRANCH $REPO \

      && chmod +x /pagure/dev/containers/runtests_py2.sh

@@ -15,10 +15,14 @@ 

      python3-flake8 \

      python3-pytest-xdist \

      python3-cchardet \

+     python3-fedora-messaging \

+     python3-pip \

      redis \

      which \

      git

  

+ RUN pip install pagure-messages

+ 

  RUN cd / \

      && GIT_TRACE=1 GIT_CURL_VERBOSE=1 git clone -b $BRANCH $REPO \

      && chmod +x /pagure/dev/containers/runtests_py3.sh

file modified
+15
@@ -2199,6 +2199,21 @@ 

  

  

  

+ NOGITHOOKS

+ ~~~~~~~~~~

+ 

+ This configuration key should not be touched. It is used in the test suite as a

+ way to prevent all the git hooks from running (which includes checking if the

+ user is allowed to push). Using this mechanism we are able to check some

+ behavior in the test suite that in a deployed pagure instance are happening in

+ a different process.

+ 

+ **Do not change this option in production**

+ 

+ Defaults to: ``None``.

+ 

+ 

+ 

  Deprecated configuration keys

  -----------------------------

  

@@ -497,6 +497,9 @@ 

          hooktype (string): The name of the hook to run: pre-receive, update

              or post-receive

      """

+     if pagure_config.get("NOGITHOOKS") or False:

+         return

+ 

      if hooktype not in ("pre-receive", "update", "post-receive"):

          raise ValueError("Hook type %s not valid" % hooktype)

      changes = extract_changes(from_stdin=hooktype != "update")

file modified
+2 -2
@@ -1505,7 +1505,7 @@ 

      @property

      def tags_text(self):

          """ Return the list of tags in a simple text form. """

-         return [tag.tag for tag in self.tags]

+         return sorted([tag.tag for tag in self.tags])

  

      @property

      def depending_text(self):
@@ -2180,7 +2180,7 @@ 

      @property

      def tags_text(self):

          """ Return the list of tags in a simple text form. """

-         return [tag.tag for tag in self.tags]

+         return sorted([tag.tag for tag in self.tags])

  

      @property

      def discussion(self):

file modified
+17 -3
@@ -80,13 +80,27 @@ 

      try:

          import fedora_messaging.api

          import fedora_messaging.exceptions

+         import pagure_messages

  

-         msg = fedora_messaging.api.Message(

-             topic="pagure.{}".format(topic), body=message

+         msg_cls = pagure_messages.get_message_object_from_topic(

+             "pagure.{}".format(topic)

          )

+ 

+         if not hasattr(msg_cls, "app_name") is False:

+             _log.warning(

+                 "pagure is about to send a message that has no schemas: %s",

+                 topic,

+             )

+ 

+         msg = msg_cls(body=message)

+         if not msg.topic:

+             msg.topic = "pagure.{}".format(topic)

          fedora_messaging.api.publish(msg)

      except ImportError:

-         _log.warning("Fedora messaging does not appear to be available")

+         _log.warning(

+             "Fedora messaging or pagure-messages does not appear to be "

+             "available"

+         )

      except fedora_messaging.exceptions.PublishReturned as e:

          _log.warning(

              "Fedora Messaging broker rejected message %s: %s", msg.id, e

file modified
+51 -17
@@ -498,7 +498,8 @@ 

  

          session.add(dbobjtag)

          # Make sure we won't have SQLAlchemy error before we continue

-         session.flush()

+         # Commit so the tags show up in the notification sent

+         session.commit()

          added_tags.append(tagobj.tag)

  

      if isinstance(obj, model.Issue):
@@ -511,7 +512,7 @@ 

                  msg=dict(

                      issue=obj.to_json(public=True),

                      project=obj.project.to_json(public=True),

-                     tags=added_tags,

+                     tags=sorted(added_tags),

                      agent=user_obj.username,

                  ),

              )
@@ -536,8 +537,9 @@ 

                  topic="pull-request.tag.added",

                  msg=dict(

                      pull_request=obj.to_json(public=True),

+                     pullrequest=obj.to_json(public=True),

                      project=obj.project.to_json(public=True),

-                     tags=added_tags,

+                     tags=sorted(added_tags),

                      agent=user_obj.username,

                  ),

              )
@@ -654,11 +656,23 @@ 

  

          pagure.lib.notify.notify_assigned_request(request, None, user_obj)

  

+         # Deprecated -- this is not consistent in both the topic and the body:

+         # request vs pull-request (topic) and request vs pullrequest (body)

          pagure.lib.notify.log(

              request.project,

              topic="request.assigned.reset",

              msg=dict(

                  request=request.to_json(public=True),

+                 pullrequest=request.to_json(public=True),

+                 project=request.project.to_json(public=True),

+                 agent=user_obj.username,

+             ),

+         )

+         pagure.lib.notify.log(

+             request.project,

+             topic="pull-request.assigned.reset",

+             msg=dict(

+                 pullrequest=request.to_json(public=True),

                  project=request.project.to_json(public=True),

                  agent=user_obj.username,

              ),
@@ -682,11 +696,23 @@ 

              request, assignee_obj, user_obj

          )

  

+         # Deprecated -- this is not consistent in both the topic and the body:

+         # request vs pull-request (topic) and request vs pullrequest (body)

          pagure.lib.notify.log(

              request.project,

              topic="request.assigned.added",

              msg=dict(

                  request=request.to_json(public=True),

+                 pullrequest=request.to_json(public=True),

+                 project=request.project.to_json(public=True),

+                 agent=user_obj.username,

+             ),

+         )

+         pagure.lib.notify.log(

+             request.project,

+             topic="pull-request.assigned.added",

+             msg=dict(

+                 pullrequest=request.to_json(public=True),

                  project=request.project.to_json(public=True),

                  agent=user_obj.username,

              ),
@@ -710,7 +736,8 @@ 

          )

          session.add(i2i)

          # Make sure we won't have SQLAlchemy error before we continue

-         session.flush()

+         # and commit so the blocking issue appears in the JSON representation

+         session.commit()

          pagure.lib.git.update_git(issue, repo=issue.project)

          pagure.lib.git.update_git(issue_blocked, repo=issue_blocked.project)

  
@@ -769,7 +796,8 @@ 

                  issue.parents.remove(parent)

  

          # Make sure we won't have SQLAlchemy error before we continue

-         session.flush()

+         # and commit so the blocking issue appears in the JSON representation

+         session.commit()

          pagure.lib.git.update_git(issue, repo=issue.project)

          pagure.lib.git.update_git(issue_blocked, repo=issue_blocked.project)

  
@@ -851,7 +879,7 @@ 

          topic="project.tag.removed",

          msg=dict(

              project=project.to_json(public=True),

-             tags=removed_tags,

+             tags=sorted(removed_tags),

              agent=user_obj.username,

          ),

      )
@@ -886,6 +914,9 @@ 

                  removed_tags.append(tag)

                  session.delete(objtag)

  

+     # Commit so the tags are updated in the notification sent

+     session.commit()

+ 

      if isinstance(obj, model.Issue):

          pagure.lib.git.update_git(obj, repo=obj.project)

  
@@ -895,7 +926,7 @@ 

              msg=dict(

                  issue=obj.to_json(public=True),

                  project=obj.project.to_json(public=True),

-                 tags=removed_tags,

+                 tags=sorted(removed_tags),

                  agent=user_obj.username,

              ),

          )
@@ -914,8 +945,9 @@ 

              topic="pull-request.tag.removed",

              msg=dict(

                  pull_request=obj.to_json(public=True),

+                 pullrequest=obj.to_json(public=True),

                  project=obj.project.to_json(public=True),

-                 tags=removed_tags,

+                 tags=sorted(removed_tags),

                  agent=user_obj.username,

              ),

          )
@@ -1151,7 +1183,7 @@ 

          update_read_only_mode(session, project, read_only=True)

          session.add(access_obj)

          session.add(project)

-         session.flush()

+         session.commit()

  

          pagure.lib.notify.log(

              project,
@@ -1178,8 +1210,8 @@ 

      # Mark the project as read only, celery will then unmark it

      update_read_only_mode(session, project, read_only=True)

      session.add(project)

-     # Make sure we won't have SQLAlchemy error before we continue

-     session.flush()

+     # Commit so the JSON sent in the notification is up to date

+     session.commit()

  

      pagure.lib.notify.log(

          project,
@@ -1263,7 +1295,8 @@ 

          project.date_modified = datetime.datetime.utcnow()

          update_read_only_mode(session, project, read_only=True)

          session.add(project)

-         session.flush()

+         # Commit so the JSON sent in the notification is up to date

+         session.commit()

  

          pagure.lib.notify.log(

              project,
@@ -1291,7 +1324,8 @@ 

      # Mark the project read_only, celery will then unmark it

      update_read_only_mode(session, project, read_only=True)

      session.add(project)

-     session.flush()

+     # Commit so the JSON sent in the notification is up to date

+     session.commit()

  

      pagure.lib.notify.log(

          project,
@@ -1516,6 +1550,8 @@ 

          token=token,

      )

  

+     action = action.replace("Flag ", "")

+ 

      pr_flag = pagure.lib.query.get_commit_flag_by_uid(

          session, request.commit_stop, flag_uid

      )
@@ -1535,8 +1571,6 @@ 

          ),

      )

  

-     action = action.replace("Flag ", "")

- 

      return ("Flag %s" % action, pr_flag.uid)

  

  
@@ -2169,7 +2203,7 @@ 

              msg=dict(

                  issue=issue.to_json(public=True),

                  project=issue.project.to_json(public=True),

-                 fields=list(set(edit)),

+                 fields=sorted(set(edit)),

                  agent=user_obj.username,

              ),

          )
@@ -2260,7 +2294,7 @@ 

              topic="project.edit",

              msg=dict(

                  project=repo.to_json(public=True),

-                 fields=update,

+                 fields=sorted(update),

                  agent=user_obj.username,

              ),

          )

file modified
+13
@@ -2163,11 +2163,24 @@ 

                  + "#usersgroups-tab"

              )

  

+         removed_groups = []

          for grp in repo.groups:

              if grp.id == groupid:

+                 removed_groups.append(grp.group_name)

                  repo.groups.remove(grp)

                  break

          try:

+             # Commit so the JSON sent on the notification is up to date

+             flask.g.session.commit()

+             pagure.lib.notify.log(

+                 repo,

+                 topic="project.group.removed",

+                 msg=dict(

+                     project=repo.to_json(public=True),

+                     removed_groups=removed_groups,

+                     agent=flask.g.fas_user.username,

+                 ),

+             )

              # Mark the project as read_only, celery will unmark it

              pagure.lib.query.update_read_only_mode(

                  flask.g.session, repo, read_only=True

@@ -7,6 +7,7 @@ 

  flake8

  flask-oidc

  mock

+ pagure-messages >= 0.0.1

  pytest

  pytest-cov

  pytest-xdist

file modified
+3
@@ -134,6 +134,8 @@ 

      # that applies to all log messages not handled by a different logger

      "root": {"level": "WARN", "handlers": ["console"]},

  }

+ 

+ NOGITHOOKS = %(nogithooks)s

  """

  # The Celery docs warn against using task_always_eager:

  # http://docs.celeryproject.org/en/latest/userguide/testing.html
@@ -396,6 +398,7 @@ 

              "repospanner_admin_override": "False",

              "repospanner_new_fork": "True",

              "repospanner_admin_migration": "False",

+             "nogithooks": False,

          }

          config_values.update(self.config_values)

          self.config_values = config_values

@@ -20,9 +20,12 @@ 

  import os

  

  import flask

+ import pagure_messages

  import json

  import munch

- from mock import patch, MagicMock

+ 

+ from fedora_messaging import api, testing

+ from mock import ANY, patch, MagicMock

  from sqlalchemy.exc import SQLAlchemyError

  

  sys.path.insert(
@@ -469,6 +472,9 @@ 

              },

          )

  

+     @patch.dict(

+         "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}

+     )

      def test_api_new_issue(self):

          """ Test the api_new_issue method of the flask api. """

          tests.create_projects(self.session)
@@ -486,9 +492,82 @@ 

          }

  

          # Valid request

-         output = self.app.post(

-             "/api/0/test/new_issue", data=data, headers=headers

-         )

+         with testing.mock_sends(

+             pagure_messages.IssueNewV1(

+                 topic="pagure.issue.new",

+                 body={

+                     "issue": {

+                         "id": 1,

+                         "title": "test issue",

+                         "content": "This issue needs attention",

+                         "status": "Open",

+                         "close_status": None,

+                         "date_created": ANY,

+                         "last_updated": ANY,

+                         "closed_at": None,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "private": False,

+                         "tags": [],

+                         "depends": [],

+                         "blocks": [],

+                         "assignee": None,

+                         "priority": None,

+                         "milestone": None,

+                         "custom_fields": [],

+                         "closed_by": None,

+                         "related_prs": [],

+                         "comments": [],

+                     },

+                     "project": {

+                         "id": 1,

+                         "name": "test",

+                         "fullname": "test",

+                         "url_path": "test",

+                         "description": "test project #1",

+                         "namespace": None,

+                         "parent": None,

+                         "date_created": ANY,

+                         "date_modified": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "access_users": {

+                             "owner": ["pingou"],

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "access_groups": {

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "tags": [],

+                         "priorities": {},

+                         "custom_keys": [],

+                         "close_status": [

+                             "Invalid",

+                             "Insufficient data",

+                             "Fixed",

+                             "Duplicate",

+                         ],

+                         "milestones": {},

+                     },

+                     "agent": "pingou",

+                 },

+             )

+         ):

+             output = self.app.post(

+                 "/api/0/test/new_issue", data=data, headers=headers

+             )

          self.assertEqual(output.status_code, 200)

          data = json.loads(output.get_data(as_text=True))

          data["issue"]["date_created"] = "1431414800"
@@ -758,6 +837,58 @@ 

  

          self.assertDictEqual(data, {"issue": exp, "message": "Issue created"})

  

+     @patch.dict(

+         "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}

+     )

+     def test_api_new_issue_private_no_fedora_messaging_notifs(self):

+         """ Test the api_new_issue method of the flask api. """

+         tests.create_projects(self.session)

+         tests.create_projects_git(

+             os.path.join(self.path, "tickets"), bare=True

+         )

+         tests.create_tokens(self.session)

+         tests.create_tokens_acl(self.session)

+ 

+         headers = {"Authorization": "token aaabbbcccddd"}

+ 

+         # Private issue: True

+         data = {

+             "title": "test issue",

+             "issue_content": "This issue needs attention",

+             "private": True,

+         }

+         output = self.app.post(

+             "/api/0/test/new_issue", data=data, headers=headers

+         )

+         self.assertEqual(output.status_code, 200)

+         data = json.loads(output.get_data(as_text=True))

+         data["issue"]["date_created"] = "1431414800"

+         data["issue"]["last_updated"] = "1431414800"

+ 

+         issue = copy.deepcopy(FULL_ISSUE_LIST[2])

+         issue["id"] = 1

+ 

+         self.assertDictEqual(

+             data, {"issue": issue, "message": "Issue created"}

+         )

+ 

+         # Private issue: 1

+         data = {

+             "title": "test issue1",

+             "issue_content": "This issue needs attention",

+             "private": 1,

+             "assignee": "foo",

+         }

+         with self.assertRaises(AssertionError) as cm:

+             with testing.mock_sends(api.Message()):

+                 output = self.app.post(

+                     "/api/0/test/new_issue", data=data, headers=headers

+                 )

+         self.assertEqual(

+             cm.exception.args[0],

+             "Expected 1 messages to be sent, but 0 were sent",

+         )

+ 

      @patch("pagure.utils.check_api_acls", MagicMock(return_value=None))

      def test_api_new_issue_raise_db_error(self):

          """ Test the api_new_issue method of the flask api. """
@@ -2982,6 +3113,9 @@ 

              },

          )

  

+     @patch.dict(

+         "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}

+     )

      def test_api_change_milestone_issue(self):

          """ Test the api_change_milestone_issue method of the flask api. """

          tests.create_projects(self.session)
@@ -3017,9 +3151,86 @@ 

          data = {"milestone": "v1.0"}

  

          # Valid requests

-         output = self.app.post(

-             "/api/0/test/issue/1/milestone", data=data, headers=headers

-         )

+         with testing.mock_sends(

+             pagure_messages.IssueEditV1(

+                 topic="pagure.issue.edit",

+                 body={

+                     "issue": {

+                         "id": 1,

+                         "title": "Test issue #1",

+                         "content": "We should work on this",

+                         "status": "Open",

+                         "close_status": None,

+                         "date_created": ANY,

+                         "last_updated": ANY,

+                         "closed_at": None,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "private": False,

+                         "tags": [],

+                         "depends": [],

+                         "blocks": [],

+                         "assignee": None,

+                         "priority": None,

+                         "milestone": "v1.0",

+                         "custom_fields": [],

+                         "closed_by": None,

+                         "related_prs": [],

+                         "comments": [],

+                     },

+                     "project": {

+                         "id": 1,

+                         "name": "test",

+                         "fullname": "test",

+                         "url_path": "test",

+                         "description": "test project #1",

+                         "namespace": None,

+                         "parent": None,

+                         "date_created": ANY,

+                         "date_modified": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "access_users": {

+                             "owner": ["pingou"],

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "access_groups": {

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "tags": [],

+                         "priorities": {},

+                         "custom_keys": [],

+                         "close_status": [

+                             "Invalid",

+                             "Insufficient data",

+                             "Fixed",

+                             "Duplicate",

+                         ],

+                         "milestones": {

+                             "v1.0": {"date": None, "active": True},

+                             "v2.0": {"date": "Soon", "active": True},

+                         },

+                     },

+                     "fields": ["milestone"],

+                     "agent": "pingou",

+                 },

+             )

+         ):

+             output = self.app.post(

+                 "/api/0/test/issue/1/milestone", data=data, headers=headers

+             )

          self.assertEqual(output.status_code, 200)

          data = json.loads(output.get_data(as_text=True))

          self.assertDictEqual(
@@ -3554,6 +3765,9 @@ 

              pagure.api.APIERROR.ETRACKERDISABLED.name, data["error_code"]

          )

  

+     @patch.dict(

+         "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}

+     )

      @patch("pagure.lib.git.update_git")

      @patch("pagure.lib.notify.send_email")

      def test_api_assign_issue(self, p_send_email, p_ugt):
@@ -3620,17 +3834,184 @@ 

          data = {"assignee": "pingou"}

  

          # Valid request

-         output = self.app.post(

-             "/api/0/test/issue/1/assign", data=data, headers=headers

-         )

+         with testing.mock_sends(

+             pagure_messages.IssueAssignedAddedV1(

+                 topic="pagure.issue.assigned.added",

+                 body={

+                     "issue": {

+                         "id": 1,

+                         "title": "Test issue #1",

+                         "content": "We should work on this",

+                         "status": "Open",

+                         "close_status": None,

+                         "date_created": ANY,

+                         "last_updated": ANY,

+                         "closed_at": None,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "private": False,

+                         "tags": [],

+                         "depends": [],

+                         "blocks": [],

+                         "assignee": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "priority": None,

+                         "milestone": None,

+                         "custom_fields": [],

+                         "closed_by": None,

+                         "related_prs": [],

+                         "comments": [],

+                     },

+                     "project": {

+                         "id": 1,

+                         "name": "test",

+                         "fullname": "test",

+                         "url_path": "test",

+                         "description": "test project #1",

+                         "namespace": None,

+                         "parent": None,

+                         "date_created": ANY,

+                         "date_modified": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "access_users": {

+                             "owner": ["pingou"],

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "access_groups": {

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "tags": [],

+                         "priorities": {},

+                         "custom_keys": [],

+                         "close_status": [

+                             "Invalid",

+                             "Insufficient data",

+                             "Fixed",

+                             "Duplicate",

+                         ],

+                         "milestones": {},

+                     },

+                     "agent": "pingou",

+                 },

+             )

+         ):

+             output = self.app.post(

+                 "/api/0/test/issue/1/assign", data=data, headers=headers

+             )

          self.assertEqual(output.status_code, 200)

          data = json.loads(output.get_data(as_text=True))

          self.assertDictEqual(data, {"message": "Issue assigned to pingou"})

  

          # Un-assign

-         output = self.app.post(

-             "/api/0/test/issue/1/assign", data=data, headers=headers

-         )

+         with testing.mock_sends(

+             pagure_messages.IssueAssignedResetV1(

+                 topic="pagure.issue.assigned.reset",

+                 body={

+                     "issue": {

+                         "id": 1,

+                         "title": "Test issue #1",

+                         "content": "We should work on this",

+                         "status": "Open",

+                         "close_status": None,

+                         "date_created": ANY,

+                         "last_updated": ANY,

+                         "closed_at": None,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "private": False,

+                         "tags": [],

+                         "depends": [],

+                         "blocks": [],

+                         "assignee": None,

+                         "priority": None,

+                         "milestone": None,

+                         "custom_fields": [],

+                         "closed_by": None,

+                         "related_prs": [],

+                         "comments": [

+                             {

+                                 "id": 1,

+                                 "comment": "**Metadata Update from @pingou**:"

+                                 "\n- Issue assigned to pingou",

+                                 "parent": None,

+                                 "date_created": ANY,

+                                 "user": {

+                                     "name": "pingou",

+                                     "fullname": "PY C",

+                                     "url_path": "user/pingou",

+                                 },

+                                 "edited_on": None,

+                                 "editor": None,

+                                 "notification": True,

+                                 "reactions": {},

+                             }

+                         ],

+                     },

+                     "project": {

+                         "id": 1,

+                         "name": "test",

+                         "fullname": "test",

+                         "url_path": "test",

+                         "description": "test project #1",

+                         "namespace": None,

+                         "parent": None,

+                         "date_created": ANY,

+                         "date_modified": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "access_users": {

+                             "owner": ["pingou"],

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "access_groups": {

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "tags": [],

+                         "priorities": {},

+                         "custom_keys": [],

+                         "close_status": [

+                             "Invalid",

+                             "Insufficient data",

+                             "Fixed",

+                             "Duplicate",

+                         ],

+                         "milestones": {},

+                     },

+                     "agent": "pingou",

+                 },

+             )

+         ):

+             output = self.app.post(

+                 "/api/0/test/issue/1/assign", data=data, headers=headers

+             )

          self.assertEqual(output.status_code, 200)

          data = json.loads(output.get_data(as_text=True))

          self.assertDictEqual(data, {"message": "Assignee reset"})

@@ -15,7 +15,9 @@ 

  import os

  

  import json

- from mock import patch, MagicMock

+ import pagure_messages

+ from fedora_messaging import api, testing

+ from mock import ANY, patch, MagicMock

  

  sys.path.insert(

      0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
@@ -219,6 +221,9 @@ 

          data = json.loads(output.get_data(as_text=True))

          self.assertDictEqual(data, {"error": "error", "error_code": "ENOCODE"})

  

+     @patch.dict(

+         "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}

+     )

      @patch("pagure.lib.notify.send_email")

      def test_flagging_a_pul_request_with_notification(self, mock_email):

          """ Test the flagging a PR. """
@@ -240,10 +245,139 @@ 

          }

  

          # Valid request

-         output = self.app.post(

-             "/api/0/test/pull-request/1/flag", data=data, headers=headers

-         )

-         self.assertEqual(output.status_code, 200)

+         with testing.mock_sends(

+             pagure_messages.CommitFlagAddedV1,

+             pagure_messages.PullRequestFlagAddedV1(

+                 topic="pagure.pull-request.flag.added",

+                 body={

+                     "pullrequest": {

+                         "id": 1,

+                         "uid": ANY,

+                         "title": "test pull-request",

+                         "branch": "master",

+                         "project": {

+                             "id": 1,

+                             "name": "test",

+                             "fullname": "test",

+                             "url_path": "test",

+                             "description": "test project #1",

+                             "namespace": None,

+                             "parent": None,

+                             "date_created": ANY,

+                             "date_modified": ANY,

+                             "user": {

+                                 "name": "pingou",

+                                 "fullname": "PY C",

+                                 "url_path": "user/pingou",

+                             },

+                             "access_users": {

+                                 "owner": ["pingou"],

+                                 "admin": [],

+                                 "commit": [],

+                                 "collaborator": [],

+                                 "ticket": [],

+                             },

+                             "access_groups": {

+                                 "admin": [],

+                                 "commit": [],

+                                 "collaborator": [],

+                                 "ticket": [],

+                             },

+                             "tags": [],

+                             "priorities": {},

+                             "custom_keys": [],

+                             "close_status": [

+                                 "Invalid",

+                                 "Insufficient data",

+                                 "Fixed",

+                                 "Duplicate",

+                             ],

+                             "milestones": {},

+                         },

+                         "branch_from": "master",

+                         "repo_from": {

+                             "id": 1,

+                             "name": "test",

+                             "fullname": "test",

+                             "url_path": "test",

+                             "description": "test project #1",

+                             "namespace": None,

+                             "parent": None,

+                             "date_created": ANY,

+                             "date_modified": ANY,

+                             "user": {

+                                 "name": "pingou",

+                                 "fullname": "PY C",

+                                 "url_path": "user/pingou",

+                             },

+                             "access_users": {

+                                 "owner": ["pingou"],

+                                 "admin": [],

+                                 "commit": [],

+                                 "collaborator": [],

+                                 "ticket": [],

+                             },

+                             "access_groups": {

+                                 "admin": [],

+                                 "commit": [],

+                                 "collaborator": [],

+                                 "ticket": [],

+                             },

+                             "tags": [],

+                             "priorities": {},

+                             "custom_keys": [],

+                             "close_status": [

+                                 "Invalid",

+                                 "Insufficient data",

+                                 "Fixed",

+                                 "Duplicate",

+                             ],

+                             "milestones": {},

+                         },

+                         "remote_git": None,

+                         "date_created": ANY,

+                         "updated_on": ANY,

+                         "last_updated": ANY,

+                         "closed_at": None,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "assignee": None,

+                         "status": "Open",

+                         "commit_start": None,

+                         "commit_stop": "hash_commit_stop",

+                         "closed_by": None,

+                         "initial_comment": None,

+                         "cached_merge_status": "unknown",

+                         "threshold_reached": None,

+                         "tags": [],

+                         "comments": [],

+                     },

+                     "flag": {

+                         "commit_hash": "hash_commit_stop",

+                         "username": "Jenkins",

+                         "percent": None,

+                         "comment": "Tests running",

+                         "status": "pending",

+                         "url": "http://jenkins.cloud.fedoraproject.org/",

+                         "date_created": ANY,

+                         "date_updated": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                     },

+                     "agent": "pingou",

+                 },

+             ),

+         ):

+             output = self.app.post(

+                 "/api/0/test/pull-request/1/flag", data=data, headers=headers

+             )

+             self.assertEqual(output.status_code, 200)

          data = json.loads(output.get_data(as_text=True))

          data["flag"]["date_created"] = "1510742565"

          data["flag"]["date_updated"] = "1510742565"
@@ -305,6 +439,9 @@ 

              user_from="Jenkins",

          )

  

+     @patch.dict(

+         "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}

+     )

      def test_updating_flag(self):

          """ Test the updating the flag of a PR. """

          headers = {"Authorization": "token aaabbbcccddd"}
@@ -374,9 +511,138 @@ 

              "uid": "jenkins_build_pagure_100+seed",

          }

  

-         output = self.app.post(

-             "/api/0/test/pull-request/1/flag", data=data, headers=headers

-         )

+         with testing.mock_sends(

+             pagure_messages.CommitFlagUpdatedV1,

+             pagure_messages.PullRequestFlagUpdatedV1(

+                 topic="pagure.pull-request.flag.updated",

+                 body={

+                     "pullrequest": {

+                         "id": 1,

+                         "uid": ANY,

+                         "title": "test pull-request",

+                         "branch": "master",

+                         "project": {

+                             "id": 1,

+                             "name": "test",

+                             "fullname": "test",

+                             "url_path": "test",

+                             "description": "test project #1",

+                             "namespace": None,

+                             "parent": None,

+                             "date_created": ANY,

+                             "date_modified": ANY,

+                             "user": {

+                                 "name": "pingou",

+                                 "fullname": "PY C",

+                                 "url_path": "user/pingou",

+                             },

+                             "access_users": {

+                                 "owner": ["pingou"],

+                                 "admin": [],

+                                 "commit": [],

+                                 "collaborator": [],

+                                 "ticket": [],

+                             },

+                             "access_groups": {

+                                 "admin": [],

+                                 "commit": [],

+                                 "collaborator": [],

+                                 "ticket": [],

+                             },

+                             "tags": [],

+                             "priorities": {},

+                             "custom_keys": [],

+                             "close_status": [

+                                 "Invalid",

+                                 "Insufficient data",

+                                 "Fixed",

+                                 "Duplicate",

+                             ],

+                             "milestones": {},

+                         },

+                         "branch_from": "master",

+                         "repo_from": {

+                             "id": 1,

+                             "name": "test",

+                             "fullname": "test",

+                             "url_path": "test",

+                             "description": "test project #1",

+                             "namespace": None,

+                             "parent": None,

+                             "date_created": ANY,

+                             "date_modified": ANY,

+                             "user": {

+                                 "name": "pingou",

+                                 "fullname": "PY C",

+                                 "url_path": "user/pingou",

+                             },

+                             "access_users": {

+                                 "owner": ["pingou"],

+                                 "admin": [],

+                                 "commit": [],

+                                 "collaborator": [],

+                                 "ticket": [],

+                             },

+                             "access_groups": {

+                                 "admin": [],

+                                 "commit": [],

+                                 "collaborator": [],

+                                 "ticket": [],

+                             },

+                             "tags": [],

+                             "priorities": {},

+                             "custom_keys": [],

+                             "close_status": [

+                                 "Invalid",

+                                 "Insufficient data",

+                                 "Fixed",

+                                 "Duplicate",

+                             ],

+                             "milestones": {},

+                         },

+                         "remote_git": None,

+                         "date_created": ANY,

+                         "updated_on": ANY,

+                         "last_updated": ANY,

+                         "closed_at": None,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "assignee": None,

+                         "status": "Open",

+                         "commit_start": None,

+                         "commit_stop": "hash_commit_stop",

+                         "closed_by": None,

+                         "initial_comment": None,

+                         "cached_merge_status": "unknown",

+                         "threshold_reached": None,

+                         "tags": [],

+                         "comments": [],

+                     },

+                     "flag": {

+                         "commit_hash": "hash_commit_stop",

+                         "username": "Jenkins",

+                         "percent": 100,

+                         "comment": "Tests passed",

+                         "status": "success",

+                         "url": "http://jenkins.cloud.fedoraproject.org/",

+                         "date_created": ANY,

+                         "date_updated": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                     },

+                     "agent": "pingou",

+                 },

+             ),

+         ):

+             output = self.app.post(

+                 "/api/0/test/pull-request/1/flag", data=data, headers=headers

+             )

          self.assertEqual(output.status_code, 200)

          data = json.loads(output.get_data(as_text=True))

          data["flag"]["date_created"] = "1510742565"

@@ -14,6 +14,7 @@ 

  import datetime

  import json

  import unittest

+ import pagure_messages

  import shutil

  import sys

  import tempfile
@@ -21,7 +22,8 @@ 

  

  import pygit2

  from celery.result import EagerResult

- from mock import patch, Mock

+ from fedora_messaging import api, testing

+ from mock import ANY, patch, Mock

  

  sys.path.insert(

      0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
@@ -2927,6 +2929,221 @@ 

  

          self.assertEqual(data, expected_output)

  

+     @patch.dict(

+         "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}

+     )

+     def test_update_flag_commit_with_uid(self):

+         """ Test flagging a commit with provided uid. """

+         repo_obj = pygit2.Repository(self.git_path)

+         commit = repo_obj.revparse_single("HEAD")

+ 

+         headers = {"Authorization": "token aaabbbcccddd"}

+         data = {

+             "username": "Jenkins",

+             "percent": 0,

+             "comment": "Tests running",

+             "url": "http://jenkins.cloud.fedoraproject.org/",

+             "uid": "jenkins_build_pagure_100+seed",

+             "status": "pending",

+         }

+         with testing.mock_sends(

+             pagure_messages.CommitFlagAddedV1(

+                 topic="pagure.commit.flag.added",

+                 body={

+                     "repo": {

+                         "id": 1,

+                         "name": "test",

+                         "fullname": "test",

+                         "url_path": "test",

+                         "description": "test project #1",

+                         "namespace": None,

+                         "parent": None,

+                         "date_created": ANY,

+                         "date_modified": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "access_users": {

+                             "owner": ["pingou"],

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "access_groups": {

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "tags": [],

+                         "priorities": {},

+                         "custom_keys": [],

+                         "close_status": [

+                             "Invalid",

+                             "Insufficient data",

+                             "Fixed",

+                             "Duplicate",

+                         ],

+                         "milestones": {},

+                     },

+                     "flag": {

+                         "commit_hash": commit.oid.hex,

+                         "username": "Jenkins",

+                         "percent": "0",

+                         "comment": "Tests running",

+                         "status": "pending",

+                         "url": "http://jenkins.cloud.fedoraproject.org/",

+                         "date_created": ANY,

+                         "date_updated": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                     },

+                     "agent": "pingou",

+                 },

+             )

+         ):

+             output = self.app.post(

+                 "/api/0/test/c/%s/flag" % commit.oid.hex,

+                 headers=headers,

+                 data=data,

+             )

+         self.assertEqual(output.status_code, 200)

+         data = json.loads(output.get_data(as_text=True))

+         data["flag"]["date_created"] = "1510742565"

+         data["flag"]["date_updated"] = "1510742565"

+         expected_output = {

+             "flag": {

+                 "comment": "Tests running",

+                 "commit_hash": commit.oid.hex,

+                 "date_created": "1510742565",

+                 "date_updated": "1510742565",

+                 "percent": 0,

+                 "status": "pending",

+                 "url": "http://jenkins.cloud.fedoraproject.org/",

+                 "user": {

+                     "default_email": "bar@pingou.com",

+                     "emails": ["bar@pingou.com", "foo@pingou.com"],

+                     "fullname": "PY C",

+                     "name": "pingou",

+                     "url_path": "user/pingou",

+                 },

+                 "username": "Jenkins",

+             },

+             "message": "Flag added",

+             "uid": "jenkins_build_pagure_100+seed",

+         }

+ 

+         self.assertEqual(data, expected_output)

+ 

+         data = {

+             "username": "Jenkins",

+             "percent": 100,

+             "comment": "Tests passed",

+             "url": "http://jenkins.cloud.fedoraproject.org/",

+             "uid": "jenkins_build_pagure_100+seed",

+             "status": "success",

+         }

+         with testing.mock_sends(

+             pagure_messages.CommitFlagUpdatedV1(

+                 topic="pagure.commit.flag.updated",

+                 body={

+                     "repo": {

+                         "id": 1,

+                         "name": "test",

+                         "fullname": "test",

+                         "url_path": "test",

+                         "description": "test project #1",

+                         "namespace": None,

+                         "parent": None,

+                         "date_created": ANY,

+                         "date_modified": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "access_users": {

+                             "owner": ["pingou"],

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "access_groups": {

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "tags": [],

+                         "priorities": {},

+                         "custom_keys": [],

+                         "close_status": [

+                             "Invalid",

+                             "Insufficient data",

+                             "Fixed",

+                             "Duplicate",

+                         ],

+                         "milestones": {},

+                     },

+                     "flag": {

+                         "commit_hash": commit.oid.hex,

+                         "username": "Jenkins",

+                         "percent": "100",

+                         "comment": "Tests passed",

+                         "status": "success",

+                         "url": "http://jenkins.cloud.fedoraproject.org/",

+                         "date_created": ANY,

+                         "date_updated": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                     },

+                     "agent": "pingou",

+                 },

+             )

+         ):

+             output = self.app.post(

+                 "/api/0/test/c/%s/flag" % commit.oid.hex,

+                 headers=headers,

+                 data=data,

+             )

+         self.assertEqual(output.status_code, 200)

+         data = json.loads(output.get_data(as_text=True))

+         data["flag"]["date_created"] = "1510742565"

+         data["flag"]["date_updated"] = "1510742565"

+         expected_output = {

+             "flag": {

+                 "comment": "Tests passed",

+                 "commit_hash": commit.oid.hex,

+                 "date_created": "1510742565",

+                 "date_updated": "1510742565",

+                 "percent": 100,

+                 "status": "success",

+                 "url": "http://jenkins.cloud.fedoraproject.org/",

+                 "user": {

+                     "default_email": "bar@pingou.com",

+                     "emails": ["bar@pingou.com", "foo@pingou.com"],

+                     "fullname": "PY C",

+                     "name": "pingou",

+                     "url_path": "user/pingou",

+                 },

+                 "username": "Jenkins",

+             },

+             "message": "Flag updated",

+             "uid": "jenkins_build_pagure_100+seed",

+         }

+ 

+         self.assertEqual(data, expected_output)

+ 

      @patch("pagure.lib.notify.send_email")

      def test_flag_commit_without_uid(self, mock_email):

          """ Test flagging a commit with missing info.
@@ -3003,6 +3220,7 @@ 

              "url": "http://jenkins.cloud.fedoraproject.org/",

              "status": "success",

          }

+ 

          output = self.app.post(

              "/api/0/test/c/%s/flag" % commit.oid.hex,

              headers=headers,
@@ -5081,6 +5299,9 @@ 

          data = json.loads(output.get_data(as_text=True))

          self.assertDictEqual(data, {"message": 'Project "api1" created'})

  

+     @patch.dict(

+         "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}

+     )

      def test_api_new_project(self):

  

          headers = {"Authorization": "token aaabbbcccddd"}
@@ -5090,7 +5311,49 @@ 

          }

  

          # Valid request

-         output = self.app.post("/api/0/new/", data=data, headers=headers)

+         with testing.mock_sends(

+             pagure_messages.ProjectNewV1(

+                 topic="pagure.project.new",

+                 body={

+                     "project": {

+                         "id": 4,

+                         "name": "test_42",

+                         "fullname": "test_42",

+                         "url_path": "test_42",

+                         "description": "Just another small test project",

+                         "namespace": None,

+                         "parent": None,

+                         "date_created": ANY,

+                         "date_modified": ANY,

+                         "user": {

+                             "name": "pingou",

+                             "fullname": "PY C",

+                             "url_path": "user/pingou",

+                         },

+                         "access_users": {

+                             "owner": ["pingou"],

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "access_groups": {

+                             "admin": [],

+                             "commit": [],

+                             "collaborator": [],

+                             "ticket": [],

+                         },

+                         "tags": [],

+                         "priorities": {},

+                         "custom_keys": [],

+                         "close_status": [],

+                         "milestones": {},

+                     },

+                     "agent": "pingou",

+                 },

+             )

+         ):

+             output = self.app.post("/api/0/new/", data=data, headers=headers)

          self.assertEqual(output.status_code, 200)

          data = json.loads(output.get_data(as_text=True))

          self.assertDictEqual(data, {"message": 'Project "test_42" created'})

@@ -142,7 +142,7 @@ 

                  )

              ]

          )

-         self.assertIn(cnt, (9, 10))

+         self.assertIn(cnt, (9, 10, 11))

  

          last_commit = repo.revparse_single("HEAD")

          patch = pagure.lib.git.commit_to_patch(repo, last_commit)

@@ -17,7 +17,9 @@ 

  import os

  

  import json

- from mock import patch, MagicMock

+ import pagure_messages

+ from fedora_messaging import api, testing

+ from mock import ANY, patch, MagicMock

  

  sys.path.insert(

      0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
@@ -28,15 +30,16 @@ 

  import tests

  

  

- class PagureRebasetests(tests.Modeltests):

+ class PagureRebaseBasetests(tests.Modeltests):

      """ Tests rebasing pull-request in pagure """

  

      maxDiff = None

+     config_values = {"authbackend": "pagure"}

  

      @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))

      def setUp(self):

          """ Set up the environnment, ran before every tests. """

-         super(PagureRebasetests, self).setUp()

+         super(PagureRebaseBasetests, self).setUp()

  

          pagure.config.config["REQUESTS_FOLDER"] = None

          tests.create_projects(self.session)
@@ -99,6 +102,10 @@ 

          self.assertEqual(len(project.requests), 1)

          self.request = self.project.requests[0]

  

+ 

+ class PagureRebasetests(PagureRebaseBasetests):

+     """ Tests rebasing pull-request in pagure """

+ 

      def test_merge_status_merge(self):

          """ Test that the PR can be merged with a merge commit. """

  
@@ -181,56 +188,6 @@ 

                  },

              )

  

-     def test_rebase_api_ui_logged_in(self):

-         """ Test the rebase PR API endpoint when logged in from the UI and

-         its outcome. """

- 

-         user = tests.FakeUser(username="pingou")

-         with tests.user_set(self.app.application, user):

-             # Get the merge status first so it's cached and can be refreshed

-             csrf_token = self.get_csrf()

-             data = {"requestid": self.request.uid, "csrf_token": csrf_token}

-             output = self.app.post("/pv/pull-request/merge", data=data)

-             self.assertEqual(output.status_code, 200)

-             data = json.loads(output.get_data(as_text=True))