Skip to content

Commit 5e0016b

Browse files
authored
fix(exports): include all applicable threads (#1733)
## Data & Sharing ### Resolved Issues * Fixed: Non-published threads may not be included in thread exports. * Fixed: A thread created in anonymous session by a logged in user may appear more than once in thread exports.
1 parent 025fae5 commit 5e0016b

2 files changed

Lines changed: 62 additions & 7 deletions

File tree

pingpong/models.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
literal,
3434
not_,
3535
or_,
36-
true,
3736
union_all,
3837
)
3938
from sqlalchemy import Enum as SQLEnum
@@ -7788,9 +7787,7 @@ async def get_thread_by_class_id(
77887787
last_activity_after: datetime | None = None,
77897788
last_activity_before: datetime | None = None,
77907789
) -> AsyncGenerator["Thread", None]:
7791-
condition = and_(
7792-
Thread.class_id == int(class_id), Thread.private.is_not(true())
7793-
)
7790+
condition = Thread.class_id == int(class_id)
77947791
if include_only_user_ids is not None:
77957792
if not include_only_user_ids:
77967793
return
@@ -7809,7 +7806,6 @@ async def get_thread_by_class_id(
78097806
condition = and_(condition, Thread.last_activity <= last_activity_before)
78107807
stmt = (
78117808
select(Thread)
7812-
.outerjoin(Thread.users)
78137809
.options(
78147810
selectinload(Thread.users).options(
78157811
load_only(

pingpong/test_models_threads.py

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,16 @@ async def test_get_thread_by_class_id_preloads_export_user_fields(db):
312312
last_name="User",
313313
anonymous_link=share_link,
314314
)
315+
second_user = models.User(
316+
email="export-user-2@example.com",
317+
display_name="Second Export User",
318+
first_name="Second",
319+
last_name="User",
320+
)
315321
thread = models.Thread(
316322
thread_id="thread_export_user_fields",
317323
class_=class_,
318-
users=[user],
324+
users=[user, second_user],
319325
display_user_info=True,
320326
)
321327
session.add(thread)
@@ -331,7 +337,10 @@ async def test_get_thread_by_class_id_preloads_export_user_fields(db):
331337
]
332338

333339
assert len(threads) == 1
334-
loaded_user = threads[0].users[0]
340+
assert len(threads[0].users) == 2
341+
loaded_user = next(
342+
user for user in threads[0].users if user.email == "export-user@example.com"
343+
)
335344
unloaded = inspect(loaded_user).unloaded
336345

337346
assert "id" not in unloaded
@@ -433,6 +442,56 @@ async def test_get_thread_by_class_id_filters_by_assistant_ids(db):
433442
]
434443

435444

445+
@pytest.mark.asyncio
446+
async def test_get_thread_by_class_id_empty_user_filter_returns_no_threads(db):
447+
async with db.async_session() as session:
448+
class_ = models.Class(name="Export Thread Empty User Filter Class")
449+
thread = models.Thread(
450+
thread_id="thread_export_empty_user_filter",
451+
class_=class_,
452+
)
453+
session.add(thread)
454+
await session.commit()
455+
class_id = class_.id
456+
457+
async with db.async_session() as session:
458+
threads = [
459+
t
460+
async for t in models.Thread.get_thread_by_class_id(
461+
session,
462+
class_id=class_id,
463+
include_only_user_ids=[],
464+
)
465+
]
466+
467+
assert threads == []
468+
469+
470+
@pytest.mark.asyncio
471+
async def test_get_thread_by_class_id_empty_assistant_filter_returns_no_threads(db):
472+
async with db.async_session() as session:
473+
class_ = models.Class(name="Export Thread Empty Assistant Filter Class")
474+
thread = models.Thread(
475+
thread_id="thread_export_empty_assistant_filter",
476+
class_=class_,
477+
)
478+
session.add(thread)
479+
await session.commit()
480+
class_id = class_.id
481+
482+
async with db.async_session() as session:
483+
threads = [
484+
t
485+
async for t in models.Thread.get_thread_by_class_id(
486+
session,
487+
class_id=class_id,
488+
include_only_assistant_ids=[],
489+
)
490+
]
491+
492+
assert threads == []
493+
494+
436495
@pytest.mark.asyncio
437496
async def test_list_messages_tool_calls_excludes_hidden_messages_by_default(db):
438497
async with db.async_session() as session:

0 commit comments

Comments
 (0)