Skip to content

Commit 0d218e0

Browse files
committed
Add delete attachments to posting states
1 parent 4432ac7 commit 0d218e0

File tree

5 files changed

+152
-25
lines changed

5 files changed

+152
-25
lines changed

misago/posting/state/base.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from django.http import HttpRequest
77
from django.utils import timezone
88

9+
from ...attachments.delete import delete_attachments
910
from ...attachments.models import Attachment
1011
from ...categories.models import Category
1112
from ...core.utils import slugify
@@ -30,6 +31,7 @@ class PostingState:
3031
thread: Thread
3132
post: Post
3233
attachments: list[Attachment]
34+
delete_attachments: list[Attachment]
3335

3436
parser_context: ParserContext
3537
message_ast: list[dict] | None
@@ -51,6 +53,7 @@ def __init__(self, request: HttpRequest):
5153
self.plugin_state = {}
5254

5355
self.attachments = []
56+
self.delete_attachments = []
5457

5558
self.store_object_state(self.user)
5659

@@ -141,6 +144,19 @@ def set_post_message(self, message: str):
141144
def set_attachments(self, attachments: list[Attachment]):
142145
self.attachments = attachments
143146

147+
def set_delete_attachments(self, attachments: list[Attachment]):
148+
self.delete_attachments = []
149+
delete_ids: set[int] = set(a.id for a in attachments)
150+
save_attachments: list[Attachment] = []
151+
152+
for attachment in self.attachments:
153+
if attachment.id in delete_ids:
154+
self.delete_attachments.append(attachment)
155+
else:
156+
save_attachments.append(attachment)
157+
158+
self.set_attachments(save_attachments)
159+
144160
def save_attachments(self):
145161
for attachment in self.attachments:
146162
if attachment.post_id:
@@ -151,3 +167,6 @@ def save_attachments(self):
151167
attachment.post = self.post
152168
attachment.uploaded_at = self.timestamp
153169
attachment.save()
170+
171+
if self.delete_attachments:
172+
delete_attachments(self.delete_attachments, request=self.request)

misago/posting/state/edit.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
from django.db import models, transaction
22
from django.http import HttpRequest
33

4-
from ...attachments.delete import delete_attachments
5-
from ...attachments.models import Attachment
64
from ...threads.checksums import update_post_checksum
75
from ...threads.models import Post
86
from ..hooks import (
@@ -18,13 +16,10 @@ class EditThreadPostState(PostingState):
1816
# This state can actually edit both post and its thread's title
1917
thread_title: str
2018
post_original: str
21-
delete_attachments: list[Attachment]
2219

2320
def __init__(self, request: HttpRequest, post: Post):
2421
super().__init__(request)
2522

26-
self.delete_attachments = []
27-
2823
self.category = post.category
2924
self.thread = post.thread
3025
self.post = post
@@ -36,19 +31,6 @@ def __init__(self, request: HttpRequest, post: Post):
3631
self.thread_title = self.thread.title
3732
self.post_original = post.original
3833

39-
def set_delete_attachments(self, attachments: list[Attachment]):
40-
self.delete_attachments = []
41-
delete_ids: list[int] = [a.id for a in attachments]
42-
save_attachments: list[Attachment] = []
43-
44-
for attachment in self.attachments:
45-
if attachment.id in delete_ids:
46-
self.delete_attachments.append(attachment)
47-
else:
48-
save_attachments.append(attachment)
49-
50-
self.set_attachments(save_attachments)
51-
5234
@transaction.atomic()
5335
def save(self):
5436
save_edit_thread_post_state_hook(self.save_action, self.request, self)
@@ -85,12 +67,6 @@ def save_category(self):
8567
self.category.last_thread_slug = self.thread.slug
8668
self.update_object(self.category)
8769

88-
def save_attachments(self):
89-
super().save_attachments()
90-
91-
if self.delete_attachments:
92-
delete_attachments(self.delete_attachments, request=self.request)
93-
9470

9571
class EditPrivateThreadPostState(EditThreadPostState):
9672
@transaction.atomic()

misago/posting/tests/test_edit_thread_post_state.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,92 @@ def test_edit_thread_post_state_save_updates_post(
3030
assert post.last_editor == user
3131
assert post.last_editor_name == user.username
3232
assert post.last_editor_slug == user.slug
33+
34+
35+
def test_edit_thread_post_state_save_updates_post_attachments(
36+
user, other_user, user_request, other_user_thread, text_file, attachment_factory
37+
):
38+
post = other_user_thread.first_post
39+
post_attachment = attachment_factory(text_file, uploader=other_user, post=post)
40+
41+
attachment = attachment_factory(text_file, uploader=user)
42+
assert not attachment.category
43+
assert not attachment.thread
44+
assert not attachment.post
45+
46+
state = EditThreadPostState(user_request, other_user_thread.first_post)
47+
state.set_post_message("Edit reply")
48+
state.set_attachments([attachment])
49+
state.save()
50+
51+
post_attachment.refresh_from_db()
52+
assert post_attachment.category == other_user_thread.category
53+
assert post_attachment.thread == other_user_thread
54+
assert post_attachment.post == post
55+
assert post_attachment.uploader == other_user
56+
assert post_attachment.uploaded_at < state.timestamp
57+
58+
attachment.refresh_from_db()
59+
assert attachment.category == other_user_thread.category
60+
assert attachment.thread == other_user_thread
61+
assert attachment.post == post
62+
assert attachment.uploader == user
63+
assert attachment.uploaded_at == state.timestamp
64+
65+
66+
def test_edit_thread_post_state_save_deletes_post_attachments(
67+
user, other_user, user_request, other_user_thread, text_file, attachment_factory
68+
):
69+
post = other_user_thread.first_post
70+
post_attachment = attachment_factory(text_file, uploader=other_user, post=post)
71+
72+
attachment = attachment_factory(text_file, uploader=user, post=post)
73+
74+
state = EditThreadPostState(user_request, other_user_thread.first_post)
75+
state.set_post_message("Edit reply")
76+
state.set_attachments([attachment, post_attachment])
77+
state.set_delete_attachments([attachment])
78+
state.save()
79+
80+
post_attachment.refresh_from_db()
81+
assert post_attachment.category == other_user_thread.category
82+
assert post_attachment.thread == other_user_thread
83+
assert post_attachment.post == post
84+
assert post_attachment.uploader == other_user
85+
assert post_attachment.uploaded_at < state.timestamp
86+
87+
attachment.refresh_from_db()
88+
assert not attachment.category
89+
assert not attachment.thread
90+
assert not attachment.post
91+
assert attachment.uploader == user
92+
assert attachment.is_deleted
93+
94+
95+
def test_edit_thread_post_state_save_deletes_temporary_attachments(
96+
user, other_user, user_request, other_user_thread, text_file, attachment_factory
97+
):
98+
post = other_user_thread.first_post
99+
post_attachment = attachment_factory(text_file, uploader=other_user, post=post)
100+
101+
temp_attachment = attachment_factory(text_file, uploader=user)
102+
103+
state = EditThreadPostState(user_request, other_user_thread.first_post)
104+
state.set_post_message("Edit reply")
105+
state.set_attachments([temp_attachment, post_attachment])
106+
state.set_delete_attachments([temp_attachment])
107+
state.save()
108+
109+
post_attachment.refresh_from_db()
110+
assert post_attachment.category == other_user_thread.category
111+
assert post_attachment.thread == other_user_thread
112+
assert post_attachment.post == post
113+
assert post_attachment.uploader == other_user
114+
assert post_attachment.uploaded_at < state.timestamp
115+
116+
temp_attachment.refresh_from_db()
117+
assert not temp_attachment.category
118+
assert not temp_attachment.thread
119+
assert not temp_attachment.post
120+
assert temp_attachment.uploader == user
121+
assert temp_attachment.is_deleted

misago/posting/tests/test_reply_thread_state.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def test_reply_thread_state_assigns_attachments_to_category_thread_and_post(
130130
assert attachment.uploaded_at == state.timestamp
131131

132132

133-
def test_reply_thread_state_updates_existing_post(
133+
def test_reply_thread_state_updates_existing_post_attachments(
134134
user, user_request, user_thread, text_file, attachment_factory
135135
):
136136
post = user_thread.first_post

misago/posting/tests/test_start_thread_state.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,46 @@ def test_start_thread_state_assigns_attachments_to_category_thread_and_post(
8585
assert attachment.thread == state.thread
8686
assert attachment.post == state.post
8787
assert attachment.uploaded_at == state.timestamp
88+
89+
90+
def test_start_thread_state_deletes_temp_attachments(
91+
user_request, default_category, user, text_file, attachment_factory
92+
):
93+
attachment = attachment_factory(text_file, uploader=user)
94+
assert not attachment.category
95+
assert not attachment.thread
96+
assert not attachment.post
97+
98+
state = StartThreadState(user_request, default_category)
99+
state.set_thread_title("Test thread")
100+
state.set_post_message("Hello world")
101+
state.set_attachments([attachment])
102+
state.set_delete_attachments([attachment])
103+
state.save()
104+
105+
attachment.refresh_from_db()
106+
assert not attachment.category
107+
assert not attachment.thread
108+
assert not attachment.post
109+
assert attachment.is_deleted
110+
111+
112+
def test_start_thread_state_delete_attachments_excludes_unknown_attachments(
113+
user_request, default_category, user, text_file, attachment_factory, post
114+
):
115+
attachment = attachment_factory(text_file, uploader=user, post=post)
116+
assert attachment.category == post.category
117+
assert attachment.thread == post.thread
118+
assert attachment.post == post
119+
120+
state = StartThreadState(user_request, default_category)
121+
state.set_thread_title("Test thread")
122+
state.set_post_message("Hello world")
123+
state.set_delete_attachments([attachment])
124+
state.save()
125+
126+
attachment.refresh_from_db()
127+
assert attachment.category == post.category
128+
assert attachment.thread == post.thread
129+
assert attachment.post == post
130+
assert not attachment.is_deleted

0 commit comments

Comments
 (0)