mirror of
https://github.com/tanrax/org-social-relay
synced 2026-01-09 22:53:32 +01:00
271 lines
10 KiB
Python
271 lines
10 KiB
Python
from django.test import TestCase, override_settings
|
|
from rest_framework.test import APIClient
|
|
from rest_framework import status
|
|
|
|
from app.feeds.models import Profile, Post
|
|
|
|
|
|
class GroupsViewTest(TestCase):
|
|
"""Test cases for the GroupsView API."""
|
|
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
self.groups_url = "/groups/"
|
|
|
|
@override_settings(ENABLED_GROUPS=[], GROUPS_MAP={})
|
|
def test_no_groups_configured(self):
|
|
"""Test GET /groups/ when no groups are configured."""
|
|
# Given: No groups configured
|
|
|
|
# When: We request groups list
|
|
response = self.client.get(self.groups_url)
|
|
|
|
# Then: Should return 404 with error message
|
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
|
self.assertEqual(response.data["type"], "Error")
|
|
self.assertIn("No groups configured", response.data["errors"][0])
|
|
|
|
@override_settings(
|
|
ENABLED_GROUPS=["emacs", "org-social", "python"],
|
|
GROUPS_MAP={"emacs": "Emacs", "org-social": "Org Social", "python": "Python"},
|
|
)
|
|
def test_list_groups_success(self):
|
|
"""Test GET /groups/ returns configured groups."""
|
|
# Given: Groups configured
|
|
|
|
# When: We request groups list
|
|
response = self.client.get(self.groups_url)
|
|
|
|
# Then: Should return success with group display names
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(response.data["type"], "Success")
|
|
self.assertEqual(len(response.data["data"]), 3)
|
|
# Data should contain display names, not slugs
|
|
self.assertIn("Emacs", response.data["data"])
|
|
self.assertIn("Org Social", response.data["data"])
|
|
self.assertIn("Python", response.data["data"])
|
|
|
|
@override_settings(
|
|
ENABLED_GROUPS=["emacs", "org-social"],
|
|
GROUPS_MAP={"emacs": "Emacs", "org-social": "Org Social"},
|
|
)
|
|
def test_list_groups_empty_groups(self):
|
|
"""Test GET /groups/ when groups are configured."""
|
|
# Given: Groups configured
|
|
|
|
# When: We request groups list
|
|
response = self.client.get(self.groups_url)
|
|
|
|
# Then: Should return group display names
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(response.data["type"], "Success")
|
|
self.assertEqual(len(response.data["data"]), 2)
|
|
self.assertIn("Emacs", response.data["data"])
|
|
self.assertIn("Org Social", response.data["data"])
|
|
|
|
|
|
class GroupMessagesViewTest(TestCase):
|
|
"""Test cases for the GroupMessagesView API."""
|
|
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
|
|
# Create test profiles
|
|
self.profile1 = Profile.objects.create(
|
|
feed="https://example.com/social.org", nick="user1"
|
|
)
|
|
self.profile2 = Profile.objects.create(
|
|
feed="https://test.com/social.org", nick="user2"
|
|
)
|
|
|
|
@override_settings(
|
|
ENABLED_GROUPS=["emacs", "python"],
|
|
GROUPS_MAP={"emacs": "Emacs", "python": "Python"},
|
|
)
|
|
def test_get_group_messages_success(self):
|
|
"""Test GET /groups/{id}/ returns group messages."""
|
|
# Given: Posts with group metadata (using slugs)
|
|
Post.objects.create(
|
|
profile=self.profile1,
|
|
post_id="2025-01-01T12:00:00+00:00",
|
|
content="First emacs post",
|
|
group="emacs",
|
|
)
|
|
Post.objects.create(
|
|
profile=self.profile2,
|
|
post_id="2025-01-01T13:00:00+00:00",
|
|
content="Second emacs post",
|
|
group="emacs",
|
|
)
|
|
# Post from non-emacs group (should not appear)
|
|
other_profile = Profile.objects.create(
|
|
feed="https://other.com/social.org", nick="other"
|
|
)
|
|
Post.objects.create(
|
|
profile=other_profile,
|
|
post_id="2025-01-01T14:00:00+00:00",
|
|
content="Other post",
|
|
group="python",
|
|
)
|
|
|
|
# When: We request emacs group messages (using slug in URL)
|
|
response = self.client.get("/groups/emacs/")
|
|
|
|
# Then: Should return only emacs posts
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(response.data["type"], "Success")
|
|
self.assertEqual(len(response.data["data"]), 2)
|
|
|
|
# Check meta - should contain display name, not slug
|
|
self.assertEqual(response.data["meta"]["group"], "Emacs")
|
|
self.assertIn("members", response.data["meta"])
|
|
|
|
# Then: Should have ETag and Last-Modified headers
|
|
self.assertIn("ETag", response)
|
|
self.assertIn("Last-Modified", response)
|
|
|
|
@override_settings(ENABLED_GROUPS=["emacs"], GROUPS_MAP={"emacs": "Emacs"})
|
|
def test_get_group_messages_with_replies(self):
|
|
"""Test group messages with reply tree structure."""
|
|
# Given: Posts with replies in group
|
|
post1 = Post.objects.create(
|
|
profile=self.profile1,
|
|
post_id="2025-01-01T12:00:00+00:00",
|
|
content="Original post",
|
|
group="emacs",
|
|
)
|
|
Post.objects.create(
|
|
profile=self.profile2,
|
|
post_id="2025-01-01T13:00:00+00:00",
|
|
content="Reply to post1",
|
|
reply_to=f"{self.profile1.feed}#{post1.post_id}",
|
|
group="emacs",
|
|
)
|
|
|
|
# When: We request group messages
|
|
response = self.client.get("/groups/emacs/")
|
|
|
|
# Then: Should return tree structure
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
data = response.data["data"]
|
|
|
|
# Find the original post
|
|
original = None
|
|
for msg in data:
|
|
if "2025-01-01T12:00:00" in msg["post"]:
|
|
original = msg
|
|
break
|
|
|
|
self.assertIsNotNone(original)
|
|
# Check if reply is in children
|
|
self.assertEqual(len(original["children"]), 1)
|
|
self.assertIn("2025-01-01T13:00:00", original["children"][0]["post"])
|
|
|
|
@override_settings(ENABLED_GROUPS=["emacs"], GROUPS_MAP={"emacs": "Emacs"})
|
|
def test_get_group_messages_empty(self):
|
|
"""Test group with no messages."""
|
|
# Given: No posts in group
|
|
|
|
# When: We request group messages
|
|
response = self.client.get("/groups/emacs/")
|
|
|
|
# Then: Should return empty data
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(response.data["type"], "Success")
|
|
self.assertEqual(response.data["data"], [])
|
|
self.assertEqual(len(response.data["data"]), 0)
|
|
|
|
@override_settings(ENABLED_GROUPS=["emacs"], GROUPS_MAP={"emacs": "Emacs"})
|
|
def test_get_group_messages_invalid_group(self):
|
|
"""Test getting messages from invalid group."""
|
|
# Given: Invalid group ID
|
|
|
|
# When: We request invalid group
|
|
response = self.client.get("/groups/invalid-group/")
|
|
|
|
# Then: Should return 404
|
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
|
self.assertEqual(response.data["type"], "Error")
|
|
|
|
@override_settings(
|
|
ENABLED_GROUPS=["emacs", "python"],
|
|
GROUPS_MAP={"emacs": "Emacs", "python": "Python"},
|
|
)
|
|
def test_get_group_messages_caching(self):
|
|
"""Test that group messages are cached."""
|
|
# Given: Posts in group
|
|
Post.objects.create(
|
|
profile=self.profile1,
|
|
post_id="2025-01-01T12:00:00+00:00",
|
|
content="Test post",
|
|
group="emacs",
|
|
)
|
|
|
|
# When: We request group messages twice
|
|
response1 = self.client.get("/groups/emacs/")
|
|
response2 = self.client.get("/groups/emacs/")
|
|
|
|
# Then: Both should succeed
|
|
self.assertEqual(response1.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(response2.status_code, status.HTTP_200_OK)
|
|
|
|
# And ETag should be the same (indicating cache hit)
|
|
self.assertEqual(response1["ETag"], response2["ETag"])
|
|
|
|
|
|
class GroupsIntegrationTest(TestCase):
|
|
"""Integration tests for groups functionality."""
|
|
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
|
|
@override_settings(
|
|
ENABLED_GROUPS=["emacs", "org-social", "python"],
|
|
GROUPS_MAP={"emacs": "Emacs", "org-social": "Org Social", "python": "Python"},
|
|
)
|
|
def test_full_group_workflow(self):
|
|
"""Test complete group workflow: list, create profile/post, retrieve."""
|
|
# Given: Initial state
|
|
feed_url = "https://example.com/social.org"
|
|
|
|
# Step 1: List groups
|
|
response = self.client.get("/groups/")
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(len(response.data["data"]), 3)
|
|
|
|
# Step 2: Create profile (simulating what would happen via feed parsing)
|
|
profile = Profile.objects.create(feed=feed_url)
|
|
|
|
# Step 3: Create posts in group (simulating what would happen via feed parsing)
|
|
Post.objects.create(
|
|
profile=profile,
|
|
post_id="2025-01-01T12:00:00+00:00",
|
|
content="My emacs config",
|
|
group="emacs",
|
|
)
|
|
|
|
# Step 4: Retrieve group messages
|
|
response = self.client.get("/groups/emacs/")
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(len(response.data["data"]), 1)
|
|
# Check that we have a post from the feed we registered
|
|
self.assertIn(
|
|
"https://example.com/social.org#", response.data["data"][0]["post"]
|
|
)
|
|
|
|
# Step 5: Verify groups list still works
|
|
response = self.client.get("/groups/")
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
# Should contain display name, not slug
|
|
self.assertIn("Emacs", response.data["data"])
|
|
|
|
@override_settings(ENABLED_GROUPS=[], GROUPS_MAP={})
|
|
def test_groups_disabled(self):
|
|
"""Test behavior when groups are not configured."""
|
|
# When: We try to access any group endpoint
|
|
response = self.client.get("/groups/")
|
|
|
|
# Then: Should indicate no groups configured
|
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
|
self.assertIn("No groups configured", response.data["errors"][0])
|