Coverage for app / backend / src / tests / test_discussions.py: 100%
119 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-03 06:18 +0000
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-03 06:18 +0000
1import grpc
2import pytest
4from couchers.db import session_scope
5from couchers.proto import discussions_pb2, notifications_pb2, threads_pb2
6from couchers.utils import now, to_aware_datetime
7from tests.fixtures.db import generate_user
8from tests.fixtures.misc import PushCollector, process_jobs
9from tests.fixtures.sessions import discussions_session, notifications_session, threads_session
10from tests.test_communities import create_community, create_group
13@pytest.fixture(autouse=True)
14def _(testconfig):
15 pass
18def test_create_discussion_errors(db):
19 user, token = generate_user()
20 with discussions_session(token) as api:
21 with pytest.raises(grpc.RpcError) as e:
22 api.CreateDiscussion(
23 discussions_pb2.CreateDiscussionReq(
24 title=None,
25 content="dummy content",
26 )
27 )
28 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
29 assert e.value.details() == "Missing discussion title."
31 with discussions_session(token) as api:
32 with pytest.raises(grpc.RpcError) as e:
33 api.CreateDiscussion(
34 discussions_pb2.CreateDiscussionReq(
35 title="dummy title",
36 content=None,
37 )
38 )
39 assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
40 assert e.value.details() == "Missing discussion content."
43def test_create_and_get_discussion(db, push_collector: PushCollector):
44 generate_user()
45 user, token = generate_user()
46 user2, token2 = generate_user()
47 generate_user()
48 generate_user()
50 with notifications_session(token2) as notifications:
51 notifications.SetNotificationSettings(
52 notifications_pb2.SetNotificationSettingsReq(
53 preferences=[
54 notifications_pb2.SingleNotificationPreference(
55 topic="discussion",
56 action="create",
57 delivery_method="push",
58 enabled=True,
59 )
60 ],
61 )
62 )
64 with session_scope() as session:
65 community = create_community(session, 0, 1, "Testing Community", [user2], [], None)
66 group_id = create_group(session, "Testing Group", [user2], [], community).id
67 community_id = community.id
68 user2_id = user2.id
70 with discussions_session(token) as api:
71 time_before_create = now()
72 res = api.CreateDiscussion(
73 discussions_pb2.CreateDiscussionReq(
74 title="dummy title",
75 content="dummy content",
76 owner_community_id=community_id,
77 )
78 )
79 time_after_create = now()
81 assert res.title == "dummy title"
82 assert res.content == "dummy content"
83 assert res.slug == "dummy-title"
84 assert time_before_create <= to_aware_datetime(res.created) <= time_after_create
85 assert res.creator_user_id == user.id
86 assert res.owner_community_id == community_id
88 discussion_id = res.discussion_id
90 process_jobs()
92 push = push_collector.pop_for_user(user2_id, last=True)
93 assert push.content.title == "New discussion: dummy title"
94 assert push.content.body == f"{user.name} started the discussion in Testing Community."
96 with discussions_session(token) as api:
97 res = api.GetDiscussion(
98 discussions_pb2.GetDiscussionReq(
99 discussion_id=discussion_id,
100 )
101 )
103 assert res.title == "dummy title"
104 assert res.content == "dummy content"
105 assert res.slug == "dummy-title"
106 assert time_before_create <= to_aware_datetime(res.created) <= time_after_create
107 assert res.creator_user_id == user.id
108 assert res.owner_community_id == community_id
110 with discussions_session(token) as api:
111 time_before_create = now()
112 res = api.CreateDiscussion(
113 discussions_pb2.CreateDiscussionReq(
114 title="dummy title",
115 content="dummy content",
116 owner_group_id=group_id,
117 )
118 )
119 time_after_create = now()
121 assert res.title == "dummy title"
122 assert res.content == "dummy content"
123 assert res.slug == "dummy-title"
124 assert time_before_create <= to_aware_datetime(res.created) <= time_after_create
125 assert res.creator_user_id == user.id
126 assert res.owner_group_id == group_id
128 discussion_id = res.discussion_id
130 with discussions_session(token) as api:
131 res = api.GetDiscussion(
132 discussions_pb2.GetDiscussionReq(
133 discussion_id=discussion_id,
134 )
135 )
137 assert res.title == "dummy title"
138 assert res.content == "dummy content"
139 assert res.slug == "dummy-title"
140 assert time_before_create <= to_aware_datetime(res.created) <= time_after_create
141 assert res.creator_user_id == user.id
142 assert res.owner_group_id == group_id
145def test_discussion_notifications_regression(db, push_collector: PushCollector):
146 generate_user()
147 user, token = generate_user()
148 user2, token2 = generate_user()
149 user3, token3 = generate_user()
150 generate_user()
151 generate_user()
153 with session_scope() as session:
154 community = create_community(session, 0, 1, "Testing Community", [user2], [], None)
155 group_id = create_group(session, "Testing Group", [user2], [], community).id
156 community_id = community.id
157 user2_id = user2.id
159 with discussions_session(token) as api:
160 time_before_create = now()
161 res = api.CreateDiscussion(
162 discussions_pb2.CreateDiscussionReq(
163 title="dummy title",
164 content="dummy content",
165 owner_community_id=community_id,
166 )
167 )
168 time_after_create = now()
170 assert res.title == "dummy title"
171 assert res.content == "dummy content"
172 assert res.slug == "dummy-title"
173 assert time_before_create <= to_aware_datetime(res.created) <= time_after_create
174 assert res.creator_user_id == user.id
175 assert res.owner_community_id == community_id
177 discussion_id = res.discussion_id
178 thread_id = res.thread.thread_id
180 with threads_session(token2) as api:
181 comment_thread_id = api.PostReply(threads_pb2.PostReplyReq(thread_id=thread_id, content="comment")).thread_id
183 with threads_session(token3) as api:
184 api.PostReply(threads_pb2.PostReplyReq(thread_id=comment_thread_id, content="reply to comment"))
186 with threads_session(token) as api:
187 api.PostReply(threads_pb2.PostReplyReq(thread_id=comment_thread_id, content="reply to reply to comment"))
189 process_jobs()
191 # User2 should get 2 notifications about 2 replies to their comment, User3 should get 1 notification about 1 reply
192 push = push_collector.pop_for_user(user2_id, last=False)
193 assert push.content.title == f"{user3.name} • dummy title"
194 assert push.topic_action == "thread:reply"
196 push = push_collector.pop_for_user(user2_id, last=True)
197 assert push.content.title == f"{user.name} • dummy title"
198 assert push.topic_action == "thread:reply"
200 push = push_collector.pop_for_user(user3.id, last=True)
201 assert push.content.title == f"{user.name} • dummy title"
202 assert push.topic_action == "thread:reply"