|
14 | 14 | class TestGetDiscussions(unittest.TestCase):
|
15 | 15 | """A class to test the get_discussions function in the discussions module."""
|
16 | 16 |
|
17 |
| - @patch("requests.post") |
18 |
| - def test_get_discussions(self, mock_post): |
19 |
| - """Test the get_discussions function with a successful GraphQL response. |
20 |
| -
|
21 |
| - This test mocks a successful GraphQL response and checks that the |
22 |
| - function returns the expected discussions. |
23 |
| -
|
24 |
| - """ |
25 |
| - # Mock the GraphQL response |
26 |
| - mock_response = { |
| 17 | + def _create_mock_response( |
| 18 | + self, discussions, has_next_page=False, end_cursor="cursor123" |
| 19 | + ): |
| 20 | + """Helper method to create a mock GraphQL response.""" |
| 21 | + return { |
27 | 22 | "data": {
|
28 | 23 | "search": {
|
29 |
| - "edges": [ |
30 |
| - { |
31 |
| - "node": { |
32 |
| - "title": "Discussion 1", |
33 |
| - "url": "https://github.com/user/repo/discussions/1", |
34 |
| - "createdAt": "2021-01-01T00:00:00Z", |
35 |
| - "comments": { |
36 |
| - "nodes": [{"createdAt": "2021-01-01T00:01:00Z"}] |
37 |
| - }, |
38 |
| - "answerChosenAt": None, |
39 |
| - "closedAt": None, |
40 |
| - } |
41 |
| - }, |
42 |
| - { |
43 |
| - "node": { |
44 |
| - "title": "Discussion 2", |
45 |
| - "url": "https://github.com/user/repo/discussions/2", |
46 |
| - "createdAt": "2021-01-02T00:00:00Z", |
47 |
| - "comments": { |
48 |
| - "nodes": [{"createdAt": "2021-01-02T00:01:00Z"}] |
49 |
| - }, |
50 |
| - "answerChosenAt": "2021-01-03T00:00:00Z", |
51 |
| - "closedAt": "2021-01-04T00:00:00Z", |
52 |
| - } |
53 |
| - }, |
54 |
| - ] |
| 24 | + "edges": [{"node": discussion} for discussion in discussions], |
| 25 | + "pageInfo": {"hasNextPage": has_next_page, "endCursor": end_cursor}, |
55 | 26 | }
|
56 | 27 | }
|
57 | 28 | }
|
| 29 | + |
| 30 | + @patch("requests.post") |
| 31 | + def test_get_discussions_single_page(self, mock_post): |
| 32 | + """Test the get_discussions function with a single page of results.""" |
| 33 | + # Mock data for two discussions |
| 34 | + mock_discussions = [ |
| 35 | + { |
| 36 | + "title": "Discussion 1", |
| 37 | + "url": "https://github.com/user/repo/discussions/1", |
| 38 | + "createdAt": "2021-01-01T00:00:00Z", |
| 39 | + "comments": {"nodes": [{"createdAt": "2021-01-01T00:01:00Z"}]}, |
| 40 | + "answerChosenAt": None, |
| 41 | + "closedAt": None, |
| 42 | + }, |
| 43 | + { |
| 44 | + "title": "Discussion 2", |
| 45 | + "url": "https://github.com/user/repo/discussions/2", |
| 46 | + "createdAt": "2021-01-02T00:00:00Z", |
| 47 | + "comments": {"nodes": [{"createdAt": "2021-01-02T00:01:00Z"}]}, |
| 48 | + "answerChosenAt": "2021-01-03T00:00:00Z", |
| 49 | + "closedAt": "2021-01-04T00:00:00Z", |
| 50 | + }, |
| 51 | + ] |
| 52 | + |
58 | 53 | mock_post.return_value.status_code = 200
|
59 |
| - mock_post.return_value.json.return_value = mock_response |
60 |
| - mock_ghe = "" |
| 54 | + mock_post.return_value.json.return_value = self._create_mock_response( |
| 55 | + mock_discussions, has_next_page=False |
| 56 | + ) |
61 | 57 |
|
62 |
| - # Call the function with mock arguments |
63 | 58 | discussions = get_discussions(
|
64 |
| - "token", "repo:user/repo type:discussions query", mock_ghe |
| 59 | + "token", "repo:user/repo type:discussions query", "" |
65 | 60 | )
|
66 | 61 |
|
67 | 62 | # Check that the function returns the expected discussions
|
68 | 63 | self.assertEqual(len(discussions), 2)
|
69 | 64 | self.assertEqual(discussions[0]["title"], "Discussion 1")
|
70 | 65 | self.assertEqual(discussions[1]["title"], "Discussion 2")
|
71 | 66 |
|
| 67 | + # Verify only one API call was made |
| 68 | + self.assertEqual(mock_post.call_count, 1) |
| 69 | + |
72 | 70 | @patch("requests.post")
|
73 |
| - def test_get_discussions_error(self, mock_post): |
74 |
| - """Test the get_discussions function with a failed GraphQL response. |
| 71 | + def test_get_discussions_multiple_pages(self, mock_post): |
| 72 | + """Test the get_discussions function with multiple pages of results.""" |
| 73 | + # Mock data for pagination |
| 74 | + page1_discussions = [ |
| 75 | + { |
| 76 | + "title": "Discussion 1", |
| 77 | + "url": "https://github.com/user/repo/discussions/1", |
| 78 | + "createdAt": "2021-01-01T00:00:00Z", |
| 79 | + "comments": {"nodes": [{"createdAt": "2021-01-01T00:01:00Z"}]}, |
| 80 | + "answerChosenAt": None, |
| 81 | + "closedAt": None, |
| 82 | + } |
| 83 | + ] |
| 84 | + |
| 85 | + page2_discussions = [ |
| 86 | + { |
| 87 | + "title": "Discussion 2", |
| 88 | + "url": "https://github.com/user/repo/discussions/2", |
| 89 | + "createdAt": "2021-01-02T00:00:00Z", |
| 90 | + "comments": {"nodes": [{"createdAt": "2021-01-02T00:01:00Z"}]}, |
| 91 | + "answerChosenAt": None, |
| 92 | + "closedAt": None, |
| 93 | + } |
| 94 | + ] |
75 | 95 |
|
76 |
| - This test mocks a failed GraphQL response and checks that the function raises a ValueError. |
| 96 | + # Configure mock to return different responses for each call |
| 97 | + mock_post.return_value.status_code = 200 |
| 98 | + mock_post.return_value.json.side_effect = [ |
| 99 | + self._create_mock_response( |
| 100 | + page1_discussions, has_next_page=True, end_cursor="cursor123" |
| 101 | + ), |
| 102 | + self._create_mock_response(page2_discussions, has_next_page=False), |
| 103 | + ] |
| 104 | + |
| 105 | + discussions = get_discussions( |
| 106 | + "token", "repo:user/repo type:discussions query", "" |
| 107 | + ) |
77 | 108 |
|
78 |
| - """ |
79 |
| - # Mock a failed GraphQL response |
| 109 | + # Check that all discussions were returned |
| 110 | + self.assertEqual(len(discussions), 2) |
| 111 | + self.assertEqual(discussions[0]["title"], "Discussion 1") |
| 112 | + self.assertEqual(discussions[1]["title"], "Discussion 2") |
| 113 | + |
| 114 | + # Verify that two API calls were made |
| 115 | + self.assertEqual(mock_post.call_count, 2) |
| 116 | + |
| 117 | + @patch("requests.post") |
| 118 | + def test_get_discussions_error_status_code(self, mock_post): |
| 119 | + """Test the get_discussions function with a failed HTTP response.""" |
80 | 120 | mock_post.return_value.status_code = 500
|
81 |
| - mock_ghe = "" |
82 | 121 |
|
83 |
| - # Call the function with mock arguments and check that it raises an error |
84 |
| - with self.assertRaises(ValueError): |
85 |
| - get_discussions("token", "repo:user/repo type:discussions query", mock_ghe) |
| 122 | + with self.assertRaises(ValueError) as context: |
| 123 | + get_discussions("token", "repo:user/repo type:discussions query", "") |
| 124 | + |
| 125 | + self.assertIn( |
| 126 | + "GraphQL query failed with status code 500", str(context.exception) |
| 127 | + ) |
| 128 | + |
| 129 | + @patch("requests.post") |
| 130 | + def test_get_discussions_graphql_error(self, mock_post): |
| 131 | + """Test the get_discussions function with GraphQL errors in response.""" |
| 132 | + mock_post.return_value.status_code = 200 |
| 133 | + mock_post.return_value.json.return_value = { |
| 134 | + "errors": [{"message": "GraphQL Error"}] |
| 135 | + } |
| 136 | + |
| 137 | + with self.assertRaises(ValueError) as context: |
| 138 | + get_discussions("token", "repo:user/repo type:discussions query", "") |
| 139 | + |
| 140 | + self.assertIn("GraphQL query failed:", str(context.exception)) |
0 commit comments