Files
meshcore-hub/tests/test_api/test_messages.py
2026-01-12 21:00:02 +00:00

186 lines
6.8 KiB
Python

"""Tests for message API routes."""
from datetime import datetime, timezone
class TestListMessages:
"""Tests for GET /messages endpoint."""
def test_list_messages_empty(self, client_no_auth):
"""Test listing messages when database is empty."""
response = client_no_auth.get("/api/v1/messages")
assert response.status_code == 200
data = response.json()
assert data["items"] == []
assert data["total"] == 0
def test_list_messages_with_data(self, client_no_auth, sample_message):
"""Test listing messages with data in database."""
response = client_no_auth.get("/api/v1/messages")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
assert data["total"] == 1
assert data["items"][0]["text"] == sample_message.text
assert data["items"][0]["message_type"] == sample_message.message_type
def test_list_messages_filter_by_type(self, client_no_auth, sample_message):
"""Test filtering messages by type."""
response = client_no_auth.get("/api/v1/messages?message_type=direct")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
response = client_no_auth.get("/api/v1/messages?message_type=channel")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 0
def test_list_messages_pagination(self, client_no_auth):
"""Test message list pagination parameters."""
response = client_no_auth.get("/api/v1/messages?limit=25&offset=10")
assert response.status_code == 200
data = response.json()
assert data["limit"] == 25
assert data["offset"] == 10
class TestGetMessage:
"""Tests for GET /messages/{id} endpoint."""
def test_get_message_success(self, client_no_auth, sample_message):
"""Test getting a specific message."""
response = client_no_auth.get(f"/api/v1/messages/{sample_message.id}")
assert response.status_code == 200
data = response.json()
assert data["text"] == sample_message.text
def test_get_message_not_found(self, client_no_auth):
"""Test getting a non-existent message."""
response = client_no_auth.get("/api/v1/messages/nonexistent-id")
assert response.status_code == 404
class TestListMessagesFilters:
"""Tests for message list query filters."""
def test_filter_by_pubkey_prefix(self, client_no_auth, sample_message):
"""Test filtering messages by pubkey_prefix."""
# Match
response = client_no_auth.get("/api/v1/messages?pubkey_prefix=abc123")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
# No match
response = client_no_auth.get("/api/v1/messages?pubkey_prefix=xyz999")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 0
def test_filter_by_channel_idx(
self, client_no_auth, sample_message, sample_message_with_receiver
):
"""Test filtering messages by channel_idx."""
# Channel 1 should match sample_message_with_receiver
response = client_no_auth.get("/api/v1/messages?channel_idx=1")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
assert data["items"][0]["channel_idx"] == 1
# Channel 0 should return no results
response = client_no_auth.get("/api/v1/messages?channel_idx=0")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 0
def test_filter_by_received_by(
self,
client_no_auth,
sample_message,
sample_message_with_receiver,
receiver_node,
):
"""Test filtering messages by receiver node."""
response = client_no_auth.get(
f"/api/v1/messages?received_by={receiver_node.public_key}"
)
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
assert data["items"][0]["text"] == sample_message_with_receiver.text
def test_filter_by_since(self, client_no_auth, api_db_session):
"""Test filtering messages by since timestamp."""
from datetime import timedelta
from meshcore_hub.common.models import Message
now = datetime.now(timezone.utc)
old_time = now - timedelta(days=7)
# Create an old message
old_msg = Message(
message_type="direct",
pubkey_prefix="old123",
text="Old message",
received_at=old_time,
)
api_db_session.add(old_msg)
api_db_session.commit()
# Filter since yesterday - should not include old message
since = (now - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%S")
response = client_no_auth.get(f"/api/v1/messages?since={since}")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 0
def test_filter_by_until(self, client_no_auth, api_db_session):
"""Test filtering messages by until timestamp."""
from datetime import timedelta
from meshcore_hub.common.models import Message
now = datetime.now(timezone.utc)
old_time = now - timedelta(days=7)
# Create an old message
old_msg = Message(
message_type="direct",
pubkey_prefix="old456",
text="Old message for until",
received_at=old_time,
)
api_db_session.add(old_msg)
api_db_session.commit()
# Filter until 5 days ago - should include old message
until = (now - timedelta(days=5)).strftime("%Y-%m-%dT%H:%M:%S")
response = client_no_auth.get(f"/api/v1/messages?until={until}")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
assert data["items"][0]["text"] == "Old message for until"
def test_filter_by_search(self, client_no_auth, sample_message):
"""Test filtering messages by text search."""
# Match
response = client_no_auth.get("/api/v1/messages?search=Hello")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
# Case insensitive match
response = client_no_auth.get("/api/v1/messages?search=hello")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
# No match
response = client_no_auth.get("/api/v1/messages?search=nonexistent")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 0