160 lines
4.3 KiB
Python
160 lines
4.3 KiB
Python
import pytest
|
|
from rest_framework.test import APIClient
|
|
|
|
from apps.notifications.services import store as services
|
|
from apps.notifications.services import RedisNotificationStore
|
|
from apps.notifications.tests.test_services import FakeRedis
|
|
from apps.users.models import User
|
|
from apps.workspaces.models import Workspace, WorkspaceMembership
|
|
|
|
|
|
@pytest.fixture()
|
|
def fake_redis(monkeypatch):
|
|
redis = FakeRedis()
|
|
monkeypatch.setattr(services, "redis_client", redis)
|
|
return redis
|
|
|
|
|
|
@pytest.fixture()
|
|
def api_client():
|
|
return APIClient()
|
|
|
|
|
|
def _create_user(index: int) -> User:
|
|
return User.objects.create_user(
|
|
mobile=f"091200000{index:02d}",
|
|
password="secret123",
|
|
first_name=f"User{index}",
|
|
)
|
|
|
|
|
|
def _notifications_for(user):
|
|
notifications, _ = RedisNotificationStore.list(
|
|
str(user.id),
|
|
paginate=False,
|
|
)
|
|
return notifications
|
|
|
|
|
|
@pytest.fixture()
|
|
def owner(db):
|
|
return _create_user(1)
|
|
|
|
|
|
@pytest.fixture()
|
|
def member(db):
|
|
return _create_user(2)
|
|
|
|
|
|
@pytest.fixture()
|
|
def another_member(db):
|
|
return _create_user(3)
|
|
|
|
|
|
@pytest.fixture()
|
|
def third_member(db):
|
|
return _create_user(4)
|
|
|
|
|
|
@pytest.fixture()
|
|
def fourth_member(db):
|
|
return _create_user(5)
|
|
|
|
|
|
def test_workspace_create_notifies_initial_members_not_owner(
|
|
fake_redis, api_client, owner, member
|
|
):
|
|
api_client.force_authenticate(user=owner)
|
|
|
|
response = api_client.post(
|
|
"/api/workspaces/",
|
|
{
|
|
"name": "Ops",
|
|
"description": "Workspace",
|
|
"members": [
|
|
{"user_id": str(member.id), "role": WorkspaceMembership.Role.ADMIN}
|
|
],
|
|
},
|
|
format="json",
|
|
)
|
|
|
|
assert response.status_code == 201
|
|
owner_notifications = _notifications_for(owner)
|
|
member_notifications = _notifications_for(member)
|
|
|
|
assert owner_notifications == []
|
|
assert len(member_notifications) == 1
|
|
assert member_notifications[0]["type"] == "workspace_membership_added"
|
|
assert member_notifications[0]["meta"]["workspace_name"] == "Ops"
|
|
assert member_notifications[0]["meta"]["new_role"] == WorkspaceMembership.Role.ADMIN
|
|
|
|
|
|
def test_workspace_membership_crud_emits_add_role_change_deactivate_and_remove(
|
|
fake_redis, api_client, owner, member
|
|
):
|
|
workspace = Workspace.objects.create(name="Design", description="", owner=owner)
|
|
api_client.force_authenticate(user=owner)
|
|
|
|
create_response = api_client.post(
|
|
"/api/workspace-memberships/",
|
|
{
|
|
"workspace": str(workspace.id),
|
|
"user": str(member.id),
|
|
"role": WorkspaceMembership.Role.MEMBER,
|
|
"is_active": True,
|
|
},
|
|
format="json",
|
|
)
|
|
assert create_response.status_code == 201
|
|
|
|
membership_id = create_response.data["id"]
|
|
notifications = _notifications_for(member)
|
|
assert [item["type"] for item in notifications] == ["workspace_membership_added"]
|
|
|
|
role_response = api_client.patch(
|
|
f"/api/workspace-memberships/{membership_id}/",
|
|
{"role": WorkspaceMembership.Role.ADMIN},
|
|
format="json",
|
|
)
|
|
assert role_response.status_code == 200
|
|
|
|
deactivate_response = api_client.patch(
|
|
f"/api/workspace-memberships/{membership_id}/",
|
|
{"is_active": False},
|
|
format="json",
|
|
)
|
|
assert deactivate_response.status_code == 200
|
|
|
|
remove_response = api_client.delete(f"/api/workspace-memberships/{membership_id}/")
|
|
assert remove_response.status_code == 204
|
|
|
|
notifications = _notifications_for(member)
|
|
assert [item["type"] for item in notifications] == [
|
|
"workspace_membership_removed",
|
|
"workspace_membership_deactivated",
|
|
"workspace_membership_role_changed",
|
|
"workspace_membership_added",
|
|
]
|
|
|
|
|
|
def test_workspace_membership_update_skips_self_notifications(
|
|
fake_redis, api_client, owner
|
|
):
|
|
workspace = Workspace.objects.create(name="Product", description="", owner=owner)
|
|
owner_membership = WorkspaceMembership.objects.get(
|
|
workspace=workspace,
|
|
user=owner,
|
|
is_deleted=False,
|
|
)
|
|
api_client.force_authenticate(user=owner)
|
|
|
|
response = api_client.patch(
|
|
f"/api/workspace-memberships/{owner_membership.id}/",
|
|
{"role": WorkspaceMembership.Role.OWNER},
|
|
format="json",
|
|
)
|
|
|
|
assert response.status_code == 403
|
|
assert _notifications_for(owner) == []
|
|
|