You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
7.0 KiB

  1. from django.test.utils import override_settings
  2. from hc.api.models import Channel, Check
  3. from hc.test import BaseTestCase
  4. class AddWebhookTestCase(BaseTestCase):
  5. def setUp(self):
  6. super().setUp()
  7. self.check = Check.objects.create(project=self.project)
  8. self.url = f"/projects/{self.project.code}/add_webhook/"
  9. def test_instructions_work(self):
  10. self.client.login(username="[email protected]", password="password")
  11. r = self.client.get(self.url)
  12. self.assertContains(r, "Executes an HTTP request")
  13. def test_it_saves_name(self):
  14. form = {
  15. "name": "Call foo.com",
  16. "method_down": "GET",
  17. "url_down": "http://foo.com",
  18. "method_up": "GET",
  19. "url_up": "",
  20. }
  21. self.client.login(username="[email protected]", password="password")
  22. r = self.client.post(self.url, form)
  23. self.assertRedirects(r, self.channels_url)
  24. c = Channel.objects.get()
  25. self.assertEqual(c.name, "Call foo.com")
  26. # Make sure it calls assign_all_checks
  27. self.assertEqual(c.checks.count(), 1)
  28. def test_it_adds_two_webhook_urls_and_redirects(self):
  29. form = {
  30. "method_down": "GET",
  31. "url_down": "http://foo.com",
  32. "method_up": "GET",
  33. "url_up": "https://bar.com",
  34. }
  35. self.client.login(username="[email protected]", password="password")
  36. r = self.client.post(self.url, form)
  37. self.assertRedirects(r, self.channels_url)
  38. c = Channel.objects.get()
  39. self.assertEqual(c.project, self.project)
  40. self.assertEqual(c.down_webhook_spec["url"], "http://foo.com")
  41. self.assertEqual(c.up_webhook_spec["url"], "https://bar.com")
  42. def test_it_adds_webhook_using_team_access(self):
  43. form = {
  44. "method_down": "GET",
  45. "url_down": "http://foo.com",
  46. "method_up": "GET",
  47. "url_up": "https://bar.com",
  48. }
  49. # Logging in as bob, not alice. Bob has team access so this
  50. # should work.
  51. self.client.login(username="[email protected]", password="password")
  52. self.client.post(self.url, form)
  53. c = Channel.objects.get()
  54. self.assertEqual(c.project, self.project)
  55. self.assertEqual(c.down_webhook_spec["url"], "http://foo.com")
  56. self.assertEqual(c.up_webhook_spec["url"], "https://bar.com")
  57. def test_it_rejects_bad_urls(self):
  58. urls = [
  59. # clearly not an URL
  60. "foo",
  61. # FTP addresses not allowed
  62. "ftp://example.org",
  63. # no loopback
  64. "http://localhost:1234/endpoint",
  65. "http://127.0.0.1/endpoint",
  66. ]
  67. self.client.login(username="[email protected]", password="password")
  68. for url in urls:
  69. form = {
  70. "method_down": "GET",
  71. "url_down": url,
  72. "method_up": "GET",
  73. "url_up": "",
  74. }
  75. r = self.client.post(self.url, form)
  76. self.assertContains(r, "Enter a valid URL.", msg_prefix=url)
  77. self.assertEqual(Channel.objects.count(), 0)
  78. def test_it_handles_empty_down_url(self):
  79. form = {
  80. "method_down": "GET",
  81. "url_down": "",
  82. "method_up": "GET",
  83. "url_up": "http://foo.com",
  84. }
  85. self.client.login(username="[email protected]", password="password")
  86. self.client.post(self.url, form)
  87. c = Channel.objects.get()
  88. self.assertEqual(c.down_webhook_spec["url"], "")
  89. self.assertEqual(c.up_webhook_spec["url"], "http://foo.com")
  90. def test_it_adds_request_body(self):
  91. form = {
  92. "method_down": "POST",
  93. "url_down": "http://foo.com",
  94. "body_down": "hello",
  95. "method_up": "GET",
  96. }
  97. self.client.login(username="[email protected]", password="password")
  98. r = self.client.post(self.url, form)
  99. self.assertRedirects(r, self.channels_url)
  100. c = Channel.objects.get()
  101. self.assertEqual(c.down_webhook_spec["body"], "hello")
  102. def test_it_adds_headers(self):
  103. form = {
  104. "method_down": "GET",
  105. "url_down": "http://foo.com",
  106. "headers_down": "test:123\ntest2:abc",
  107. "method_up": "GET",
  108. }
  109. self.client.login(username="[email protected]", password="password")
  110. r = self.client.post(self.url, form)
  111. self.assertRedirects(r, self.channels_url)
  112. c = Channel.objects.get()
  113. self.assertEqual(
  114. c.down_webhook_spec["headers"], {"test": "123", "test2": "abc"}
  115. )
  116. def test_it_rejects_bad_headers(self):
  117. self.client.login(username="[email protected]", password="password")
  118. form = {
  119. "method_down": "GET",
  120. "url_down": "http://example.org",
  121. "headers_down": "invalid-header\nfoo:bar",
  122. "method_up": "GET",
  123. }
  124. r = self.client.post(self.url, form)
  125. self.assertContains(r, """invalid-header""")
  126. self.assertEqual(Channel.objects.count(), 0)
  127. def test_it_rejects_non_latin1_in_header_name(self):
  128. self.client.login(username="[email protected]", password="password")
  129. form = {
  130. "method_down": "GET",
  131. "url_down": "http://example.org",
  132. "headers_down": "fō:bar",
  133. "method_up": "GET",
  134. }
  135. r = self.client.post(self.url, form)
  136. self.assertContains(r, """must not contain special characters""")
  137. self.assertEqual(Channel.objects.count(), 0)
  138. def test_it_strips_headers(self):
  139. form = {
  140. "method_down": "GET",
  141. "url_down": "http://foo.com",
  142. "headers_down": " test : 123 ",
  143. "method_up": "GET",
  144. }
  145. self.client.login(username="[email protected]", password="password")
  146. r = self.client.post(self.url, form)
  147. self.assertRedirects(r, self.channels_url)
  148. c = Channel.objects.get()
  149. self.assertEqual(c.down_webhook_spec["headers"], {"test": "123"})
  150. def test_it_rejects_both_empty(self):
  151. self.client.login(username="[email protected]", password="password")
  152. form = {
  153. "method_down": "GET",
  154. "url_down": "",
  155. "method_up": "GET",
  156. "url_up": "",
  157. }
  158. r = self.client.post(self.url, form)
  159. self.assertContains(r, "Enter a valid URL.")
  160. self.assertEqual(Channel.objects.count(), 0)
  161. def test_it_requires_rw_access(self):
  162. self.bobs_membership.role = "r"
  163. self.bobs_membership.save()
  164. self.client.login(username="[email protected]", password="password")
  165. r = self.client.get(self.url)
  166. self.assertEqual(r.status_code, 403)
  167. @override_settings(WEBHOOKS_ENABLED=False)
  168. def test_it_handles_disabled_integration(self):
  169. self.client.login(username="[email protected]", password="password")
  170. r = self.client.get(self.url)
  171. self.assertEqual(r.status_code, 404)