github_helpers_test.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. """Tests for github_helpers.py."""
  2. __copyright__ = """
  3. Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  4. Exceptions. See /LICENSE for license information.
  5. SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. """
  7. import unittest
  8. from unittest import mock
  9. import github_helpers
  10. _TEST_QUERY = """
  11. query {
  12. top(login: "foo") {
  13. child(first: 100%(cursor)s) {
  14. nodes {
  15. login
  16. }
  17. %(pagination)s
  18. }
  19. }
  20. }
  21. """
  22. _TEST_QUERY_PATH = ("top", "child")
  23. _EXP_QUERY_FIRST_PAGE = """
  24. query {
  25. top(login: "foo") {
  26. child(first: 100) {
  27. nodes {
  28. login
  29. }
  30. pageInfo {
  31. hasNextPage
  32. endCursor
  33. }
  34. totalCount
  35. }
  36. }
  37. }
  38. """
  39. _EXP_QUERY_SECOND_PAGE = """
  40. query {
  41. top(login: "foo") {
  42. child(first: 100 after: "CURSOR") {
  43. nodes {
  44. login
  45. }
  46. pageInfo {
  47. hasNextPage
  48. endCursor
  49. }
  50. totalCount
  51. }
  52. }
  53. }
  54. """
  55. class TestGithubHelpers(unittest.TestCase):
  56. def setUp(self):
  57. patcher = mock.patch.object(
  58. github_helpers.Client, "__init__", lambda self, parsed_args: None
  59. )
  60. self.addCleanup(patcher.stop)
  61. patcher.start()
  62. self.client = github_helpers.Client(None)
  63. @staticmethod
  64. def mock_result(nodes, total_count=None, has_next_page=False):
  65. if total_count is None:
  66. total_count = len(nodes)
  67. end_cursor = None
  68. if has_next_page:
  69. end_cursor = "CURSOR"
  70. return {
  71. "top": {
  72. "child": {
  73. "nodes": nodes,
  74. "pageInfo": {
  75. "hasNextPage": has_next_page,
  76. "endCursor": end_cursor,
  77. },
  78. "totalCount": total_count,
  79. }
  80. }
  81. }
  82. def test_execute_and_paginate_empty(self):
  83. self.client.execute = mock.MagicMock(return_value=self.mock_result([]))
  84. self.assertEqual(
  85. list(
  86. self.client.execute_and_paginate(_TEST_QUERY, _TEST_QUERY_PATH)
  87. ),
  88. [],
  89. )
  90. self.client.execute.assert_called_once_with(_EXP_QUERY_FIRST_PAGE)
  91. def test_execute_and_paginate_one_page(self):
  92. self.client.execute = mock.MagicMock(
  93. return_value=self.mock_result(["foo", "bar", "baz"])
  94. )
  95. self.assertEqual(
  96. list(
  97. self.client.execute_and_paginate(_TEST_QUERY, _TEST_QUERY_PATH)
  98. ),
  99. ["foo", "bar", "baz"],
  100. )
  101. self.client.execute.assert_called_once_with(_EXP_QUERY_FIRST_PAGE)
  102. def test_execute_and_paginate_one_page_count_mismatch(self):
  103. self.client.execute = mock.MagicMock(
  104. return_value=self.mock_result(["foo"], total_count=2),
  105. )
  106. self.assertRaises(
  107. AssertionError,
  108. list,
  109. self.client.execute_and_paginate(_TEST_QUERY, _TEST_QUERY_PATH),
  110. )
  111. self.client.execute.assert_called_once_with(_EXP_QUERY_FIRST_PAGE)
  112. def test_execute_and_paginate_two_page(self):
  113. def paging(query):
  114. if query == _EXP_QUERY_FIRST_PAGE:
  115. return self.mock_result(
  116. ["foo", "bar"], total_count=3, has_next_page=True
  117. )
  118. elif query == _EXP_QUERY_SECOND_PAGE:
  119. return self.mock_result(["baz"], total_count="unused")
  120. else:
  121. raise ValueError("Bad query: %s" % query)
  122. self.client.execute = mock.MagicMock(side_effect=paging)
  123. self.assertEqual(
  124. list(
  125. self.client.execute_and_paginate(_TEST_QUERY, _TEST_QUERY_PATH)
  126. ),
  127. ["foo", "bar", "baz"],
  128. )
  129. self.assertEqual(self.client.execute.call_count, 2)
  130. def test_execute_and_paginate_first_page_done(self):
  131. self.client.execute = mock.MagicMock()
  132. self.assertEqual(
  133. list(
  134. self.client.execute_and_paginate(
  135. _TEST_QUERY,
  136. _TEST_QUERY_PATH,
  137. first_page=self.mock_result(["foo"]),
  138. )
  139. ),
  140. ["foo"],
  141. )
  142. self.assertEqual(self.client.execute.call_count, 0)
  143. def test_execute_and_paginate_first_page_continue(self):
  144. self.client.execute = mock.MagicMock(
  145. return_value=self.mock_result(["bar"], total_count="unused")
  146. )
  147. self.assertEqual(
  148. list(
  149. self.client.execute_and_paginate(
  150. _TEST_QUERY,
  151. _TEST_QUERY_PATH,
  152. first_page=self.mock_result(
  153. ["foo"], total_count=2, has_next_page=True
  154. ),
  155. )
  156. ),
  157. ["foo", "bar"],
  158. )
  159. self.client.execute.assert_called_once_with(_EXP_QUERY_SECOND_PAGE)
  160. if __name__ == "__main__":
  161. unittest.main()