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

rafalp / Misago / 17496798327

05 Sep 2025 02:59PM UTC coverage: 96.509% (-0.3%) from 96.769%
17496798327

Pull #1995

github

web-flow
Merge 17284d7d7 into 6bb938c90
Pull Request #1995: Move `Post` model from `misago.threads` to `misago.posts`

1884 of 1974 new or added lines in 149 files covered. (95.44%)

305 existing lines in 16 files now uncovered.

66716 of 69129 relevant lines covered (96.51%)

0.97 hits per line

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

21.82
/misago/threads/moderation/posts.py
1
from django.db import transaction
1✔
2
from django.utils import timezone
1✔
3
from django.utils.translation import pgettext
1✔
4

5
from .exceptions import ModerationError
1✔
6

7
__all__ = [
1✔
8
    "approve_post",
9
    "protect_post",
10
    "unprotect_post",
11
    "unhide_post",
12
    "hide_post",
13
    "delete_post",
14
]
15

16

17
def approve_post(user, post):
1✔
18
    if not post.is_unapproved:
×
19
        return False
×
20

21
    post.is_unapproved = False
×
22
    post.save(update_fields=["is_unapproved"])
×
23
    return True
×
24

25

26
def protect_post(user, post):
1✔
UNCOV
27
    if post.is_protected:
×
UNCOV
28
        return False
×
29

UNCOV
30
    post.is_protected = True
×
UNCOV
31
    post.save(update_fields=["is_protected"])
×
UNCOV
32
    if post.is_best_answer:
×
33
        post.thread.best_answer_is_protected = True
×
34
        post.thread.save(update_fields=["best_answer_is_protected"])
×
UNCOV
35
    return True
×
36

37

38
def unprotect_post(user, post):
1✔
UNCOV
39
    if not post.is_protected:
×
UNCOV
40
        return False
×
41

UNCOV
42
    post.is_protected = False
×
UNCOV
43
    post.save(update_fields=["is_protected"])
×
UNCOV
44
    if post.is_best_answer:
×
45
        post.thread.best_answer_is_protected = False
×
46
        post.thread.save(update_fields=["best_answer_is_protected"])
×
UNCOV
47
    return True
×
48

49

50
def unhide_post(user, post):
1✔
UNCOV
51
    if post.is_first_post:
×
UNCOV
52
        raise ModerationError(
×
53
            pgettext(
54
                "post unhide",
55
                "You can't make original post visible without revealing the thread.",
56
            )
57
        )
58

UNCOV
59
    if not post.is_hidden:
×
UNCOV
60
        return False
×
61

UNCOV
62
    post.is_hidden = False
×
UNCOV
63
    post.save(update_fields=["is_hidden"])
×
UNCOV
64
    return True
×
65

66

67
def hide_post(user, post):
1✔
UNCOV
68
    if post.is_first_post:
×
UNCOV
69
        raise ModerationError(
×
70
            pgettext("post hide", "You can't hide original post without hiding thread.")
71
        )
72

UNCOV
73
    if post.is_hidden:
×
UNCOV
74
        return False
×
75

UNCOV
76
    post.is_hidden = True
×
UNCOV
77
    post.hidden_by = user
×
UNCOV
78
    post.hidden_by_name = user.username
×
UNCOV
79
    post.hidden_by_slug = user.slug
×
UNCOV
80
    post.hidden_on = timezone.now()
×
UNCOV
81
    post.save(
×
82
        update_fields=[
83
            "is_hidden",
84
            "hidden_by",
85
            "hidden_by_name",
86
            "hidden_by_slug",
87
            "hidden_on",
88
        ]
89
    )
UNCOV
90
    return True
×
91

92

93
@transaction.atomic
1✔
94
def delete_post(user, post):
1✔
UNCOV
95
    if post.is_first_post:
×
UNCOV
96
        raise ModerationError(
×
97
            pgettext(
98
                "post delete", "You can't delete original post without deleting thread."
99
            )
100
        )
101

UNCOV
102
    post.delete()
×
UNCOV
103
    return True
×
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