• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rafalp / Misago / 15760070102

19 Jun 2025 02:18PM UTC coverage: 97.286% (+0.07%) from 97.214%
15760070102

Pull #1944

github

web-flow
Merge 1e99a089b into 7565eefd3
Pull Request #1944: Replace thread events with updates

2828 of 2914 new or added lines in 89 files covered. (97.05%)

13 existing lines in 4 files now uncovered.

74124 of 76192 relevant lines covered (97.29%)

0.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.27
/misago/threads/tests/test_prefetch_posts_feed_related_objects.py
1
import pytest
1✔
2

3
from ...conf.test import override_dynamic_settings
1✔
4
from ...permissions.enums import CategoryPermission
1✔
5
from ...permissions.models import CategoryGroupPermission
1✔
6
from ...permissions.proxy import UserPermissionsProxy
1✔
7
from ..prefetch import (
1✔
8
    PrefetchPostsFeedRelatedObjects,
9
    prefetch_posts_feed_related_objects,
10
)
11

12

13
def apple(*args):
1✔
NEW
14
    pass
×
15

16

17
def orange(*args):
1✔
NEW
18
    pass
×
19

20

21
def tomato(*args):
1✔
NEW
22
    pass
×
23

24

25
def test_prefetch_posts_feed_related_objects_add_appends_operation(
1✔
26
    dynamic_settings, cache_versions, user
27
):
28
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
29
    prefetch = PrefetchPostsFeedRelatedObjects(dynamic_settings, permissions, posts=[])
1✔
30

31
    prefetch.add(apple)
1✔
32
    assert prefetch.operations == [apple]
1✔
33

34

35
def test_prefetch_posts_feed_related_objects_add_before_inserts_operation(
1✔
36
    dynamic_settings, cache_versions, user
37
):
38
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
39
    prefetch = PrefetchPostsFeedRelatedObjects(dynamic_settings, permissions, posts=[])
1✔
40

41
    prefetch.add(apple)
1✔
42
    prefetch.add(tomato)
1✔
43

44
    prefetch.add_before(tomato, orange)
1✔
45

46

47
def test_prefetch_posts_feed_related_objects_add_before_raises_for_not_found_item(
1✔
48
    dynamic_settings, cache_versions, user
49
):
50
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
51
    prefetch = PrefetchPostsFeedRelatedObjects(dynamic_settings, permissions, posts=[])
1✔
52

53
    prefetch.add(apple)
1✔
54

55
    with pytest.raises(ValueError):
1✔
56
        prefetch.add_before(tomato, orange)
1✔
57

58

59
def test_prefetch_posts_feed_related_objects_add_after_inserts_operation(
1✔
60
    dynamic_settings, cache_versions, user
61
):
62
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
63
    prefetch = PrefetchPostsFeedRelatedObjects(dynamic_settings, permissions, posts=[])
1✔
64

65
    prefetch.add(apple)
1✔
66
    prefetch.add(tomato)
1✔
67

68
    prefetch.add_after(apple, orange)
1✔
69
    assert prefetch.operations == [apple, orange, tomato]
1✔
70

71

72
def test_prefetch_posts_feed_related_objects_add_after_raises_for_not_found_item(
1✔
73
    dynamic_settings, cache_versions, user
74
):
75
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
76
    prefetch = PrefetchPostsFeedRelatedObjects(dynamic_settings, permissions, posts=[])
1✔
77

78
    prefetch.add(apple)
1✔
79

80
    with pytest.raises(ValueError):
1✔
81
        prefetch.add_after(tomato, orange)
1✔
82

83

84
def test_prefetch_posts_feed_related_objects_supports_membership_test(
1✔
85
    dynamic_settings, cache_versions, user
86
):
87
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
88
    prefetch = PrefetchPostsFeedRelatedObjects(dynamic_settings, permissions, posts=[])
1✔
89

90
    prefetch.add(apple)
1✔
91
    assert apple in prefetch
1✔
92
    assert orange not in prefetch
1✔
93

94

95
def test_prefetch_posts_feed_related_objects_preloads_categories(
1✔
96
    django_assert_num_queries,
97
    dynamic_settings,
98
    cache_versions,
99
    anonymous_user,
100
    default_category,
101
    sibling_category,
102
):
103
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
104
    permissions.permissions
1✔
105
    permissions.is_global_moderator
1✔
106

107
    with django_assert_num_queries(0):
1✔
108
        data = prefetch_posts_feed_related_objects(
1✔
109
            dynamic_settings,
110
            permissions,
111
            [],
112
            categories=[default_category, sibling_category],
113
        )
114

115
        assert data["categories"] == {
1✔
116
            default_category.id: default_category,
117
            sibling_category.id: sibling_category,
118
        }
119

120

121
def test_prefetch_posts_feed_related_objects_prefetches_threads_categories(
1✔
122
    django_assert_num_queries,
123
    dynamic_settings,
124
    cache_versions,
125
    anonymous_user,
126
    default_category,
127
    thread,
128
    user_thread,
129
):
130
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
131
    permissions.permissions
1✔
132
    permissions.is_global_moderator
1✔
133

134
    with django_assert_num_queries(1):
1✔
135
        data = prefetch_posts_feed_related_objects(
1✔
136
            dynamic_settings, permissions, [], threads=[thread, user_thread]
137
        )
138
        assert data["categories"] == {default_category.id: default_category}
1✔
139

140

141
def test_prefetch_posts_feed_related_objects_prefetches_posts_categories(
1✔
142
    django_assert_num_queries,
143
    dynamic_settings,
144
    cache_versions,
145
    anonymous_user,
146
    default_category,
147
    post,
148
    user_reply,
149
    other_user_reply,
150
):
151
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
152
    permissions.permissions
1✔
153
    permissions.is_global_moderator
1✔
154

155
    with django_assert_num_queries(5):
1✔
156
        data = prefetch_posts_feed_related_objects(
1✔
157
            dynamic_settings, permissions, [post, user_reply, other_user_reply]
158
        )
159
        assert data["categories"] == {default_category.id: default_category}
1✔
160

161

162
def test_prefetch_posts_feed_related_objects_prefetches_thread_update_context_categories(
1✔
163
    django_assert_num_queries,
164
    dynamic_settings,
165
    cache_versions,
166
    anonymous_user,
167
    guests_group,
168
    sibling_category,
169
    thread_update_category_context,
170
):
171
    CategoryGroupPermission.objects.create(
1✔
172
        category=sibling_category,
173
        group=guests_group,
174
        permission=CategoryPermission.SEE,
175
    )
176

177
    thread_update_category_context.context_id = sibling_category.id
1✔
178
    thread_update_category_context.save()
1✔
179

180
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
181
    permissions.permissions
1✔
182
    permissions.is_global_moderator
1✔
183

184
    with django_assert_num_queries(3):
1✔
185
        data = prefetch_posts_feed_related_objects(
1✔
186
            dynamic_settings,
187
            permissions,
188
            [],
189
            thread_updates=[thread_update_category_context],
190
        )
191
        assert data["categories"] == {sibling_category.id: sibling_category}
1✔
192

193

194
def test_prefetch_posts_feed_related_objects_prefetches_attachments_categories(
1✔
195
    django_assert_num_queries,
196
    dynamic_settings,
197
    cache_versions,
198
    anonymous_user,
199
    default_category,
200
    text_attachment,
201
    user_text_attachment,
202
    post,
203
):
204
    text_attachment.associate_with_post(post)
1✔
205
    text_attachment.save()
1✔
206

207
    user_text_attachment.associate_with_post(post)
1✔
208
    user_text_attachment.save()
1✔
209

210
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
211
    permissions.permissions
1✔
212
    permissions.is_global_moderator
1✔
213

214
    with django_assert_num_queries(3):
1✔
215
        data = prefetch_posts_feed_related_objects(
1✔
216
            dynamic_settings,
217
            permissions,
218
            [],
219
            attachments=[text_attachment, user_text_attachment],
220
        )
221
        assert data["categories"] == {default_category.id: default_category}
1✔
222

223

224
def test_prefetch_posts_feed_related_objects_excludes_inaccessible_categories(
1✔
225
    django_assert_num_queries,
226
    dynamic_settings,
227
    cache_versions,
228
    anonymous_user,
229
    default_category,
230
    sibling_category,
231
    thread,
232
    user_thread,
233
):
234
    user_thread.category = sibling_category
1✔
235
    user_thread.save()
1✔
236

237
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
238
    permissions.permissions
1✔
239
    permissions.is_global_moderator
1✔
240

241
    with django_assert_num_queries(1):
1✔
242
        data = prefetch_posts_feed_related_objects(
1✔
243
            dynamic_settings, permissions, [], threads=[thread, user_thread]
244
        )
245
        assert data["categories"] == {default_category.id: default_category}
1✔
246

247

248
def test_prefetch_posts_feed_related_objects_preloads_threads(
1✔
249
    django_assert_num_queries,
250
    dynamic_settings,
251
    cache_versions,
252
    anonymous_user,
253
    thread,
254
    user_thread,
255
):
256
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
257
    permissions.permissions
1✔
258
    permissions.is_global_moderator
1✔
259

260
    with django_assert_num_queries(1):
1✔
261
        data = prefetch_posts_feed_related_objects(
1✔
262
            dynamic_settings, permissions, [], threads=[thread, user_thread]
263
        )
264
        assert data["threads"] == {
1✔
265
            thread.id: thread,
266
            user_thread.id: user_thread,
267
        }
268

269

270
def test_prefetch_posts_feed_related_objects_prefetches_posts_threads(
1✔
271
    django_assert_num_queries,
272
    dynamic_settings,
273
    cache_versions,
274
    anonymous_user,
275
    thread,
276
    post,
277
    user_reply,
278
    other_user_reply,
279
):
280
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
281
    permissions.permissions
1✔
282
    permissions.is_global_moderator
1✔
283

284
    with django_assert_num_queries(5):
1✔
285
        data = prefetch_posts_feed_related_objects(
1✔
286
            dynamic_settings, permissions, [post, user_reply, other_user_reply]
287
        )
288
        assert data["threads"] == {thread.id: thread}
1✔
289

290

291
def test_prefetch_posts_feed_related_objects_prefetches_thread_update_context_threads(
1✔
292
    django_assert_num_queries,
293
    dynamic_settings,
294
    cache_versions,
295
    anonymous_user,
296
    other_thread,
297
    thread_update_thread_context,
298
):
299
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
300
    permissions.permissions
1✔
301
    permissions.is_global_moderator
1✔
302

303
    with django_assert_num_queries(4):
1✔
304
        data = prefetch_posts_feed_related_objects(
1✔
305
            dynamic_settings,
306
            permissions,
307
            [],
308
            thread_updates=[thread_update_thread_context],
309
        )
310
        assert data["threads"] == {other_thread.id: other_thread}
1✔
311

312

313
def test_prefetch_posts_feed_related_objects_prefetches_attachments_threads(
1✔
314
    django_assert_num_queries,
315
    dynamic_settings,
316
    cache_versions,
317
    anonymous_user,
318
    thread,
319
    post,
320
    text_attachment,
321
):
322
    text_attachment.associate_with_post(post)
1✔
323
    text_attachment.save()
1✔
324

325
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
326
    permissions.permissions
1✔
327
    permissions.is_global_moderator
1✔
328

329
    with django_assert_num_queries(3):
1✔
330
        data = prefetch_posts_feed_related_objects(
1✔
331
            dynamic_settings, permissions, [], attachments=[text_attachment]
332
        )
333
        assert data["threads"] == {thread.id: thread}
1✔
334

335

336
def test_prefetch_posts_feed_related_objects_excludes_inaccessible_threads(
1✔
337
    django_assert_num_queries,
338
    dynamic_settings,
339
    cache_versions,
340
    anonymous_user,
341
    default_category,
342
    thread,
343
    post,
344
    hidden_thread,
345
):
346
    post.metadata["posts"] = [hidden_thread.first_post_id]
1✔
347

348
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
349
    permissions.permissions
1✔
350
    permissions.is_global_moderator
1✔
351

352
    with django_assert_num_queries(1):
1✔
353
        data = prefetch_posts_feed_related_objects(
1✔
354
            dynamic_settings, permissions, [], threads=[thread]
355
        )
356
        assert data["categories"] == {default_category.id: default_category}
1✔
357

358

359
def test_prefetch_posts_feed_related_objects_preloads_posts(
1✔
360
    django_assert_num_queries,
361
    dynamic_settings,
362
    cache_versions,
363
    anonymous_user,
364
    post,
365
    user_reply,
366
):
367
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
368
    permissions.permissions
1✔
369
    permissions.is_global_moderator
1✔
370

371
    with django_assert_num_queries(5):
1✔
372
        data = prefetch_posts_feed_related_objects(
1✔
373
            dynamic_settings, permissions, [post, user_reply]
374
        )
375
        assert data["posts"] == {
1✔
376
            post.id: post,
377
            user_reply.id: user_reply,
378
        }
379

380

381
def test_prefetch_posts_feed_related_objects_prefetches_quoted_posts(
1✔
382
    django_assert_num_queries,
383
    dynamic_settings,
384
    cache_versions,
385
    anonymous_user,
386
    post,
387
    user_reply,
388
):
389
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
390
    permissions.permissions
1✔
391
    permissions.is_global_moderator
1✔
392

393
    post.metadata["posts"] = [user_reply.id]
1✔
394

395
    with django_assert_num_queries(6):
1✔
396
        data = prefetch_posts_feed_related_objects(
1✔
397
            dynamic_settings, permissions, [post]
398
        )
399
        assert data["posts"] == {
1✔
400
            post.id: post,
401
            user_reply.id: user_reply,
402
        }
403

404

405
def test_prefetch_posts_feed_related_objects_prefetches_quoted_posts_for_unsaved_post(
1✔
406
    django_assert_num_queries,
407
    dynamic_settings,
408
    cache_versions,
409
    anonymous_user,
410
    post,
411
    user_reply,
412
):
413
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
414
    permissions.permissions
1✔
415
    permissions.is_global_moderator
1✔
416

417
    post.id = None
1✔
418
    post.metadata["posts"] = [user_reply.id]
1✔
419

420
    with django_assert_num_queries(5):
1✔
421
        data = prefetch_posts_feed_related_objects(
1✔
422
            dynamic_settings, permissions, [post]
423
        )
424
        assert data["posts"] == {
1✔
425
            user_reply.id: user_reply,
426
        }
427

428

429
def test_prefetch_posts_feed_related_objects_excludes_inaccessible_quoted_posts(
1✔
430
    django_assert_num_queries,
431
    dynamic_settings,
432
    cache_versions,
433
    user,
434
    post,
435
    user_reply,
436
    private_thread,
437
    user_private_thread,
438
):
439
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
440
    permissions.permissions
1✔
441
    permissions.is_global_moderator
1✔
442

443
    post.metadata["posts"] = [
1✔
444
        private_thread.first_post_id,
445
        user_private_thread.first_post_id,
446
    ]
447
    post.save()
1✔
448

449
    with django_assert_num_queries(6):
1✔
450
        data = prefetch_posts_feed_related_objects(
1✔
451
            dynamic_settings, permissions, [post, user_reply]
452
        )
453
        assert data["posts"] == {
1✔
454
            post.id: post,
455
            user_reply.id: user_reply,
456
            user_private_thread.first_post_id: user_private_thread.first_post,
457
        }
458

459

460
def test_prefetch_posts_feed_related_objects_fetches_posts_metadata_posts(
1✔
461
    django_assert_num_queries,
462
    dynamic_settings,
463
    cache_versions,
464
    anonymous_user,
465
    post,
466
    user_reply,
467
):
468
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
469
    permissions.permissions
1✔
470
    permissions.is_global_moderator
1✔
471

472
    post.metadata["posts"] = [user_reply.id]
1✔
473
    post.save()
1✔
474

475
    with django_assert_num_queries(6):
1✔
476
        data = prefetch_posts_feed_related_objects(
1✔
477
            dynamic_settings, permissions, [post]
478
        )
479
        assert data["posts"] == {
1✔
480
            post.id: post,
481
            user_reply.id: user_reply,
482
        }
483

484

485
def test_prefetch_posts_feed_related_objects_prefetches_attachments_posts(
1✔
486
    django_assert_num_queries,
487
    dynamic_settings,
488
    cache_versions,
489
    anonymous_user,
490
    post,
491
    user_reply,
492
    text_attachment,
493
    user_text_attachment,
494
):
495
    text_attachment.associate_with_post(post)
1✔
496
    text_attachment.save()
1✔
497

498
    user_text_attachment.associate_with_post(user_reply)
1✔
499
    user_text_attachment.save()
1✔
500

501
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
502
    permissions.permissions
1✔
503
    permissions.is_global_moderator
1✔
504

505
    with django_assert_num_queries(5):
1✔
506
        data = prefetch_posts_feed_related_objects(
1✔
507
            dynamic_settings,
508
            permissions,
509
            [],
510
            attachments=[text_attachment, user_text_attachment],
511
        )
512
        assert data["posts"] == {
1✔
513
            post.id: post,
514
            user_reply.id: user_reply,
515
        }
516

517

518
def test_prefetch_posts_feed_related_objects_preloads_attachments(
1✔
519
    django_assert_num_queries,
520
    dynamic_settings,
521
    cache_versions,
522
    anonymous_user,
523
    text_attachment,
524
    user_text_attachment,
525
    post,
526
):
527
    text_attachment.associate_with_post(post)
1✔
528
    text_attachment.save()
1✔
529

530
    user_text_attachment.associate_with_post(post)
1✔
531
    user_text_attachment.save()
1✔
532

533
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
534
    permissions.permissions
1✔
535
    permissions.is_global_moderator
1✔
536

537
    with django_assert_num_queries(3):
1✔
538
        data = prefetch_posts_feed_related_objects(
1✔
539
            dynamic_settings,
540
            permissions,
541
            [],
542
            attachments=[text_attachment, user_text_attachment],
543
        )
544
        assert data["attachments"] == {
1✔
545
            text_attachment.id: text_attachment,
546
            user_text_attachment.id: user_text_attachment,
547
        }
548

549

550
def test_prefetch_posts_feed_related_objects_removes_preloaded_attachments_without_permission(
1✔
551
    django_assert_num_queries,
552
    dynamic_settings,
553
    cache_versions,
554
    user,
555
    text_attachment,
556
    user_text_attachment,
557
):
558
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
559
    permissions.permissions
1✔
560
    permissions.is_global_moderator
1✔
561

562
    with django_assert_num_queries(1):
1✔
563
        data = prefetch_posts_feed_related_objects(
1✔
564
            dynamic_settings,
565
            permissions,
566
            [],
567
            attachments=[text_attachment, user_text_attachment],
568
        )
569
        assert data["attachments"] == {
1✔
570
            user_text_attachment.id: user_text_attachment,
571
        }
572

573

574
def test_prefetch_posts_feed_related_objects_fetches_posts_attachments(
1✔
575
    django_assert_num_queries,
576
    dynamic_settings,
577
    cache_versions,
578
    anonymous_user,
579
    text_attachment,
580
    user_text_attachment,
581
    post,
582
    user_reply,
583
):
584
    text_attachment.associate_with_post(post)
1✔
585
    text_attachment.save()
1✔
586

587
    user_text_attachment.associate_with_post(user_reply)
1✔
588
    user_text_attachment.save()
1✔
589

590
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
591
    permissions.permissions
1✔
592
    permissions.is_global_moderator
1✔
593

594
    with django_assert_num_queries(5):
1✔
595
        data = prefetch_posts_feed_related_objects(
1✔
596
            dynamic_settings, permissions, [post, user_reply]
597
        )
598
        assert data["attachments"] == {
1✔
599
            text_attachment.id: text_attachment,
600
            user_text_attachment.id: user_text_attachment,
601
        }
602

603

604
def test_prefetch_posts_feed_related_objects_fetches_posts_metadata_attachments(
1✔
605
    django_assert_num_queries,
606
    dynamic_settings,
607
    cache_versions,
608
    anonymous_user,
609
    text_attachment,
610
    user_text_attachment,
611
    post,
612
    user_reply,
613
    other_user_reply,
614
):
615
    text_attachment.associate_with_post(other_user_reply)
1✔
616
    text_attachment.save()
1✔
617

618
    user_text_attachment.associate_with_post(other_user_reply)
1✔
619
    user_text_attachment.save()
1✔
620

621
    post.metadata["attachments"] = [text_attachment.id]
1✔
622
    post.save()
1✔
623

624
    user_reply.metadata["attachments"] = [user_text_attachment.id]
1✔
625
    user_reply.save()
1✔
626

627
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
628
    permissions.permissions
1✔
629
    permissions.is_global_moderator
1✔
630

631
    with django_assert_num_queries(6):
1✔
632
        data = prefetch_posts_feed_related_objects(
1✔
633
            dynamic_settings, permissions, [post, user_reply]
634
        )
635
        assert data["attachments"] == {
1✔
636
            text_attachment.id: text_attachment,
637
            user_text_attachment.id: user_text_attachment,
638
        }
639

640

641
@override_dynamic_settings(additional_embedded_attachments_limit=0)
1✔
642
def test_prefetch_posts_feed_related_objects_doesnt_fetch_posts_metadata_attachments_if_its_disabled(
1✔
643
    django_assert_num_queries,
644
    dynamic_settings,
645
    cache_versions,
646
    anonymous_user,
647
    text_attachment,
648
    user_text_attachment,
649
    post,
650
    user_reply,
651
    other_user_reply,
652
):
653
    text_attachment.associate_with_post(other_user_reply)
1✔
654
    text_attachment.save()
1✔
655

656
    user_text_attachment.associate_with_post(other_user_reply)
1✔
657
    user_text_attachment.save()
1✔
658

659
    post.metadata["attachments"] = [text_attachment.id]
1✔
660
    post.save()
1✔
661

662
    user_reply.metadata["attachments"] = [user_text_attachment.id]
1✔
663
    user_reply.save()
1✔
664

665
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
666
    permissions.permissions
1✔
667
    permissions.is_global_moderator
1✔
668

669
    with django_assert_num_queries(5):
1✔
670
        data = prefetch_posts_feed_related_objects(
1✔
671
            dynamic_settings, permissions, [post, user_reply]
672
        )
673
        assert data["attachments"] == {}
1✔
674

675

676
@override_dynamic_settings(additional_embedded_attachments_limit=1)
1✔
677
def test_prefetch_posts_feed_related_objects_fetch_posts_metadata_attachments_is_limited(
1✔
678
    django_assert_num_queries,
679
    dynamic_settings,
680
    cache_versions,
681
    anonymous_user,
682
    text_attachment,
683
    user_text_attachment,
684
    post,
685
    user_reply,
686
    other_user_reply,
687
):
688
    text_attachment.associate_with_post(other_user_reply)
1✔
689
    text_attachment.save()
1✔
690

691
    user_text_attachment.associate_with_post(other_user_reply)
1✔
692
    user_text_attachment.save()
1✔
693

694
    post.metadata["attachments"] = [text_attachment.id]
1✔
695
    post.save()
1✔
696

697
    user_reply.metadata["attachments"] = [user_text_attachment.id]
1✔
698
    user_reply.save()
1✔
699

700
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
701
    permissions.permissions
1✔
702
    permissions.is_global_moderator
1✔
703

704
    with django_assert_num_queries(6):
1✔
705
        data = prefetch_posts_feed_related_objects(
1✔
706
            dynamic_settings, permissions, [post, user_reply]
707
        )
708
        assert data["attachments"] == {user_text_attachment.id: user_text_attachment}
1✔
709

710

711
def test_prefetch_posts_feed_related_objects_fetch_posts_metadata_attachments_excludes_unused_attachments(
1✔
712
    django_assert_num_queries,
713
    dynamic_settings,
714
    cache_versions,
715
    user,
716
    text_attachment,
717
    user_text_attachment,
718
    post,
719
    user_reply,
720
    other_user_reply,
721
):
722
    text_attachment.associate_with_post(other_user_reply)
1✔
723
    text_attachment.save()
1✔
724

725
    post.metadata["attachments"] = [text_attachment.id]
1✔
726
    post.save()
1✔
727

728
    user_reply.metadata["attachments"] = [user_text_attachment.id]
1✔
729
    user_reply.save()
1✔
730

731
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
732
    permissions.permissions
1✔
733
    permissions.is_global_moderator
1✔
734

735
    with django_assert_num_queries(6):
1✔
736
        data = prefetch_posts_feed_related_objects(
1✔
737
            dynamic_settings, permissions, [post, user_reply]
738
        )
739
        assert data["attachments"] == {
1✔
740
            text_attachment.id: text_attachment,
741
        }
742

743

744
def test_prefetch_posts_feed_related_objects_fetch_posts_metadata_attachments_excludes_inaccessible_attachments(
1✔
745
    django_assert_num_queries,
746
    dynamic_settings,
747
    cache_versions,
748
    anonymous_user,
749
    text_attachment,
750
    user_text_attachment,
751
    post,
752
    user_reply,
753
    other_user_reply,
754
    private_thread,
755
):
756
    text_attachment.associate_with_post(other_user_reply)
1✔
757
    text_attachment.save()
1✔
758

759
    user_text_attachment.associate_with_post(private_thread.first_post)
1✔
760
    user_text_attachment.save()
1✔
761

762
    post.metadata["attachments"] = [text_attachment.id]
1✔
763
    post.save()
1✔
764

765
    user_reply.metadata["attachments"] = [user_text_attachment.id]
1✔
766
    user_reply.save()
1✔
767

768
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
769
    permissions.permissions
1✔
770
    permissions.is_global_moderator
1✔
771

772
    with django_assert_num_queries(7):
1✔
773
        data = prefetch_posts_feed_related_objects(
1✔
774
            dynamic_settings, permissions, [post, user_reply]
775
        )
776
        assert data["attachments"] == {
1✔
777
            text_attachment.id: text_attachment,
778
        }
779

780

781
def test_prefetch_posts_feed_related_objects_fetch_posts_metadata_attachments_excludes_attachments_with_permission_denied(
1✔
782
    django_assert_num_queries,
783
    dynamic_settings,
784
    cache_versions,
785
    anonymous_user,
786
    guests_group,
787
    text_attachment,
788
    user_text_attachment,
789
    sibling_category,
790
    post,
791
    user_reply,
792
    other_thread,
793
):
794
    CategoryGroupPermission.objects.create(
1✔
795
        category=sibling_category,
796
        group=guests_group,
797
        permission=CategoryPermission.SEE,
798
    )
799
    CategoryGroupPermission.objects.create(
1✔
800
        category=sibling_category,
801
        group=guests_group,
802
        permission=CategoryPermission.BROWSE,
803
    )
804

805
    other_thread.category = sibling_category
1✔
806
    other_thread.save()
1✔
807

808
    other_thread.first_post.category = sibling_category
1✔
809
    other_thread.first_post.save()
1✔
810

811
    text_attachment.associate_with_post(post)
1✔
812
    text_attachment.save()
1✔
813

814
    user_text_attachment.associate_with_post(other_thread.first_post)
1✔
815
    user_text_attachment.save()
1✔
816

817
    post.metadata["attachments"] = [text_attachment.id]
1✔
818
    post.save()
1✔
819

820
    user_reply.metadata["attachments"] = [user_text_attachment.id]
1✔
821
    user_reply.save()
1✔
822

823
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
824
    permissions.permissions
1✔
825
    permissions.is_global_moderator
1✔
826

827
    with django_assert_num_queries(6):
1✔
828
        data = prefetch_posts_feed_related_objects(
1✔
829
            dynamic_settings, permissions, [post, user_reply]
830
        )
831
        assert data["attachments"] == {
1✔
832
            text_attachment.id: text_attachment,
833
        }
834
        assert tuple(data["attachment_errors"]) == (user_text_attachment.id,)
1✔
835
        assert data["attachment_errors"][user_text_attachment.id].permission_denied
1✔
836

837

838
def test_prefetch_posts_feed_related_objects_prefetches_private_threads_members(
1✔
839
    django_assert_num_queries,
840
    dynamic_settings,
841
    cache_versions,
842
    anonymous_user,
843
    user_private_thread,
844
):
845
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
846
    permissions.permissions
1✔
847
    permissions.is_global_moderator
1✔
848

849
    with django_assert_num_queries(2):
1✔
850
        prefetch_posts_feed_related_objects(
1✔
851
            dynamic_settings, permissions, [], threads=[user_private_thread]
852
        )
853

854
    with django_assert_num_queries(0):
1✔
855
        user_private_thread.private_thread_member_ids
1✔
856

857

858
def test_prefetch_posts_feed_related_objects_preloads_users(
1✔
859
    django_assert_num_queries,
860
    dynamic_settings,
861
    cache_versions,
862
    anonymous_user,
863
    user,
864
    other_user,
865
):
866
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
867
    permissions.permissions
1✔
868
    permissions.is_global_moderator
1✔
869

870
    with django_assert_num_queries(1):
1✔
871
        data = prefetch_posts_feed_related_objects(
1✔
872
            dynamic_settings, permissions, [], users=[user, other_user]
873
        )
874
        assert data["users"] == {
1✔
875
            user.id: user,
876
            other_user.id: other_user,
877
        }
878

879

880
def test_prefetch_posts_feed_related_objects_preloads_user_from_permissions(
1✔
881
    django_assert_num_queries,
882
    dynamic_settings,
883
    cache_versions,
884
    user,
885
):
886
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
887
    permissions.permissions
1✔
888
    permissions.is_global_moderator
1✔
889

890
    with django_assert_num_queries(1):
1✔
891
        data = prefetch_posts_feed_related_objects(dynamic_settings, permissions, [])
1✔
892
        assert data["users"] == {user.id: user}
1✔
893

894
    with django_assert_num_queries(0):
1✔
895
        assert data["users"][user.id].group
1✔
896

897

898
def test_prefetch_posts_feed_related_objects_doesnt_preload_anonymous_user_from_permissions(
1✔
899
    django_assert_num_queries,
900
    dynamic_settings,
901
    cache_versions,
902
    anonymous_user,
903
    post,
904
):
905
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
906
    permissions.permissions
1✔
907
    permissions.is_global_moderator
1✔
908

909
    with django_assert_num_queries(3):
1✔
910
        data = prefetch_posts_feed_related_objects(
1✔
911
            dynamic_settings, permissions, [post]
912
        )
913
        assert data["users"] == {}
1✔
914

915

916
def test_prefetch_posts_feed_related_objects_prefetches_posts_users(
1✔
917
    django_assert_num_queries,
918
    dynamic_settings,
919
    cache_versions,
920
    user,
921
    other_user,
922
    user_reply,
923
    other_user_reply,
924
):
925
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
926
    permissions.permissions
1✔
927
    permissions.is_global_moderator
1✔
928

929
    with django_assert_num_queries(5):
1✔
930
        data = prefetch_posts_feed_related_objects(
1✔
931
            dynamic_settings, permissions, [user_reply, other_user_reply]
932
        )
933
        assert data["users"] == {user.id: user, other_user.id: other_user}
1✔
934

935
    with django_assert_num_queries(0):
1✔
936
        assert data["users"][user.id].group
1✔
937
        assert data["users"][other_user.id].group
1✔
938

939

940
def test_prefetch_posts_feed_related_objects_prefetches_thread_update_users(
1✔
941
    django_assert_num_queries,
942
    dynamic_settings,
943
    cache_versions,
944
    anonymous_user,
945
    user,
946
    thread_update,
947
):
948
    permissions = UserPermissionsProxy(anonymous_user, cache_versions)
1✔
949
    permissions.permissions
1✔
950
    permissions.is_global_moderator
1✔
951

952
    with django_assert_num_queries(2):
1✔
953
        data = prefetch_posts_feed_related_objects(
1✔
954
            dynamic_settings, permissions, [], thread_updates=[thread_update]
955
        )
956
        assert data["users"] == {user.id: user}
1✔
957

958
    with django_assert_num_queries(0):
1✔
959
        assert data["users"][user.id].group
1✔
960

961

962
def test_prefetch_posts_feed_related_objects_prefetches_thread_update_context_users(
1✔
963
    django_assert_num_queries,
964
    dynamic_settings,
965
    cache_versions,
966
    user,
967
    other_user,
968
    thread_update_user_context,
969
):
970
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
971
    permissions.permissions
1✔
972
    permissions.is_global_moderator
1✔
973

974
    with django_assert_num_queries(2):
1✔
975
        data = prefetch_posts_feed_related_objects(
1✔
976
            dynamic_settings,
977
            permissions,
978
            [],
979
            thread_updates=[thread_update_user_context],
980
        )
981
        assert data["users"] == {user.id: user, other_user.id: other_user}
1✔
982

983
    with django_assert_num_queries(0):
1✔
984
        assert data["users"][user.id].group
1✔
985
        assert data["users"][other_user.id].group
1✔
986

987

988
def test_prefetch_posts_feed_related_objects_doesnt_prefetch_anonymous_posts_users(
1✔
989
    django_assert_num_queries,
990
    dynamic_settings,
991
    cache_versions,
992
    user,
993
    post,
994
):
995
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
996
    permissions.permissions
1✔
997
    permissions.is_global_moderator
1✔
998

999
    with django_assert_num_queries(4):
1✔
1000
        data = prefetch_posts_feed_related_objects(
1✔
1001
            dynamic_settings, permissions, [post]
1002
        )
1003
        assert data["users"] == {user.id: user}
1✔
1004

1005
    with django_assert_num_queries(0):
1✔
1006
        assert data["users"][user.id].group
1✔
1007

1008

1009
def test_prefetch_posts_feed_related_objects_prefetches_objects_in_cascade(
1✔
1010
    django_assert_num_queries,
1011
    dynamic_settings,
1012
    cache_versions,
1013
    user,
1014
    other_user,
1015
    default_category,
1016
    private_threads_category,
1017
    thread,
1018
    post,
1019
    user_reply,
1020
    other_user_reply,
1021
    user_private_thread,
1022
    text_attachment,
1023
    user_text_attachment,
1024
    other_user_text_attachment,
1025
):
1026
    permissions = UserPermissionsProxy(user, cache_versions)
1✔
1027
    permissions.permissions
1✔
1028
    permissions.is_global_moderator
1✔
1029

1030
    text_attachment.associate_with_post(post)
1✔
1031
    text_attachment.save()
1✔
1032

1033
    other_user_text_attachment.associate_with_post(user_private_thread.first_post)
1✔
1034
    other_user_text_attachment.save()
1✔
1035

1036
    user_reply.metadata["attachments"] = [
1✔
1037
        user_text_attachment.id,
1038
        other_user_text_attachment.id,
1039
    ]
1040
    user_reply.save()
1✔
1041

1042
    with django_assert_num_queries(7):
1✔
1043
        data = prefetch_posts_feed_related_objects(
1✔
1044
            dynamic_settings,
1045
            permissions,
1046
            [post, user_reply, other_user_reply],
1047
        )
1048

1049
        assert default_category.id in data["categories"]
1✔
1050
        assert private_threads_category.id in data["categories"]
1✔
1051

1052
        assert thread.id in data["threads"]
1✔
1053
        assert user_private_thread.id in data["threads"]
1✔
1054

1055
        assert data["threads"][user_private_thread.id].private_thread_member_ids
1✔
1056

1057
        assert post.id in data["posts"]
1✔
1058
        assert user_reply.id in data["posts"]
1✔
1059
        assert other_user_reply.id in data["posts"]
1✔
1060
        assert user_private_thread.first_post_id in data["posts"]
1✔
1061

1062
        assert user.id in data["users"]
1✔
1063
        assert other_user.id in data["users"]
1✔
1064

1065
        assert data["users"][user.id].group
1✔
1066
        assert data["users"][other_user.id].group
1✔
1067

1068
        assert text_attachment.id in data["attachments"]
1✔
1069
        assert other_user_text_attachment.id in data["attachments"]
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc