Skip to content

Commit 16e6a28

Browse files
authored
chore: Convert webhooks webhooks TestCase to normal test function (#3374)
1 parent 2d78b88 commit 16e6a28

File tree

1 file changed

+133
-130
lines changed

1 file changed

+133
-130
lines changed

api/tests/unit/webhooks/test_unit_webhooks.py

+133-130
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import hmac
33
import json
44
from typing import Type
5-
from unittest import TestCase, mock
5+
from unittest import mock
6+
from unittest.mock import MagicMock
67

78
import pytest
89
import responses
@@ -13,7 +14,6 @@
1314

1415
from environments.models import Environment, Webhook
1516
from organisations.models import Organisation, OrganisationWebhook
16-
from projects.models import Project
1717
from webhooks.sample_webhook_data import (
1818
environment_webhook_data,
1919
organisation_webhook_data,
@@ -29,134 +29,137 @@
2929
)
3030

3131

32-
@pytest.mark.django_db
33-
class WebhooksTestCase(TestCase):
34-
def setUp(self) -> None:
35-
organisation = Organisation.objects.create(name="Test organisation")
36-
project = Project.objects.create(name="Test project", organisation=organisation)
37-
self.environment = Environment.objects.create(
38-
name="Test environment", project=project
39-
)
40-
41-
@mock.patch("webhooks.webhooks.requests")
42-
def test_requests_made_to_all_urls_for_environment(self, mock_requests):
43-
# Given
44-
webhook_1 = Webhook.objects.create(
45-
url="http://url.1.com", enabled=True, environment=self.environment
46-
)
47-
webhook_2 = Webhook.objects.create(
48-
url="http://url.2.com", enabled=True, environment=self.environment
49-
)
50-
51-
# When
52-
call_environment_webhooks(
53-
environment_id=self.environment.id,
54-
data={},
55-
event_type=WebhookEventType.FLAG_UPDATED.value,
56-
)
57-
58-
# Then
59-
assert len(mock_requests.post.call_args_list) == 2
60-
61-
# and
62-
call_1_args, _ = mock_requests.post.call_args_list[0]
63-
call_2_args, _ = mock_requests.post.call_args_list[1]
64-
all_call_args = call_1_args + call_2_args
65-
assert all(
66-
str(webhook.url) in all_call_args for webhook in (webhook_1, webhook_2)
67-
)
68-
69-
@mock.patch("webhooks.webhooks.requests")
70-
def test_request_not_made_to_disabled_webhook(self, mock_requests):
71-
# Given
72-
Webhook.objects.create(
73-
url="http://url.1.com", enabled=False, environment=self.environment
74-
)
75-
76-
# When
77-
call_environment_webhooks(
78-
environment_id=self.environment.id,
79-
data={},
80-
event_type=WebhookEventType.FLAG_UPDATED.value,
81-
)
82-
83-
# Then
84-
mock_requests.post.assert_not_called()
85-
86-
@mock.patch("webhooks.webhooks.requests")
87-
def test_trigger_sample_webhook_makes_correct_post_request_for_environment(
88-
self, mock_request
89-
):
90-
url = "http://test.test"
91-
webhook = Webhook(url=url)
92-
trigger_sample_webhook(webhook, WebhookType.ENVIRONMENT)
93-
args, kwargs = mock_request.post.call_args
94-
assert json.loads(kwargs["data"]) == environment_webhook_data
95-
assert args[0] == url
96-
97-
@mock.patch("webhooks.webhooks.requests")
98-
def test_trigger_sample_webhook_makes_correct_post_request_for_organisation(
99-
self, mock_request
100-
):
101-
url = "http://test.test"
102-
webhook = OrganisationWebhook(url=url)
103-
104-
trigger_sample_webhook(webhook, WebhookType.ORGANISATION)
105-
args, kwargs = mock_request.post.call_args
106-
assert json.loads(kwargs["data"]) == organisation_webhook_data
107-
assert args[0] == url
108-
109-
@mock.patch("webhooks.webhooks.WebhookSerializer")
110-
@mock.patch("webhooks.webhooks.requests")
111-
def test_request_made_with_correct_signature(
112-
self, mock_requests, webhook_serializer
113-
):
114-
# Given
115-
payload = {"key": "value"}
116-
webhook_serializer.return_value.data = payload
117-
secret = "random_key"
118-
Webhook.objects.create(
119-
url="http://url.1.com",
120-
enabled=True,
121-
environment=self.environment,
122-
secret=secret,
123-
)
124-
125-
expected_signature = hmac.new(
126-
key=secret.encode(),
127-
msg=json.dumps(payload).encode(),
128-
digestmod=hashlib.sha256,
129-
).hexdigest()
130-
131-
call_environment_webhooks(
132-
environment_id=self.environment.id,
133-
data={},
134-
event_type=WebhookEventType.FLAG_UPDATED.value,
135-
)
136-
# When
137-
_, kwargs = mock_requests.post.call_args_list[0]
138-
# Then
139-
received_signature = kwargs["headers"][FLAGSMITH_SIGNATURE_HEADER]
140-
assert hmac.compare_digest(expected_signature, received_signature) is True
141-
142-
@mock.patch("webhooks.webhooks.requests")
143-
def test_request_does_not_have_signature_header_if_secret_is_not_set(
144-
self, mock_requests
145-
):
146-
# Given
147-
Webhook.objects.create(
148-
url="http://url.1.com", enabled=True, environment=self.environment
149-
)
150-
# When
151-
call_environment_webhooks(
152-
environment_id=self.environment.id,
153-
data={},
154-
event_type=WebhookEventType.FLAG_UPDATED.value,
155-
)
156-
157-
# Then
158-
_, kwargs = mock_requests.post.call_args_list[0]
159-
assert FLAGSMITH_SIGNATURE_HEADER not in kwargs["headers"]
32+
@mock.patch("webhooks.webhooks.requests")
33+
def test_webhooks_requests_made_to_all_urls_for_environment(
34+
mock_requests: MagicMock,
35+
environment: Environment,
36+
) -> None:
37+
# Given
38+
webhook_1 = Webhook.objects.create(
39+
url="http://url.1.com", enabled=True, environment=environment
40+
)
41+
webhook_2 = Webhook.objects.create(
42+
url="http://url.2.com", enabled=True, environment=environment
43+
)
44+
45+
# When
46+
call_environment_webhooks(
47+
environment_id=environment.id,
48+
data={},
49+
event_type=WebhookEventType.FLAG_UPDATED.value,
50+
)
51+
52+
# Then
53+
assert len(mock_requests.post.call_args_list) == 2
54+
55+
# and
56+
call_1_args, _ = mock_requests.post.call_args_list[0]
57+
call_2_args, _ = mock_requests.post.call_args_list[1]
58+
all_call_args = call_1_args + call_2_args
59+
assert all(str(webhook.url) in all_call_args for webhook in (webhook_1, webhook_2))
60+
61+
62+
@mock.patch("webhooks.webhooks.requests")
63+
def test_webhooks_request_not_made_to_disabled_webhook(
64+
mock_requests: MagicMock,
65+
environment: Environment,
66+
) -> None:
67+
# Given
68+
Webhook.objects.create(
69+
url="http://url.1.com", enabled=False, environment=environment
70+
)
71+
72+
# When
73+
call_environment_webhooks(
74+
environment_id=environment.id,
75+
data={},
76+
event_type=WebhookEventType.FLAG_UPDATED.value,
77+
)
78+
79+
# Then
80+
mock_requests.post.assert_not_called()
81+
82+
83+
@mock.patch("webhooks.webhooks.requests")
84+
def test_trigger_sample_webhook_makes_correct_post_request_for_environment(
85+
mock_request: MagicMock,
86+
) -> None:
87+
url = "http://test.test"
88+
webhook = Webhook(url=url)
89+
trigger_sample_webhook(webhook, WebhookType.ENVIRONMENT)
90+
args, kwargs = mock_request.post.call_args
91+
assert json.loads(kwargs["data"]) == environment_webhook_data
92+
assert args[0] == url
93+
94+
95+
@mock.patch("webhooks.webhooks.requests")
96+
def test_trigger_sample_webhook_makes_correct_post_request_for_organisation(
97+
mock_request: MagicMock,
98+
) -> None:
99+
url = "http://test.test"
100+
webhook = OrganisationWebhook(url=url)
101+
102+
trigger_sample_webhook(webhook, WebhookType.ORGANISATION)
103+
args, kwargs = mock_request.post.call_args
104+
assert json.loads(kwargs["data"]) == organisation_webhook_data
105+
assert args[0] == url
106+
107+
108+
@mock.patch("webhooks.webhooks.WebhookSerializer")
109+
@mock.patch("webhooks.webhooks.requests")
110+
def test_request_made_with_correct_signature(
111+
mock_requests: MagicMock,
112+
webhook_serializer: MagicMock,
113+
environment: Environment,
114+
) -> None:
115+
# Given
116+
payload = {"key": "value"}
117+
webhook_serializer.return_value.data = payload
118+
secret = "random_key"
119+
Webhook.objects.create(
120+
url="http://url.1.com",
121+
enabled=True,
122+
environment=environment,
123+
secret=secret,
124+
)
125+
126+
expected_signature = hmac.new(
127+
key=secret.encode(),
128+
msg=json.dumps(payload).encode(),
129+
digestmod=hashlib.sha256,
130+
).hexdigest()
131+
132+
call_environment_webhooks(
133+
environment_id=environment.id,
134+
data={},
135+
event_type=WebhookEventType.FLAG_UPDATED.value,
136+
)
137+
# When
138+
_, kwargs = mock_requests.post.call_args_list[0]
139+
# Then
140+
received_signature = kwargs["headers"][FLAGSMITH_SIGNATURE_HEADER]
141+
assert hmac.compare_digest(expected_signature, received_signature) is True
142+
143+
144+
@mock.patch("webhooks.webhooks.requests")
145+
def test_request_does_not_have_signature_header_if_secret_is_not_set(
146+
mock_requests: MagicMock,
147+
environment: Environment,
148+
) -> None:
149+
# Given
150+
Webhook.objects.create(
151+
url="http://url.1.com", enabled=True, environment=environment
152+
)
153+
# When
154+
call_environment_webhooks(
155+
environment_id=environment.id,
156+
data={},
157+
event_type=WebhookEventType.FLAG_UPDATED.value,
158+
)
159+
160+
# Then
161+
_, kwargs = mock_requests.post.call_args_list[0]
162+
assert FLAGSMITH_SIGNATURE_HEADER not in kwargs["headers"]
160163

161164

162165
@pytest.mark.parametrize("expected_error", [ConnectionError, Timeout])

0 commit comments

Comments
 (0)