✅(pytest) fail on tests external calls
The backend tests must not try to call the real world.
This commit is contained in:
30
src/backend/conftest.py
Normal file
30
src/backend/conftest.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
"""Global fixtures for the backend tests."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from urllib3.connectionpool import HTTPConnectionPool
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def no_http_requests(monkeypatch):
|
||||||
|
"""
|
||||||
|
Prevents HTTP requests from being made during tests.
|
||||||
|
This is useful for tests that do not require actual HTTP requests
|
||||||
|
and helps to avoid network-related issues.
|
||||||
|
|
||||||
|
Credits: https://blog.jerrycodes.com/no-http-requests/
|
||||||
|
"""
|
||||||
|
|
||||||
|
allowed_hosts = {"localhost"}
|
||||||
|
original_urlopen = HTTPConnectionPool.urlopen
|
||||||
|
|
||||||
|
def urlopen_mock(self, method, url, *args, **kwargs):
|
||||||
|
if self.host in allowed_hosts:
|
||||||
|
return original_urlopen(self, method, url, *args, **kwargs)
|
||||||
|
|
||||||
|
raise RuntimeError(
|
||||||
|
f"The test was about to {method} {self.scheme}://{self.host}{url}"
|
||||||
|
)
|
||||||
|
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"urllib3.connectionpool.HTTPConnectionPool.urlopen", urlopen_mock
|
||||||
|
)
|
||||||
@@ -4,7 +4,6 @@ Test for team accesses API endpoints in People's core app : delete
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
import re
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import responses
|
import responses
|
||||||
@@ -157,16 +156,18 @@ def test_api_team_accesses_delete_owners_last_owner():
|
|||||||
assert models.TeamAccess.objects.count() == 1
|
assert models.TeamAccess.objects.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
@responses.activate
|
||||||
def test_api_team_accesses_delete_webhook():
|
def test_api_team_accesses_delete_webhook():
|
||||||
"""
|
"""
|
||||||
When the team has a webhook, deleting a team access should fire a call.
|
When the team has a webhook, deleting a team access should fire a call.
|
||||||
"""
|
"""
|
||||||
user = factories.UserFactory()
|
user = factories.UserFactory()
|
||||||
team = factories.TeamFactory(users=[(user, "administrator")])
|
team = factories.TeamFactory(users=[(user, "administrator")])
|
||||||
webhook = factories.TeamWebhookFactory(team=team)
|
|
||||||
access = factories.TeamAccessFactory(
|
access = factories.TeamAccessFactory(
|
||||||
team=team, role=random.choice(["member", "administrator"])
|
team=team, role=random.choice(["member", "administrator"])
|
||||||
)
|
)
|
||||||
|
# add webhook after access to prevent webhook from being triggered
|
||||||
|
webhook = factories.TeamWebhookFactory(team=team)
|
||||||
|
|
||||||
assert models.TeamAccess.objects.count() == 2
|
assert models.TeamAccess.objects.count() == 2
|
||||||
assert models.TeamAccess.objects.filter(user=access.user).exists()
|
assert models.TeamAccess.objects.filter(user=access.user).exists()
|
||||||
@@ -174,42 +175,34 @@ def test_api_team_accesses_delete_webhook():
|
|||||||
client = APIClient()
|
client = APIClient()
|
||||||
client.force_login(user)
|
client.force_login(user)
|
||||||
|
|
||||||
with responses.RequestsMock() as rsps:
|
patch_response = responses.patch(webhook.url, status=200, json={})
|
||||||
# Ensure successful response by scim provider using "responses":
|
|
||||||
rsp = rsps.add(
|
|
||||||
rsps.PATCH,
|
|
||||||
re.compile(r".*/Groups/.*"),
|
|
||||||
body="{}",
|
|
||||||
status=200,
|
|
||||||
content_type="application/json",
|
|
||||||
)
|
|
||||||
|
|
||||||
response = client.delete(
|
response = client.delete(
|
||||||
f"/api/v1.0/teams/{team.id!s}/accesses/{access.id!s}/",
|
f"/api/v1.0/teams/{team.id!s}/accesses/{access.id!s}/",
|
||||||
)
|
)
|
||||||
assert response.status_code == 204
|
assert response.status_code == 204
|
||||||
|
|
||||||
assert rsp.call_count == 1
|
# Check the request was made
|
||||||
assert rsps.calls[0].request.url == webhook.url
|
assert patch_response.call_count == 1
|
||||||
|
|
||||||
# Payload sent to scim provider
|
# Payload sent to scim provider
|
||||||
payload = json.loads(rsps.calls[0].request.body)
|
scim_payload = json.loads(patch_response.calls[0].request.body)
|
||||||
assert payload == {
|
assert scim_payload == {
|
||||||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
||||||
"Operations": [
|
"Operations": [
|
||||||
{
|
{
|
||||||
"op": "remove",
|
"op": "remove",
|
||||||
"path": "members",
|
"path": "members",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"value": str(access.user.id),
|
"value": str(access.user.id),
|
||||||
"email": access.user.email,
|
"email": access.user.email,
|
||||||
"type": "User",
|
"type": "User",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
assert models.TeamAccess.objects.count() == 1
|
assert models.TeamAccess.objects.count() == 1
|
||||||
assert models.TeamAccess.objects.filter(user=access.user).exists() is False
|
assert models.TeamAccess.objects.filter(user=access.user).exists() is False
|
||||||
|
|||||||
@@ -83,47 +83,41 @@ def test_models_team_accesses_create_webhook():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@responses.activate
|
||||||
def test_models_team_accesses_delete_webhook():
|
def test_models_team_accesses_delete_webhook():
|
||||||
"""
|
"""
|
||||||
When the team has a webhook, deleting a team access should fire a call.
|
When the team has a webhook, deleting a team access should fire a call.
|
||||||
"""
|
"""
|
||||||
team = factories.TeamFactory()
|
team = factories.TeamFactory()
|
||||||
webhook = factories.TeamWebhookFactory(team=team)
|
|
||||||
access = factories.TeamAccessFactory(team=team)
|
access = factories.TeamAccessFactory(team=team)
|
||||||
|
# add webhook after access to prevent webhook from being triggered
|
||||||
|
webhook = factories.TeamWebhookFactory(team=team)
|
||||||
|
|
||||||
with responses.RequestsMock() as rsps:
|
# Ensure successful response by scim provider using "responses":
|
||||||
# Ensure successful response by scim provider using "responses":
|
rsp = responses.patch(webhook.url, status=200, json={})
|
||||||
rsp = rsps.add(
|
|
||||||
rsps.PATCH,
|
|
||||||
re.compile(r".*/Groups/.*"),
|
|
||||||
body="{}",
|
|
||||||
status=200,
|
|
||||||
content_type="application/json",
|
|
||||||
)
|
|
||||||
|
|
||||||
access.delete()
|
access.delete()
|
||||||
|
|
||||||
assert rsp.call_count == 1
|
assert rsp.call_count == 1
|
||||||
assert rsps.calls[0].request.url == webhook.url
|
|
||||||
|
|
||||||
# Payload sent to scim provider
|
# Payload sent to scim provider
|
||||||
payload = json.loads(rsps.calls[0].request.body)
|
payload = json.loads(rsp.calls[0].request.body)
|
||||||
assert payload == {
|
assert payload == {
|
||||||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
||||||
"Operations": [
|
"Operations": [
|
||||||
{
|
{
|
||||||
"op": "remove",
|
"op": "remove",
|
||||||
"path": "members",
|
"path": "members",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"value": str(access.user.id),
|
"value": str(access.user.id),
|
||||||
"email": access.user.email,
|
"email": access.user.email,
|
||||||
"type": "User",
|
"type": "User",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
assert models.TeamAccess.objects.exists() is False
|
assert models.TeamAccess.objects.exists() is False
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user