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

rafalp / Misago / 12296543641

12 Dec 2024 12:36PM UTC coverage: 97.12% (-0.4%) from 97.477%
12296543641

push

github

web-flow
Mark known failing tests as expected fails (#1826)

31 of 31 new or added lines in 10 files covered. (100.0%)

365 existing lines in 45 files now uncovered.

61789 of 63621 relevant lines covered (97.12%)

0.97 hits per line

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

93.03
/misago/threads/tests/test_thread_postsplit_api.py
1
import json
1✔
2
from unittest import expectedFailure
1✔
3

4
from django.urls import reverse
1✔
5

6
from .. import test
1✔
7
from ...categories.models import Category
1✔
8
from ...conf.test import override_dynamic_settings
1✔
9
from ...users.test import AuthenticatedUserTestCase
1✔
10
from ..models import Post
1✔
11
from ..test import patch_category_acl, patch_other_category_acl
1✔
12

13

14
class ThreadPostSplitApiTestCase(AuthenticatedUserTestCase):
1✔
15
    def setUp(self):
1✔
16
        super().setUp()
1✔
17

18
        self.category = Category.objects.get(slug="first-category")
1✔
19
        self.thread = test.post_thread(category=self.category)
1✔
20
        self.posts = [
1✔
21
            test.reply_thread(self.thread).pk,
22
            test.reply_thread(self.thread).pk,
23
        ]
24

25
        self.api_link = reverse(
1✔
26
            "misago:api:thread-post-split", kwargs={"thread_pk": self.thread.pk}
27
        )
28

29
        Category(name="Other category", slug="other-category").insert_at(
1✔
30
            self.category, position="last-child", save=True
31
        )
32
        self.other_category = Category.objects.get(slug="other-category")
1✔
33

34
    def test_anonymous_user(self):
1✔
35
        """you need to authenticate to split posts"""
36
        self.logout_user()
1✔
37

38
        response = self.client.post(
1✔
39
            self.api_link, json.dumps({}), content_type="application/json"
40
        )
41
        self.assertEqual(response.status_code, 403)
1✔
42
        self.assertEqual(
1✔
43
            response.json(), {"detail": "This action is not available to guests."}
44
        )
45

46
    @patch_category_acl({"can_move_posts": False})
1✔
47
    def test_no_permission(self):
1✔
48
        """api validates permission to split"""
49
        response = self.client.post(
1✔
50
            self.api_link, json.dumps({}), content_type="application/json"
51
        )
52
        self.assertEqual(response.status_code, 403)
1✔
53
        self.assertEqual(
1✔
54
            response.json(), {"detail": "You can't split posts from this thread."}
55
        )
56

57
    @patch_category_acl({"can_move_posts": True})
1✔
58
    def test_empty_data(self):
1✔
59
        """api handles empty data"""
60
        response = self.client.post(self.api_link)
1✔
61
        self.assertEqual(response.status_code, 400)
1✔
62
        self.assertEqual(
1✔
63
            response.json(),
64
            {"detail": "You have to specify at least one post to split."},
65
        )
66

67
    @patch_category_acl({"can_move_posts": True})
1✔
68
    def test_invalid_data(self):
1✔
69
        """api handles post that is invalid type"""
70
        response = self.client.post(
1✔
71
            self.api_link, "[]", content_type="application/json"
72
        )
73
        self.assertEqual(response.status_code, 400)
1✔
74
        self.assertEqual(
1✔
75
            response.json(),
76
            {
77
                "non_field_errors": [
78
                    "Invalid data. Expected a dictionary, but got list."
79
                ]
80
            },
81
        )
82

83
        response = self.client.post(
1✔
84
            self.api_link, "123", content_type="application/json"
85
        )
86
        self.assertEqual(response.status_code, 400)
1✔
87
        self.assertEqual(
1✔
88
            response.json(),
89
            {"non_field_errors": ["Invalid data. Expected a dictionary, but got int."]},
90
        )
91

92
        response = self.client.post(
1✔
93
            self.api_link, '"string"', content_type="application/json"
94
        )
95
        self.assertEqual(response.status_code, 400)
1✔
96
        self.assertEqual(
1✔
97
            response.json(),
98
            {"non_field_errors": ["Invalid data. Expected a dictionary, but got str."]},
99
        )
100

101
        response = self.client.post(
1✔
102
            self.api_link, "malformed", content_type="application/json"
103
        )
104
        self.assertEqual(response.status_code, 400)
1✔
105
        self.assertEqual(
1✔
106
            response.json(),
107
            {"detail": "JSON parse error - Expecting value: line 1 column 1 (char 0)"},
108
        )
109

110
    @patch_category_acl({"can_move_posts": True})
1✔
111
    def test_no_posts_ids(self):
1✔
112
        """api rejects no posts ids"""
113
        response = self.client.post(
1✔
114
            self.api_link, json.dumps({}), content_type="application/json"
115
        )
116
        self.assertEqual(response.status_code, 400)
1✔
117
        self.assertEqual(
1✔
118
            response.json(),
119
            {"detail": "You have to specify at least one post to split."},
120
        )
121

122
    @patch_category_acl({"can_move_posts": True})
1✔
123
    def test_empty_posts_ids(self):
1✔
124
        """api rejects empty posts ids list"""
125
        response = self.client.post(
1✔
126
            self.api_link, json.dumps({"posts": []}), content_type="application/json"
127
        )
128
        self.assertEqual(response.status_code, 400)
1✔
129
        self.assertEqual(
1✔
130
            response.json(),
131
            {"detail": "You have to specify at least one post to split."},
132
        )
133

134
    @patch_category_acl({"can_move_posts": True})
1✔
135
    def test_invalid_posts_data(self):
1✔
136
        """api handles invalid data"""
137
        response = self.client.post(
1✔
138
            self.api_link,
139
            json.dumps({"posts": "string"}),
140
            content_type="application/json",
141
        )
142
        self.assertEqual(response.status_code, 400)
1✔
143
        self.assertEqual(
1✔
144
            response.json(), {"detail": 'Expected a list of items but got type "str".'}
145
        )
146

147
    @patch_category_acl({"can_move_posts": True})
1✔
148
    def test_invalid_posts_ids(self):
1✔
149
        """api handles invalid post id"""
150
        response = self.client.post(
1✔
151
            self.api_link,
152
            json.dumps({"posts": [1, 2, "string"]}),
153
            content_type="application/json",
154
        )
155
        self.assertEqual(response.status_code, 400)
1✔
156
        self.assertEqual(
1✔
157
            response.json(), {"detail": "One or more post ids received were invalid."}
158
        )
159

160
    @override_dynamic_settings(posts_per_page=5, posts_per_page_orphans=3)
1✔
161
    @patch_category_acl({"can_move_posts": True})
1✔
162
    def test_split_limit(self):
1✔
163
        """api rejects more posts than split limit"""
164
        response = self.client.post(
1✔
165
            self.api_link,
166
            json.dumps({"posts": list(range(9))}),
167
            content_type="application/json",
168
        )
169
        self.assertEqual(response.status_code, 400)
1✔
170
        self.assertEqual(
1✔
171
            response.json(),
172
            {"detail": "No more than 8 posts can be split at a single time."},
173
        )
174

175
    @patch_category_acl({"can_move_posts": True})
1✔
176
    def test_split_invisible(self):
1✔
177
        """api validates posts visibility"""
178
        response = self.client.post(
1✔
179
            self.api_link,
180
            json.dumps(
181
                {"posts": [test.reply_thread(self.thread, is_unapproved=True).pk]}
182
            ),
183
            content_type="application/json",
184
        )
185
        self.assertEqual(response.status_code, 400)
1✔
186
        self.assertEqual(
1✔
187
            response.json(),
188
            {"detail": "One or more posts to split could not be found."},
189
        )
190

191
    @patch_category_acl({"can_move_posts": True})
1✔
192
    def test_split_event(self):
1✔
193
        """api rejects events split"""
194
        response = self.client.post(
1✔
195
            self.api_link,
196
            json.dumps({"posts": [test.reply_thread(self.thread, is_event=True).pk]}),
197
            content_type="application/json",
198
        )
199
        self.assertEqual(response.status_code, 400)
1✔
200
        self.assertEqual(response.json(), {"detail": "Events can't be split."})
1✔
201

202
    @patch_category_acl({"can_move_posts": True})
1✔
203
    def test_split_first_post(self):
1✔
204
        """api rejects first post split"""
205
        response = self.client.post(
1✔
206
            self.api_link,
207
            json.dumps({"posts": [self.thread.first_post_id]}),
208
            content_type="application/json",
209
        )
210
        self.assertEqual(response.status_code, 400)
1✔
211
        self.assertEqual(
1✔
212
            response.json(), {"detail": "Thread's first post can't be split."}
213
        )
214

215
    @patch_category_acl({"can_move_posts": True})
1✔
216
    def test_split_hidden_posts(self):
1✔
217
        """api recjects attempt to split urneadable hidden post"""
218
        response = self.client.post(
1✔
219
            self.api_link,
220
            json.dumps({"posts": [test.reply_thread(self.thread, is_hidden=True).pk]}),
221
            content_type="application/json",
222
        )
223
        self.assertEqual(response.status_code, 400)
1✔
224
        self.assertEqual(
1✔
225
            response.json(),
226
            {"detail": "You can't split posts the content you can't see."},
227
        )
228

229
    @patch_category_acl({"can_move_posts": True, "can_close_threads": False})
1✔
230
    def test_split_posts_closed_thread_no_permission(self):
1✔
231
        """api recjects attempt to split posts from closed thread"""
232
        self.thread.is_closed = True
1✔
233
        self.thread.save()
1✔
234

235
        response = self.client.post(
1✔
236
            self.api_link,
237
            json.dumps({"posts": [test.reply_thread(self.thread).pk]}),
238
            content_type="application/json",
239
        )
240
        self.assertEqual(response.status_code, 400)
1✔
241
        self.assertEqual(
1✔
242
            response.json(),
243
            {"detail": "This thread is closed. You can't split posts in it."},
244
        )
245

246
    @patch_category_acl({"can_move_posts": True, "can_close_threads": False})
1✔
247
    def test_split_posts_closed_category_no_permission(self):
1✔
248
        """api recjects attempt to split posts from closed thread"""
249
        self.category.is_closed = True
1✔
250
        self.category.save()
1✔
251

252
        response = self.client.post(
1✔
253
            self.api_link,
254
            json.dumps({"posts": [test.reply_thread(self.thread).pk]}),
255
            content_type="application/json",
256
        )
257
        self.assertEqual(response.status_code, 400)
1✔
258
        self.assertEqual(
1✔
259
            response.json(),
260
            {"detail": "This category is closed. You can't split posts in it."},
261
        )
262

263
    @patch_category_acl({"can_move_posts": True})
1✔
264
    def test_split_other_thread_posts(self):
1✔
265
        """api recjects attempt to split other thread's post"""
266
        other_thread = test.post_thread(self.category)
1✔
267

268
        response = self.client.post(
1✔
269
            self.api_link,
270
            json.dumps({"posts": [test.reply_thread(other_thread, is_hidden=True).pk]}),
271
            content_type="application/json",
272
        )
273
        self.assertEqual(response.status_code, 400)
1✔
274
        self.assertEqual(
1✔
275
            response.json(),
276
            {"detail": "One or more posts to split could not be found."},
277
        )
278

279
    @patch_category_acl({"can_move_posts": True})
1✔
280
    def test_split_empty_new_thread_data(self):
1✔
281
        """api handles empty form data"""
282
        response = self.client.post(
1✔
283
            self.api_link,
284
            json.dumps({"posts": self.posts}),
285
            content_type="application/json",
286
        )
287
        self.assertEqual(response.status_code, 400)
1✔
288

289
        response_json = response.json()
1✔
290
        self.assertEqual(
1✔
291
            response_json,
292
            {
293
                "title": ["This field is required."],
294
                "category": ["This field is required."],
295
            },
296
        )
297

298
    @patch_category_acl({"can_move_posts": True})
1✔
299
    def test_split_invalid_final_title(self):
1✔
300
        """api rejects split because final thread title was invalid"""
301
        response = self.client.post(
1✔
302
            self.api_link,
303
            json.dumps(
304
                {"posts": self.posts, "title": "$$$", "category": self.category.id}
305
            ),
306
            content_type="application/json",
307
        )
308
        self.assertEqual(response.status_code, 400)
1✔
309

310
        response_json = response.json()
1✔
311
        self.assertEqual(
1✔
312
            response_json,
313
            {
314
                "title": [
315
                    "Thread title should be at least 5 characters long (it has 3)."
316
                ]
317
            },
318
        )
319

320
    @patch_other_category_acl({"can_see": False})
1✔
321
    @patch_category_acl({"can_move_posts": True})
1✔
322
    def test_split_invalid_category(self):
1✔
323
        """api rejects split because final category was invalid"""
324
        response = self.client.post(
1✔
325
            self.api_link,
326
            json.dumps(
327
                {
328
                    "posts": self.posts,
329
                    "title": "Valid thread title",
330
                    "category": self.other_category.id,
331
                }
332
            ),
333
            content_type="application/json",
334
        )
335
        self.assertEqual(response.status_code, 400)
1✔
336

337
        response_json = response.json()
1✔
338
        self.assertEqual(
1✔
339
            response_json, {"category": ["Requested category could not be found."]}
340
        )
341

342
    @patch_category_acl({"can_move_posts": True, "can_start_threads": False})
1✔
343
    def test_split_unallowed_start_thread(self):
1✔
344
        """api rejects split because category isn't allowing starting threads"""
345
        response = self.client.post(
1✔
346
            self.api_link,
347
            json.dumps(
348
                {
349
                    "posts": self.posts,
350
                    "title": "Valid thread title",
351
                    "category": self.category.id,
352
                }
353
            ),
354
            content_type="application/json",
355
        )
356
        self.assertEqual(response.status_code, 400)
1✔
357

358
        response_json = response.json()
1✔
359
        self.assertEqual(
1✔
360
            response_json,
361
            {"category": ["You can't create new threads in selected category."]},
362
        )
363

364
    @patch_category_acl({"can_move_posts": True})
1✔
365
    def test_split_invalid_weight(self):
1✔
366
        """api rejects split because final weight was invalid"""
367
        response = self.client.post(
1✔
368
            self.api_link,
369
            json.dumps(
370
                {
371
                    "posts": self.posts,
372
                    "title": "Valid thread title",
373
                    "category": self.category.id,
374
                    "weight": 4,
375
                }
376
            ),
377
            content_type="application/json",
378
        )
379
        self.assertEqual(response.status_code, 400)
1✔
380

381
        response_json = response.json()
1✔
382
        self.assertEqual(
1✔
383
            response_json, {"weight": ["Ensure this value is less than or equal to 2."]}
384
        )
385

386
    @patch_category_acl({"can_move_posts": True})
1✔
387
    def test_split_unallowed_global_weight(self):
1✔
388
        """api rejects split because global weight was unallowed"""
389
        response = self.client.post(
1✔
390
            self.api_link,
391
            json.dumps(
392
                {
393
                    "posts": self.posts,
394
                    "title": "Valid thread title",
395
                    "category": self.category.id,
396
                    "weight": 2,
397
                }
398
            ),
399
            content_type="application/json",
400
        )
401
        self.assertEqual(response.status_code, 400)
1✔
402

403
        response_json = response.json()
1✔
404
        self.assertEqual(
1✔
405
            response_json,
406
            {
407
                "weight": [
408
                    "You don't have permission to pin threads "
409
                    "globally in this category."
410
                ]
411
            },
412
        )
413

414
    @patch_category_acl({"can_move_posts": True, "can_pin_threads": 0})
1✔
415
    def test_split_unallowed_local_weight(self):
1✔
416
        """api rejects split because local weight was unallowed"""
417
        response = self.client.post(
1✔
418
            self.api_link,
419
            json.dumps(
420
                {
421
                    "posts": self.posts,
422
                    "title": "Valid thread title",
423
                    "category": self.category.id,
424
                    "weight": 1,
425
                }
426
            ),
427
            content_type="application/json",
428
        )
429
        self.assertEqual(response.status_code, 400)
1✔
430

431
        response_json = response.json()
1✔
432
        self.assertEqual(
1✔
433
            response_json,
434
            {"weight": ["You don't have permission to pin threads in this category."]},
435
        )
436

437
    @patch_category_acl({"can_move_posts": True, "can_pin_threads": 1})
1✔
438
    def test_split_allowed_local_weight(self):
1✔
439
        """api allows local weight"""
440
        response = self.client.post(
1✔
441
            self.api_link,
442
            json.dumps(
443
                {
444
                    "posts": self.posts,
445
                    "title": "$$$",
446
                    "category": self.category.id,
447
                    "weight": 1,
448
                }
449
            ),
450
            content_type="application/json",
451
        )
452
        self.assertEqual(response.status_code, 400)
1✔
453

454
        response_json = response.json()
1✔
455
        self.assertEqual(
1✔
456
            response_json,
457
            {
458
                "title": [
459
                    "Thread title should be at least 5 characters long (it has 3)."
460
                ]
461
            },
462
        )
463

464
    @patch_category_acl({"can_move_posts": True, "can_pin_threads": 2})
1✔
465
    def test_split_allowed_global_weight(self):
1✔
466
        """api allows global weight"""
467
        response = self.client.post(
1✔
468
            self.api_link,
469
            json.dumps(
470
                {
471
                    "posts": self.posts,
472
                    "title": "$$$",
473
                    "category": self.category.id,
474
                    "weight": 2,
475
                }
476
            ),
477
            content_type="application/json",
478
        )
479
        self.assertEqual(response.status_code, 400)
1✔
480

481
        response_json = response.json()
1✔
482
        self.assertEqual(
1✔
483
            response_json,
484
            {
485
                "title": [
486
                    "Thread title should be at least 5 characters long (it has 3)."
487
                ]
488
            },
489
        )
490

491
    @patch_category_acl({"can_move_posts": True, "can_close_threads": False})
1✔
492
    def test_split_unallowed_close(self):
1✔
493
        """api rejects split because closing thread was unallowed"""
494
        response = self.client.post(
1✔
495
            self.api_link,
496
            json.dumps(
497
                {
498
                    "posts": self.posts,
499
                    "title": "Valid thread title",
500
                    "category": self.category.id,
501
                    "is_closed": True,
502
                }
503
            ),
504
            content_type="application/json",
505
        )
506
        self.assertEqual(response.status_code, 400)
1✔
507

508
        response_json = response.json()
1✔
509
        self.assertEqual(
1✔
510
            response_json,
511
            {
512
                "is_closed": [
513
                    "You don't have permission to close threads in this category."
514
                ]
515
            },
516
        )
517

518
    @patch_category_acl({"can_move_posts": True, "can_close_threads": True})
1✔
519
    def test_split_with_close(self):
1✔
520
        """api allows for closing thread"""
521
        response = self.client.post(
1✔
522
            self.api_link,
523
            json.dumps(
524
                {
525
                    "posts": self.posts,
526
                    "title": "$$$",
527
                    "category": self.category.id,
528
                    "weight": 0,
529
                    "is_closed": True,
530
                }
531
            ),
532
            content_type="application/json",
533
        )
534
        self.assertEqual(response.status_code, 400)
1✔
535

536
        response_json = response.json()
1✔
537
        self.assertEqual(
1✔
538
            response_json,
539
            {
540
                "title": [
541
                    "Thread title should be at least 5 characters long (it has 3)."
542
                ]
543
            },
544
        )
545

546
    @patch_category_acl({"can_move_posts": True, "can_hide_threads": 0})
1✔
547
    def test_split_unallowed_hidden(self):
1✔
548
        """api rejects split because hidden thread was unallowed"""
549
        response = self.client.post(
1✔
550
            self.api_link,
551
            json.dumps(
552
                {
553
                    "posts": self.posts,
554
                    "title": "Valid thread title",
555
                    "category": self.category.id,
556
                    "is_hidden": True,
557
                }
558
            ),
559
            content_type="application/json",
560
        )
561
        self.assertEqual(response.status_code, 400)
1✔
562

563
        response_json = response.json()
1✔
564
        self.assertEqual(
1✔
565
            response_json,
566
            {
567
                "is_hidden": [
568
                    "You don't have permission to hide threads in this category."
569
                ]
570
            },
571
        )
572

573
    @patch_category_acl({"can_move_posts": True, "can_hide_threads": 1})
1✔
574
    def test_split_with_hide(self):
1✔
575
        """api allows for hiding thread"""
576
        response = self.client.post(
1✔
577
            self.api_link,
578
            json.dumps(
579
                {
580
                    "posts": self.posts,
581
                    "title": "$$$",
582
                    "category": self.category.id,
583
                    "weight": 0,
584
                    "is_hidden": True,
585
                }
586
            ),
587
            content_type="application/json",
588
        )
589
        self.assertEqual(response.status_code, 400)
1✔
590

591
        response_json = response.json()
1✔
592
        self.assertEqual(
1✔
593
            response_json,
594
            {
595
                "title": [
596
                    "Thread title should be at least 5 characters long (it has 3)."
597
                ]
598
            },
599
        )
600

601
    @patch_category_acl({"can_move_posts": True})
1✔
602
    def test_split(self):
1✔
603
        """api splits posts to new thread"""
604
        self.thread.refresh_from_db()
1✔
605
        self.assertEqual(self.thread.replies, 2)
1✔
606

607
        response = self.client.post(
1✔
608
            self.api_link,
609
            json.dumps(
610
                {
611
                    "posts": self.posts,
612
                    "title": "Split thread.",
613
                    "category": self.category.id,
614
                }
615
            ),
616
            content_type="application/json",
617
        )
618
        self.assertEqual(response.status_code, 200)
1✔
619

620
        # thread was created
621
        split_thread = self.category.thread_set.get(slug="split-thread")
1✔
622
        self.assertEqual(split_thread.replies, 1)
1✔
623

624
        # posts were removed from old thread
625
        self.thread.refresh_from_db()
1✔
626
        self.assertEqual(self.thread.replies, 0)
1✔
627

628
        # posts were moved to new thread
629
        self.assertEqual(split_thread.post_set.filter(pk__in=self.posts).count(), 2)
1✔
630

631
    @patch_category_acl({"can_move_posts": True})
1✔
632
    def test_split_best_answer(self):
1✔
633
        """api splits best answer to new thread"""
634
        best_answer = test.reply_thread(self.thread)
1✔
635

636
        self.thread.set_best_answer(self.user, best_answer)
1✔
637
        self.thread.synchronize()
1✔
638
        self.thread.save()
1✔
639

640
        self.thread.refresh_from_db()
1✔
641
        self.assertEqual(self.thread.best_answer, best_answer)
1✔
642
        self.assertEqual(self.thread.replies, 3)
1✔
643

644
        response = self.client.post(
1✔
645
            self.api_link,
646
            json.dumps(
647
                {
648
                    "posts": [best_answer.pk],
649
                    "title": "Split thread.",
650
                    "category": self.category.id,
651
                }
652
            ),
653
            content_type="application/json",
654
        )
655
        self.assertEqual(response.status_code, 200)
1✔
656

657
        # best_answer was moved and unmarked
658
        self.thread.refresh_from_db()
1✔
659
        self.assertEqual(self.thread.replies, 2)
1✔
660
        self.assertIsNone(self.thread.best_answer)
1✔
661

662
        split_thread = self.category.thread_set.get(slug="split-thread")
1✔
663
        self.assertEqual(split_thread.replies, 0)
1✔
664
        self.assertIsNone(split_thread.best_answer)
1✔
665

666
    @expectedFailure
1✔
667
    @patch_other_category_acl(
1✔
668
        {
669
            "can_start_threads": True,
670
            "can_close_threads": True,
671
            "can_hide_threads": True,
672
            "can_pin_threads": 2,
673
        }
674
    )
675
    @patch_category_acl({"can_move_posts": True})
1✔
676
    def test_split_kitchensink(self):
1✔
677
        """api splits posts with kitchensink"""
678
        self.thread.refresh_from_db()
1✔
679
        self.assertEqual(self.thread.replies, 2)
1✔
680

681
        poststracker.save_read(self.user, self.thread.first_post)
1✔
UNCOV
682
        for post in self.posts:
×
UNCOV
683
            poststracker.save_read(
×
684
                self.user, Post.objects.select_related().get(pk=post)
685
            )
686

UNCOV
687
        response = self.client.post(
×
688
            self.api_link,
689
            json.dumps(
690
                {
691
                    "posts": self.posts,
692
                    "title": "Split thread",
693
                    "category": self.other_category.id,
694
                    "weight": 2,
695
                    "is_closed": 1,
696
                    "is_hidden": 1,
697
                }
698
            ),
699
            content_type="application/json",
700
        )
UNCOV
701
        self.assertEqual(response.status_code, 200)
×
702

703
        # thread was created
UNCOV
704
        split_thread = self.other_category.thread_set.get(slug="split-thread")
×
UNCOV
705
        self.assertEqual(split_thread.replies, 1)
×
UNCOV
706
        self.assertEqual(split_thread.weight, 2)
×
UNCOV
707
        self.assertTrue(split_thread.is_closed)
×
UNCOV
708
        self.assertTrue(split_thread.is_hidden)
×
709

710
        # posts were removed from old thread
UNCOV
711
        self.thread.refresh_from_db()
×
UNCOV
712
        self.assertEqual(self.thread.replies, 0)
×
713

714
        # posts were moved to new thread
UNCOV
715
        self.assertEqual(split_thread.post_set.filter(pk__in=self.posts).count(), 2)
×
716

717
        # postreads were removed
UNCOV
718
        postreads = self.user.postread_set.filter(post__is_event=False).order_by("id")
×
719

UNCOV
720
        postreads_threads = list(postreads.values_list("thread_id", flat=True))
×
UNCOV
721
        self.assertEqual(postreads_threads, [self.thread.pk])
×
722

UNCOV
723
        postreads_categories = list(postreads.values_list("category_id", flat=True))
×
UNCOV
724
        self.assertEqual(postreads_categories, [self.category.pk])
×
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