# -*- coding: utf-8 -*-
from __future__ import unicode_literals
__requires__ = ['SQLAlchemy >= 0.8']
import pkg_resources
import datetime
import unittest
import shutil
import sys
import tempfile
import os
import json
import pygit2
from mock import patch, MagicMock
sys.path.insert(0, os.path.join(os.path.dirname(
os.path.abspath(__file__)), '..'))
import pagure.lib.query
import tests
from pagure.lib.repo import PagureRepo
FULL_ISSUE_LIST = [
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "We should work on this",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 8,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": True,
"status": "Open",
"tags": [],
"title": "Test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 7,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": True,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 6,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": True,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 5,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 4,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 3,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 2,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 1,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
]
class PagurePrivateRepotest(tests.Modeltests):
""" Tests for private repo in pagure """
maxDiff = None
def setUp(self):
""" Set up the environnment, ran before every tests. """
super(PagurePrivateRepotest, self).setUp()
pagure.config.config['TESTING'] = True
pagure.config.config['DATAGREPPER_URL'] = None
pagure.config.config['PRIVATE_PROJECTS'] = True
pagure.config.config['VIRUS_SCAN_ATTACHMENTS'] = False
def set_up_git_repo(
self, new_project=None, branch_from='feature', mtype='FF'):
""" Set up the git repo and create the corresponding PullRequest
object.
"""
# Create a git repo to play with
gitrepo = os.path.join(self.path, 'repos', 'pmc.git')
repo = pygit2.init_repository(gitrepo, bare=True)
newpath = tempfile.mkdtemp(prefix='pagure-private-test')
repopath = os.path.join(newpath, 'test')
clone_repo = pygit2.clone_repository(gitrepo, repopath)
# Create a file in that git repo
with open(os.path.join(repopath, 'sources'), 'w') as stream:
stream.write('foo\n bar')
clone_repo.index.add('sources')
clone_repo.index.write()
# Commits the files added
tree = clone_repo.index.write_tree()
author = pygit2.Signature(
'Alice Author', 'alice@authors.tld')
committer = pygit2.Signature(
'Cecil Committer', 'cecil@committers.tld')
clone_repo.create_commit(
'refs/heads/master', # the name of the reference to update
author,
committer,
'Add sources file for testing',
# binary string representing the tree object ID
tree,
# list of binary strings representing parents of the new commit
[]
)
refname = 'refs/heads/master:refs/heads/master'
ori_remote = clone_repo.remotes[0]
PagureRepo.push(ori_remote, refname)
first_commit = repo.revparse_single('HEAD')
if mtype == 'merge':
with open(os.path.join(repopath, '.gitignore'), 'w') as stream:
stream.write('*~')
clone_repo.index.add('.gitignore')
clone_repo.index.write()
# Commits the files added
tree = clone_repo.index.write_tree()
author = pygit2.Signature(
'Alice Äuthòr', 'alice@äuthòrs.tld')
committer = pygit2.Signature(
'Cecil Cõmmîttër', 'cecil@cõmmîttërs.tld')
clone_repo.create_commit(
'refs/heads/master',
author,
committer,
'Add .gitignore file for testing',
# binary string representing the tree object ID
tree,
# list of binary strings representing parents of the new commit
[first_commit.oid.hex]
)
refname = 'refs/heads/master:refs/heads/master'
ori_remote = clone_repo.remotes[0]
PagureRepo.push(ori_remote, refname)
if mtype == 'conflicts':
with open(os.path.join(repopath, 'sources'), 'w') as stream:
stream.write('foo\n bar\nbaz')
clone_repo.index.add('sources')
clone_repo.index.write()
# Commits the files added
tree = clone_repo.index.write_tree()
author = pygit2.Signature(
'Alice Author', 'alice@authors.tld')
committer = pygit2.Signature(
'Cecil Committer', 'cecil@committers.tld')
clone_repo.create_commit(
'refs/heads/master',
author,
committer,
'Add sources conflicting',
# binary string representing the tree object ID
tree,
# list of binary strings representing parents of the new commit
[first_commit.oid.hex]
)
refname = 'refs/heads/master:refs/heads/master'
ori_remote = clone_repo.remotes[0]
PagureRepo.push(ori_remote, refname)
# Set the second repo
new_gitrepo = repopath
if new_project:
# Create a new git repo to play with
new_gitrepo = os.path.join(newpath, new_project.fullname)
if not os.path.exists(new_gitrepo):
os.makedirs(new_gitrepo)
new_repo = pygit2.clone_repository(gitrepo, new_gitrepo)
repo = pygit2.Repository(new_gitrepo)
if mtype != 'nochanges':
# Edit the sources file again
with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream:
stream.write('foo\n bar\nbaz\n boose')
repo.index.add('sources')
repo.index.write()
# Commits the files added
tree = repo.index.write_tree()
author = pygit2.Signature(
'Alice Author', 'alice@authors.tld')
committer = pygit2.Signature(
'Cecil Committer', 'cecil@committers.tld')
repo.create_commit(
'refs/heads/%s' % branch_from,
author,
committer,
'A commit on branch %s' % branch_from,
tree,
[first_commit.oid.hex]
)
refname = 'refs/heads/%s' % (branch_from)
ori_remote = repo.remotes[0]
PagureRepo.push(ori_remote, refname)
# Create a PR for these changes
project = pagure.lib.query._get_project(self.session, 'pmc')
req = pagure.lib.query.new_pull_request(
session=self.session,
repo_from=project,
branch_from=branch_from,
repo_to=project,
branch_to='master',
title='PR from the %s branch' % branch_from,
user='pingou',
)
self.session.commit()
self.assertEqual(req.id, 1)
self.assertEqual(req.title, 'PR from the %s branch' % branch_from)
shutil.rmtree(newpath)
def test_index(self):
""" Test the index endpoint. """
output = self.app.get('/')
self.assertEqual(output.status_code, 200)
self.assertIn(
'<h3 class="m-0 font-weight-bold">All Projects '
'<span class="badge badge-secondary">0</span></h3>',
output.get_data(as_text=True))
# Add a private project
item = pagure.lib.model.Project(
user_id=2, # foo
name='test3',
description='test project description',
hook_token='aaabbbeee',
private=True,
)
self.session.add(item)
# Add a public project
item = pagure.lib.model.Project(
user_id=2, # foo
name='test4',
description='test project description',
hook_token='aaabbbeeeccceee',
)
self.session.add(item)
self.session.commit()
output = self.app.get('/?page=abc')
self.assertEqual(output.status_code, 200)
output_text = output.get_data(as_text=True)
self.assertIn(
'<h3 class="m-0 font-weight-bold">All Projects '
'<span class="badge badge-secondary">1</span></h3>',
output_text)
user = tests.FakeUser(username='foo')
with tests.user_set(self.app.application, user):
output = self.app.get('/', follow_redirects=True)
output_text = output.get_data(as_text=True)
self.assertIn(
'<h4 class="font-weight-bold mb-0">My Projects</h4>',
output_text)
self.assertIn('2 Projects</span>', output_text)
self.assertNotIn(
'<span class="d-none d-md-inline">Forks', output_text)
self.assertEqual(
output_text.count('<span class="d-none d-md-inline">Groups'), 0)
def test_view_user(self):
""" Test the view_user endpoint. """
output = self.app.get('/user/foo?repopage=abc&forkpage=def')
self.assertEqual(output.status_code, 200)
output_text = output.get_data(as_text=True)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
<span class="d-none d-md-inline">Projects </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-code-fork"></i>
<span class="d-none d-md-inline">Forks </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-users"></i>
<span class="d-none d-md-inline">Groups </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
# Add a private project
item = pagure.lib.model.Project(
user_id=2, # foo
name='test3',
description='test project description',
hook_token='aaabbbeee',
private=True,
)
self.session.add(item)
# Add a public project
item = pagure.lib.model.Project(
user_id=2, # foo
name='test4',
description='test project description',
hook_token='aaabbbeeeccceee',
)
self.session.add(item)
self.session.commit()
self.gitrepos = tests.create_projects_git(
pagure.config.config['GIT_FOLDER'])
output = self.app.get('/user/foo')
self.assertEqual(output.status_code, 200)
output_text = output.get_data(as_text=True)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
<span class="d-none d-md-inline">Projects </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
1
</span>
</div>""", output_text)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-code-fork"></i>
<span class="d-none d-md-inline">Forks </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-users"></i>
<span class="d-none d-md-inline">Groups </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
user = tests.FakeUser(username='foo')
with tests.user_set(self.app.application, user):
output = self.app.get('/user/foo')
output_text = output.get_data(as_text=True)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
<span class="d-none d-md-inline">Projects </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
1
</span>
</div>""", output_text)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-code-fork"></i>
<span class="d-none d-md-inline">Forks </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-users"></i>
<span class="d-none d-md-inline">Groups </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
user.username = 'pingou'
with tests.user_set(self.app.application, user):
output = self.app.get('/user/foo')
output_text = output.get_data(as_text=True)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
<span class="d-none d-md-inline">Projects </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
1
</span>
</div>""", output_text)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-code-fork"></i>
<span class="d-none d-md-inline">Forks </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-users"></i>
<span class="d-none d-md-inline">Groups </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output_text)
# Check pingou has 0 projects
user.username = 'pingou'
with tests.user_set(self.app.application, user):
output = self.app.get('/', follow_redirects=True)
output_text = output.get_data(as_text=True)
self.assertIn(
'<h4 class="font-weight-bold mb-0">My Projects</h4>',
output_text)
self.assertIn(
'0 Projects</span>',
output_text)
self.assertNotIn(
'<span class="d-none d-md-inline">Forks',
output_text)
self.assertEqual(
output_text.count('<span class="d-none d-md-inline">Groups'), 0)
repo = pagure.lib.query._get_project(self.session, 'test3')
msg = pagure.lib.query.add_user_to_project(
session=self.session,
project=repo,
new_user='pingou',
user='foo',
)
self.session.commit()
self.assertEqual(msg, 'User added')
# New user added to private projects
user.username = 'pingou'
with tests.user_set(self.app.application, user):
output = self.app.get('/', follow_redirects=True)
output_text = output.get_data(as_text=True)
self.assertIn(
'<h4 class="font-weight-bold mb-0">My Projects</h4>',
output_text)
self.assertIn(
'1 Projects</span>',
output_text)
self.assertNotIn(
'<span class="d-none d-md-inline">Forks',
output_text)
self.assertEqual(
output_text.count('<span class="d-none d-md-inline">Groups'), 0)
@patch('pagure.decorators.admin_session_timedout')
def test_private_settings_ui(self, ast):
""" Test UI for private repo"""
ast.return_value = False
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
# Add a git repo
repo_path = os.path.join(
pagure.config.config.get('GIT_FOLDER'), 'test4.git')
if not os.path.exists(repo_path):
os.makedirs(repo_path)
pygit2.init_repository(repo_path)
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
tests.create_projects(self.session)
tests.create_projects_git(pagure.config.config.get('GIT_FOLDER'))
output = self.app.get('/test/settings')
# Check for a public repo
self.assertEqual(output.status_code, 200)
self.assertNotIn(
'<input type="checkbox" value="private" name="private"',
output.get_data(as_text=True))
output = self.app.get('/test4/settings')
# Check for private repo
self.assertEqual(output.status_code, 200)
self.assertIn(
'<input type="checkbox" value="private" name="private" checked="" />',
output.get_data(as_text=True))
# Check the new project form has 'private' checkbox
output = self.app.get('/new')
self.assertEqual(output.status_code, 200)
self.assertIn(
'<input id="private" name="private" type="checkbox" value="y">',
output.get_data(as_text=True))
@patch('pagure.decorators.admin_session_timedout')
def test_private_settings_ui_update_privacy_false(self, ast):
""" Test UI for private repo"""
ast.return_value = False
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
# Add a git repo
repo_path = os.path.join(
pagure.config.config.get('GIT_FOLDER'), 'test4.git')
pygit2.init_repository(repo_path)
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
# Check for private repo
output = self.app.get('/test4/settings')
self.assertEqual(output.status_code, 200)
self.assertIn(
'<input type="checkbox" value="private" name="private" checked="" />',
output.get_data(as_text=True))
self.session.commit()
repo = pagure.lib.query._get_project(self.session, 'test4')
self.assertTrue(repo.private)
# Make the project public
data = {
'description': 'test project description',
'private': False,
'csrf_token': self.get_csrf(),
}
output = self.app.post(
'/test4/update', data=data, follow_redirects=True)
self.assertEqual(output.status_code, 200)
self.assertIn(
'Project updated',
output.get_data(as_text=True))
self.assertNotIn(
'<input type="checkbox" value="private" name="private" checked="" />',
output.get_data(as_text=True))
self.session.commit()
repo = pagure.lib.query._get_project(self.session, 'test4')
self.assertFalse(repo.private)
@patch('pagure.decorators.admin_session_timedout')
def test_private_settings_ui_update_privacy_true(self, ast):
""" Test UI for private repo"""
ast.return_value = False
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=False,
)
self.session.add(item)
self.session.commit()
# Add a git repo
repo_path = os.path.join(
pagure.config.config.get('GIT_FOLDER'), 'test4.git')
pygit2.init_repository(repo_path)
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
# Check for public repo
output = self.app.get('/test4/settings')
self.assertEqual(output.status_code, 200)
self.assertNotIn(
'<input type="checkbox" value="private" name="private" checked=""/>',
output.get_data(as_text=True))
self.session.commit()
repo = pagure.lib.query._get_project(self.session, 'test4')
self.assertFalse(repo.private)
# Make the project private
data = {
'description': 'test project description',
'private': True,
'csrf_token': self.get_csrf(),
}
output = self.app.post(
'/test4/update', data=data, follow_redirects=True)
self.assertEqual(output.status_code, 200)
self.assertIn(
'Project updated',
output.get_data(as_text=True))
self.assertNotIn(
'<input type="checkbox" value="private" name="private" checked=""/>',
output.get_data(as_text=True))
# No change since we can't do public -> private
self.session.commit()
repo = pagure.lib.query._get_project(self.session, 'test4')
self.assertFalse(repo.private)
@patch('pagure.lib.notify.send_email')
def test_private_pr(self, send_email):
"""Test pull request made to the private repo"""
send_email.return_value = True
# Add a private project
item = pagure.lib.model.Project(
user_id=1, # pingou
name='pmc',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
repo = pagure.lib.query._get_project(self.session, 'pmc')
msg = pagure.lib.query.add_user_to_project(
session=self.session,
project=repo,
new_user='foo',
user='pingou',
)
self.session.commit()
self.assertEqual(msg, 'User added')
# Create all the git repos
tests.create_projects_git(
os.path.join(self.path, 'requests'), bare=True)
# Add a git repo
repo_path = os.path.join(
pagure.config.config.get('REQUESTS_FOLDER'), 'pmc.git')
if not os.path.exists(repo_path):
os.makedirs(repo_path)
pygit2.init_repository(repo_path, bare=True)
# Check repo was created - Doesn't show on the public page
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
output = self.app.get('/user/pingou/')
self.assertEqual(output.status_code, 200)
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
<span class="d-none d-md-inline">Projects </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output.get_data(as_text=True))
self.assertIn(
"""<span>
<i class="fa fa-fw text-muted fa-code-fork"></i>
<span class="d-none d-md-inline">Forks </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
0
</span>
</div>""", output.get_data(as_text=True))
# Shows on the front page
output = self.app.get('/dashboard/projects')
self.assertEqual(output.status_code, 200)
self.assertIn(
"""<span>
<i class="fa fa-calendar-o fa-rotate-270 fa-fw text-muted"></i>
<span class="d-none d-md-inline">Projects </span>
</span>
<div class="ml-auto">
<span class="badge badge-secondary">
1
</span>
</div>""", output.get_data(as_text=True))
self.set_up_git_repo(new_project=None, branch_from='feature')
project = pagure.lib.query._get_project(self.session, 'pmc')
self.assertEqual(len(project.requests), 1)
output = self.app.get('/pmc/pull-request/1')
self.assertEqual(output.status_code, 200)
# Check repo was created
user = tests.FakeUser()
with tests.user_set(self.app.application, user):
output = self.app.get('/pmc/pull-requests')
self.assertEqual(output.status_code, 404)
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
output = self.app.get('/pmc/pull-requests')
self.assertEqual(output.status_code, 200)
user = tests.FakeUser(username='foo')
with tests.user_set(self.app.application, user):
output = self.app.get('/pmc/pull-requests')
self.assertEqual(output.status_code, 200)
@patch('pagure.lib.git.update_git')
@patch('pagure.lib.notify.send_email')
def test_private_repo_issues_ui(self, p_send_email, p_ugt):
""" Test issues made to private repo"""
p_send_email.return_value = True
p_ugt.return_value = True
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
for repo in ['GIT_FOLDER', 'TICKETS_FOLDER']:
# Add a git repo
repo_path = os.path.join(
pagure.config.config.get(repo), 'test4.git')
if not os.path.exists(repo_path):
os.makedirs(repo_path)
pygit2.init_repository(repo_path)
# Check if the private repo issues are publicly not accesible
output = self.app.get('/test4/issues')
self.assertEqual(output.status_code, 404)
# Create issues to play with
repo = pagure.lib.query._get_project(self.session, 'test4')
msg = pagure.lib.query.new_issue(
session=self.session,
repo=repo,
title='Test issue',
content='We should work on this',
user='pingou',
)
self.session.commit()
self.assertEqual(msg.title, 'Test issue')
user = tests.FakeUser()
with tests.user_set(self.app.application, user):
# Whole list
output = self.app.get('/test4/issues')
self.assertEqual(output.status_code, 404)
# Check single issue
output = self.app.get('/test4/issue/1')
self.assertEqual(output.status_code, 404)
user = tests.FakeUser()
with tests.user_set(self.app.application, user):
# Whole list
output = self.app.get('/test4/issues')
self.assertEqual(output.status_code, 404)
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
# Whole list
output = self.app.get('/test4/issues')
self.assertEqual(output.status_code, 200)
self.assertIn(
'<title>Issues - test4 - Pagure</title>', output.get_data(as_text=True))
self.assertTrue(
'<span class="fa fa-fw fa-exclamation-circle"></span> 1 Open Issues\n' in output.get_data(as_text=True))
# Check single issue
output = self.app.get('/test4/issue/1')
self.assertEqual(output.status_code, 200)
repo = pagure.lib.query._get_project(self.session, 'test4')
msg = pagure.lib.query.add_user_to_project(
session=self.session,
project=repo,
new_user='foo',
user='pingou',
)
self.session.commit()
self.assertEqual(msg, 'User added')
user.username = 'foo'
with tests.user_set(self.app.application, user):
# Whole list
output = self.app.get('/test4/issues')
self.assertEqual(output.status_code, 200)
self.assertIn(
'<title>Issues - test4 - Pagure</title>', output.get_data(as_text=True))
self.assertTrue(
'<span class="fa fa-fw fa-exclamation-circle"></span> 1 Open Issues\n' in output.get_data(as_text=True))
# Check single issue
output = self.app.get('/test4/issue/1')
self.assertEqual(output.status_code, 200)
@patch('pagure.decorators.admin_session_timedout')
def test_private_repo_ui_for_different_repo_user(self, ast):
""" Test the private repo for different ACLS"""
ast.return_value = False
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
repo = pagure.lib.query._get_project(self.session, "test4")
# Add a git repo
repo_path = os.path.join(
pagure.config.config.get('GIT_FOLDER'), 'test4.git')
pygit2.init_repository(repo_path)
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
# Check for private repo
output = self.app.get('/test4')
self.assertEqual(output.status_code, 200)
# Check if the user who doesn't have access to private repo can access it
user = tests.FakeUser(username="foo")
with tests.user_set(self.app.application, user):
output = self.app.get('/test4')
self.assertEqual(output.status_code, 404)
# Add commit access to a user
pagure.lib.query.add_user_to_project(
self.session,
project=repo,
new_user="foo",
user="pingou",
access='commit'
)
self.session.commit()
repo = pagure.lib.query._get_project(self.session, "test4")
self.assertEqual(len(repo.users), 1)
# Check if the user can access private repo
user = tests.FakeUser(username="foo")
with tests.user_set(self.app.application, user):
output = self.app.get('/test4')
self.assertEqual(output.status_code, 200)
# Making a new user bar
item = pagure.lib.model.User(
user='bar',
fullname='bar baz',
password='foo',
default_email='bar@bar.com',
)
self.session.add(item)
item = pagure.lib.model.UserEmail(
user_id=3,
email='bar@bar.com')
self.session.add(item)
self.session.commit()
# Check that bar shouldn't be able to access the project
user = tests.FakeUser(username="bar")
with tests.user_set(self.app.application, user):
output = self.app.get('/test4')
self.assertEqual(output.status_code, 404)
# Adding a ticket level access to bar
pagure.lib.query.add_user_to_project(
self.session,
project=repo,
new_user="bar",
user="pingou",
access='ticket'
)
self.session.commit()
repo = pagure.lib.query._get_project(self.session, "test4")
self.assertEqual(len(repo.users), 2)
# Check if the ticket level access user can access the project
user = tests.FakeUser(username="bar")
with tests.user_set(self.app.application, user):
output = self.app.get('/test4')
self.assertEqual(output.status_code, 200)
# API checks
def test_api_private_repo_projects(self):
""" Test api points for private repo for projects"""
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
# Create a git repo to play with
gitrepo = os.path.join(self.path, 'repos', 'test4.git')
repo = pygit2.init_repository(gitrepo, bare=True)
newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
repopath = os.path.join(newpath, 'repos', 'test4')
clone_repo = pygit2.clone_repository(gitrepo, repopath)
# Create a file in that git repo
with open(os.path.join(repopath, 'sources'), 'w') as stream:
stream.write('foo\n bar')
clone_repo.index.add('sources')
clone_repo.index.write()
# Commits the files added
tree = clone_repo.index.write_tree()
author = pygit2.Signature(
'Alice Author', 'alice@authors.tld')
committer = pygit2.Signature(
'Cecil Committer', 'cecil@committers.tld')
clone_repo.create_commit(
'refs/heads/master', # the name of the reference to update
author,
committer,
'Add sources file for testing',
# binary string representing the tree object ID
tree,
# list of binary strings representing parents of the new commit
[]
)
refname = 'refs/heads/master:refs/heads/master'
ori_remote = clone_repo.remotes[0]
PagureRepo.push(ori_remote, refname)
# Tag our first commit
first_commit = repo.revparse_single('HEAD')
tagger = pygit2.Signature('Alice Doe', 'adoe@example.com', 12347, 0)
repo.create_tag(
"0.0.1", first_commit.oid.hex, pygit2.GIT_OBJ_COMMIT, tagger,
"Release 0.0.1")
# Create a token for foo for this project
item = pagure.lib.model.Token(
id='foobar_token',
user_id=1,
project_id=1,
expiration=datetime.datetime.utcnow() + datetime.timedelta(
days=30)
)
self.session.add(item)
self.session.commit()
item = pagure.lib.model.TokenAcl(
token_id='foobar_token',
acl_id=1,
)
self.session.add(item)
self.session.commit()
# Check if the admin requests
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
# Check tags
output = self.app.get('/api/0/test4/git/tags')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{'tags': ['0.0.1'], 'total_tags': 1}
)
output = self.app.get('/api/0/test4/git/tags')
self.assertEqual(output.status_code, 404)
# Chekc if user is not admin
user = tests.FakeUser()
with tests.user_set(self.app.application, user):
output = self.app.get('/api/0/test4/git/tags')
self.assertEqual(output.status_code, 404)
shutil.rmtree(newpath)
# Check before adding
repo = pagure.lib.query._get_project(self.session, 'test4')
self.assertEqual(repo.tags, [])
# Adding a tag
output = pagure.lib.query.update_tags(
self.session, repo, 'infra', 'pingou')
self.assertEqual(output, ['Project tagged with: infra'])
# Check after adding
repo = pagure.lib.query._get_project(self.session, 'test4')
self.assertEqual(len(repo.tags), 1)
self.assertEqual(repo.tags_text, ['infra'])
# Check the API
output = self.app.get('/api/0/projects?tags=inf')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
del data['pagination']
self.assertDictEqual(
data,
{
'args': {
'fork': None,
'namespace': None,
'owner': None,
'page': 1,
'pattern': None,
'per_page': 20,
'short': False,
'tags': ['inf'],
'username': None
},
'projects': [],
'total_projects': 0
}
)
# Request by not a loggged in user
output = self.app.get('/api/0/projects?tags=infra')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
del data['pagination']
self.assertDictEqual(
data,
{
'args': {
'fork': None,
'namespace': None,
'owner': None,
'page': 1,
'pattern': None,
'per_page': 20,
'short': False,
'tags': ['infra'],
'username': None
},
'projects': [],
'total_projects': 0
}
)
user = tests.FakeUser()
with tests.user_set(self.app.application, user):
# Request by a non authorized user
output = self.app.get('/api/0/projects?tags=infra')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
del data['pagination']
self.assertDictEqual(
data,
{
'args': {
'fork': None,
'namespace': None,
'owner': None,
'page': 1,
'pattern': None,
'per_page': 20,
'short': False,
'tags': ['infra'],
'username': None
},
'projects': [],
'total_projects': 0
}
)
user.username = 'pingou'
with tests.user_set(self.app.application, user):
# Private repo username is compulsion to pass
output = self.app.get('/api/0/projects?tags=infra')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
del data['pagination']
self.assertDictEqual(
data,
{
'args': {
'fork': None,
'namespace': None,
'owner': None,
'page': 1,
'pattern': None,
'per_page': 20,
'short': False,
'tags': ['infra'],
'username': None
},
'projects': [],
'total_projects': 0
}
)
output = self.app.get('/api/0/projects?username=pingou')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['projects'][0]['date_created'] = "1436527638"
data['projects'][0]['date_modified'] = "1436527638"
del data['pagination']
self.assertDictEqual(
data,
{
"args": {
"fork": None,
"namespace": None,
"owner": None,
"page": 1,
"pattern": None,
"per_page": 20,
"short": False,
"tags": [],
"username": "pingou"
},
"total_projects": 1,
"projects": [
{
"access_groups": {
"admin": [],
"commit": [],
"ticket": []
},
"access_users": {
"admin": [],
"commit": [],
"owner": [
"pingou"
],
"ticket": []
},
"close_status": [],
"custom_keys": [],
"date_created": "1436527638",
"date_modified": "1436527638",
"description": "test project description",
"id": 1,
"milestones": {},
"name": "test4",
"fullname": "test4",
"url_path": "test4",
"namespace": None,
"parent": None,
"priorities": {},
"tags": ["infra"],
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
]
}
)
output = self.app.get('/api/0/projects?username=pingou&tags=infra')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['projects'][0]['date_created'] = "1436527638"
data['projects'][0]['date_modified'] = "1436527638"
del data['pagination']
self.assertDictEqual(
data,
{
"args": {
"fork": None,
"namespace": None,
"owner": None,
"page": 1,
"pattern": None,
"per_page": 20,
"short": False,
"tags": ["infra"],
"username": "pingou"
},
"total_projects": 1,
"projects": [
{
"access_groups": {
"admin": [],
"commit": [],
"ticket": []
},
"access_users": {
"admin": [],
"commit": [],
"owner": [
"pingou"
],
"ticket": []
},
"close_status": [],
"custom_keys": [],
"date_created": "1436527638",
"date_modified": "1436527638",
"description": "test project description",
"id": 1,
"milestones": {},
"name": "test4",
"fullname": "test4",
"url_path": "test4",
"namespace": None,
"parent": None,
"priorities": {},
"tags": ["infra"],
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
]
}
)
# Api pull-request views
@patch('pagure.lib.notify.send_email')
def test_api_private_repo_fork(self, send_email):
""" Test api endpoints in api/fork"""
send_email.return_value = True
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
tests.create_tokens(self.session)
tests.create_tokens_acl(self.session)
headers = {'Authorization': 'token aaabbbcccddd'}
# Create a pull-request
repo = pagure.lib.query._get_project(self.session, 'test4')
forked_repo = pagure.lib.query._get_project(self.session, 'test4')
req = pagure.lib.query.new_pull_request(
session=self.session,
repo_from=forked_repo,
branch_from='master',
repo_to=repo,
branch_to='master',
title='test pull-request',
user='pingou',
)
self.session.commit()
self.assertEqual(req.id, 1)
self.assertEqual(req.title, 'test pull-request')
# Check list of PR
output = self.app.get('/api/0/test4/pull-requests')
self.assertEqual(output.status_code, 404)
# Check single PR
output = self.app.get('/api/0/test/pull-request/1')
self.assertEqual(output.status_code, 404)
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
# List pull-requests
output = self.app.get('/api/0/test4/pull-requests')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['requests'][0]['date_created'] = '1431414800'
data['requests'][0]['updated_on'] = '1431414800'
data['requests'][0]['project']['date_created'] = '1431414800'
data['requests'][0]['project']['date_modified'] = '1431414800'
data['requests'][0]['repo_from']['date_created'] = '1431414800'
data['requests'][0]['repo_from']['date_modified'] = '1431414800'
data['requests'][0]['uid'] = '1431414800'
data['requests'][0]['last_updated'] = '1431414800'
for k in ['first', 'last']:
self.assertIsNotNone(data['pagination'][k])
data['pagination'][k] = 'http://localhost...'
self.assertDictEqual(
data,
{
"args": {
"assignee": None,
"author": None,
"page": 1,
"per_page": 20,
"status": True
},
"pagination": {
"first": 'http://localhost...',
"last": 'http://localhost...',
"next": None,
"page": 1,
"pages": 1,
"per_page": 20,
"prev": None
},
"requests": [
{
"assignee": None,
"branch": "master",
"branch_from": "master",
"cached_merge_status": "unknown",
"closed_at": None,
"closed_by": None,
"comments": [],
"commit_start": None,
"commit_stop": None,
"date_created": "1431414800",
"last_updated": "1431414800",
"id": 1,
"initial_comment": None,
"project": {
"access_groups": {
"admin": [],
"commit": [],
"ticket": []
},
"access_users": {
"admin": [],
"commit": [],
"owner": [
"pingou"
],
"ticket": []
},
"close_status": [],
"custom_keys": [],
"date_created": "1431414800",
"date_modified": "1431414800",
"description": "test project description",
"id": 1,
"milestones": {},
"name": "test4",
"fullname": "test4",
"url_path": "test4",
"namespace": None,
"parent": None,
"priorities": {},
"tags": [],
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
"remote_git": None,
"repo_from": {
"access_groups": {
"admin": [],
"commit": [],
"ticket": []
},
"access_users": {
"admin": [],
"commit": [],
"owner": [
"pingou"
],
"ticket": []
},
"close_status": [],
"custom_keys": [],
"date_created": "1431414800",
"date_modified": "1431414800",
"description": "test project description",
"id": 1,
"milestones": {},
"fullname": "test4",
"url_path": "test4",
"name": "test4",
"namespace": None,
"parent": None,
"priorities": {},
"tags": [],
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
"status": "Open",
"threshold_reached": None,
"title": "test pull-request",
"uid": "1431414800",
"updated_on": "1431414800",
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
],
"total_requests": 1
}
)
headers = {'Authorization': 'token foobar_token'}
# Access Pull-Request authenticated
output = self.app.get(
'/api/0/test4/pull-requests', headers=headers)
self.assertEqual(output.status_code, 200)
data2 = json.loads(output.get_data(as_text=True))
data2['requests'][0]['date_created'] = '1431414800'
data2['requests'][0]['updated_on'] = '1431414800'
data2['requests'][0]['project']['date_created'] = '1431414800'
data2['requests'][0]['project']['date_modified'] = '1431414800'
data2['requests'][0]['repo_from']['date_created'] = '1431414800'
data2['requests'][0]['repo_from']['date_modified'] = '1431414800'
data2['requests'][0]['uid'] = '1431414800'
data2['requests'][0]['last_updated'] = '1431414800'
for k in ['first', 'last']:
self.assertIsNotNone(data['pagination'][k])
data2['pagination'][k] = 'http://localhost...'
self.assertDictEqual(data, data2)
# For single PR
output = self.app.get('/api/0/test4/pull-request/1')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['date_created'] = '1431414800'
data['updated_on'] = '1431414800'
data['project']['date_created'] = '1431414800'
data['project']['date_modified'] = '1431414800'
data['repo_from']['date_created'] = '1431414800'
data['repo_from']['date_modified'] = '1431414800'
data['uid'] = '1431414800'
data['last_updated'] = '1431414800'
self.assertDictEqual(
data,
{
"assignee": None,
"branch": "master",
"branch_from": "master",
"cached_merge_status": "unknown",
"closed_at": None,
"closed_by": None,
"comments": [],
"commit_start": None,
"commit_stop": None,
"date_created": "1431414800",
"last_updated": "1431414800",
"id": 1,
"initial_comment": None,
"project": {
"access_groups": {
"admin": [],
"commit": [],
"ticket": []
},
"access_users": {
"admin": [],
"commit": [],
"owner": [
"pingou"
],
"ticket": []
},
"close_status": [],
"custom_keys": [],
"date_created": "1431414800",
"date_modified": "1431414800",
"description": "test project description",
"id": 1,
"milestones": {},
"name": "test4",
"fullname": "test4",
"url_path": "test4",
"namespace": None,
"parent": None,
"priorities": {},
"tags": [],
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
"remote_git": None,
"repo_from": {
"access_groups": {
"admin": [],
"commit": [],
"ticket": []
},
"access_users": {
"admin": [],
"commit": [],
"owner": [
"pingou"
],
"ticket": []
},
"close_status": [],
"custom_keys": [],
"date_created": "1431414800",
"date_modified": "1431414800",
"description": "test project description",
"id": 1,
"milestones": {},
"name": "test4",
"fullname": "test4",
"url_path": "test4",
"namespace": None,
"parent": None,
"priorities": {},
"tags": [],
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
"status": "Open",
"threshold_reached": None,
"title": "test pull-request",
"uid": "1431414800",
"updated_on": "1431414800",
"user": {
"fullname": "PY C",
"name": "pingou"
},
}
)
# Access Pull-Request authenticated
output = self.app.get(
'/api/0/test4/pull-request/1', headers=headers)
self.assertEqual(output.status_code, 200)
data2 = json.loads(output.get_data(as_text=True))
data2['date_created'] = '1431414800'
data2['project']['date_created'] = '1431414800'
data2['project']['date_modified'] = '1431414800'
data2['repo_from']['date_created'] = '1431414800'
data2['repo_from']['date_modified'] = '1431414800'
data2['uid'] = '1431414800'
data2['date_created'] = '1431414800'
data2['updated_on'] = '1431414800'
data2['last_updated'] = '1431414800'
self.assertDictEqual(data, data2)
@patch('pagure.lib.notify.send_email')
def test_api_pr_private_repo_add_comment(self, mockemail):
""" Test the api_pull_request_add_comment method of the flask api. """
mockemail.return_value = True
pagure.config.config['REQUESTS_FOLDER'] = None
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
tests.create_tokens(self.session)
tests.create_tokens_acl(self.session)
headers = {'Authorization': 'token aaabbbcccddd'}
# Create a pull-request
repo = pagure.lib.query._get_project(self.session, 'test4')
forked_repo = pagure.lib.query._get_project(self.session, 'test4')
req = pagure.lib.query.new_pull_request(
session=self.session,
repo_from=forked_repo,
branch_from='master',
repo_to=repo,
branch_to='master',
title='test pull-request',
user='pingou',
)
self.session.commit()
self.assertEqual(req.id, 1)
self.assertEqual(req.title, 'test pull-request')
# Check comments before
self.session.commit()
request = pagure.lib.query.search_pull_requests(
self.session, project_id=1, requestid=1)
self.assertEqual(len(request.comments), 0)
data = {
'title': 'test issue',
}
# Incomplete request
output = self.app.post(
'/api/0/test4/pull-request/1/comment', data=data, headers=headers)
self.assertEqual(output.status_code, 400)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Invalid or incomplete input submitted",
"error_code": "EINVALIDREQ",
"errors": {"comment": ["This field is required."]}
}
)
# No change
self.session.commit()
request = pagure.lib.query.search_pull_requests(
self.session, project_id=1, requestid=1)
self.assertEqual(len(request.comments), 0)
data = {
'comment': 'This is a very interesting question',
}
# Valid request
output = self.app.post(
'/api/0/test4/pull-request/1/comment', data=data, headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{'message': 'Comment added'}
)
# One comment added
self.session.commit()
request = pagure.lib.query.search_pull_requests(
self.session, project_id=1, requestid=1)
self.assertEqual(len(request.comments), 1)
@patch('pagure.lib.notify.send_email')
def test_api_private_repo_pr_add_flag(self, mockemail):
""" Test the api_pull_request_add_flag method of the flask api. """
mockemail.return_value = True
pagure.config.config['REQUESTS_FOLDER'] = None
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test2',
description='test project description',
hook_token='foo_bar',
private=True,
)
self.session.add(item)
self.session.commit()
tests.create_tokens(self.session)
tests.create_tokens_acl(self.session)
headers = {'Authorization': 'token aaabbbcccddd'}
# Invalid project
output = self.app.post(
'/api/0/foo/pull-request/1/flag', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Valid token, wrong project
output = self.app.post(
'/api/0/test2/pull-request/1/flag', headers=headers)
self.assertEqual(output.status_code, 401)
data = json.loads(output.get_data(as_text=True))
self.assertEqual(sorted(data.keys()), ['error', 'error_code'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.name, data['error_code'])
# No input
output = self.app.post(
'/api/0/test4/pull-request/1/flag', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Pull-Request not found",
"error_code": "ENOREQ",
}
)
# Create a pull-request
repo = pagure.lib.query._get_project(self.session, 'test4')
forked_repo = pagure.lib.query._get_project(self.session, 'test4')
req = pagure.lib.query.new_pull_request(
session=self.session,
repo_from=forked_repo,
branch_from='master',
repo_to=repo,
branch_to='master',
title='test pull-request',
user='pingou',
)
self.session.commit()
self.assertEqual(req.id, 1)
self.assertEqual(req.title, 'test pull-request')
# Check comments before
self.session.commit()
request = pagure.lib.query.search_pull_requests(
self.session, project_id=1, requestid=1)
self.assertEqual(len(request.flags), 0)
data = {
'username': 'Jenkins',
'percent': 100,
'url': 'http://jenkins.cloud.fedoraproject.org/',
'uid': 'jenkins_build_pagure_100+seed',
}
# Incomplete request
output = self.app.post(
'/api/0/test4/pull-request/1/flag', data=data, headers=headers)
self.assertEqual(output.status_code, 400)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Invalid or incomplete input submitted",
"error_code": "EINVALIDREQ",
"errors": {"comment": ["This field is required."]}
}
)
# No change
self.session.commit()
request = pagure.lib.query.search_pull_requests(
self.session, project_id=1, requestid=1)
self.assertEqual(len(request.flags), 0)
data = {
'username': 'Jenkins',
'percent': 0,
'comment': 'Tests failed',
'url': 'http://jenkins.cloud.fedoraproject.org/',
'uid': 'jenkins_build_pagure_100+seed',
}
# Valid request
output = self.app.post(
'/api/0/test4/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'
data['flag']['pull_request_uid'] = '62b49f00d489452994de5010565fab81'
data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
self.assertDictEqual(
data,
{
'flag': {
'comment': 'Tests failed',
'date_created': '1510742565',
'date_updated': '1510742565',
'percent': 0,
'pull_request_uid': '62b49f00d489452994de5010565fab81',
'status': 'failure',
'url': 'http://jenkins.cloud.fedoraproject.org/',
'user': {
'default_email': 'bar@pingou.com',
'emails': ['bar@pingou.com', 'foo@pingou.com'],
'fullname': 'PY C',
'name': 'pingou'},
'username': 'Jenkins'},
'message': 'Flag added',
'uid': 'jenkins_build_pagure_100+seed',
'avatar_url': 'https://seccdn.libravatar.org/avatar/...',
'user': 'pingou'
}
)
# One flag added
self.session.commit()
request = pagure.lib.query.search_pull_requests(
self.session, project_id=1, requestid=1)
self.assertEqual(len(request.flags), 1)
self.assertEqual(request.flags[0].comment, 'Tests failed')
self.assertEqual(request.flags[0].percent, 0)
# Update flag
data = {
'username': 'Jenkins',
'percent': 100,
'comment': 'Tests passed',
'url': 'http://jenkins.cloud.fedoraproject.org/',
'uid': 'jenkins_build_pagure_100+seed',
}
output = self.app.post(
'/api/0/test4/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'
data['flag']['pull_request_uid'] = '62b49f00d489452994de5010565fab81'
data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
self.assertDictEqual(
data,
{
'flag': {
'comment': 'Tests passed',
'date_created': '1510742565',
'date_updated': '1510742565',
'percent': 100,
'pull_request_uid': '62b49f00d489452994de5010565fab81',
'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'},
'username': 'Jenkins'},
'message': 'Flag updated',
'uid': 'jenkins_build_pagure_100+seed',
'avatar_url': 'https://seccdn.libravatar.org/avatar/...',
'user': 'pingou'
}
)
# One flag added
self.session.commit()
request = pagure.lib.query.search_pull_requests(
self.session, project_id=1, requestid=1)
self.assertEqual(len(request.flags), 1)
self.assertEqual(request.flags[0].comment, 'Tests passed')
self.assertEqual(request.flags[0].percent, 100)
@patch('pagure.lib.notify.send_email')
def test_api_private_repo_pr_close(self, send_email):
""" Test the api_pull_request_close method of the flask api. """
send_email.return_value = True
pagure.config.config['REQUESTS_FOLDER'] = None
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
tests.create_tokens(self.session)
tests.create_tokens_acl(self.session)
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test2',
description='test project description',
hook_token='foo_bar',
private=True,
)
self.session.add(item)
self.session.commit()
# Create the pull-request to close
repo = pagure.lib.query._get_project(self.session, 'test4')
forked_repo = pagure.lib.query._get_project(self.session, 'test4')
req = pagure.lib.query.new_pull_request(
session=self.session,
repo_from=forked_repo,
branch_from='master',
repo_to=repo,
branch_to='master',
title='test pull-request',
user='pingou',
)
self.session.commit()
self.assertEqual(req.id, 1)
self.assertEqual(req.title, 'test pull-request')
headers = {'Authorization': 'token aaabbbcccddd'}
# Invalid project
output = self.app.post(
'/api/0/foo/pull-request/1/close', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Valid token, wrong project
output = self.app.post(
'/api/0/test2/pull-request/1/close', headers=headers)
self.assertEqual(output.status_code, 401)
data = json.loads(output.get_data(as_text=True))
self.assertEqual(sorted(data.keys()), ['error', 'error_code'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.name, data['error_code'])
# Invalid PR
output = self.app.post(
'/api/0/test4/pull-request/2/close', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{'error': 'Pull-Request not found', 'error_code': "ENOREQ"}
)
# Create a token for foo for this project
item = pagure.lib.model.Token(
id='foobar_token',
user_id=2,
project_id=1,
expiration=datetime.datetime.utcnow() + datetime.timedelta(
days=30)
)
self.session.add(item)
self.session.commit()
# Allow the token to close PR
acls = pagure.lib.query.get_acls(self.session)
acl = None
for acl in acls:
if acl.name == 'pull_request_close':
break
item = pagure.lib.model.TokenAcl(
token_id='foobar_token',
acl_id=acl.id,
)
self.session.add(item)
self.session.commit()
headers = {'Authorization': 'token foobar_token'}
# User not admin
output = self.app.post(
'/api/0/test4/pull-request/1/close', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
headers = {'Authorization': 'token aaabbbcccddd'}
# Close PR
output = self.app.post(
'/api/0/test4/pull-request/1/close', headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{"message": "Pull-request closed!"}
)
@patch('pagure.lib.notify.send_email')
def test_api_private_repo_pr_merge(self, send_email):
""" Test the api_pull_request_merge method of the flask api. """
send_email.return_value = True
pagure.config.config['REQUESTS_FOLDER'] = None
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
tests.create_projects_git(os.path.join(self.path, 'requests'),
bare=True)
tests.add_readme_git_repo(os.path.join(self.path, 'repos',
'test4.git'))
tests.add_commit_git_repo(os.path.join(self.path, 'repos',
'test4.git'),
branch='test')
tests.create_tokens(self.session)
tests.create_tokens_acl(self.session)
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test2',
description='test project description',
hook_token='foo_bar',
private=True,
)
self.session.add(item)
self.session.commit()
# Create the pull-request to close
repo = pagure.lib.query._get_project(self.session, 'test4')
forked_repo = pagure.lib.query._get_project(self.session, 'test4')
req = pagure.lib.query.new_pull_request(
session=self.session,
repo_from=forked_repo,
branch_from='test',
repo_to=repo,
branch_to='master',
title='test pull-request',
user='pingou',
)
self.session.commit()
self.assertEqual(req.id, 1)
self.assertEqual(req.title, 'test pull-request')
headers = {'Authorization': 'token aaabbbcccddd'}
# Invalid project
output = self.app.post(
'/api/0/foo/pull-request/1/merge', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Valid token, wrong project
output = self.app.post(
'/api/0/test2/pull-request/1/merge', headers=headers)
self.assertEqual(output.status_code, 401)
data = json.loads(output.get_data(as_text=True))
self.assertEqual(sorted(data.keys()), ['error', 'error_code'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.name, data['error_code'])
# Invalid PR
output = self.app.post(
'/api/0/test4/pull-request/2/merge', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{'error': 'Pull-Request not found', 'error_code': "ENOREQ"}
)
# Create a token for foo for this project
item = pagure.lib.model.Token(
id='foobar_token',
user_id=2,
project_id=1,
expiration=datetime.datetime.utcnow() + datetime.timedelta(
days=30)
)
self.session.add(item)
self.session.commit()
# Allow the token to merge PR
acls = pagure.lib.query.get_acls(self.session)
acl = None
for acl in acls:
if acl.name == 'pull_request_merge':
break
item = pagure.lib.model.TokenAcl(
token_id='foobar_token',
acl_id=acl.id,
)
self.session.add(item)
self.session.commit()
headers = {'Authorization': 'token foobar_token'}
# User not admin
output = self.app.post(
'/api/0/test4/pull-request/1/merge', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
headers = {'Authorization': 'token aaabbbcccddd'}
# Merge PR
output = self.app.post(
'/api/0/test4/pull-request/1/merge', headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{"message": "Changes merged!"}
)
def test_api_private_repo_new_issue(self):
""" Test the api_new_issue method of the flask api. """
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
for repo in ['GIT_FOLDER', 'TICKETS_FOLDER']:
# Add a git repo
repo_path = os.path.join(
pagure.config.config.get(repo), 'test4.git')
if not os.path.exists(repo_path):
os.makedirs(repo_path)
pygit2.init_repository(repo_path, bare=True)
tests.create_tokens(self.session)
tests.create_tokens_acl(self.session)
# Add private repo
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test2',
description='test project description',
hook_token='foo_bar',
private=True,
)
self.session.add(item)
self.session.commit()
headers = {'Authorization': 'token aaabbbcccddd'}
# Valid token, wrong project
output = self.app.post('/api/0/test2/new_issue', headers=headers)
self.assertEqual(output.status_code, 401)
data = json.loads(output.get_data(as_text=True))
self.assertEqual(sorted(data.keys()), ['error', 'error_code'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.name, data['error_code'])
# No input
output = self.app.post('/api/0/test4/new_issue', headers=headers)
self.assertEqual(output.status_code, 400)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Invalid or incomplete input submitted",
"error_code": "EINVALIDREQ",
"errors": {
"issue_content": ["This field is required."],
"title": ["This field is required."]
}
})
data = {
'title': 'test issue',
}
# Invalid repo
output = self.app.post(
'/api/0/foo/new_issue', data=data, headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Incomplete request
output = self.app.post(
'/api/0/test4/new_issue', data=data, headers=headers)
self.assertEqual(output.status_code, 400)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Invalid or incomplete input submitted",
"error_code": "EINVALIDREQ",
"errors": {
"issue_content": ["This field is required."],
"title": ["This field is required."]
}
}
)
data = {
'title': 'test issue',
'issue_content': 'This issue needs attention',
}
# Valid request
output = self.app.post(
'/api/0/test4/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'
self.assertDictEqual(
data,
{
'issue': FULL_ISSUE_LIST[7],
'message': 'Issue created'
}
)
def test_api_private_repo_view_issues(self):
""" Test the api_view_issues method of the flask api. """
self.test_api_private_repo_new_issue()
# Invalid repo
output = self.app.get('/api/0/foo/issues')
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# List all opened issues
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
output = self.app.get('/api/0/test4/issues')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['issues'][0]['date_created'] = '1431414800'
data['issues'][0]['last_updated'] = '1431414800'
for k in ['first', 'last']:
self.assertIsNotNone(data['pagination'][k])
data['pagination'][k] = 'http://localhost...'
self.assertDictEqual(
data,
{
"args": {
"assignee": None,
"author": None,
"milestones": [],
"no_stones": None,
"order": None,
"priority": None,
"since": None,
"status": None,
"tags": []
},
"total_issues": 1,
"issues": [
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"last_updated": "1431414800",
"depends": [],
"id": 1,
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
],
'pagination': {
u'first': u'http://localhost...',
u'last': u'http://localhost...',
u'next': None,
u'page': 1,
u'pages': 1,
u'per_page': 20,
u'prev': None
},
}
)
# Create private issue
repo = pagure.lib.query._get_project(self.session, 'test4')
msg = pagure.lib.query.new_issue(
session=self.session,
repo=repo,
title='Test issue',
content='We should work on this',
user='pingou',
private=True,
)
self.session.commit()
self.assertEqual(msg.title, 'Test issue')
# Private issues are retrieved
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
output = self.app.get('/api/0/test4/issues')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['issues'][0]['date_created'] = '1431414800'
data['issues'][0]['last_updated'] = '1431414800'
data['issues'][1]['date_created'] = '1431414800'
data['issues'][1]['last_updated'] = '1431414800'
for k in ['first', 'last']:
self.assertIsNotNone(data['pagination'][k])
data['pagination'][k] = 'http://localhost...'
self.assertDictEqual(
data,
{
"args": {
"assignee": None,
"author": None,
"milestones": [],
"no_stones": None,
"order": None,
"priority": None,
"status": None,
"since": None,
"tags": []
},
"issues": [
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "We should work on this",
"custom_fields": [],
"date_created": "1431414800",
"last_updated": "1431414800",
"depends": [],
"id": 2,
"milestone": None,
"priority": None,
"private": True,
"status": "Open",
"tags": [],
"title": "Test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"last_updated": "1431414800",
"depends": [],
"id": 1,
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
],
'pagination': {
u'first': u'http://localhost...',
u'last': u'http://localhost...',
u'next': None,
u'page': 1,
u'pages': 1,
u'per_page': 20,
u'prev': None
},
"total_issues": 2
}
)
# Access issues authenticated but non-existing token
headers = {'Authorization': 'token aaabbbccc'}
output = self.app.get('/api/0/test4/issues', headers=headers)
self.assertEqual(output.status_code, 401)
headers = {'Authorization': 'token aaabbbcccddd'}
# Access issues authenticated correctly
output = self.app.get('/api/0/test4/issues', headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['issues'][0]['date_created'] = '1431414800'
data['issues'][0]['last_updated'] = '1431414800'
data['issues'][1]['date_created'] = '1431414800'
data['issues'][1]['last_updated'] = '1431414800'
for k in ['first', 'last']:
self.assertIsNotNone(data['pagination'][k])
data['pagination'][k] = 'http://localhost...'
self.assertDictEqual(
data,
{
"args": {
"assignee": None,
"author": None,
"milestones": [],
"no_stones": None,
"order": None,
"priority": None,
"status": None,
"since": None,
"tags": []
},
"issues": [
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "We should work on this",
"custom_fields": [],
"date_created": "1431414800",
"last_updated": "1431414800",
"depends": [],
"id": 2,
"milestone": None,
"priority": None,
"private": True,
"status": "Open",
"tags": [],
"title": "Test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"last_updated": "1431414800",
"depends": [],
"id": 1,
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
],
'pagination': {
u'first': u'http://localhost...',
u'last': u'http://localhost...',
u'next': None,
u'page': 1,
u'pages': 1,
u'per_page': 20,
u'prev': None
},
"total_issues": 2
}
)
# List closed issue
output = self.app.get(
'/api/0/test4/issues?status=Closed', headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
for k in ['first', 'last']:
self.assertIsNotNone(data['pagination'][k])
data['pagination'][k] = 'http://localhost...'
self.assertDictEqual(
data,
{
"args": {
"assignee": None,
"author": None,
"milestones": [],
"no_stones": None,
"order": None,
"priority": None,
"status": "Closed",
"since": None,
"tags": []
},
"issues": [],
'pagination': {
u'first': u'http://localhost...',
u'last': u'http://localhost...',
u'next': None,
u'page': 1,
u'pages': 0,
u'per_page': 20,
u'prev': None
},
"total_issues": 0,
}
)
# List closed issue
output = self.app.get(
'/api/0/test4/issues?status=Invalid', headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
for k in ['first', 'last']:
self.assertIsNotNone(data['pagination'][k])
data['pagination'][k] = 'http://localhost...'
self.assertDictEqual(
data,
{
"args": {
"assignee": None,
"author": None,
"milestones": [],
"no_stones": None,
"order": None,
"priority": None,
"status": "Invalid",
"since": None,
"tags": []
},
"issues": [],
'pagination': {
u'first': u'http://localhost...',
u'last': u'http://localhost...',
u'next': None,
u'page': 1,
u'pages': 0,
u'per_page': 20,
u'prev': None
},
"total_issues": 0,
}
)
# List all issues
output = self.app.get(
'/api/0/test4/issues?status=All', headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['issues'][0]['date_created'] = '1431414800'
data['issues'][0]['last_updated'] = '1431414800'
data['issues'][1]['date_created'] = '1431414800'
data['issues'][1]['last_updated'] = '1431414800'
for k in ['first', 'last']:
self.assertIsNotNone(data['pagination'][k])
data['pagination'][k] = 'http://localhost...'
self.assertDictEqual(
data,
{
"args": {
"assignee": None,
"author": None,
"milestones": [],
"no_stones": None,
"order": None,
"priority": None,
"since": None,
"status": "All",
"tags": []
},
"issues": [
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "We should work on this",
"custom_fields": [],
"date_created": "1431414800",
"last_updated": "1431414800",
"depends": [],
"id": 2,
"milestone": None,
"priority": None,
"private": True,
"status": "Open",
"tags": [],
"title": "Test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
},
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"last_updated": "1431414800",
"depends": [],
"id": 1,
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
],
'pagination': {
u'first': u'http://localhost...',
u'last': u'http://localhost...',
u'next': None,
u'page': 1,
u'pages': 1,
u'per_page': 20,
u'prev': None
},
"total_issues": 2
}
)
def test_api_pivate_repo_view_issue(self):
""" Test the api_view_issue method of the flask api. """
self.test_api_private_repo_new_issue()
# Invalid repo
output = self.app.get('/api/0/foo/issue/1')
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Invalid issue for this repo
output = self.app.get('/api/0/test4/issue/1')
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Un-authorized user
user = tests.FakeUser()
with tests.user_set(self.app.application, user):
output = self.app.get('/api/0/test4/issue/1')
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Valid issue
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
output = self.app.get('/api/0/test4/issue/1')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['date_created'] = '1431414800'
data['last_updated'] = '1431414800'
self.assertDictEqual(
data,
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 1,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
)
headers = {'Authorization': 'token aaabbbccc'}
# Access issue authenticated but non-existing token
output = self.app.get('/api/0/test4/issue/1', headers=headers)
self.assertEqual(output.status_code, 401)
data = json.loads(output.get_data(as_text=True))
self.assertEqual(sorted(data.keys()), ['error', 'error_code'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.name, data['error_code'])
headers = {'Authorization': 'token aaabbbcccddd'}
# Access issue authenticated correctly
output = self.app.get('/api/0/test4/issue/1', headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['date_created'] = '1431414800'
data['last_updated'] = '1431414800'
self.assertDictEqual(
data,
{
"assignee": None,
"blocks": [],
"close_status": None,
"closed_at": None,
"closed_by": None,
"comments": [],
"content": "This issue needs attention",
"custom_fields": [],
"date_created": "1431414800",
"depends": [],
"id": 1,
"last_updated": "1431414800",
"milestone": None,
"priority": None,
"private": False,
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
)
@patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
def test_api_private_repo_change_status_issue(self):
""" Test the api_change_status_issue method of the flask api. """
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
self.session.add(item)
self.session.commit()
for repo in ['GIT_FOLDER', 'TICKETS_FOLDER']:
# Add a git repo
repo_path = os.path.join(
pagure.config.config.get(repo), 'test4.git')
if not os.path.exists(repo_path):
os.makedirs(repo_path)
pygit2.init_repository(repo_path, bare=True)
tests.create_tokens(self.session)
tests.create_tokens_acl(self.session)
headers = {'Authorization': 'token aaabbbcccddd'}
# Invalid project
output = self.app.post('/api/0/foo/issue/1/status', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Valid token, wrong project
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
output = self.app.post(
'/api/0/test2/issue/1/status', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# No input
output = self.app.post('/api/0/test4/issue/1/status', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Issue not found",
"error_code": "ENOISSUE",
}
)
# Create normal issue
repo = pagure.lib.query._get_project(self.session, 'test4')
msg = pagure.lib.query.new_issue(
session=self.session,
repo=repo,
title='Test issue #1',
content='We should work on this',
user='pingou',
private=False,
)
self.session.commit()
self.assertEqual(msg.title, 'Test issue #1')
# Check status before
repo = pagure.lib.query._get_project(self.session, 'test4')
issue = pagure.lib.query.search_issues(self.session, repo, issueid=1)
self.assertEqual(issue.status, 'Open')
data = {
'title': 'test issue',
}
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
# Incomplete request
output = self.app.post(
'/api/0/test4/issue/1/status', data=data, headers=headers)
self.assertEqual(output.status_code, 400)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Invalid or incomplete input submitted",
"error_code": "EINVALIDREQ",
"errors": {"status": ["Not a valid choice"]}
}
)
# No change
repo = pagure.lib.query._get_project(self.session, 'test4')
issue = pagure.lib.query.search_issues(self.session, repo, issueid=1)
self.assertEqual(issue.status, 'Open')
data = {
'status': 'Open',
}
# Valid request but no change
output = self.app.post(
'/api/0/test4/issue/1/status', data=data, headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{'message': 'No changes'}
)
# No change
repo = pagure.lib.query._get_project(self.session, 'test4')
issue = pagure.lib.query.search_issues(self.session, repo, issueid=1)
self.assertEqual(issue.status, 'Open')
data = {
'status': 'Fixed',
}
# Valid request
output = self.app.post(
'/api/0/test4/issue/1/status', data=data, headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{'message':[
'Issue status updated to: Closed (was: Open)',
'Issue close_status updated to: Fixed'
]}
)
@patch('pagure.lib.git.update_git')
@patch('pagure.lib.notify.send_email')
def test_api_private_repo_comment_issue(self, p_send_email, p_ugt):
""" Test the api_comment_issue method of the flask api. """
p_send_email.return_value = True
p_ugt.return_value = True
item = pagure.lib.model.Project(
user_id=1, # pingou
name='test4',
description='test project description',
hook_token='aaabbbeeeceee',
private=True,
)
self.session.add(item)
self.session.commit()
tests.create_tokens(self.session)
tests.create_tokens_acl(self.session)
headers = {'Authorization': 'token aaabbbcccddd'}
# Invalid project
output = self.app.post('/api/0/foo/issue/1/comment', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Project not found",
"error_code": "ENOPROJECT",
}
)
# Invalid token, right project
headers = {'Authorization': 'token aaabbbccc'}
output = self.app.post('/api/0/test4/issue/1/comment', headers=headers)
self.assertEqual(output.status_code, 401)
data = json.loads(output.get_data(as_text=True))
self.assertEqual(sorted(data.keys()), ['error', 'error_code'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.name, data['error_code'])
headers = {'Authorization': 'token aaabbbcccddd'}
# No input
output = self.app.post('/api/0/test4/issue/1/comment', headers=headers)
self.assertEqual(output.status_code, 404)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Issue not found",
"error_code": "ENOISSUE",
}
)
# Create normal issue
repo = pagure.lib.query._get_project(self.session, 'test4')
msg = pagure.lib.query.new_issue(
session=self.session,
repo=repo,
title='Test issue #1',
content='We should work on this',
user='pingou',
private=False,
issue_uid='aaabbbccc1',
)
self.session.commit()
self.assertEqual(msg.title, 'Test issue #1')
# Check comments before
self.session.commit()
repo = pagure.lib.query._get_project(self.session, 'test4')
issue = pagure.lib.query.search_issues(self.session, repo, issueid=1)
self.assertEqual(len(issue.comments), 0)
data = {
'title': 'test issue',
}
# Incomplete request
output = self.app.post(
'/api/0/test4/issue/1/comment', data=data, headers=headers)
self.assertEqual(output.status_code, 400)
data = json.loads(output.get_data(as_text=True))
self.assertDictEqual(
data,
{
"error": "Invalid or incomplete input submitted",
"error_code": "EINVALIDREQ",
"errors": {"comment": ["This field is required."]}
}
)
# No change
self.session.commit()
repo = pagure.lib.query._get_project(self.session, 'test4')
issue = pagure.lib.query.search_issues(self.session, repo, issueid=1)
self.assertEqual(issue.status, 'Open')
data = {
'comment': 'This is a very interesting question',
}
# Valid request
output = self.app.post(
'/api/0/test4/issue/1/comment', data=data, headers=headers)
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
self.assertDictEqual(
data,
{'message': 'Comment added',
'avatar_url': 'https://seccdn.libravatar.org/avatar/...',
'user': 'pingou'}
)
# One comment added
self.session.commit()
repo = pagure.lib.query._get_project(self.session, 'test4')
issue = pagure.lib.query.search_issues(self.session, repo, issueid=1)
self.assertEqual(len(issue.comments), 1)
@patch('pagure.lib.git.update_git')
@patch('pagure.lib.notify.send_email')
def test_api_view_issue_comment(self, p_send_email, p_ugt):
""" Test the api_view_issue_comment endpoint. """
p_send_email.return_value = True
p_ugt.return_value = True
self.test_api_private_repo_comment_issue()
# View a comment that does not exist
output = self.app.get('/api/0/foo/issue/100/comment/2')
self.assertEqual(output.status_code, 404)
# Issue exists but not the comment
output = self.app.get('/api/0/test/issue/1/comment/2')
self.assertEqual(output.status_code, 404)
# Issue and comment exists
output = self.app.get('/api/0/test/issue/1/comment/1')
self.assertEqual(output.status_code, 404)
user = tests.FakeUser(username='pingou')
with tests.user_set(self.app.application, user):
output = self.app.get('/api/0/test4/issue/1/comment/1')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['date_created'] = '1435821770'
data["comment_date"] = "2015-07-02 09:22"
data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
self.assertDictEqual(
data,
{
"avatar_url": "https://seccdn.libravatar.org/avatar/...",
"comment": "This is a very interesting question",
"comment_date": "2015-07-02 09:22",
"notification": False,
"date_created": "1435821770",
"edited_on": None,
"editor": None,
"id": 1,
"parent": None,
"reactions": {},
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
)
# Issue and comment exists, using UID
output = self.app.get('/api/0/test4/issue/aaabbbccc1/comment/1')
self.assertEqual(output.status_code, 200)
data = json.loads(output.get_data(as_text=True))
data['date_created'] = '1435821770'
data["comment_date"] = "2015-07-02 09:22"
data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
self.assertDictEqual(
data,
{
"avatar_url": "https://seccdn.libravatar.org/avatar/...",
"comment": "This is a very interesting question",
"comment_date": "2015-07-02 09:22",
"notification": False,
"date_created": "1435821770",
"edited_on": None,
"editor": None,
"id": 1,
"parent": None,
"reactions": {},
"user": {
"fullname": "PY C",
"name": "pingou"
}
}
)
if __name__ == '__main__':
unittest.main(verbosity=2)