Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: adds test with RequestsMock for create_pull_request unit tests #99

Merged
merged 5 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 22 additions & 43 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pre-commit = "^3.4.0"
pytest = "^7.3.2"
pytest-cov = "^4.1.0"
pytest-skip-slow = "^0.0.5"
responses = "^0.24.1"


[tool.coverage.run]
branch = true
Expand Down
371 changes: 371 additions & 0 deletions tests/data/json/github_example_pull_response.json

Large diffs are not rendered by default.

114 changes: 114 additions & 0 deletions tests/data/json/github_example_repo_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"id": 654286523,
"node_id": "R_kgDOJv-euw",
"name": "repo",
"full_name": "owner/repo",
"private": false,
"owner": {
"login": "owner",
"id": 8826520,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjg4MjY1MjA=",
"avatar_url": "https://avatars.githubusercontent.com/u/8826520?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/owner",
"html_url": "https://github.com/owner",
"followers_url": "https://api.github.com/users/owner/followers",
"following_url": "https://api.github.com/users/owner/following{/other_user}",
"gists_url": "https://api.github.com/users/owner/gists{/gist_id}",
"starred_url": "https://api.github.com/users/owner/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/owner/subscriptions",
"organizations_url": "https://api.github.com/users/owner/orgs",
"repos_url": "https://api.github.com/users/owner/repos",
"events_url": "https://api.github.com/users/owner/events{/privacy}",
"received_events_url": "https://api.github.com/users/owner/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/owner/repo",
"description": "An example project",
"fork": false,
"url": "https://api.github.com/repos/owner/repo",
"forks_url": "https://api.github.com/repos/owner/repo/forks",
"keys_url": "https://api.github.com/repos/owner/repo/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/owner/repo/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/owner/repo/teams",
"hooks_url": "https://api.github.com/repos/owner/repo/hooks",
"issue_events_url": "https://api.github.com/repos/owner/repo/issues/events{/number}",
"events_url": "https://api.github.com/repos/owner/repo/events",
"assignees_url": "https://api.github.com/repos/owner/repo/assignees{/user}",
"branches_url": "https://api.github.com/repos/owner/repo/branches{/branch}",
"tags_url": "https://api.github.com/repos/owner/repo/tags",
"blobs_url": "https://api.github.com/repos/owner/repo/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/owner/repo/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/owner/repo/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/owner/repo/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/owner/repo/statuses/{sha}",
"languages_url": "https://api.github.com/repos/owner/repo/languages",
"stargazers_url": "https://api.github.com/repos/owner/repo/stargazers",
"contributors_url": "https://api.github.com/repos/owner/repo/contributors",
"subscribers_url": "https://api.github.com/repos/owner/repo/subscribers",
"subscription_url": "https://api.github.com/repos/owner/repo/subscription",
"commits_url": "https://api.github.com/repos/owner/repo/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/owner/repo/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/owner/repo/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/owner/repo/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/owner/repo/contents/{+path}",
"compare_url": "https://api.github.com/repos/owner/repo/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/owner/repo/merges",
"archive_url": "https://api.github.com/repos/owner/repo/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/owner/repo/downloads",
"issues_url": "https://api.github.com/repos/owner/repo/issues{/number}",
"pulls_url": "https://api.github.com/repos/owner/repo/pulls{/number}",
"milestones_url": "https://api.github.com/repos/owner/repo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/owner/repo/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/owner/repo/labels{/name}",
"releases_url": "https://api.github.com/repos/owner/repo/releases{/id}",
"deployments_url": "https://api.github.com/repos/owner/repo/deployments",
"created_at": "2023-06-15T19:44:03Z",
"updated_at": "2023-10-30T20:55:12Z",
"pushed_at": "2023-12-07T15:36:41Z",
"git_url": "git://github.com/owner/repo.git",
"ssh_url": "[email protected]:owner/repo.git",
"clone_url": "https://github.com/owner/repo.git",
"svn_url": "https://github.com/owner/repo",
"homepage": "",
"size": 673,
"stargazers_count": 4,
"watchers_count": 4,
"language": "Python",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"has_discussions": true,
"forks_count": 3,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 10,
"allow_forking": true,
"is_template": false,
"web_commit_signoff_required": false,
"topics": [],
"visibility": "public",
"forks": 3,
"open_issues": 10,
"watchers": 4,
"default_branch": "main",
"permissions": {},
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"allow_auto_merge": true,
"delete_branch_on_merge": false,
"allow_update_branch": true,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_message": "COMMIT_MESSAGES",
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"merge_commit_message": "PR_TITLE",
"merge_commit_title": "MERGE_MESSAGE",
"network_count": 3,
"subscribers_count": 6
}

6 changes: 1 addition & 5 deletions tests/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,4 @@ To run the end-to-end tests, follow these steps:
export TRESTLEBOT_IMAGE=quay.io/continuouscompliance/trestle-bot:latest
```

- When created tests that push to a branch, ensure the name is "test". This is because the mock API server is configured to only allow pushes to a branch named "test".

## Future Improvements
- Create endpoints that mock GitHub and GitLab API calls for pull request creation.
- Add more end-to-end tests to cover more use cases.
- When created tests that push to a branch, ensure the name is "test". This is because the mock API server is configured to only allow pushes to a branch named "test".
43 changes: 41 additions & 2 deletions tests/trestlebot/test_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@

"""Test for GitHub provider logic"""

from typing import Tuple
import json
import re
from typing import Generator, Tuple
from unittest.mock import patch

import pytest
from git.repo import Repo
from responses import GET, POST, RequestsMock

from tests.testutils import clean
from tests.testutils import JSON_TEST_DATA_PATH, clean
from trestlebot.github import GitHub
from trestlebot.provider import GitProviderException

Expand Down Expand Up @@ -73,6 +76,42 @@
gh.parse_repository("https://notgithub.com/owner/repo.git")


@pytest.fixture
def resp_merge_requests() -> Generator[RequestsMock, None, None]:
"""Mock the GitHub API for pull request creation"""
repo_content = json.load(
open(JSON_TEST_DATA_PATH / "github_example_repo_response.json")
)
pr_content = json.load(
open(JSON_TEST_DATA_PATH / "github_example_pull_response.json")
)
with RequestsMock() as rsps:
rsps.add(
method=POST,
url=re.compile(r"https://api.github.com/repos/owner/repo/pulls"),
Fixed Show fixed Hide fixed
json=pr_content,
content_type="application/json",
status=201,
)
rsps.add(
method=GET,
url=re.compile(r"https://api.github.com/repos/owner/repo"),
Fixed Show fixed Hide fixed
json=repo_content,
content_type="application/json",
status=200,
)
yield rsps


def test_create_pull_request(resp_merge_requests: RequestsMock) -> None:
"""Test creating a pull request"""
gh = GitHub("fake")
pr_number = gh.create_pull_request(
"owner", "repo", "main", "test", "My PR", "Has Changes"
)
assert pr_number == 123


def test_create_pull_request_invalid_repo() -> None:
"""Test triggering an error during pull request creation"""
gh = GitHub("fake")
Expand Down
47 changes: 46 additions & 1 deletion tests/trestlebot/test_gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@

"""Test for GitLab provider logic"""

from typing import Callable, Tuple
import re
from typing import Callable, Generator, Tuple
from unittest.mock import patch

import pytest
from git.repo import Repo
from gitlab.exceptions import GitlabAuthenticationError, GitlabCreateError
from responses import GET, POST, RequestsMock

from tests.testutils import clean
from trestlebot.gitlab import GitLab
Expand Down Expand Up @@ -111,6 +113,49 @@ def test_parse_repository_with_incorrect_name() -> None:
gl.parse_repository("https://notgitlab.com/owner/repo.git")


mr_content = {
"id": 123,
"title": "Example Merge Request",
"description": "This is an example merge request description.",
"state": "opened",
"created_at": "2023-12-06T08:30:00Z",
"updated_at": "2023-12-06T09:15:00Z",
"source_branch": "feature-branch",
"target_branch": "main",
"author": {"id": 789, "name": "Jane Doe", "username": "janedoe"},
"merge_status": "can_be_merged",
}


@pytest.fixture
def resp_merge_requests() -> Generator[RequestsMock, None, None]:
with RequestsMock() as rsps:
rsps.add(
method=POST,
url=re.compile(r"http://localhost/api/v4/projects/1/merge_requests"),
json=mr_content,
content_type="application/json",
status=201,
)
rsps.add(
method=GET,
url=re.compile(r"http://localhost/api/v4/projects/owner%2Frepo"),
json={"name": "name", "id": 1},
content_type="application/json",
status=200,
)
yield rsps


def test_create_pull_request(resp_merge_requests: RequestsMock) -> None:
"""Test creating a pull request"""
gl = GitLab("fake", "http://localhost")
pr_number = gl.create_pull_request(
"owner", "repo", "main", "test", "My PR", "Has Changes"
)
assert pr_number == 123


def create_side_effect(name: str) -> None:
raise GitlabCreateError("example")

Expand Down