Skip to content

Commit 9c6d184

Browse files
committed
Address review comments
1 parent 30da027 commit 9c6d184

7 files changed

Lines changed: 55 additions & 35 deletions

File tree

app/backend/src/couchers/i18n/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
"invalid_phone": "Phone number must be in international format without punctuation.",
124124
"invalid_recipients": "Invalid recipients list.",
125125
"invalid_region": "Invalid region.",
126+
"invalid_thread_filter": "Invalid message thread filter.",
126127
"invalid_token": "Invalid token.",
127128
"invalid_username": "Invalid username.",
128129
"invalid_website_url": "Invalid website URL or text, make sure URL starts with \"https://\", and that the text is included in the URL.",

app/backend/src/couchers/servicers/conversations.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,7 @@ def _host_request_thread_to_pb(
406406
public-trip offer the roles are reversed relative to initiator/recipient
407407
(initiator = offering host, recipient = traveller).
408408
"""
409-
is_public_trip_offer = host_request.public_trip_id is not None
410-
if is_public_trip_offer:
409+
if host_request.public_trip_id is not None:
411410
surfer_user_id = host_request.recipient_user_id
412411
host_user_id = host_request.initiator_user_id
413412
else:
@@ -429,8 +428,6 @@ def _host_request_thread_to_pb(
429428
if host_request.initiator_user_id == user_id
430429
else host_request.is_recipient_archived
431430
),
432-
is_public_trip_offer=is_public_trip_offer,
433-
viewer_is_host=(host_user_id == user_id),
434431
public_trip_id=host_request.public_trip_id,
435432
unseen_message_count=unseen_message_count,
436433
)
@@ -724,12 +721,15 @@ def ListMessageThreads(
724721
) -> conversations_pb2.ListMessageThreadsRes:
725722
thread_filter = request.filter
726723

724+
if thread_filter == conversations_pb2.MESSAGE_THREAD_FILTER_UNSPECIFIED:
725+
context.abort_with_error_code(grpc.StatusCode.INVALID_ARGUMENT, "invalid_thread_filter")
726+
727727
if thread_filter == conversations_pb2.MESSAGE_THREAD_FILTER_PUBLIC_TRIPS and not context.get_boolean_value(
728728
"public_trips_enabled", False
729729
):
730730
return conversations_pb2.ListMessageThreadsRes(threads=[], no_more=True)
731731

732-
page_size = request.number if request.number != 0 else DEFAULT_PAGINATION_LENGTH
732+
page_size = request.page_size if request.page_size != 0 else DEFAULT_PAGINATION_LENGTH
733733
page_size = min(page_size, MAX_PAGE_SIZE)
734734
only_archived = request.only_archived if request.HasField("only_archived") else None
735735
unread = thread_filter == conversations_pb2.MESSAGE_THREAD_FILTER_UNREAD
@@ -807,6 +807,9 @@ def MarkAllThreadsSeen(
807807
) -> empty_pb2.Empty:
808808
thread_filter = request.filter
809809

810+
if thread_filter == conversations_pb2.MESSAGE_THREAD_FILTER_UNSPECIFIED:
811+
context.abort_with_error_code(grpc.StatusCode.INVALID_ARGUMENT, "invalid_thread_filter")
812+
810813
if thread_filter == conversations_pb2.MESSAGE_THREAD_FILTER_PUBLIC_TRIPS and not context.get_boolean_value(
811814
"public_trips_enabled", False
812815
):

app/backend/src/couchers/servicers/public_trips.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,10 @@ def public_trip_to_pb(
9191
.group_by(HostRequest.status)
9292
).all()
9393
)
94-
pb.offer_tally.CopyFrom(
95-
public_trips_pb2.PublicTripOfferTally(
96-
pending=counts_by_status.get(HostRequestStatus.pending, 0),
97-
accepted=counts_by_status.get(HostRequestStatus.accepted, 0)
98-
+ counts_by_status.get(HostRequestStatus.confirmed, 0),
99-
declined=counts_by_status.get(HostRequestStatus.rejected, 0),
100-
)
101-
)
94+
pb.offer_tally.pending = counts_by_status.get(HostRequestStatus.pending, 0)
95+
pb.offer_tally.accepted = counts_by_status.get(HostRequestStatus.accepted, 0)
96+
pb.offer_tally.confirmed = counts_by_status.get(HostRequestStatus.confirmed, 0)
97+
pb.offer_tally.declined = counts_by_status.get(HostRequestStatus.rejected, 0)
10298
else:
10399
# The viewer's own existing offer on this trip (if any), so the client can
104100
# show an "already offered" state and link to the thread.

app/backend/src/tests/test_message_threads.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from datetime import timedelta
22

3+
import grpc
34
import pytest
45

56
from couchers.db import session_scope
@@ -146,7 +147,7 @@ def test_list_message_threads_single_cursor_pagination_across_kinds(db, moderato
146147
with conversations_session(token1) as c:
147148
res = c.ListMessageThreads(
148149
conversations_pb2.ListMessageThreadsReq(
149-
filter=conversations_pb2.MESSAGE_THREAD_FILTER_ALL, number=3, page_token=page_token
150+
filter=conversations_pb2.MESSAGE_THREAD_FILTER_ALL, page_size=3, page_token=page_token
150151
)
151152
)
152153
for t in res.threads:
@@ -183,6 +184,23 @@ def test_list_message_threads_chats_filter_excludes_host_requests(db, moderator)
183184
assert res.threads[0].group_chat.group_chat_id == chat_id
184185

185186

187+
def test_message_threads_reject_unspecified_filter(db):
188+
user1, token1 = generate_user()
189+
190+
with conversations_session(token1) as c:
191+
with pytest.raises(grpc.RpcError) as e:
192+
c.ListMessageThreads(
193+
conversations_pb2.ListMessageThreadsReq(filter=conversations_pb2.MESSAGE_THREAD_FILTER_UNSPECIFIED)
194+
)
195+
assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
196+
197+
with pytest.raises(grpc.RpcError) as e:
198+
c.MarkAllThreadsSeen(
199+
conversations_pb2.MarkAllThreadsSeenReq(filter=conversations_pb2.MESSAGE_THREAD_FILTER_UNSPECIFIED)
200+
)
201+
assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
202+
203+
186204
def test_list_message_threads_unread_filter(db, moderator):
187205
user1, token1 = generate_user()
188206
user2, token2 = generate_user()
@@ -251,11 +269,11 @@ def test_list_message_threads_public_trip_offer_role_based(db, moderator):
251269
assert len(res.threads) == 1
252270
hr = res.threads[0].host_request
253271
assert hr.host_request_id == request_id
254-
assert hr.is_public_trip_offer
272+
assert hr.HasField("public_trip_id")
255273
assert hr.public_trip_id == trip_id
274+
# viewer is the offering host: host_user_id == own id (viewer_is_host derived client-side)
256275
assert hr.host_user_id == host.id
257276
assert hr.surfer_user_id == traveler.id
258-
assert hr.viewer_is_host
259277

260278
# not under SURFING for the host
261279
res = c.ListMessageThreads(
@@ -270,8 +288,9 @@ def test_list_message_threads_public_trip_offer_role_based(db, moderator):
270288
)
271289
assert [t.host_request.host_request_id for t in res.threads] == [request_id]
272290
assert res.threads[0].host_request.surfer_user_id == traveler.id
291+
# viewer is the traveller, not the host: host_user_id != own id
273292
assert res.threads[0].host_request.host_user_id == host.id
274-
assert not res.threads[0].host_request.viewer_is_host
293+
assert res.threads[0].host_request.host_user_id != traveler.id
275294

276295
res = c.ListMessageThreads(
277296
conversations_pb2.ListMessageThreadsReq(filter=conversations_pb2.MESSAGE_THREAD_FILTER_PUBLIC_TRIPS)

app/backend/src/tests/test_public_trips.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,8 +1026,8 @@ def test_list_public_trips_by_user_offer_tally_owner(db):
10261026
trip = next(t for t in res.public_trips if t.trip_id == trip_id)
10271027
assert trip.HasField("offer_tally")
10281028
assert trip.offer_tally.pending == 1
1029-
# accepted bucket includes confirmed
1030-
assert trip.offer_tally.accepted == 2
1029+
assert trip.offer_tally.accepted == 1
1030+
assert trip.offer_tally.confirmed == 1
10311031
assert trip.offer_tally.declined == 1
10321032
# cancelled is excluded from offers_count and the tally
10331033
assert trip.offers_count == 4

app/proto/conversations.proto

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,13 @@ message ListGroupChatsRes {
198198
}
199199

200200
enum MessageThreadFilter {
201-
MESSAGE_THREAD_FILTER_ALL = 0;
202-
MESSAGE_THREAD_FILTER_UNREAD = 1;
203-
MESSAGE_THREAD_FILTER_CHATS = 2; // group chats + DMs only
204-
MESSAGE_THREAD_FILTER_HOSTING = 3; // role-based: I am the host of the stay
205-
MESSAGE_THREAD_FILTER_SURFING = 4; // role-based: I am the guest/traveller
206-
MESSAGE_THREAD_FILTER_PUBLIC_TRIPS = 5; // my incoming public-trip offers (I'm the traveller)
201+
MESSAGE_THREAD_FILTER_UNSPECIFIED = 0;
202+
MESSAGE_THREAD_FILTER_ALL = 1;
203+
MESSAGE_THREAD_FILTER_UNREAD = 2;
204+
MESSAGE_THREAD_FILTER_CHATS = 3; // group chats + DMs only
205+
MESSAGE_THREAD_FILTER_HOSTING = 4; // role-based: I am the host of the stay
206+
MESSAGE_THREAD_FILTER_SURFING = 5; // role-based: I am the guest/traveller
207+
MESSAGE_THREAD_FILTER_PUBLIC_TRIPS = 6; // my incoming public-trip offers (I'm the traveller)
207208
}
208209

209210
// A host request (or public-trip offer) shaped for the unified thread list.
@@ -222,12 +223,11 @@ message HostRequestThread {
222223
Message latest_message = 9;
223224
string hosting_city = 10;
224225
bool is_archived = 11;
225-
// true if this thread is a public-trip offer (public_trip_id is set)
226-
bool is_public_trip_offer = 12;
227-
// true if the viewer is the host of the stay
228-
bool viewer_is_host = 13;
229-
optional uint64 public_trip_id = 14;
230-
uint32 unseen_message_count = 15;
226+
// Set iff this thread is a public-trip offer; presence is the "is offer" flag,
227+
// and the value links to the trip. The viewer's role is derived client-side:
228+
// the viewer is the host iff host_user_id is their own user id.
229+
optional uint64 public_trip_id = 12;
230+
uint32 unseen_message_count = 13;
231231
}
232232

233233
message MessageThread {
@@ -241,8 +241,8 @@ message ListMessageThreadsReq {
241241
MessageThreadFilter filter = 1;
242242
// orthogonal: when present, restrict to archived (true) or non-archived (false)
243243
optional bool only_archived = 2;
244-
uint32 number = 3;
245-
// opaque cursor; the Message.id high-water mark
244+
uint32 page_size = 3;
245+
// pagination cursor; pass back the next_page_token from the previous response, or empty for the first page
246246
string page_token = 4;
247247
}
248248

app/proto/public_trips.proto

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ message PublicTrip {
7474

7575
message PublicTripOfferTally {
7676
int32 pending = 1;
77-
int32 accepted = 2; // accepted + confirmed
78-
int32 declined = 3; // rejected
77+
int32 accepted = 2;
78+
int32 confirmed = 3;
79+
int32 declined = 4; // rejected
7980
}
8081

8182
message CreatePublicTripReq {

0 commit comments

Comments
 (0)