desmos_bindings/posts/
msg.rs

1//! Contains the messages that can be sent to the chain to interact with the x/posts module.
2
3use crate::posts::types::AttachmentContent;
4use crate::posts::types::*;
5use cosmwasm_std::Addr;
6
7/// Represents the messages to interact with the posts module.
8pub struct PostsMsg {}
9
10impl PostsMsg {
11    /// Creates an instance of [`MsgCreatePost`].
12    ///
13    /// * `subspace_id` - Id of the subspace inside which the post must be created.
14    /// * `section_id` - Id of the section inside which the post must be created.
15    /// * `external_id` - External id for this post.
16    /// * `text` - Text of the post.
17    /// * `entities` - Entities connected to this post.
18    /// * `tags` - Tags related to this post.
19    /// * `attachments` - Attachments of the post.
20    /// * `author` - Author of the post.
21    /// * `conversation_id` - Id of the original post of the conversation.
22    /// * `reply_settings` - Reply settings of this post.
23    /// * `reference_posts` - A list this posts references (either as a reply, repost or quote).
24    pub fn create_post(
25        subspace_id: u64,
26        section_id: u32,
27        external_id: Option<&str>,
28        text: &str,
29        entities: Option<Entities>,
30        tags: Vec<&str>,
31        attachments: Vec<AttachmentContent>,
32        author: Addr,
33        conversation_id: Option<u64>,
34        reply_settings: ReplySetting,
35        referenced_posts: Vec<PostReference>,
36    ) -> MsgCreatePost {
37        MsgCreatePost {
38            subspace_id,
39            section_id,
40            external_id: external_id.unwrap_or_default().into(),
41            text: text.into(),
42            entities,
43            attachments: attachments.into_iter().map(Into::into).collect(),
44            tags: tags.into_iter().map(Into::into).collect(),
45            author: author.into(),
46            conversation_id: conversation_id.unwrap_or_default(),
47            reply_settings: reply_settings.into(),
48            referenced_posts,
49        }
50    }
51
52    /// Creates an instance of [`MsgEditPost`].
53    ///
54    /// * `subspace_id` - Id of the subspace inside which the post is.
55    /// * `post_id` - Id of the post to edit.
56    /// * `text` - New text of the post. It will not change the current post's text if set this field to `None`.
57    /// * `entities` - New entities connected to this post. These will always replace the current post's entities.
58    /// * `editor` - Editor of the post.
59    pub fn edit_post(
60        subspace_id: u64,
61        post_id: u64,
62        text: Option<&str>,
63        entities: Option<Entities>,
64        tags: Vec<&str>,
65        editor: Addr,
66    ) -> MsgEditPost {
67        MsgEditPost {
68            subspace_id,
69            post_id,
70            text: text.unwrap_or("[do-not-modify]").into(),
71            entities,
72            tags: tags.into_iter().map(Into::into).collect(),
73            editor: editor.into(),
74        }
75    }
76
77    /// Creates an instance of [`MsgDeletePost`].
78    ///
79    /// * `subspace_id` - Id of the subspace containing the post.
80    /// * `post_id` - Id of the post to be deleted.
81    /// * `signer` - User that is deleting the post.
82    pub fn delete_post(subspace_id: u64, post_id: u64, signer: Addr) -> MsgDeletePost {
83        MsgDeletePost {
84            subspace_id,
85            post_id,
86            signer: signer.into(),
87        }
88    }
89
90    /// Creates an instance of [`MsgAddPostAttachment`].
91    ///
92    /// * `subspace_id` - Id of the subspace containing the post.
93    /// * `post_id` - Id of the post from which to remove the attachment.
94    /// * `attachment_id` - Id of the attachment to be removed.
95    /// * `editor` - User that is removing the attachment.
96    pub fn add_post_attachment(
97        subspace_id: u64,
98        post_id: u64,
99        content: AttachmentContent,
100        editor: Addr,
101    ) -> MsgAddPostAttachment {
102        MsgAddPostAttachment {
103            subspace_id,
104            post_id,
105            content: Some(content.into()),
106            editor: editor.into(),
107        }
108    }
109
110    /// Creates an instance of [`MsgRemovePostAttachment`].
111    ///
112    /// * `subspace_id` - Id of the subspace containing the post.
113    /// * `post_id` - Id of the post from which to remove the attachment.
114    /// * `attachment_id` - Id of the attachment to be removed.
115    /// * `editor` - User that is removing the attachment.
116    pub fn remove_post_attachment(
117        subspace_id: u64,
118        post_id: u64,
119        attachment_id: u32,
120        editor: Addr,
121    ) -> MsgRemovePostAttachment {
122        MsgRemovePostAttachment {
123            subspace_id,
124            post_id,
125            attachment_id,
126            editor: editor.into(),
127        }
128    }
129
130    /// Creates an instance of [`MsgAnswerPoll`].
131    /// * `subspace_id` - Id of the subspace containing the post.
132    /// * `post_id` - Id of the post that contains the poll to be answered.
133    /// * `poll_id` - Id of the poll to be answered.
134    /// * `answers_indexes` - Indexes of the answer inside the ProvidedAnswers array.
135    /// * `signer` - Address of the user answering the poll.
136    pub fn answer_poll(
137        subspace_id: u64,
138        post_id: u64,
139        poll_id: u32,
140        answers_indexes: Vec<u32>,
141        signer: Addr,
142    ) -> MsgAnswerPoll {
143        MsgAnswerPoll {
144            subspace_id,
145            post_id,
146            poll_id,
147            answers_indexes,
148            signer: signer.into(),
149        }
150    }
151
152    /// Creates an instance of [`MsgMovePost`].
153    /// * `subspace_id` - Id of the subspace where the post is currently located.
154    /// * `post_id` - Id of the post to be moved.
155    /// * `target_subspace_id` - Id of the target subspace to which the post will be moved.
156    /// * `target_section_id` - Id of the target section to which the post will be moved.
157    /// * `owner` - Address of the post owner.
158    pub fn move_post(
159        subspace_id: u64,
160        post_id: u64,
161        target_subspace_id: u64,
162        target_section_id: u32,
163        owner: Addr,
164    ) -> MsgMovePost {
165        MsgMovePost {
166            subspace_id,
167            post_id,
168            target_subspace_id,
169            target_section_id,
170            owner: owner.into(),
171        }
172    }
173
174    /// Creates an instance of [`MsgRequestPostOwnerTransfer`].
175    /// * `subspace_id` - Id of the subspace that holds the post which ownership should be transferred.
176    /// * `post_id` - Id of the post which will be transferred.
177    /// * `receiver` - Address of the post ownership receiver.
178    /// * `sender` - Address of the sender who is creating a transfer request.
179    pub fn request_post_owner_transfer(
180        subspace_id: u64,
181        post_id: u64,
182        receiver: Addr,
183        sender: Addr,
184    ) -> MsgRequestPostOwnerTransfer {
185        MsgRequestPostOwnerTransfer {
186            subspace_id,
187            post_id,
188            receiver: receiver.into(),
189            sender: sender.into(),
190        }
191    }
192
193    /// Creates an instance of [`MsgCancelPostOwnerTransferRequest`].
194    /// * `subspace_id` - Id of the subspace that holds the post for which the request should be canceled.
195    /// * `post_id` - Id of the post for which the request will be cancelled.
196    /// * `sender` - Address of the transfer request sender.
197    pub fn cancel_post_owner_transfer_request(
198        subspace_id: u64,
199        post_id: u64,
200        sender: Addr,
201    ) -> MsgCancelPostOwnerTransferRequest {
202        MsgCancelPostOwnerTransferRequest {
203            subspace_id,
204            post_id,
205            sender: sender.into(),
206        }
207    }
208
209    /// Creates an instance of [`MsgAcceptPostOwnerTransferRequest`].
210    /// * `subspace_id` - Id of the subspace holding the post for which the request will be accepted.
211    /// * `post_id` - Id of the post for which the request will be accepted.
212    /// * `receiver` - Address of the request receiver.
213    pub fn accept_post_owner_transfer_request(
214        subspace_id: u64,
215        post_id: u64,
216        receiver: Addr,
217    ) -> MsgAcceptPostOwnerTransferRequest {
218        MsgAcceptPostOwnerTransferRequest {
219            subspace_id,
220            post_id,
221            receiver: receiver.into(),
222        }
223    }
224
225    /// Creates an instance of [`MsgRefusePostOwnerTransferRequest`].
226    /// * `subspace_id` - Id of the subspace holding the post for which the request will be refused.
227    /// * `post_id` - Id of the post for which the request will be refused.
228    /// * `receiver` - Address of the request receiver.
229    pub fn refuse_post_owner_transfer_request(
230        subspace_id: u64,
231        post_id: u64,
232        receiver: Addr,
233    ) -> MsgRefusePostOwnerTransferRequest {
234        MsgRefusePostOwnerTransferRequest {
235            subspace_id,
236            post_id,
237            receiver: receiver.into(),
238        }
239    }
240}
241
242#[cfg(test)]
243mod tests {
244    use super::*;
245    use crate::cosmos_types::Timestamp;
246    use chrono::DateTime;
247
248    #[test]
249    fn test_create_post() {
250        let msg = PostsMsg::create_post(
251            1,
252            1,
253            Some("1"),
254            "test",
255            None,
256            vec![],
257            vec![
258                AttachmentContent::Media(Media {
259                    uri: "ftp://domain.io/image.png".into(),
260                    mime_type: "image/png".into(),
261                }),
262                AttachmentContent::Poll(Poll {
263                    question: "questions?".into(),
264                    provided_answers: vec![poll::ProvidedAnswer {
265                        text: "Answer 1".into(),
266                        attachments: vec![],
267                    }],
268                    end_date: Some(Timestamp::from(DateTime::from(
269                        DateTime::parse_from_rfc3339("2140-01-01T10:00:20.021Z").unwrap(),
270                    ))),
271                    allows_multiple_answers: false,
272                    allows_answer_edits: false,
273                    final_tally_results: None,
274                }),
275            ],
276            Addr::unchecked("user"),
277            Some(1),
278            ReplySetting::Everyone,
279            vec![],
280        );
281
282        let expected = MsgCreatePost {
283            subspace_id: 1,
284            section_id: 1,
285            external_id: "1".into(),
286            text: "test".into(),
287            entities: None,
288            tags: vec![],
289            attachments: vec![
290                AttachmentContent::Media(Media {
291                    uri: "ftp://domain.io/image.png".into(),
292                    mime_type: "image/png".into(),
293                })
294                .into(),
295                AttachmentContent::Poll(Poll {
296                    question: "questions?".into(),
297                    provided_answers: vec![poll::ProvidedAnswer {
298                        text: "Answer 1".into(),
299                        attachments: vec![],
300                    }],
301                    end_date: Some(Timestamp::from(DateTime::from(
302                        DateTime::parse_from_rfc3339("2140-01-01T10:00:20.021Z").unwrap(),
303                    ))),
304                    allows_multiple_answers: false,
305                    allows_answer_edits: false,
306                    final_tally_results: None,
307                })
308                .into(),
309            ],
310            author: "user".into(),
311            conversation_id: 1,
312            reply_settings: ReplySetting::Everyone.into(),
313            referenced_posts: vec![],
314        };
315
316        assert_eq!(expected, msg)
317    }
318
319    #[test]
320    fn test_edit_post_with_new_text() {
321        let msg = PostsMsg::edit_post(
322            1,
323            1,
324            Some("new text"),
325            None,
326            vec![],
327            Addr::unchecked("user"),
328        );
329
330        let expected = MsgEditPost {
331            subspace_id: 1,
332            post_id: 1,
333            text: "new text".into(),
334            entities: None,
335            tags: vec![],
336            editor: "user".into(),
337        };
338
339        assert_eq!(expected, msg)
340    }
341
342    #[test]
343    fn test_edit_post_without_new_text() {
344        let msg = PostsMsg::edit_post(1, 1, None, None, vec![], Addr::unchecked("user"));
345
346        let expected = MsgEditPost {
347            subspace_id: 1,
348            post_id: 1,
349            text: "[do-not-modify]".into(),
350            entities: None,
351            tags: vec![],
352            editor: "user".into(),
353        };
354
355        assert_eq!(expected, msg)
356    }
357
358    #[test]
359    fn test_delete_post() {
360        let msg = PostsMsg::delete_post(1, 1, Addr::unchecked("user"));
361
362        let expected = MsgDeletePost {
363            subspace_id: 1,
364            post_id: 1,
365            signer: "user".into(),
366        };
367
368        assert_eq!(expected, msg)
369    }
370
371    #[test]
372    fn test_add_post_attachment() {
373        let msg = PostsMsg::add_post_attachment(
374            1,
375            1,
376            AttachmentContent::Media(Media {
377                uri: "ftp://domain.io/image.png".into(),
378                mime_type: "image/png".into(),
379            }),
380            Addr::unchecked("user"),
381        );
382
383        let expected = MsgAddPostAttachment {
384            subspace_id: 1,
385            post_id: 1,
386            content: Some(
387                AttachmentContent::Media(Media {
388                    uri: "ftp://domain.io/image.png".into(),
389                    mime_type: "image/png".into(),
390                })
391                .into(),
392            ),
393            editor: "user".into(),
394        };
395
396        assert_eq!(expected, msg)
397    }
398
399    #[test]
400    fn test_remove_post_attachment() {
401        let msg = PostsMsg::remove_post_attachment(1, 1, 1, Addr::unchecked("user"));
402
403        let expected = MsgRemovePostAttachment {
404            subspace_id: 1,
405            post_id: 1,
406            attachment_id: 1,
407            editor: "user".into(),
408        };
409
410        assert_eq!(expected, msg)
411    }
412
413    #[test]
414    fn test_answer_poll() {
415        let msg = PostsMsg::answer_poll(1, 1, 1, vec![1], Addr::unchecked("user"));
416
417        let expected = MsgAnswerPoll {
418            subspace_id: 1,
419            post_id: 1,
420            poll_id: 1,
421            answers_indexes: vec![1],
422            signer: "user".into(),
423        };
424
425        assert_eq!(expected, msg)
426    }
427
428    #[test]
429    fn test_move_post() {
430        let msg = PostsMsg::move_post(1, 1, 2, 0, Addr::unchecked("user"));
431
432        let expected = MsgMovePost {
433            subspace_id: 1,
434            post_id: 1,
435            target_subspace_id: 2,
436            target_section_id: 0,
437            owner: "user".into(),
438        };
439
440        assert_eq!(expected, msg)
441    }
442
443    #[test]
444    fn test_request_post_owner_transfer() {
445        let msg = PostsMsg::request_post_owner_transfer(
446            1,
447            1,
448            Addr::unchecked("receiver"),
449            Addr::unchecked("sender"),
450        );
451
452        let expected = MsgRequestPostOwnerTransfer {
453            subspace_id: 1,
454            post_id: 1,
455            receiver: "receiver".into(),
456            sender: "sender".into(),
457        };
458
459        assert_eq!(expected, msg)
460    }
461
462    #[test]
463    fn test_cancel_post_owner_transfer_request() {
464        let msg = PostsMsg::cancel_post_owner_transfer_request(1, 1, Addr::unchecked("sender"));
465
466        let expected = MsgCancelPostOwnerTransferRequest {
467            subspace_id: 1,
468            post_id: 1,
469            sender: "sender".into(),
470        };
471
472        assert_eq!(expected, msg)
473    }
474
475    #[test]
476    fn test_accept_post_owner_transfer_request() {
477        let msg = PostsMsg::accept_post_owner_transfer_request(1, 1, Addr::unchecked("receiver"));
478
479        let expected = MsgAcceptPostOwnerTransferRequest {
480            subspace_id: 1,
481            post_id: 1,
482            receiver: "receiver".into(),
483        };
484
485        assert_eq!(expected, msg)
486    }
487
488    #[test]
489    fn test_refuse_post_owner_transfer_request() {
490        let msg = PostsMsg::refuse_post_owner_transfer_request(1, 1, Addr::unchecked("receiver"));
491
492        let expected = MsgRefusePostOwnerTransferRequest {
493            subspace_id: 1,
494            post_id: 1,
495            receiver: "receiver".into(),
496        };
497
498        assert_eq!(expected, msg)
499    }
500}