# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import
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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "Test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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(
'
All Projects '
'0
',
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(
'All Projects '
'1
',
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(
'My Projects
',
output_text,
)
self.assertIn("2 Projects", output_text)
self.assertNotIn(
'Forks', output_text
)
self.assertEqual(
output_text.count('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(
"""
Projects
0
""",
output_text,
)
self.assertIn(
"""
Forks
0
""",
output_text,
)
self.assertIn(
"""
Groups
0
""",
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(
"""
Projects
1
""",
output_text,
)
self.assertIn(
"""
Forks
0
""",
output_text,
)
self.assertIn(
"""
Groups
0
""",
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(
"""
Projects
1
""",
output_text,
)
self.assertIn(
"""
Forks
0
""",
output_text,
)
self.assertIn(
"""
Groups
0
""",
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(
"""
Projects
1
""",
output_text,
)
self.assertIn(
"""
Forks
0
""",
output_text,
)
self.assertIn(
"""
Groups
0
""",
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(
'My Projects
',
output_text,
)
self.assertIn("0 Projects", output_text)
self.assertNotIn(
'Forks', output_text
)
self.assertEqual(
output_text.count('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(
'My Projects
',
output_text,
)
self.assertIn("1 Projects", output_text)
self.assertNotIn(
'Forks', output_text
)
self.assertEqual(
output_text.count('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(
'',
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(
'',
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(
'',
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(
'',
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(
'',
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(
'',
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(
"""
Projects
0
""",
output.get_data(as_text=True),
)
self.assertIn(
"""
Forks
0
""",
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(
"""
Projects
1
""",
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(
"Issues - test4 - Pagure",
output.get_data(as_text=True),
)
self.assertTrue(
' 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(
"Issues - test4 - Pagure",
output.get_data(as_text=True),
)
self.assertTrue(
' 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": [],
"collaborator": [],
"commit": [],
"ticket": [],
},
"access_users": {
"admin": [],
"collaborator": [],
"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",
"url_path": "user/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": [],
"collaborator": [],
"commit": [],
"ticket": [],
},
"access_users": {
"admin": [],
"collaborator": [],
"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",
"url_path": "user/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,
"tags": [],
"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": [],
"collaborator": [],
"commit": [],
"ticket": [],
},
"access_users": {
"admin": [],
"collaborator": [],
"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",
"url_path": "user/pingou",
},
},
"remote_git": None,
"repo_from": {
"access_groups": {
"admin": [],
"collaborator": [],
"commit": [],
"ticket": [],
},
"access_users": {
"admin": [],
"collaborator": [],
"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",
"url_path": "user/pingou",
},
},
"status": "Open",
"tags": [],
"threshold_reached": None,
"title": "test pull-request",
"uid": "1431414800",
"updated_on": "1431414800",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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": [],
"collaborator": [],
"commit": [],
"ticket": [],
},
"access_users": {
"admin": [],
"collaborator": [],
"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",
"url_path": "user/pingou",
},
},
"remote_git": None,
"repo_from": {
"access_groups": {
"admin": [],
"collaborator": [],
"commit": [],
"ticket": [],
},
"access_users": {
"admin": [],
"collaborator": [],
"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",
"url_path": "user/pingou",
},
},
"status": "Open",
"tags": [],
"threshold_reached": None,
"title": "test pull-request",
"uid": "1431414800",
"updated_on": "1431414800",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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",
"url_path": "user/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",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/pingou",
},
}
],
"pagination": {
"first": "http://localhost...",
"last": "http://localhost...",
"next": None,
"page": 1,
"pages": 1,
"per_page": 20,
"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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "Test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/pingou",
},
},
],
"pagination": {
"first": "http://localhost...",
"last": "http://localhost...",
"next": None,
"page": 1,
"pages": 1,
"per_page": 20,
"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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "Test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/pingou",
},
},
],
"pagination": {
"first": "http://localhost...",
"last": "http://localhost...",
"next": None,
"page": 1,
"pages": 1,
"per_page": 20,
"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": {
"first": "http://localhost...",
"last": "http://localhost...",
"next": None,
"page": 1,
"pages": 0,
"per_page": 20,
"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": {
"first": "http://localhost...",
"last": "http://localhost...",
"next": None,
"page": 1,
"pages": 0,
"per_page": 20,
"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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "Test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/pingou",
},
},
],
"pagination": {
"first": "http://localhost...",
"last": "http://localhost...",
"next": None,
"page": 1,
"pages": 1,
"per_page": 20,
"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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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", "errors"]
)
self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data["error"])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.name, data["error_code"]
)
self.assertEqual(data["errors"], "Invalid token")
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,
"related_prs": [],
"status": "Open",
"tags": [],
"title": "test issue",
"user": {
"fullname": "PY C",
"name": "pingou",
"url_path": "user/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", "errors"]
)
self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data["error"])
self.assertEqual(
pagure.api.APIERROR.EINVALIDTOK.name, data["error_code"]
)
self.assertEqual(data["errors"], "Invalid token")
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",
"url_path": "user/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",
"url_path": "user/pingou",
},
},
)
if __name__ == "__main__":
unittest.main(verbosity=2)