test(messages): cover 7-day edit window enforcement
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-03-08 20:26:21 +03:00
parent f6c686a343
commit f57e254bcc
3 changed files with 45 additions and 1 deletions

View File

@@ -978,6 +978,10 @@ Body:
Response: `200` + `MessageRead` Response: `200` + `MessageRead`
Errors:
- `403` - not message author or message is older than 7 days.
### DELETE `/api/v1/messages/{message_id}?for_all=false` ### DELETE `/api/v1/messages/{message_id}?for_all=false`
Auth required. Auth required.

View File

@@ -14,7 +14,7 @@ Legend:
5. Chat List - `DONE` (all/pinned/archive/sort/unread) 5. Chat List - `DONE` (all/pinned/archive/sort/unread)
6. Chat Types - `DONE` (private/group/channel) 6. Chat Types - `DONE` (private/group/channel)
7. Chat Creation - `DONE` (private/group/channel) 7. Chat Creation - `DONE` (private/group/channel)
8. Messages (base) - `DONE` (send/read/edit/delete/delete for all; group UI shows sender names over bubbles + sender avatars on incoming message clusters) 8. Messages (base) - `DONE` (send/read/edit/delete/delete for all; 7-day edit window enforced and covered by integration tests; group UI shows sender names over bubbles + sender avatars on incoming message clusters)
9. Message Types - `PARTIAL` (text/photo/video/docs/audio/voice/circle; GIF/stickers via dedicated system missing) 9. Message Types - `PARTIAL` (text/photo/video/docs/audio/voice/circle; GIF/stickers via dedicated system missing)
10. Reply/Quote/Threads - `PARTIAL` (reply + quote-like UI + thread panel with nested replies, no dedicated full thread navigation yet) 10. Reply/Quote/Threads - `PARTIAL` (reply + quote-like UI + thread panel with nested replies, no dedicated full thread navigation yet)
11. Forwarding - `DONE` (single + bulk + without author) 11. Forwarding - `DONE` (single + bulk + without author)

View File

@@ -1,7 +1,10 @@
from datetime import datetime, timedelta, timezone
from sqlalchemy import select from sqlalchemy import select
from app.auth.models import EmailVerificationToken from app.auth.models import EmailVerificationToken
from app.chats.models import ChatType from app.chats.models import ChatType
from app.messages.models import Message
async def _create_verified_user(client, db_session, email: str, username: str, password: str) -> dict: async def _create_verified_user(client, db_session, email: str, username: str, password: str) -> dict:
@@ -61,6 +64,43 @@ async def test_private_chat_message_lifecycle(client, db_session):
assert delete_message_response.status_code == 204 assert delete_message_response.status_code == 204
async def test_edit_message_older_than_7_days_is_forbidden(client, db_session):
u1 = await _create_verified_user(client, db_session, "edit_older_u1@example.com", "edit_older_u1", "strongpass123")
u2 = await _create_verified_user(client, db_session, "edit_older_u2@example.com", "edit_older_u2", "strongpass123")
me_u2 = await client.get("/api/v1/auth/me", headers={"Authorization": f"Bearer {u2['access_token']}"})
u2_id = me_u2.json()["id"]
create_chat_response = await client.post(
"/api/v1/chats",
headers={"Authorization": f"Bearer {u1['access_token']}"},
json={"type": ChatType.PRIVATE.value, "title": None, "member_ids": [u2_id]},
)
assert create_chat_response.status_code == 200
chat_id = create_chat_response.json()["id"]
send_message_response = await client.post(
"/api/v1/messages",
headers={"Authorization": f"Bearer {u1['access_token']}"},
json={"chat_id": chat_id, "type": "text", "text": "original"},
)
assert send_message_response.status_code == 201
message_id = send_message_response.json()["id"]
message_row = await db_session.execute(select(Message).where(Message.id == message_id))
message = message_row.scalar_one()
message.created_at = datetime.now(timezone.utc) - timedelta(days=8)
await db_session.commit()
edit_message_response = await client.put(
f"/api/v1/messages/{message_id}",
headers={"Authorization": f"Bearer {u1['access_token']}"},
json={"text": "edited text"},
)
assert edit_message_response.status_code == 403
assert "7 days" in edit_message_response.json().get("detail", "")
async def test_private_chat_respects_contacts_only_policy(client, db_session): async def test_private_chat_respects_contacts_only_policy(client, db_session):
u1 = await _create_verified_user(client, db_session, "pm_u1@example.com", "pm_user_one", "strongpass123") u1 = await _create_verified_user(client, db_session, "pm_u1@example.com", "pm_user_one", "strongpass123")
u2 = await _create_verified_user(client, db_session, "pm_u2@example.com", "pm_user_two", "strongpass123") u2 = await _create_verified_user(client, db_session, "pm_u2@example.com", "pm_user_two", "strongpass123")