Issues (87)

tcms/issuetracker/tests/test_azureboards.py (1 issue)

1
# pylint: disable=attribute-defined-outside-init
2
3
import os
4
import unittest
5
6
from django.utils import timezone
7
8
from tcms.core.contrib.linkreference.models import LinkReference
9
from tcms.issuetracker.azure_boards import AzureBoards, AzureBoardsAPI
10
from tcms.rpc.tests.utils import APITestCase
11
from tcms.testcases.models import BugSystem
12
from tcms.tests.factories import ComponentFactory, TestExecutionFactory
13
14
15
@unittest.skipUnless(
16
    os.getenv("TEST_BUGTRACKER_INTEGRATION"),
17
    "Bug tracker integration testing not enabled",
18
)
19
class TestAzureIntegration(APITestCase):
20
    existing_bug_id = 717
21
    existing_bug_url = (
22
        "https://dev.azure.com/kiwitcms/boards-integration/_workitems/edit/717"
23
    )
24
25
    def _fixture_setup(self):
26
        super()._fixture_setup()
27
28
        self.execution_1 = TestExecutionFactory()
29
        self.execution_1.case.summary = "Tested at " + timezone.now().isoformat()
30
        self.execution_1.case.text = "Given-When-Then"
31
        self.execution_1.case.save()  # will generate history object
32
        self.execution_1.run.summary = (
33
            "Automated TR for Azure integration on " + timezone.now().isoformat()
34
        )
35
        self.execution_1.run.save()
36
37
        self.component = ComponentFactory(
38
            name="AzureBoards integration", product=self.execution_1.run.plan.product
39
        )
40
        self.execution_1.case.add_component(self.component)
41
42
        bug_system = BugSystem.objects.create(  # nosec:B106:hardcoded_password_funcarg
43
            name="Azure for kiwitcms/test-azure-integration",
44
            tracker_type="tcms.issuetracker.azure_boards.AzureBoards",
45
            base_url="https://dev.azure.com/kiwitcms/boards-integration",
46
            api_password=os.getenv("AZURE_BOARDS_INTEGRATION_API_TOKEN"),
47
        )
48
        self.integration = AzureBoards(bug_system, None)
49
50
    def test_bug_id_from_url(self):
51
        result = self.integration.bug_id_from_url(self.existing_bug_url)
52
        self.assertEqual(self.existing_bug_id, result)
53
54
    def test_details(self):
55
        result = self.integration.details(self.existing_bug_url)
56
57
        self.assertEqual("A pre-existing public issue", result["title"])
58
        self.assertIn(
59
            "The whole boards-integration project is public so this issue should be public as well",
60
            result["description"],
61
        )
62
63
    def test_auto_update_bugtracker(self):
64
        last_comment = None
65
        initial_comments = self.integration.rpc.get_comments(self.existing_bug_id)
66
67
        try:
68
            # simulate user adding a new bug URL to a TE and clicking
69
            # 'Automatically update bug tracker'
70
            result = self.rpc_client.TestExecution.add_link(
71
                {
72
                    "execution_id": self.execution_1.pk,
73
                    "is_defect": True,
74
                    "url": self.existing_bug_url,
75
                },
76
                True,
77
            )
78
79
            # making sure RPC above returned the same URL
80
            self.assertEqual(self.existing_bug_url, result["url"])
81
82
            # wait until comments have been refreshed b/c this seem to happen async
83
            initial_comments_length = initial_comments["count"]
84
            current_comments_length = initial_comments_length
85
            while current_comments_length != initial_comments_length + 1:
86
                comments = self.integration.rpc.get_comments(self.existing_bug_id)
87
                current_comments_length = comments["count"]
88
89
            last_comment = comments["comments"][0]
90
91
            # assert that a comment has been added as the last one
92
            # and also verify its text
93
            for expected_string in [
94
                "Confirmed via test execution",
95
                f"TR-{self.execution_1.run_id}: {self.execution_1.run.summary}",
96
                self.execution_1.run.get_full_url(),
97
                f"TE-{self.execution_1.pk}: {self.execution_1.case.summary}",
98
            ]:
99
                self.assertIn(expected_string, last_comment["text"])
100
        finally:
101
            if last_comment:
102
                self.integration.rpc.delete_comment(
103
                    self.existing_bug_id, last_comment["id"]
104
                )
105
106 View Code Duplication
    def test_report_issue_from_test_execution_1click_works(self):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
107
        # simulate user clicking the 'Report bug' button in TE widget, TR page
108
        result = self.rpc_client.Bug.report(
109
            self.execution_1.pk, self.integration.bug_system.pk
110
        )
111
        self.assertEqual(result["rc"], 0)
112
        self.assertIn(self.integration.bug_system.base_url, result["response"])
113
        self.assertIn("/_workitems/edit/", result["response"])
114
115
        new_issue_id = self.integration.bug_id_from_url(result["response"])
116
        issue = self.integration.rpc.get_issue(new_issue_id)
117
118
        self.assertEqual(
119
            f"Failed test: {self.execution_1.case.summary}",
120
            issue["fields"]["System.Title"],
121
        )
122
        for expected_string in [
123
            f"Filed from execution {self.execution_1.get_full_url()}",
124
            self.execution_1.run.plan.product.name,
125
            self.component.name,
126
            "Steps to reproduce",
127
            self.execution_1.case.text,
128
        ]:
129
            self.assertIn(expected_string, issue["fields"]["System.Description"])
130
131
        # verify that LR has been added to TE
132
        self.assertTrue(
133
            LinkReference.objects.filter(
134
                execution=self.execution_1,
135
                url=result["response"],
136
                is_defect=True,
137
            ).exists()
138
        )
139
140
        # Set work item done after test is finished
141
        close_issue(self.integration.rpc, new_issue_id)
142
143
    def test_report_issue_from_test_execution_empty_baseurl_exception(self):
144
        # simulate user clicking the 'Report bug' button in TE widget, TR page
145
        bug_system = BugSystem.objects.create(  # nosec:B106:hardcoded_password_funcarg
146
            name="Azure for kiwitcms/test-azure-integration Exception",
147
            tracker_type="tcms.issuetracker.azure_boards.AzureBoards",
148
            base_url="incorrect_url",
149
            api_password=os.getenv("AZURE_BOARDS_INTEGRATION_API_TOKEN"),
150
        )
151
        integration = AzureBoards(bug_system, None)
152
        result = self.rpc_client.Bug.report(
153
            self.execution_1.pk, integration.bug_system.pk
154
        )
155
        self.assertIn("_workitems/create/Issue", result["response"])
156
157
158
@unittest.skipUnless(
159
    os.getenv("TEST_BUGTRACKER_INTEGRATION"),
160
    "Bug tracker integration testing not enabled",
161
)
162
class TestAzureBoardsAPI(unittest.TestCase):
163
    @classmethod
164
    def setUpClass(cls):
165
        super().setUpClass()
166
        api_password = os.getenv("AZURE_BOARDS_INTEGRATION_API_TOKEN")
167
        base_url = "https://dev.azure.com/kiwitcms/boards-integration"
168
        cls.api_instance = AzureBoardsAPI(base_url, api_password)
169
170
        test_create_body = [
171
            {
172
                "op": "add",
173
                "path": "/fields/System.Title",
174
                "from": "null",
175
                "value": "Test Issue",
176
            }
177
        ]
178
        result = cls.api_instance.create_issue(test_create_body)
179
        cls.issue_id = result["id"]
180
181
    @classmethod
182
    def tearDownClass(cls):
183
        close_issue(cls.api_instance, cls.issue_id)
184
        return super().tearDownClass()
185
186
    def test_create_issue(self):
187
        test_create_body = [
188
            {
189
                "op": "add",
190
                "path": "/fields/System.Title",
191
                "from": "null",
192
                "value": "Test Issue",
193
            }
194
        ]
195
        result = self.api_instance.create_issue(test_create_body)
196
        self.assertEqual(result["fields"]["System.Title"], "Test Issue")
197
198
        # Close work item after test is finished.
199
        close_issue(self.api_instance, result["id"])
200
201
    def test_update_issue(self):
202
        test_update_body = [
203
            {
204
                "op": "replace",
205
                "path": "/fields/System.Description",
206
                "from": "null",
207
                "value": "Updated Description",
208
            }
209
        ]
210
        result = self.api_instance.update_issue(self.issue_id, test_update_body)
211
        self.assertEqual(result["fields"]["System.Description"], "Updated Description")
212
213
    def test_add_comment(self):
214
        test_comment_body = {"text": "Test Updated Comment"}
215
        result = self.api_instance.add_comment(self.issue_id, test_comment_body)
216
        self.assertNotIn("message", result)
217
        self.assertEqual(result["text"], "Test Updated Comment")
218
219
220
def close_issue(instance, issue_id):
221
    close_issue_body = [
222
        {
223
            "op": "replace",
224
            "path": "/fields/System.State",
225
            "from": "null",
226
            "value": "Done",
227
        }
228
    ]
229
    instance.update_issue(issue_id, close_issue_body)
230