Blame tests/test_progit_flask_api_issue.py

Pierre-Yves Chibon 993597
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
"""
Pierre-Yves Chibon 993597
 (c) 2015 - Copyright Red Hat Inc
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
 Authors:
Pierre-Yves Chibon 993597
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
"""
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
__requires__ = ['SQLAlchemy >= 0.8']
Pierre-Yves Chibon 993597
import pkg_resources
Pierre-Yves Chibon 993597
Pierre-Yves Chibon f69837
import datetime
Pierre-Yves Chibon 993597
import unittest
Pierre-Yves Chibon 993597
import shutil
Pierre-Yves Chibon 993597
import sys
Pierre-Yves Chibon 993597
import os
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
import json
Pierre-Yves Chibon 993597
from mock import patch
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
sys.path.insert(0, os.path.join(os.path.dirname(
Pierre-Yves Chibon 993597
    os.path.abspath(__file__)), '..'))
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
import pagure.lib
Pierre-Yves Chibon 993597
import tests
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
class PagureFlaskApiIssuetests(tests.Modeltests):
Pierre-Yves Chibon 993597
    """ Tests for the flask API of pagure for issue """
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
    def setUp(self):
Pierre-Yves Chibon 993597
        """ Set up the environnment, ran before every tests. """
Pierre-Yves Chibon 993597
        super(PagureFlaskApiIssuetests, self).setUp()
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
        pagure.APP.config['TESTING'] = True
Pierre-Yves Chibon 993597
        pagure.SESSION = self.session
Pierre-Yves Chibon 993597
        pagure.api.SESSION = self.session
Pierre-Yves Chibon 993597
        pagure.api.issue.SESSION = self.session
Pierre-Yves Chibon 993597
        pagure.lib.SESSION = self.session
Pierre-Yves Chibon e5c5fc
Pierre-Yves Chibon 0e5cb2
        pagure.APP.config['TICKETS_FOLDER'] = None
Pierre-Yves Chibon e5c5fc
Pierre-Yves Chibon 993597
        self.app = pagure.APP.test_client()
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
    def test_api_new_issue(self):
Pierre-Yves Chibon 3e3362
        """ Test the api_new_issue method of the flask api. """
Pierre-Yves Chibon 993597
        tests.create_projects(self.session)
Pierre-Yves Chibon e5c5fc
        tests.create_projects_git(os.path.join(tests.HERE, 'tickets'))
Pierre-Yves Chibon 993597
        tests.create_tokens(self.session)
Pierre-Yves Chibon 993597
        tests.create_tokens_acl(self.session)
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
        headers = {'Authorization': 'token aaabbbcccddd'}
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
        # Valid token, wrong project
Pierre-Yves Chibon 993597
        output = self.app.post('/api/0/test2/new_issue', headers=headers)
Pierre-Yves Chibon 993597
        self.assertEqual(output.status_code, 401)
Pierre-Yves Chibon 993597
        data = json.loads(output.data)
Pierre-Yves Chibon 993597
        self.assertDictEqual(
Pierre-Yves Chibon 993597
            data,
Pierre-Yves Chibon 993597
            {
Pierre-Yves Chibon 993597
              "error": "Invalid or expired token. Please visit " \
Pierre-Yves Chibon 1e2669
                  "https://pagure.org/ to get or renew your API token.",
Pierre-Yves Chibon d661a4
              "error_code": "EINVALIDTOK",
Pierre-Yves Chibon 993597
            }
Pierre-Yves Chibon 993597
        )
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
        # No input
Pierre-Yves Chibon 993597
        output = self.app.post('/api/0/test/new_issue', headers=headers)
Pierre-Yves Chibon 993597
        self.assertEqual(output.status_code, 400)
Pierre-Yves Chibon 993597
        data = json.loads(output.data)
Pierre-Yves Chibon 993597
        self.assertDictEqual(
Pierre-Yves Chibon 993597
            data,
Pierre-Yves Chibon 993597
            {
Pierre-Yves Chibon 993597
              "error": "Invalid or incomplete input submited",
Pierre-Yves Chibon d661a4
              "error_code": "EINVALIDREQ",
Pierre-Yves Chibon 993597
            }
Pierre-Yves Chibon 993597
        )
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
        data = {
Pierre-Yves Chibon 993597
            'title': 'test issue',
Pierre-Yves Chibon 993597
        }
Pierre-Yves Chibon 993597
Pierre-Yves Chibon f69837
        # Invalid repo
Pierre-Yves Chibon f69837
        output = self.app.post(
Pierre-Yves Chibon f69837
            '/api/0/foo/new_issue', data=data, headers=headers)
Pierre-Yves Chibon f69837
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon f69837
        data = json.loads(output.data)
Pierre-Yves Chibon f69837
        self.assertDictEqual(
Pierre-Yves Chibon f69837
            data,
Pierre-Yves Chibon f69837
            {
Pierre-Yves Chibon f69837
              "error": "Project not found",
Pierre-Yves Chibon d661a4
              "error_code": "ENOPROJECT",
Pierre-Yves Chibon f69837
            }
Pierre-Yves Chibon f69837
        )
Pierre-Yves Chibon f69837
Pierre-Yves Chibon 993597
        # Incomplete request
Pierre-Yves Chibon 993597
        output = self.app.post(
Pierre-Yves Chibon 993597
            '/api/0/test/new_issue', data=data, headers=headers)
Pierre-Yves Chibon 993597
        self.assertEqual(output.status_code, 400)
Pierre-Yves Chibon 993597
        data = json.loads(output.data)
Pierre-Yves Chibon 993597
        self.assertDictEqual(
Pierre-Yves Chibon 993597
            data,
Pierre-Yves Chibon 993597
            {
Pierre-Yves Chibon 993597
              "error": "Invalid or incomplete input submited",
Pierre-Yves Chibon d661a4
              "error_code": "EINVALIDREQ",
Pierre-Yves Chibon 993597
            }
Pierre-Yves Chibon 993597
        )
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
        data = {
Pierre-Yves Chibon 993597
            'title': 'test issue',
Pierre-Yves Chibon 993597
            'issue_content': 'This issue needs attention',
Pierre-Yves Chibon 993597
        }
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
        # Valid request
Pierre-Yves Chibon 993597
        output = self.app.post(
Pierre-Yves Chibon 993597
            '/api/0/test/new_issue', data=data, headers=headers)
Pierre-Yves Chibon 993597
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 993597
        data = json.loads(output.data)
Pierre-Yves Chibon 993597
        self.assertDictEqual(
Pierre-Yves Chibon 993597
            data,
Pierre-Yves Chibon ee68c9
            {'message': 'Issue created'}
Pierre-Yves Chibon 993597
        )
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 13e2e9
    def test_api_view_issues(self):
Pierre-Yves Chibon 13e2e9
        """ Test the api_view_issues method of the flask api. """
Pierre-Yves Chibon 13e2e9
        self.test_api_new_issue()
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 13e2e9
        # Invalid repo
Pierre-Yves Chibon 13e2e9
        output = self.app.get('/api/0/foo/issues')
Pierre-Yves Chibon 13e2e9
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 13e2e9
        data = json.loads(output.data)
Pierre-Yves Chibon 13e2e9
        self.assertDictEqual(
Pierre-Yves Chibon 13e2e9
            data,
Pierre-Yves Chibon 13e2e9
            {
Pierre-Yves Chibon 13e2e9
              "error": "Project not found",
Pierre-Yves Chibon 13e2e9
              "error_code": "ENOPROJECT",
Pierre-Yves Chibon 13e2e9
            }
Pierre-Yves Chibon 13e2e9
        )
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 13e2e9
        # List all opened issues
Pierre-Yves Chibon 13e2e9
        output = self.app.get('/api/0/test/issues')
Pierre-Yves Chibon 13e2e9
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 13e2e9
        data = json.loads(output.data)
Pierre-Yves Chibon 13e2e9
        data['issues'][0]['date_created'] = '1431414800'
Pierre-Yves Chibon 13e2e9
        self.assertDictEqual(
Pierre-Yves Chibon 13e2e9
            data,
Pierre-Yves Chibon 13e2e9
            {
Pierre-Yves Chibon 316f15
              "args": {
Pierre-Yves Chibon 316f15
                "assignee": None,
Pierre-Yves Chibon 316f15
                "author": None,
Pierre-Yves Chibon 316f15
                "status": None,
Pierre-Yves Chibon 316f15
                "tags": []
Pierre-Yves Chibon 316f15
              },
Pierre-Yves Chibon 226628
              "total_issues": 1,
Pierre-Yves Chibon 13e2e9
              "issues": [
Pierre-Yves Chibon 13e2e9
                {
Pierre-Yves Chibon 13e2e9
                  "assignee": None,
Pierre-Yves Chibon 13e2e9
                  "blocks": [],
Pierre-Yves Chibon 13e2e9
                  "comments": [],
Pierre-Yves Chibon 13e2e9
                  "content": "This issue needs attention",
Pierre-Yves Chibon 13e2e9
                  "date_created": "1431414800",
Pierre-Yves Chibon 13e2e9
                  "depends": [],
Pierre-Yves Chibon 13e2e9
                  "id": 1,
Pierre-Yves Chibon 13e2e9
                  "private": False,
Pierre-Yves Chibon 13e2e9
                  "status": "Open",
Pierre-Yves Chibon 13e2e9
                  "tags": [],
Pierre-Yves Chibon 13e2e9
                  "title": "test issue",
Pierre-Yves Chibon 13e2e9
                  "user": {
Pierre-Yves Chibon 13e2e9
                    "fullname": "PY C",
Pierre-Yves Chibon 13e2e9
                    "name": "pingou"
Pierre-Yves Chibon 13e2e9
                  }
Pierre-Yves Chibon 13e2e9
                }
Pierre-Yves Chibon 316f15
              ]
Pierre-Yves Chibon 13e2e9
            }
Pierre-Yves Chibon 13e2e9
        )
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 13e2e9
        # Create private issue
Pierre-Yves Chibon 13e2e9
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 13e2e9
        msg = pagure.lib.new_issue(
Pierre-Yves Chibon 13e2e9
            session=self.session,
Pierre-Yves Chibon 13e2e9
            repo=repo,
Pierre-Yves Chibon 13e2e9
            title='Test issue',
Pierre-Yves Chibon 13e2e9
            content='We should work on this',
Pierre-Yves Chibon 13e2e9
            user='pingou',
Pierre-Yves Chibon 13e2e9
            ticketfolder=None,
Pierre-Yves Chibon 13e2e9
            private=True,
Pierre-Yves Chibon 13e2e9
        )
Pierre-Yves Chibon 13e2e9
        self.session.commit()
Pierre-Yves Chibon 13e2e9
        self.assertEqual(msg.title, 'Test issue')
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 13e2e9
        # Access issues un-authenticated
Pierre-Yves Chibon 13e2e9
        output = self.app.get('/api/0/test/issues')
Pierre-Yves Chibon 13e2e9
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 13e2e9
        data = json.loads(output.data)
Pierre-Yves Chibon 13e2e9
        data['issues'][0]['date_created'] = '1431414800'
Pierre-Yves Chibon 13e2e9
        self.assertDictEqual(
Pierre-Yves Chibon 13e2e9
            data,
Pierre-Yves Chibon 13e2e9
            {
Pierre-Yves Chibon 316f15
              "args": {
Pierre-Yves Chibon 316f15
                "assignee": None,
Pierre-Yves Chibon 316f15
                "author": None,
Pierre-Yves Chibon 316f15
                "status": None,
Pierre-Yves Chibon 316f15
                "tags": []
Pierre-Yves Chibon 316f15
              },
Pierre-Yves Chibon 226628
              "total_issues": 1,
Pierre-Yves Chibon 13e2e9
              "issues": [
Pierre-Yves Chibon 13e2e9
                {
Pierre-Yves Chibon 13e2e9
                  "assignee": None,
Pierre-Yves Chibon 13e2e9
                  "blocks": [],
Pierre-Yves Chibon 13e2e9
                  "comments": [],
Pierre-Yves Chibon 13e2e9
                  "content": "This issue needs attention",
Pierre-Yves Chibon 13e2e9
                  "date_created": "1431414800",
Pierre-Yves Chibon 13e2e9
                  "depends": [],
Pierre-Yves Chibon 13e2e9
                  "id": 1,
Pierre-Yves Chibon 13e2e9
                  "private": False,
Pierre-Yves Chibon 13e2e9
                  "status": "Open",
Pierre-Yves Chibon 13e2e9
                  "tags": [],
Pierre-Yves Chibon 13e2e9
                  "title": "test issue",
Pierre-Yves Chibon 13e2e9
                  "user": {
Pierre-Yves Chibon 13e2e9
                    "fullname": "PY C",
Pierre-Yves Chibon 13e2e9
                    "name": "pingou"
Pierre-Yves Chibon 13e2e9
                  }
Pierre-Yves Chibon 13e2e9
                }
Pierre-Yves Chibon 316f15
              ]
Pierre-Yves Chibon 13e2e9
            }
Pierre-Yves Chibon 13e2e9
        )
Pierre-Yves Chibon 13e2e9
        headers = {'Authorization': 'token aaabbbccc'}
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon c4fef5
        # Access issues authenticated but non-existing token
Pierre-Yves Chibon c4fef5
        output = self.app.get('/api/0/test/issues', headers=headers)
Pierre-Yves Chibon c4fef5
        self.assertEqual(output.status_code, 401)
Pierre-Yves Chibon c4fef5
Pierre-Yves Chibon c4fef5
        # Create a new token for another user
Pierre-Yves Chibon c4fef5
        item = pagure.lib.model.Token(
Pierre-Yves Chibon c4fef5
            id='bar_token',
Pierre-Yves Chibon c4fef5
            user_id=2,
Pierre-Yves Chibon c4fef5
            project_id=1,
Pierre-Yves Chibon c4fef5
            expiration=datetime.datetime.utcnow() + datetime.timedelta(
Pierre-Yves Chibon c4fef5
                days=30)
Pierre-Yves Chibon c4fef5
        )
Pierre-Yves Chibon c4fef5
        self.session.add(item)
Pierre-Yves Chibon c4fef5
Pierre-Yves Chibon c4fef5
        headers = {'Authorization': 'token bar_token'}
Pierre-Yves Chibon c4fef5
Pierre-Yves Chibon 13e2e9
        # Access issues authenticated but wrong token
Pierre-Yves Chibon 13e2e9
        output = self.app.get('/api/0/test/issues', headers=headers)
Pierre-Yves Chibon 13e2e9
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 13e2e9
        data = json.loads(output.data)
Pierre-Yves Chibon 13e2e9
        data['issues'][0]['date_created'] = '1431414800'
Pierre-Yves Chibon 13e2e9
        self.assertDictEqual(
Pierre-Yves Chibon 13e2e9
            data,
Pierre-Yves Chibon 13e2e9
            {
Pierre-Yves Chibon 316f15
              "args": {
Pierre-Yves Chibon 316f15
                "assignee": None,
Pierre-Yves Chibon 316f15
                "author": None,
Pierre-Yves Chibon 316f15
                "status": None,
Pierre-Yves Chibon 316f15
                "tags": []
Pierre-Yves Chibon 316f15
              },
Pierre-Yves Chibon 226628
              "total_issues": 1,
Pierre-Yves Chibon 13e2e9
              "issues": [
Pierre-Yves Chibon 13e2e9
                {
Pierre-Yves Chibon 13e2e9
                  "assignee": None,
Pierre-Yves Chibon 13e2e9
                  "blocks": [],
Pierre-Yves Chibon 13e2e9
                  "comments": [],
Pierre-Yves Chibon 13e2e9
                  "content": "This issue needs attention",
Pierre-Yves Chibon 13e2e9
                  "date_created": "1431414800",
Pierre-Yves Chibon 13e2e9
                  "depends": [],
Pierre-Yves Chibon 13e2e9
                  "id": 1,
Pierre-Yves Chibon 13e2e9
                  "private": False,
Pierre-Yves Chibon 13e2e9
                  "status": "Open",
Pierre-Yves Chibon 13e2e9
                  "tags": [],
Pierre-Yves Chibon 13e2e9
                  "title": "test issue",
Pierre-Yves Chibon 13e2e9
                  "user": {
Pierre-Yves Chibon 13e2e9
                    "fullname": "PY C",
Pierre-Yves Chibon 13e2e9
                    "name": "pingou"
Pierre-Yves Chibon 13e2e9
                  }
Pierre-Yves Chibon 13e2e9
                }
Pierre-Yves Chibon 316f15
              ]
Pierre-Yves Chibon 13e2e9
            }
Pierre-Yves Chibon 13e2e9
        )
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 13e2e9
        headers = {'Authorization': 'token aaabbbcccddd'}
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 13e2e9
        # Access issues authenticated correctly
Pierre-Yves Chibon 13e2e9
        output = self.app.get('/api/0/test/issues', headers=headers)
Pierre-Yves Chibon 13e2e9
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 13e2e9
        data = json.loads(output.data)
Pierre-Yves Chibon 13e2e9
        data['issues'][0]['date_created'] = '1431414800'
Pierre-Yves Chibon 13e2e9
        data['issues'][1]['date_created'] = '1431414800'
Pierre-Yves Chibon 13e2e9
        self.assertDictEqual(
Pierre-Yves Chibon 13e2e9
            data,
Pierre-Yves Chibon 13e2e9
            {
Pierre-Yves Chibon 316f15
              "args": {
Pierre-Yves Chibon 316f15
                "assignee": None,
Pierre-Yves Chibon 316f15
                "author": None,
Pierre-Yves Chibon 316f15
                "status": None,
Pierre-Yves Chibon 316f15
                "tags": []
Pierre-Yves Chibon 316f15
              },
Pierre-Yves Chibon 226628
              "total_issues": 2,
Pierre-Yves Chibon 13e2e9
              "issues": [
Pierre-Yves Chibon 13e2e9
                {
Pierre-Yves Chibon 13e2e9
                  "assignee": None,
Pierre-Yves Chibon 13e2e9
                  "blocks": [],
Pierre-Yves Chibon 13e2e9
                  "comments": [],
Pierre-Yves Chibon 13e2e9
                  "content": "This issue needs attention",
Pierre-Yves Chibon 13e2e9
                  "date_created": "1431414800",
Pierre-Yves Chibon 13e2e9
                  "depends": [],
Pierre-Yves Chibon 13e2e9
                  "id": 1,
Pierre-Yves Chibon 13e2e9
                  "private": False,
Pierre-Yves Chibon 13e2e9
                  "status": "Open",
Pierre-Yves Chibon 13e2e9
                  "tags": [],
Pierre-Yves Chibon 13e2e9
                  "title": "test issue",
Pierre-Yves Chibon 13e2e9
                  "user": {
Pierre-Yves Chibon 13e2e9
                    "fullname": "PY C",
Pierre-Yves Chibon 13e2e9
                    "name": "pingou"
Pierre-Yves Chibon 13e2e9
                  }
Pierre-Yves Chibon 13e2e9
                },
Pierre-Yves Chibon 13e2e9
                {
Pierre-Yves Chibon 13e2e9
                  "assignee": None,
Pierre-Yves Chibon 13e2e9
                  "blocks": [],
Pierre-Yves Chibon 13e2e9
                  "comments": [],
Pierre-Yves Chibon 13e2e9
                  "content": "We should work on this",
Pierre-Yves Chibon 13e2e9
                  "date_created": "1431414800",
Pierre-Yves Chibon 13e2e9
                  "depends": [],
Pierre-Yves Chibon 13e2e9
                  "id": 2,
Pierre-Yves Chibon 13e2e9
                  "private": True,
Pierre-Yves Chibon 13e2e9
                  "status": "Open",
Pierre-Yves Chibon 13e2e9
                  "tags": [],
Pierre-Yves Chibon 13e2e9
                  "title": "Test issue",
Pierre-Yves Chibon 13e2e9
                  "user": {
Pierre-Yves Chibon 13e2e9
                    "fullname": "PY C",
Pierre-Yves Chibon 13e2e9
                    "name": "pingou"
Pierre-Yves Chibon 13e2e9
                  }
Pierre-Yves Chibon 13e2e9
                }
Pierre-Yves Chibon 316f15
              ]
Pierre-Yves Chibon 13e2e9
            }
Pierre-Yves Chibon 13e2e9
        )
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 13e2e9
        # List closed issue
Pierre-Yves Chibon 13e2e9
        output = self.app.get('/api/0/test/issues?status=Closed', headers=headers)
Pierre-Yves Chibon 13e2e9
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 13e2e9
        data = json.loads(output.data)
Pierre-Yves Chibon 13e2e9
        self.assertDictEqual(
Pierre-Yves Chibon 13e2e9
            data,
Pierre-Yves Chibon 13e2e9
            {
Pierre-Yves Chibon 316f15
              "args": {
Pierre-Yves Chibon 316f15
                "assignee": None,
Pierre-Yves Chibon 316f15
                "author": None,
Pierre-Yves Chibon 316f15
                "status": "Closed",
Pierre-Yves Chibon 316f15
                "tags": []
Pierre-Yves Chibon 316f15
              },
Pierre-Yves Chibon 226628
              "total_issues": 0,
Pierre-Yves Chibon 316f15
              "issues": []
Pierre-Yves Chibon 13e2e9
            }
Pierre-Yves Chibon 13e2e9
        )
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 13e2e9
        # List closed issue
Pierre-Yves Chibon 13e2e9
        output = self.app.get('/api/0/test/issues?status=Invalid', headers=headers)
Pierre-Yves Chibon 13e2e9
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 13e2e9
        data = json.loads(output.data)
Pierre-Yves Chibon 13e2e9
        self.assertDictEqual(
Pierre-Yves Chibon 13e2e9
            data,
Pierre-Yves Chibon 13e2e9
            {
Pierre-Yves Chibon 316f15
              "args": {
Pierre-Yves Chibon 316f15
                "assignee": None,
Pierre-Yves Chibon 316f15
                "author": None,
Pierre-Yves Chibon 316f15
                "status": "Invalid",
Pierre-Yves Chibon 316f15
                "tags": []
Pierre-Yves Chibon 316f15
              },
Pierre-Yves Chibon 226628
              "total_issues": 0,
Pierre-Yves Chibon 316f15
              "issues": []
Pierre-Yves Chibon 13e2e9
            }
Pierre-Yves Chibon 13e2e9
        )
Pierre-Yves Chibon 13e2e9
Pierre-Yves Chibon 1c76b9
    def test_api_view_issue(self):
Pierre-Yves Chibon 1c76b9
        """ Test the api_view_issue method of the flask api. """
Pierre-Yves Chibon 1c76b9
        self.test_api_new_issue()
Pierre-Yves Chibon 1c76b9
Pierre-Yves Chibon 4a277d
        # Invalid repo
Pierre-Yves Chibon 4a277d
        output = self.app.get('/api/0/foo/issue/1')
Pierre-Yves Chibon 4a277d
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 4a277d
        data = json.loads(output.data)
Pierre-Yves Chibon 4a277d
        self.assertDictEqual(
Pierre-Yves Chibon 4a277d
            data,
Pierre-Yves Chibon 4a277d
            {
Pierre-Yves Chibon 4a277d
              "error": "Project not found",
Pierre-Yves Chibon d661a4
              "error_code": "ENOPROJECT",
Pierre-Yves Chibon 4a277d
            }
Pierre-Yves Chibon 4a277d
        )
Pierre-Yves Chibon 4a277d
Pierre-Yves Chibon 4a277d
        # Invalid issue for this repo
Pierre-Yves Chibon 1c76b9
        output = self.app.get('/api/0/test2/issue/1')
Pierre-Yves Chibon 1c76b9
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 1c76b9
        data = json.loads(output.data)
Pierre-Yves Chibon 1c76b9
        self.assertDictEqual(
Pierre-Yves Chibon 1c76b9
            data,
Pierre-Yves Chibon 1c76b9
            {
Pierre-Yves Chibon 1c76b9
              "error": "Issue not found",
Pierre-Yves Chibon d661a4
              "error_code": "ENOISSUE",
Pierre-Yves Chibon 1c76b9
            }
Pierre-Yves Chibon 1c76b9
        )
Pierre-Yves Chibon 1c76b9
Pierre-Yves Chibon 4a277d
        # Valid issue
Pierre-Yves Chibon 1c76b9
        output = self.app.get('/api/0/test/issue/1')
Pierre-Yves Chibon 1c76b9
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 1c76b9
        data = json.loads(output.data)
Pierre-Yves Chibon 1c76b9
        data['date_created'] = '1431414800'
Pierre-Yves Chibon 1c76b9
        self.assertDictEqual(
Pierre-Yves Chibon 1c76b9
            data,
Pierre-Yves Chibon 1c76b9
            {
Pierre-Yves Chibon 1c76b9
              "assignee": None,
Pierre-Yves Chibon 1c76b9
              "blocks": [],
Pierre-Yves Chibon 1c76b9
              "comments": [],
Pierre-Yves Chibon 1c76b9
              "content": "This issue needs attention",
Pierre-Yves Chibon 1c76b9
              "date_created": "1431414800",
Pierre-Yves Chibon 1c76b9
              "depends": [],
Pierre-Yves Chibon 1c76b9
              "id": 1,
Pierre-Yves Chibon 1c76b9
              "private": False,
Pierre-Yves Chibon 1c76b9
              "status": "Open",
Pierre-Yves Chibon 1c76b9
              "tags": [],
Pierre-Yves Chibon 1c76b9
              "title": "test issue",
Pierre-Yves Chibon 1c76b9
              "user": {
Pierre-Yves Chibon 1c76b9
                "fullname": "PY C",
Pierre-Yves Chibon 1c76b9
                "name": "pingou"
Pierre-Yves Chibon 1c76b9
              }
Pierre-Yves Chibon 1c76b9
            }
Pierre-Yves Chibon 1c76b9
        )
Pierre-Yves Chibon 1c76b9
Pierre-Yves Chibon 4a277d
        # Create private issue
Pierre-Yves Chibon 4a277d
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 4a277d
        msg = pagure.lib.new_issue(
Pierre-Yves Chibon 4a277d
            session=self.session,
Pierre-Yves Chibon 4a277d
            repo=repo,
Pierre-Yves Chibon 4a277d
            title='Test issue',
Pierre-Yves Chibon 4a277d
            content='We should work on this',
Pierre-Yves Chibon 4a277d
            user='pingou',
Pierre-Yves Chibon 4a277d
            ticketfolder=None,
Pierre-Yves Chibon 4a277d
            private=True,
Pierre-Yves Chibon 7b4f84
            issue_uid='aaabbbccc',
Pierre-Yves Chibon 4a277d
        )
Pierre-Yves Chibon 4a277d
        self.session.commit()
Pierre-Yves Chibon 4a277d
        self.assertEqual(msg.title, 'Test issue')
Pierre-Yves Chibon 4a277d
Pierre-Yves Chibon 4a277d
        # Access private issue un-authenticated
Pierre-Yves Chibon 4a277d
        output = self.app.get('/api/0/test/issue/2')
Pierre-Yves Chibon 4a277d
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 4a277d
        data = json.loads(output.data)
Pierre-Yves Chibon 4a277d
        self.assertDictEqual(
Pierre-Yves Chibon 4a277d
            data,
Pierre-Yves Chibon 4a277d
            {
Pierre-Yves Chibon 4a277d
              "error": "You are not allowed to view this issue",
Pierre-Yves Chibon 76338b
              "error_code": "EISSUENOTALLOWED",
Pierre-Yves Chibon 4a277d
            }
Pierre-Yves Chibon 4a277d
        )
Pierre-Yves Chibon 4a277d
Pierre-Yves Chibon 4a277d
        headers = {'Authorization': 'token aaabbbccc'}
Pierre-Yves Chibon 4a277d
Pierre-Yves Chibon c4fef5
        # Access private issue authenticated but non-existing token
Pierre-Yves Chibon c4fef5
        output = self.app.get('/api/0/test/issue/2', headers=headers)
Pierre-Yves Chibon c4fef5
        self.assertEqual(output.status_code, 401)
Pierre-Yves Chibon c4fef5
        data = json.loads(output.data)
Pierre-Yves Chibon c4fef5
        self.assertDictEqual(
Pierre-Yves Chibon c4fef5
            data,
Pierre-Yves Chibon c4fef5
            {
Pierre-Yves Chibon c4fef5
              "error": "Invalid or expired token. Please visit https://pagure.org/ to get or renew your API token.",
Pierre-Yves Chibon c4fef5
              "error_code": "EINVALIDTOK"
Pierre-Yves Chibon c4fef5
            }
Pierre-Yves Chibon c4fef5
        )
Pierre-Yves Chibon c4fef5
Pierre-Yves Chibon c4fef5
        # Create a new token for another user
Pierre-Yves Chibon c4fef5
        item = pagure.lib.model.Token(
Pierre-Yves Chibon c4fef5
            id='bar_token',
Pierre-Yves Chibon c4fef5
            user_id=2,
Pierre-Yves Chibon c4fef5
            project_id=1,
Pierre-Yves Chibon c4fef5
            expiration=datetime.datetime.utcnow() + datetime.timedelta(
Pierre-Yves Chibon c4fef5
                days=30)
Pierre-Yves Chibon c4fef5
        )
Pierre-Yves Chibon c4fef5
        self.session.add(item)
Pierre-Yves Chibon c4fef5
Pierre-Yves Chibon c4fef5
        headers = {'Authorization': 'token bar_token'}
Pierre-Yves Chibon c4fef5
Pierre-Yves Chibon 4a277d
        # Access private issue authenticated but wrong token
Pierre-Yves Chibon 4a277d
        output = self.app.get('/api/0/test/issue/2', headers=headers)
Pierre-Yves Chibon 4a277d
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 4a277d
        data = json.loads(output.data)
Pierre-Yves Chibon 4a277d
        self.assertDictEqual(
Pierre-Yves Chibon 4a277d
            data,
Pierre-Yves Chibon 4a277d
            {
Pierre-Yves Chibon 4a277d
              "error": "You are not allowed to view this issue",
Pierre-Yves Chibon 76338b
              "error_code": "EISSUENOTALLOWED",
Pierre-Yves Chibon 4a277d
            }
Pierre-Yves Chibon 4a277d
        )
Pierre-Yves Chibon 4a277d
Pierre-Yves Chibon 4a277d
        headers = {'Authorization': 'token aaabbbcccddd'}
Pierre-Yves Chibon 4a277d
Pierre-Yves Chibon 4a277d
        # Access private issue authenticated correctly
Pierre-Yves Chibon 4a277d
        output = self.app.get('/api/0/test/issue/2', headers=headers)
Pierre-Yves Chibon 4a277d
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 7b4f84
        data = json.loads(output.data)
Pierre-Yves Chibon 7b4f84
        data['date_created'] = '1431414800'
Pierre-Yves Chibon 7b4f84
        self.assertDictEqual(
Pierre-Yves Chibon 7b4f84
            data,
Pierre-Yves Chibon 7b4f84
            {
Pierre-Yves Chibon 7b4f84
              "assignee": None,
Pierre-Yves Chibon 7b4f84
              "blocks": [],
Pierre-Yves Chibon 7b4f84
              "comments": [],
Pierre-Yves Chibon 7b4f84
              "content": "We should work on this",
Pierre-Yves Chibon 7b4f84
              "date_created": "1431414800",
Pierre-Yves Chibon 7b4f84
              "depends": [],
Pierre-Yves Chibon 7b4f84
              "id": 2,
Pierre-Yves Chibon 7b4f84
              "private": True,
Pierre-Yves Chibon 7b4f84
              "status": "Open",
Pierre-Yves Chibon 7b4f84
              "tags": [],
Pierre-Yves Chibon 7b4f84
              "title": "Test issue",
Pierre-Yves Chibon 7b4f84
              "user": {
Pierre-Yves Chibon 7b4f84
                "fullname": "PY C",
Pierre-Yves Chibon 7b4f84
                "name": "pingou"
Pierre-Yves Chibon 7b4f84
              }
Pierre-Yves Chibon 7b4f84
            }
Pierre-Yves Chibon 7b4f84
        )
Pierre-Yves Chibon 7b4f84
Pierre-Yves Chibon 7b4f84
        # Access private issue authenticated correctly using the issue's uid
Pierre-Yves Chibon 7b4f84
        output = self.app.get('/api/0/test/issue/aaabbbccc', headers=headers)
Pierre-Yves Chibon 7b4f84
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 4a277d
        data = json.loads(output.data)
Pierre-Yves Chibon 4a277d
        data['date_created'] = '1431414800'
Pierre-Yves Chibon 4a277d
        self.assertDictEqual(
Pierre-Yves Chibon 4a277d
            data,
Pierre-Yves Chibon 4a277d
            {
Pierre-Yves Chibon 4a277d
              "assignee": None,
Pierre-Yves Chibon 4a277d
              "blocks": [],
Pierre-Yves Chibon 4a277d
              "comments": [],
Pierre-Yves Chibon 4a277d
              "content": "We should work on this",
Pierre-Yves Chibon 4a277d
              "date_created": "1431414800",
Pierre-Yves Chibon 4a277d
              "depends": [],
Pierre-Yves Chibon 4a277d
              "id": 2,
Pierre-Yves Chibon 4a277d
              "private": True,
Pierre-Yves Chibon 4a277d
              "status": "Open",
Pierre-Yves Chibon 4a277d
              "tags": [],
Pierre-Yves Chibon 4a277d
              "title": "Test issue",
Pierre-Yves Chibon 4a277d
              "user": {
Pierre-Yves Chibon 4a277d
                "fullname": "PY C",
Pierre-Yves Chibon 4a277d
                "name": "pingou"
Pierre-Yves Chibon 4a277d
              }
Pierre-Yves Chibon 4a277d
            }
Pierre-Yves Chibon 4a277d
        )
Pierre-Yves Chibon 4a277d
Pierre-Yves Chibon 218ed6
    def test_api_change_status_issue(self):
Pierre-Yves Chibon 218ed6
        """ Test the api_change_status_issue method of the flask api. """
Pierre-Yves Chibon 218ed6
        tests.create_projects(self.session)
Pierre-Yves Chibon 218ed6
        tests.create_projects_git(os.path.join(tests.HERE, 'tickets'))
Pierre-Yves Chibon 218ed6
        tests.create_tokens(self.session)
Pierre-Yves Chibon 218ed6
        tests.create_tokens_acl(self.session)
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        headers = {'Authorization': 'token aaabbbcccddd'}
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon f69837
        # Invalid project
Pierre-Yves Chibon f69837
        output = self.app.post('/api/0/foo/issue/1/status', headers=headers)
Pierre-Yves Chibon f69837
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon f69837
        data = json.loads(output.data)
Pierre-Yves Chibon f69837
        self.assertDictEqual(
Pierre-Yves Chibon f69837
            data,
Pierre-Yves Chibon f69837
            {
Pierre-Yves Chibon f69837
              "error": "Project not found",
Pierre-Yves Chibon d661a4
              "error_code": "ENOPROJECT",
Pierre-Yves Chibon f69837
            }
Pierre-Yves Chibon f69837
        )
Pierre-Yves Chibon f69837
Pierre-Yves Chibon 218ed6
        # Valid token, wrong project
Pierre-Yves Chibon 218ed6
        output = self.app.post('/api/0/test2/issue/1/status', headers=headers)
Pierre-Yves Chibon 218ed6
        self.assertEqual(output.status_code, 401)
Pierre-Yves Chibon 218ed6
        data = json.loads(output.data)
Pierre-Yves Chibon 218ed6
        self.assertDictEqual(
Pierre-Yves Chibon 218ed6
            data,
Pierre-Yves Chibon 218ed6
            {
Pierre-Yves Chibon 218ed6
              "error": "Invalid or expired token. Please visit " \
Pierre-Yves Chibon 1e2669
                  "https://pagure.org/ to get or renew your API token.",
Pierre-Yves Chibon d661a4
              "error_code": "EINVALIDTOK",
Pierre-Yves Chibon 218ed6
            }
Pierre-Yves Chibon 218ed6
        )
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        # No input
Pierre-Yves Chibon 218ed6
        output = self.app.post('/api/0/test/issue/1/status', headers=headers)
Pierre-Yves Chibon 218ed6
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 218ed6
        data = json.loads(output.data)
Pierre-Yves Chibon 218ed6
        self.assertDictEqual(
Pierre-Yves Chibon 218ed6
            data,
Pierre-Yves Chibon 218ed6
            {
Pierre-Yves Chibon 218ed6
              "error": "Issue not found",
Pierre-Yves Chibon d661a4
              "error_code": "ENOISSUE",
Pierre-Yves Chibon 218ed6
            }
Pierre-Yves Chibon 218ed6
        )
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        # Create normal issue
Pierre-Yves Chibon 218ed6
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 218ed6
        msg = pagure.lib.new_issue(
Pierre-Yves Chibon 218ed6
            session=self.session,
Pierre-Yves Chibon 218ed6
            repo=repo,
Pierre-Yves Chibon 218ed6
            title='Test issue #1',
Pierre-Yves Chibon 218ed6
            content='We should work on this',
Pierre-Yves Chibon 218ed6
            user='pingou',
Pierre-Yves Chibon 218ed6
            ticketfolder=None,
Pierre-Yves Chibon 218ed6
            private=False,
Pierre-Yves Chibon 218ed6
        )
Pierre-Yves Chibon 218ed6
        self.session.commit()
Pierre-Yves Chibon 218ed6
        self.assertEqual(msg.title, 'Test issue #1')
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon f69837
        # Create another project
Pierre-Yves Chibon f69837
        item = pagure.lib.model.Project(
Pierre-Yves Chibon f69837
            user_id=2,  # pingou
Pierre-Yves Chibon f69837
            name='foo',
Pierre-Yves Chibon f69837
            description='test project #3',
Pierre-Yves Chibon f69837
            hook_token='aaabbbdddeee',
Pierre-Yves Chibon f69837
        )
Pierre-Yves Chibon f69837
        self.session.add(item)
Pierre-Yves Chibon f69837
        self.session.commit()
Pierre-Yves Chibon f69837
Pierre-Yves Chibon f69837
        # Create a token for pingou for this project
Pierre-Yves Chibon f69837
        item = pagure.lib.model.Token(
Pierre-Yves Chibon f69837
            id='pingou_foo',
Pierre-Yves Chibon f69837
            user_id=1,
Pierre-Yves Chibon f69837
            project_id=3,
Pierre-Yves Chibon f69837
            expiration=datetime.datetime.utcnow() + datetime.timedelta(
Pierre-Yves Chibon f69837
                days=30)
Pierre-Yves Chibon f69837
        )
Pierre-Yves Chibon f69837
        self.session.add(item)
Pierre-Yves Chibon f69837
        self.session.commit()
Pierre-Yves Chibon f69837
Pierre-Yves Chibon f69837
        # Give `change_status_issue` to this token
Pierre-Yves Chibon f69837
        item = pagure.lib.model.TokenAcl(
Pierre-Yves Chibon f69837
            token_id='pingou_foo',
Pierre-Yves Chibon e1ff5c
            acl_id=6,
Pierre-Yves Chibon f69837
        )
Pierre-Yves Chibon f69837
        self.session.add(item)
Pierre-Yves Chibon f69837
        self.session.commit()
Pierre-Yves Chibon f69837
Pierre-Yves Chibon f69837
        repo = pagure.lib.get_project(self.session, 'foo')
Pierre-Yves Chibon 218ed6
        # Create private issue
Pierre-Yves Chibon 218ed6
        msg = pagure.lib.new_issue(
Pierre-Yves Chibon 218ed6
            session=self.session,
Pierre-Yves Chibon 218ed6
            repo=repo,
Pierre-Yves Chibon 218ed6
            title='Test issue',
Pierre-Yves Chibon 218ed6
            content='We should work on this',
Pierre-Yves Chibon f69837
            user='foo',
Pierre-Yves Chibon 218ed6
            ticketfolder=None,
Pierre-Yves Chibon 218ed6
            private=True,
Pierre-Yves Chibon 218ed6
        )
Pierre-Yves Chibon 218ed6
        self.session.commit()
Pierre-Yves Chibon 218ed6
        self.assertEqual(msg.title, 'Test issue')
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        # Check status before
Pierre-Yves Chibon 218ed6
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 218ed6
        issue = pagure.lib.search_issues(self.session, repo, issueid=1)
Pierre-Yves Chibon 218ed6
        self.assertEqual(issue.status, 'Open')
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        data = {
Pierre-Yves Chibon 218ed6
            'title': 'test issue',
Pierre-Yves Chibon 218ed6
        }
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        # Incomplete request
Pierre-Yves Chibon 218ed6
        output = self.app.post(
Pierre-Yves Chibon 218ed6
            '/api/0/test/issue/1/status', data=data, headers=headers)
Pierre-Yves Chibon 218ed6
        self.assertEqual(output.status_code, 400)
Pierre-Yves Chibon 218ed6
        data = json.loads(output.data)
Pierre-Yves Chibon 218ed6
        self.assertDictEqual(
Pierre-Yves Chibon 218ed6
            data,
Pierre-Yves Chibon 218ed6
            {
Pierre-Yves Chibon 218ed6
              "error": "Invalid or incomplete input submited",
Pierre-Yves Chibon d661a4
              "error_code": "EINVALIDREQ",
Pierre-Yves Chibon 218ed6
            }
Pierre-Yves Chibon 218ed6
        )
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        # No change
Pierre-Yves Chibon 218ed6
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 218ed6
        issue = pagure.lib.search_issues(self.session, repo, issueid=1)
Pierre-Yves Chibon 218ed6
        self.assertEqual(issue.status, 'Open')
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        data = {
Pierre-Yves Chibon 218ed6
            'status': 'Open',
Pierre-Yves Chibon 218ed6
        }
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        # Valid request but no change
Pierre-Yves Chibon 218ed6
        output = self.app.post(
Pierre-Yves Chibon 218ed6
            '/api/0/test/issue/1/status', data=data, headers=headers)
Pierre-Yves Chibon 218ed6
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 218ed6
        data = json.loads(output.data)
Pierre-Yves Chibon 218ed6
        self.assertDictEqual(
Pierre-Yves Chibon 218ed6
            data,
Pierre-Yves Chibon 218ed6
            {'message': 'No changes'}
Pierre-Yves Chibon 218ed6
        )
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        # No change
Pierre-Yves Chibon 218ed6
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 218ed6
        issue = pagure.lib.search_issues(self.session, repo, issueid=1)
Pierre-Yves Chibon 218ed6
        self.assertEqual(issue.status, 'Open')
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        data = {
Pierre-Yves Chibon 218ed6
            'status': 'Fixed',
Pierre-Yves Chibon 218ed6
        }
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon 218ed6
        # Valid request
Pierre-Yves Chibon 218ed6
        output = self.app.post(
Pierre-Yves Chibon 218ed6
            '/api/0/test/issue/1/status', data=data, headers=headers)
Pierre-Yves Chibon 218ed6
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 218ed6
        data = json.loads(output.data)
Pierre-Yves Chibon 218ed6
        self.assertDictEqual(
Pierre-Yves Chibon 218ed6
            data,
Pierre-Yves Chibon 754e40
            {'message': 'Successfully edited issue #1'}
Pierre-Yves Chibon 218ed6
        )
Pierre-Yves Chibon 218ed6
Pierre-Yves Chibon f69837
        headers = {'Authorization': 'token pingou_foo'}
Pierre-Yves Chibon f69837
Pierre-Yves Chibon f69837
        # Un-authorized issue
Pierre-Yves Chibon f69837
        output = self.app.post(
Pierre-Yves Chibon f69837
            '/api/0/foo/issue/1/status', data=data, headers=headers)
Pierre-Yves Chibon f69837
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon f69837
        data = json.loads(output.data)
Pierre-Yves Chibon f69837
        self.assertDictEqual(
Pierre-Yves Chibon f69837
            data,
Pierre-Yves Chibon f69837
            {
Pierre-Yves Chibon f69837
              "error": "You are not allowed to view this issue",
Pierre-Yves Chibon 76338b
              "error_code": "EISSUENOTALLOWED",
Pierre-Yves Chibon f69837
            }
Pierre-Yves Chibon f69837
        )
Pierre-Yves Chibon f69837
Pierre-Yves Chibon 5aca93
    @patch('pagure.lib.git.update_git')
Pierre-Yves Chibon 5aca93
    @patch('pagure.lib.notify.send_email')
Pierre-Yves Chibon 5aca93
    def test_api_comment_issue(self, p_send_email, p_ugt):
Pierre-Yves Chibon fc6bd4
        """ Test the api_comment_issue method of the flask api. """
Pierre-Yves Chibon 5aca93
        p_send_email.return_value = True
Pierre-Yves Chibon 5aca93
        p_ugt.return_value = True
Pierre-Yves Chibon 5aca93
Pierre-Yves Chibon fc6bd4
        tests.create_projects(self.session)
Pierre-Yves Chibon fc6bd4
        tests.create_tokens(self.session)
Pierre-Yves Chibon fc6bd4
        tests.create_tokens_acl(self.session)
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        headers = {'Authorization': 'token aaabbbcccddd'}
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Invalid project
Pierre-Yves Chibon fc6bd4
        output = self.app.post('/api/0/foo/issue/1/comment', headers=headers)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon fc6bd4
        data = json.loads(output.data)
Pierre-Yves Chibon fc6bd4
        self.assertDictEqual(
Pierre-Yves Chibon fc6bd4
            data,
Pierre-Yves Chibon fc6bd4
            {
Pierre-Yves Chibon fc6bd4
              "error": "Project not found",
Pierre-Yves Chibon d661a4
              "error_code": "ENOPROJECT",
Pierre-Yves Chibon fc6bd4
            }
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Valid token, wrong project
Pierre-Yves Chibon fc6bd4
        output = self.app.post('/api/0/test2/issue/1/comment', headers=headers)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(output.status_code, 401)
Pierre-Yves Chibon fc6bd4
        data = json.loads(output.data)
Pierre-Yves Chibon fc6bd4
        self.assertDictEqual(
Pierre-Yves Chibon fc6bd4
            data,
Pierre-Yves Chibon fc6bd4
            {
Pierre-Yves Chibon fc6bd4
              "error": "Invalid or expired token. Please visit " \
Pierre-Yves Chibon 1e2669
                  "https://pagure.org/ to get or renew your API token.",
Pierre-Yves Chibon d661a4
              "error_code": "EINVALIDTOK",
Pierre-Yves Chibon fc6bd4
            }
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # No input
Pierre-Yves Chibon fc6bd4
        output = self.app.post('/api/0/test/issue/1/comment', headers=headers)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon fc6bd4
        data = json.loads(output.data)
Pierre-Yves Chibon fc6bd4
        self.assertDictEqual(
Pierre-Yves Chibon fc6bd4
            data,
Pierre-Yves Chibon fc6bd4
            {
Pierre-Yves Chibon fc6bd4
              "error": "Issue not found",
Pierre-Yves Chibon d661a4
              "error_code": "ENOISSUE",
Pierre-Yves Chibon fc6bd4
            }
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Create normal issue
Pierre-Yves Chibon fc6bd4
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon fc6bd4
        msg = pagure.lib.new_issue(
Pierre-Yves Chibon fc6bd4
            session=self.session,
Pierre-Yves Chibon fc6bd4
            repo=repo,
Pierre-Yves Chibon fc6bd4
            title='Test issue #1',
Pierre-Yves Chibon fc6bd4
            content='We should work on this',
Pierre-Yves Chibon fc6bd4
            user='pingou',
Pierre-Yves Chibon fc6bd4
            ticketfolder=None,
Pierre-Yves Chibon fc6bd4
            private=False,
Pierre-Yves Chibon 5aca93
            issue_uid='aaabbbccc#1',
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
        self.session.commit()
Pierre-Yves Chibon fc6bd4
        self.assertEqual(msg.title, 'Test issue #1')
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Check comments before
Pierre-Yves Chibon fc6bd4
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon fc6bd4
        issue = pagure.lib.search_issues(self.session, repo, issueid=1)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(len(issue.comments), 0)
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        data = {
Pierre-Yves Chibon fc6bd4
            'title': 'test issue',
Pierre-Yves Chibon fc6bd4
        }
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Incomplete request
Pierre-Yves Chibon fc6bd4
        output = self.app.post(
Pierre-Yves Chibon fc6bd4
            '/api/0/test/issue/1/comment', data=data, headers=headers)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(output.status_code, 400)
Pierre-Yves Chibon fc6bd4
        data = json.loads(output.data)
Pierre-Yves Chibon fc6bd4
        self.assertDictEqual(
Pierre-Yves Chibon fc6bd4
            data,
Pierre-Yves Chibon fc6bd4
            {
Pierre-Yves Chibon fc6bd4
              "error": "Invalid or incomplete input submited",
Pierre-Yves Chibon d661a4
              "error_code": "EINVALIDREQ",
Pierre-Yves Chibon fc6bd4
            }
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # No change
Pierre-Yves Chibon fc6bd4
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon fc6bd4
        issue = pagure.lib.search_issues(self.session, repo, issueid=1)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(issue.status, 'Open')
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        data = {
Pierre-Yves Chibon fc6bd4
            'comment': 'This is a very interesting question',
Pierre-Yves Chibon fc6bd4
        }
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Valid request
Pierre-Yves Chibon fc6bd4
        output = self.app.post(
Pierre-Yves Chibon fc6bd4
            '/api/0/test/issue/1/comment', data=data, headers=headers)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon fc6bd4
        data = json.loads(output.data)
Pierre-Yves Chibon fc6bd4
        self.assertDictEqual(
Pierre-Yves Chibon fc6bd4
            data,
Pierre-Yves Chibon fc6bd4
            {'message': 'Comment added'}
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # One comment added
Pierre-Yves Chibon fc6bd4
        repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon fc6bd4
        issue = pagure.lib.search_issues(self.session, repo, issueid=1)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(len(issue.comments), 1)
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Create another project
Pierre-Yves Chibon fc6bd4
        item = pagure.lib.model.Project(
Pierre-Yves Chibon fc6bd4
            user_id=2,  # foo
Pierre-Yves Chibon fc6bd4
            name='foo',
Pierre-Yves Chibon fc6bd4
            description='test project #3',
Pierre-Yves Chibon fc6bd4
            hook_token='aaabbbdddeee',
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
        self.session.add(item)
Pierre-Yves Chibon fc6bd4
        self.session.commit()
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Create a token for pingou for this project
Pierre-Yves Chibon fc6bd4
        item = pagure.lib.model.Token(
Pierre-Yves Chibon fc6bd4
            id='pingou_foo',
Pierre-Yves Chibon fc6bd4
            user_id=1,
Pierre-Yves Chibon fc6bd4
            project_id=3,
Pierre-Yves Chibon fc6bd4
            expiration=datetime.datetime.utcnow() + datetime.timedelta(
Pierre-Yves Chibon fc6bd4
                days=30)
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
        self.session.add(item)
Pierre-Yves Chibon fc6bd4
        self.session.commit()
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Give `change_status_issue` to this token
Pierre-Yves Chibon fc6bd4
        item = pagure.lib.model.TokenAcl(
Pierre-Yves Chibon fc6bd4
            token_id='pingou_foo',
Pierre-Yves Chibon e1ff5c
            acl_id=1,
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
        self.session.add(item)
Pierre-Yves Chibon fc6bd4
        self.session.commit()
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        repo = pagure.lib.get_project(self.session, 'foo')
Pierre-Yves Chibon fc6bd4
        # Create private issue
Pierre-Yves Chibon fc6bd4
        msg = pagure.lib.new_issue(
Pierre-Yves Chibon fc6bd4
            session=self.session,
Pierre-Yves Chibon fc6bd4
            repo=repo,
Pierre-Yves Chibon fc6bd4
            title='Test issue',
Pierre-Yves Chibon fc6bd4
            content='We should work on this',
Pierre-Yves Chibon fc6bd4
            user='foo',
Pierre-Yves Chibon fc6bd4
            ticketfolder=None,
Pierre-Yves Chibon fc6bd4
            private=True,
Pierre-Yves Chibon 5aca93
            issue_uid='aaabbbccc#2',
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
        self.session.commit()
Pierre-Yves Chibon fc6bd4
        self.assertEqual(msg.title, 'Test issue')
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Check before
Pierre-Yves Chibon fc6bd4
        repo = pagure.lib.get_project(self.session, 'foo')
Pierre-Yves Chibon fc6bd4
        issue = pagure.lib.search_issues(self.session, repo, issueid=1)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(len(issue.comments), 0)
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        data = {
Pierre-Yves Chibon fc6bd4
            'comment': 'This is a very interesting question',
Pierre-Yves Chibon fc6bd4
        }
Pierre-Yves Chibon fc6bd4
        headers = {'Authorization': 'token pingou_foo'}
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # Valid request but un-authorized
Pierre-Yves Chibon fc6bd4
        output = self.app.post(
Pierre-Yves Chibon fc6bd4
            '/api/0/foo/issue/1/comment', data=data, headers=headers)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon fc6bd4
        data = json.loads(output.data)
Pierre-Yves Chibon fc6bd4
        self.assertDictEqual(
Pierre-Yves Chibon fc6bd4
            data,
Pierre-Yves Chibon fc6bd4
            {
Pierre-Yves Chibon fc6bd4
              "error": "You are not allowed to view this issue",
Pierre-Yves Chibon 76338b
              "error_code": "EISSUENOTALLOWED",
Pierre-Yves Chibon fc6bd4
            }
Pierre-Yves Chibon fc6bd4
        )
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon fc6bd4
        # No comment added
Pierre-Yves Chibon fc6bd4
        repo = pagure.lib.get_project(self.session, 'foo')
Pierre-Yves Chibon fc6bd4
        issue = pagure.lib.search_issues(self.session, repo, issueid=1)
Pierre-Yves Chibon fc6bd4
        self.assertEqual(len(issue.comments), 0)
Pierre-Yves Chibon fc6bd4
Pierre-Yves Chibon 5711a1
        # Create token for user foo
Pierre-Yves Chibon 5711a1
        item = pagure.lib.model.Token(
Pierre-Yves Chibon 5711a1
            id='foo_token2',
Pierre-Yves Chibon 5711a1
            user_id=2,
Pierre-Yves Chibon 5711a1
            project_id=3,
Pierre-Yves Chibon 5711a1
            expiration=datetime.datetime.utcnow() + datetime.timedelta(days=30)
Pierre-Yves Chibon 5711a1
        )
Pierre-Yves Chibon 5711a1
        self.session.add(item)
Pierre-Yves Chibon 5711a1
        self.session.commit()
Pierre-Yves Chibon 5711a1
        tests.create_tokens_acl(self.session, token_id='foo_token2')
Pierre-Yves Chibon 5711a1
Pierre-Yves Chibon 5711a1
        data = {
Pierre-Yves Chibon 5711a1
            'comment': 'This is a very interesting question',
Pierre-Yves Chibon 5711a1
        }
Pierre-Yves Chibon 5711a1
        headers = {'Authorization': 'token foo_token2'}
Pierre-Yves Chibon 5711a1
Pierre-Yves Chibon 5711a1
        # Valid request and authorized
Pierre-Yves Chibon 5711a1
        output = self.app.post(
Pierre-Yves Chibon 5711a1
            '/api/0/foo/issue/1/comment', data=data, headers=headers)
Pierre-Yves Chibon 5711a1
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 5711a1
        data = json.loads(output.data)
Pierre-Yves Chibon 5711a1
        self.assertDictEqual(
Pierre-Yves Chibon 5711a1
            data,
Pierre-Yves Chibon 5711a1
            {'message': 'Comment added'}
Pierre-Yves Chibon 5711a1
        )
Pierre-Yves Chibon 5711a1
Pierre-Yves Chibon 896cc0
    @patch('pagure.lib.git.update_git')
Pierre-Yves Chibon 896cc0
    @patch('pagure.lib.notify.send_email')
Pierre-Yves Chibon 896cc0
    def test_api_view_issue_comment(self, p_send_email, p_ugt):
Pierre-Yves Chibon 896cc0
        """ Test the api_view_issue_comment endpoint. """
Pierre-Yves Chibon 896cc0
        p_send_email.return_value = True
Pierre-Yves Chibon 896cc0
        p_ugt.return_value = True
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        self.test_api_comment_issue()
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # View a comment that does not exist
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/foo/issue/100/comment/2')
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # Issue exists but not the comment
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/test/issue/1/comment/2')
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # Issue and comment exists
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/test/issue/1/comment/1')
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 896cc0
        data = json.loads(output.data)
Pierre-Yves Chibon 896cc0
        data['date_created'] = '1435821770'
Pierre-Yves Chibon 896cc0
        data["comment_date"] = "2015-07-02 09:22"
Pierre-Yves Chibon 896cc0
        data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
Pierre-Yves Chibon 896cc0
        self.assertDictEqual(
Pierre-Yves Chibon 896cc0
            data,
Pierre-Yves Chibon 896cc0
            {
Pierre-Yves Chibon 896cc0
              "avatar_url": "https://seccdn.libravatar.org/avatar/...",
Pierre-Yves Chibon 896cc0
              "comment": "This is a very interesting question",
Pierre-Yves Chibon 896cc0
              "comment_date": "2015-07-02 09:22",
Pierre-Yves Chibon 896cc0
              "date_created": "1435821770",
Pierre-Yves Chibon 37b343
              "edited_on": None,
Pierre-Yves Chibon 37b343
              "editor": None,
Pierre-Yves Chibon 896cc0
              "id": 1,
Pierre-Yves Chibon 896cc0
              "parent": None,
Pierre-Yves Chibon 896cc0
              "user": {
Pierre-Yves Chibon 896cc0
                "fullname": "PY C",
Pierre-Yves Chibon 896cc0
                "name": "pingou"
Pierre-Yves Chibon 896cc0
              }
Pierre-Yves Chibon 896cc0
            }
Pierre-Yves Chibon 896cc0
        )
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # Issue and comment exists, using UID
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/test/issue/aaabbbccc#1/comment/1')
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 896cc0
        data = json.loads(output.data)
Pierre-Yves Chibon 896cc0
        data['date_created'] = '1435821770'
Pierre-Yves Chibon 896cc0
        data["comment_date"] = "2015-07-02 09:22"
Pierre-Yves Chibon 896cc0
        data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
Pierre-Yves Chibon 896cc0
        self.assertDictEqual(
Pierre-Yves Chibon 896cc0
            data,
Pierre-Yves Chibon 896cc0
            {
Pierre-Yves Chibon 896cc0
              "avatar_url": "https://seccdn.libravatar.org/avatar/...",
Pierre-Yves Chibon 896cc0
              "comment": "This is a very interesting question",
Pierre-Yves Chibon 896cc0
              "comment_date": "2015-07-02 09:22",
Pierre-Yves Chibon 896cc0
              "date_created": "1435821770",
Pierre-Yves Chibon 37b343
              "edited_on": None,
Pierre-Yves Chibon 37b343
              "editor": None,
Pierre-Yves Chibon 896cc0
              "id": 1,
Pierre-Yves Chibon 896cc0
              "parent": None,
Pierre-Yves Chibon 896cc0
              "user": {
Pierre-Yves Chibon 896cc0
                "fullname": "PY C",
Pierre-Yves Chibon 896cc0
                "name": "pingou"
Pierre-Yves Chibon 896cc0
              }
Pierre-Yves Chibon 896cc0
            }
Pierre-Yves Chibon 896cc0
        )
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # Private issue
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/foo/issue/1/comment/2')
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # Private issue - Auth - wrong token
Pierre-Yves Chibon 896cc0
        headers = {'Authorization': 'token pingou_foo'}
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/foo/issue/1/comment/2', headers=headers)
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # Private issue - Auth - Invalid token
Pierre-Yves Chibon 896cc0
        headers = {'Authorization': 'token aaabbbcccddd'}
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/foo/issue/1/comment/2', headers=headers)
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 401)
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # Private issue - Auth - valid token - unknown comment
Pierre-Yves Chibon 896cc0
        headers = {'Authorization': 'token foo_token2'}
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/foo/issue/1/comment/3', headers=headers)
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 896cc0
        # Private issue - Auth - valid token - known comment
Pierre-Yves Chibon 896cc0
        headers = {'Authorization': 'token foo_token2'}
Pierre-Yves Chibon 896cc0
        output = self.app.get('/api/0/foo/issue/1/comment/2', headers=headers)
Pierre-Yves Chibon 896cc0
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 896cc0
        data = json.loads(output.data)
Pierre-Yves Chibon 896cc0
        data['date_created'] = '1435821770'
Pierre-Yves Chibon 896cc0
        data["comment_date"] = "2015-07-02 09:22"
Pierre-Yves Chibon 896cc0
        data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
Pierre-Yves Chibon 896cc0
        self.assertDictEqual(
Pierre-Yves Chibon 896cc0
            data,
Pierre-Yves Chibon 896cc0
            {
Pierre-Yves Chibon 896cc0
              "avatar_url": "https://seccdn.libravatar.org/avatar/...",
Pierre-Yves Chibon 896cc0
              "comment": "This is a very interesting question",
Pierre-Yves Chibon 896cc0
              "comment_date": "2015-07-02 09:22",
Pierre-Yves Chibon 896cc0
              "date_created": "1435821770",
Pierre-Yves Chibon 37b343
              "edited_on": None,
Pierre-Yves Chibon 37b343
              "editor": None,
Pierre-Yves Chibon 896cc0
              "id": 2,
Pierre-Yves Chibon 896cc0
              "parent": None,
Pierre-Yves Chibon 896cc0
              "user": {
Pierre-Yves Chibon 896cc0
                "fullname": "foo bar",
Pierre-Yves Chibon 896cc0
                "name": "foo"
Pierre-Yves Chibon 896cc0
              }
Pierre-Yves Chibon 896cc0
            }
Pierre-Yves Chibon 896cc0
        )
Pierre-Yves Chibon 896cc0
Pierre-Yves Chibon 993597
Pierre-Yves Chibon 993597
if __name__ == '__main__':
Pierre-Yves Chibon 993597
    SUITE = unittest.TestLoader().loadTestsFromTestCase(
Pierre-Yves Chibon 993597
        PagureFlaskApiIssuetests)
Pierre-Yves Chibon 993597
    unittest.TextTestRunner(verbosity=2).run(SUITE)