|
1 | 1 | from pathlib import Path
|
2 |
| -from typing import Any |
| 2 | +from typing import Any, Optional |
3 | 3 | from unittest import mock
|
4 | 4 | from unittest.mock import MagicMock, call, patch
|
5 | 5 |
|
@@ -105,6 +105,33 @@ def test_OperatorReview_github_repo_org(
|
105 | 105 | assert review_community.github_repo_org == "my-org"
|
106 | 106 |
|
107 | 107 |
|
| 108 | +def test_OperatorReview_github_repo_name( |
| 109 | + review_community: check_permissions.OperatorReview, |
| 110 | +) -> None: |
| 111 | + assert review_community.github_repo_name == "my-org/repo-123" |
| 112 | + |
| 113 | + |
| 114 | +@patch("operatorcert.entrypoints.check_permissions.Github") |
| 115 | +@patch("operatorcert.entrypoints.check_permissions.Auth.Token") |
| 116 | +def test_OperatorReview_pr_labels( |
| 117 | + mock_token: MagicMock, |
| 118 | + mock_github: MagicMock, |
| 119 | + review_community: check_permissions.OperatorReview, |
| 120 | +) -> None: |
| 121 | + repo = MagicMock() |
| 122 | + pull = MagicMock() |
| 123 | + |
| 124 | + def _mock_label(name: str) -> MagicMock: |
| 125 | + m = MagicMock() |
| 126 | + m.name = name |
| 127 | + return m |
| 128 | + |
| 129 | + pull.get_labels.return_value = [_mock_label("foo"), _mock_label("bar")] |
| 130 | + repo.get_pull.return_value = pull |
| 131 | + mock_github.return_value.get_repo.return_value = repo |
| 132 | + assert review_community.pr_labels == {"foo", "bar"} |
| 133 | + |
| 134 | + |
108 | 135 | @pytest.mark.parametrize(
|
109 | 136 | "is_org_member, is_partner, permission_partner, permission_community, permission_partner_called, permission_community_called, expected_result",
|
110 | 137 | [
|
@@ -225,31 +252,73 @@ def test_OperatorReview_check_permission_for_partner(
|
225 | 252 | review_partner.check_permission_for_partner()
|
226 | 253 |
|
227 | 254 |
|
| 255 | +@pytest.mark.parametrize( |
| 256 | + ["reviewers", "labels", "owners_review", "result"], |
| 257 | + [ |
| 258 | + pytest.param( |
| 259 | + [], |
| 260 | + set(), |
| 261 | + False, |
| 262 | + check_permissions.MaintainersReviewNeeded, |
| 263 | + id="No reviewers", |
| 264 | + ), |
| 265 | + pytest.param( |
| 266 | + ["owner", "foo"], |
| 267 | + set(), |
| 268 | + False, |
| 269 | + True, |
| 270 | + id="author is reviewer", |
| 271 | + ), |
| 272 | + pytest.param( |
| 273 | + ["foo", "bar"], |
| 274 | + set(), |
| 275 | + True, |
| 276 | + False, |
| 277 | + id="author is not reviewer", |
| 278 | + ), |
| 279 | + pytest.param( |
| 280 | + ["bar", "baz"], |
| 281 | + {"approved"}, |
| 282 | + False, |
| 283 | + True, |
| 284 | + id="author is not reviewer, PR approved", |
| 285 | + ), |
| 286 | + ], |
| 287 | +) |
228 | 288 | @patch(
|
229 | 289 | "operatorcert.entrypoints.check_permissions.OperatorReview.request_review_from_owners"
|
230 | 290 | )
|
231 | 291 | @patch(
|
232 | 292 | "operatorcert.entrypoints.check_permissions.OperatorReview.reviewers",
|
233 | 293 | new_callable=mock.PropertyMock,
|
234 | 294 | )
|
| 295 | +@patch( |
| 296 | + "operatorcert.entrypoints.check_permissions.OperatorReview.pr_labels", |
| 297 | + new_callable=mock.PropertyMock, |
| 298 | +) |
235 | 299 | def test_OperatorReview_check_permission_for_community(
|
| 300 | + mock_labels: MagicMock, |
236 | 301 | mock_reviewers: MagicMock,
|
237 | 302 | mock_review_from_owners: MagicMock,
|
238 | 303 | review_community: check_permissions.OperatorReview,
|
| 304 | + reviewers: list[str], |
| 305 | + labels: set[str], |
| 306 | + owners_review: bool, |
| 307 | + result: bool | type, |
239 | 308 | ) -> None:
|
240 |
| - mock_reviewers.return_value = [] |
241 |
| - with pytest.raises(check_permissions.MaintainersReviewNeeded): |
242 |
| - review_community.check_permission_for_community() |
243 |
| - |
244 |
| - mock_reviewers.return_value = ["user1", "user2"] |
| 309 | + mock_reviewers.return_value = reviewers |
| 310 | + mock_labels.return_value = labels |
245 | 311 |
|
246 |
| - assert review_community.check_permission_for_community() == False |
247 |
| - mock_review_from_owners.assert_called_once() |
| 312 | + if isinstance(result, bool): |
| 313 | + assert review_community.check_permission_for_community() == result |
| 314 | + else: |
| 315 | + with pytest.raises(result): |
| 316 | + review_community.check_permission_for_community() |
248 | 317 |
|
249 |
| - mock_review_from_owners.reset_mock() |
250 |
| - mock_reviewers.return_value = ["owner"] |
251 |
| - assert review_community.check_permission_for_community() == True |
252 |
| - mock_review_from_owners.assert_not_called() |
| 318 | + if owners_review: |
| 319 | + mock_review_from_owners.assert_called_once() |
| 320 | + else: |
| 321 | + mock_review_from_owners.assert_not_called() |
253 | 322 |
|
254 | 323 |
|
255 | 324 | @patch("operatorcert.entrypoints.check_permissions.run_command")
|
@@ -283,10 +352,11 @@ def test_OperatorReview_request_review_from_owners(
|
283 | 352 | "comment",
|
284 | 353 | review_community.pull_request_url,
|
285 | 354 | "--body",
|
286 |
| - "Author of the PR is not listed as one of the reviewers in ci.yaml.\n" |
287 |
| - "Please review the PR and approve it with \\`/lgtm\\` comment.\n" |
288 |
| - "@user1, @user2 \n\nConsider adding author of the PR to the ci.yaml " |
289 |
| - "file if you want automated approval for a followup submissions.", |
| 355 | + "The author of the PR is not listed as one of the reviewers in ci.yaml.\n" |
| 356 | + "@user1, @user2: please review the PR and approve it with an `/approve` comment.\n\n" |
| 357 | + "Consider adding the author of the PR to the list of reviewers in " |
| 358 | + "the ci.yaml file if you want automated merge without explicit " |
| 359 | + "approval.", |
290 | 360 | ]
|
291 | 361 | )
|
292 | 362 |
|
|
0 commit comments