Skip to content

Commit 52174e9

Browse files
committed
Add test for GitHub integration class
1 parent 65ed770 commit 52174e9

File tree

4 files changed

+193
-5
lines changed

4 files changed

+193
-5
lines changed

.github/workflows/testing.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,19 @@ jobs:
3535
echo "username = kiwitcms-bot" >> ~/.tcms.conf
3636
echo "password = ${{ secrets.TCMS_PASSWORD }}" >> ~/.tcms.conf
3737
38-
- name: Execute tests
38+
- name: Install dependencies
3939
run: |
4040
sudo apt-get install libkrb5-dev
4141
4242
pip install -r devel.txt
4343
4444
docker exec -i postgresql_database psql -c "ALTER USER kiwi CREATEDB;"
4545
46+
- name: Execute tests
47+
env:
48+
KIWI_GITHUB_APP_ID: ${{ secrets.KIWI_GITHUB_APP_ID }}
49+
KIWI_GITHUB_APP_PRIVATE_KEY: ${{ secrets.KIWI_GITHUB_APP_PRIVATE_KEY }}
50+
run: |
4651
# report to Kiwi TCMS only if we have access to secrets
4752
if [ -n "${{ secrets.TCMS_PASSWORD }}" ]; then
4853
export DJANGO_TEST_RUNNER="tcms_django_plugin.TestRunner"

devel.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ factory_boy
44
flake8
55
coverage
66
kiwitcms-django-plugin
7+
parameterized
78
pylint
89
pylint-django
910
psycopg2
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# Copyright (c) 2023 Alexander Todorov <[email protected]>
2+
3+
# Licensed under the GPL 3.0: https://www.gnu.org/licenses/gpl-3.0.txt
4+
# pylint: disable=attribute-defined-outside-init
5+
6+
import os
7+
import time
8+
import unittest
9+
10+
from django.http import HttpRequest
11+
from django.utils import timezone
12+
from parameterized import parameterized
13+
14+
from tcms.testcases.models import BugSystem
15+
from tcms.tests.factories import ComponentFactory, TestExecutionFactory
16+
17+
from tcms_github_app.issues import Integration
18+
from tcms_github_app.tests import AppInstallationFactory, LoggedInTestCase
19+
20+
21+
@unittest.skipUnless(
22+
os.getenv("KIWI_GITHUB_APP_ID") and os.getenv("KIWI_GITHUB_APP_PRIVATE_KEY"),
23+
"Testing environment not configured",
24+
)
25+
class TestGitHubIntegration(LoggedInTestCase):
26+
public_bug_url = "https://github.com/kiwitcms/test-github-integration/issues/1"
27+
private_bug_url = "https://github.com/kiwitcms/private-test-github-integration/issues/1"
28+
29+
@classmethod
30+
def setUpClass(cls):
31+
super().setUpClass()
32+
33+
cls.execution_1 = TestExecutionFactory()
34+
cls.execution_1.case.summary = "kiwitcms-github-app at " + timezone.now().isoformat()
35+
cls.execution_1.case.text = "Given-When-Then"
36+
cls.execution_1.case.save() # will generate history object
37+
cls.execution_1.run.summary = (
38+
"Automated TR for GitHub integration on " + timezone.now().isoformat()
39+
)
40+
cls.execution_1.run.save()
41+
42+
cls.component = ComponentFactory(
43+
name="GitHub integration", product=cls.execution_1.run.plan.product
44+
)
45+
cls.execution_1.case.add_component(cls.component)
46+
47+
AppInstallationFactory(
48+
installation=6185099,
49+
sender=1002300,
50+
tenant_pk=cls.tenant.pk
51+
)
52+
53+
# simulate a tenant request for bugtracker integration class
54+
request = HttpRequest()
55+
request.META['HTTP_HOST'] = cls.tenant.get_primary_domain().domain
56+
request.tenant = cls.tenant
57+
58+
public_bug_system = BugSystem.objects.create( # nosec:B106:hardcoded_password_funcarg
59+
name="App integration for kiwitcms/test-github-integration",
60+
tracker_type="tcms_github_app.issues.Integration",
61+
base_url="https://github.com/kiwitcms/test-github-integration",
62+
)
63+
cls.public_tracker = Integration(public_bug_system, request)
64+
65+
private_bug_system = BugSystem.objects.create( # nosec:B106:hardcoded_password_funcarg
66+
name="App integration for kiwitcms/private-test-github-integration",
67+
tracker_type="tcms_github_app.issues.Integration",
68+
base_url="https://github.com/kiwitcms/private-test-github-integration",
69+
)
70+
cls.private_tracker = Integration(private_bug_system, request)
71+
72+
def test_details_for_public_url(self):
73+
result = self.public_tracker.details(self.public_bug_url)
74+
75+
self.assertEqual("Hello GitHub", result["title"])
76+
self.assertEqual(
77+
"This issue is used in automated tests that verify Kiwi TCMS - GitHub "
78+
"bug tracking integration!",
79+
result["description"],
80+
)
81+
82+
def test_details_for_private_url(self):
83+
result = self.private_tracker.details(self.private_bug_url)
84+
85+
self.assertEqual("Hello Private GitHub", result["title"])
86+
self.assertEqual(
87+
"This issue is used in automated tests that verify "
88+
"Kiwi TCMS - GitHub bug tracking integration!",
89+
result["description"],
90+
)
91+
92+
@parameterized.expand(
93+
[
94+
("public",),
95+
("private",),
96+
]
97+
)
98+
def test_auto_update_bugtracker(self, name):
99+
tracker = getattr(self, f"{name}_tracker")
100+
bug_url = getattr(self, f"{name}_bug_url")
101+
102+
repo_id = tracker.repo_id
103+
repo = tracker.rpc.get_repo(repo_id)
104+
issue = repo.get_issue(1)
105+
106+
# make sure there are no comments to confuse the test
107+
initial_comments_count = 0
108+
for comment in issue.get_comments():
109+
initial_comments_count += 1
110+
self.assertNotIn(self.execution_1.run.summary, comment.body)
111+
112+
# simulate user adding a new bug URL to a TE and clicking
113+
# 'Automatically update bug tracker'
114+
tracker.add_testexecution_to_issue([self.execution_1], bug_url)
115+
116+
# wait until comments have been refreshed b/c this seem to happen async
117+
retries = 0
118+
last_comment = None
119+
current_comment_count = 0
120+
while current_comment_count <= initial_comments_count:
121+
current_comment_count = 0
122+
# .get_comments() returns an iterator
123+
for comment in issue.get_comments():
124+
current_comment_count += 1
125+
last_comment = comment
126+
127+
time.sleep(1)
128+
retries += 1
129+
self.assertLess(retries, 20)
130+
131+
# reporter was kiwi-tcms (the app)
132+
self.assertEqual(last_comment.user.login, "kiwi-tcms[bot]")
133+
134+
# assert that a comment has been added as the last one
135+
# and also verify its text
136+
for expected_string in [
137+
"Confirmed via test execution",
138+
f"TR-{self.execution_1.run_id}: {self.execution_1.run.summary}",
139+
self.execution_1.run.get_full_url(),
140+
f"TE-{self.execution_1.pk}: {self.execution_1.case.summary}",
141+
]:
142+
self.assertIn(expected_string, last_comment.body)
143+
144+
# clean up after ourselves in case everything above looks good
145+
last_comment.delete()
146+
147+
@parameterized.expand(
148+
[
149+
("public_tracker",),
150+
("private_tracker",),
151+
]
152+
)
153+
def test_report_issue_from_test_execution_1click(self, name):
154+
tracker = getattr(self, name)
155+
156+
# simulate user clicking the 'Report bug' button in TE widget, TR page
157+
url = tracker.report_issue_from_testexecution(self.execution_1, self.tester)
158+
159+
self.assertIn(tracker.bug_system.base_url, url)
160+
self.assertIn("/issues/", url)
161+
162+
new_issue_id = tracker.bug_id_from_url(url)
163+
repo_id = tracker.repo_id
164+
repo = tracker.rpc.get_repo(repo_id)
165+
issue = repo.get_issue(new_issue_id)
166+
167+
# reporter was kiwi-tcms (the app)
168+
self.assertEqual("kiwi-tcms[bot]", issue.user.login)
169+
170+
self.assertEqual(f"Failed test: {self.execution_1.case.summary}", issue.title)
171+
for expected_string in [
172+
f"Filed from execution {self.execution_1.get_full_url()}",
173+
"Reporter",
174+
self.execution_1.run.plan.product.name,
175+
self.component.name,
176+
"Steps to reproduce",
177+
self.execution_1.case.text,
178+
]:
179+
self.assertIn(expected_string, issue.body)
180+
181+
# close issue after we're done
182+
issue.edit(state="closed")

test_project/settings.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2019-2022 Alexander Todorov <[email protected]>
1+
# Copyright (c) 2019-2023 Alexander Todorov <[email protected]>
22
#
33
# Licensed under the GPL 3.0: https://www.gnu.org/licenses/gpl-3.0.txt
44
#
@@ -81,8 +81,8 @@
8181
# NOTE: must be bytes, not string
8282
KIWI_GITHUB_APP_SECRET = b'S3cr3t'
8383

84-
KIWI_GITHUB_APP_ID = 12345
85-
KIWI_GITHUB_APP_PRIVATE_KEY = """
84+
KIWI_GITHUB_APP_ID = os.getenv("KIWI_GITHUB_APP_ID", "1234567890")
85+
KIWI_GITHUB_APP_PRIVATE_KEY = os.getenv("KIWI_GITHUB_APP_PRIVATE_KEY", """
8686
-----BEGIN RSA PRIVATE KEY-----
8787
MIIEowIBAAKCAQEAtJFKoaSWDYpUvdjUaqW3Ft5p9O78rwJEBuJnEmmCPmZTz1tz
8888
Hh2suPtWvolU/E1oOhbu0YPLHke0TC5uuBg5i5oA3b1UyfHdSiUYKmp0Mp9wkOpS
@@ -109,7 +109,7 @@
109109
Yp38AwKBgBrNcGBQLrOXqmEJ0tYLg7DIoxvJrLvxtu2mbdohWS9rQFjkkA7+IsML
110110
e6AQ/4uLtKdXZafgGSgqJ6tlB3J924Vb0HWmvnBcc2JCEPkgjuVDjXEMaqwIKjHa
111111
a3C9rG6XtvAyGvIbXKI3tCNURbsjsgVwOgS6kESboZ576iDeH/eO
112-
-----END RSA PRIVATE KEY-----""".strip()
112+
-----END RSA PRIVATE KEY-----""").strip()
113113

114114
# Allows us to hook-up kiwitcms-django-plugin at will
115115
TEST_RUNNER = os.environ.get("DJANGO_TEST_RUNNER", "django.test.runner.DiscoverRunner")

0 commit comments

Comments
 (0)