]> Untitled Git - lemmy.git/blob - crates/db_schema/src/aggregates/comment_aggregates.rs
d47899bbffb11f766008faa19ba9b8b401c27011
[lemmy.git] / crates / db_schema / src / aggregates / comment_aggregates.rs
1 use crate::{newtypes::CommentId, schema::comment_aggregates};
2 use diesel::{result::Error, *};
3 use serde::{Deserialize, Serialize};
4
5 #[derive(
6   Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone,
7 )]
8 #[table_name = "comment_aggregates"]
9 pub struct CommentAggregates {
10   pub id: i32,
11   pub comment_id: CommentId,
12   pub score: i64,
13   pub upvotes: i64,
14   pub downvotes: i64,
15   pub published: chrono::NaiveDateTime,
16 }
17
18 impl CommentAggregates {
19   pub fn read(conn: &PgConnection, comment_id: CommentId) -> Result<Self, Error> {
20     comment_aggregates::table
21       .filter(comment_aggregates::comment_id.eq(comment_id))
22       .first::<Self>(conn)
23   }
24 }
25
26 #[cfg(test)]
27 mod tests {
28   use crate::{
29     aggregates::comment_aggregates::CommentAggregates,
30     establish_unpooled_connection,
31     source::{
32       comment::{Comment, CommentForm, CommentLike, CommentLikeForm},
33       community::{Community, CommunityForm},
34       person::{Person, PersonForm},
35       post::{Post, PostForm},
36     },
37     traits::{Crud, Likeable},
38   };
39   use serial_test::serial;
40
41   #[test]
42   #[serial]
43   fn test_crud() {
44     let conn = establish_unpooled_connection();
45
46     let new_person = PersonForm {
47       name: "thommy_comment_agg".into(),
48       ..PersonForm::default()
49     };
50
51     let inserted_person = Person::create(&conn, &new_person).unwrap();
52
53     let another_person = PersonForm {
54       name: "jerry_comment_agg".into(),
55       ..PersonForm::default()
56     };
57
58     let another_inserted_person = Person::create(&conn, &another_person).unwrap();
59
60     let new_community = CommunityForm {
61       name: "TIL_comment_agg".into(),
62       title: "nada".to_owned(),
63       ..CommunityForm::default()
64     };
65
66     let inserted_community = Community::create(&conn, &new_community).unwrap();
67
68     let new_post = PostForm {
69       name: "A test post".into(),
70       creator_id: inserted_person.id,
71       community_id: inserted_community.id,
72       ..PostForm::default()
73     };
74
75     let inserted_post = Post::create(&conn, &new_post).unwrap();
76
77     let comment_form = CommentForm {
78       content: "A test comment".into(),
79       creator_id: inserted_person.id,
80       post_id: inserted_post.id,
81       ..CommentForm::default()
82     };
83
84     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
85
86     let child_comment_form = CommentForm {
87       content: "A test comment".into(),
88       creator_id: inserted_person.id,
89       post_id: inserted_post.id,
90       parent_id: Some(inserted_comment.id),
91       ..CommentForm::default()
92     };
93
94     let _inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
95
96     let comment_like = CommentLikeForm {
97       comment_id: inserted_comment.id,
98       post_id: inserted_post.id,
99       person_id: inserted_person.id,
100       score: 1,
101     };
102
103     CommentLike::like(&conn, &comment_like).unwrap();
104
105     let comment_aggs_before_delete = CommentAggregates::read(&conn, inserted_comment.id).unwrap();
106
107     assert_eq!(1, comment_aggs_before_delete.score);
108     assert_eq!(1, comment_aggs_before_delete.upvotes);
109     assert_eq!(0, comment_aggs_before_delete.downvotes);
110
111     // Add a post dislike from the other person
112     let comment_dislike = CommentLikeForm {
113       comment_id: inserted_comment.id,
114       post_id: inserted_post.id,
115       person_id: another_inserted_person.id,
116       score: -1,
117     };
118
119     CommentLike::like(&conn, &comment_dislike).unwrap();
120
121     let comment_aggs_after_dislike = CommentAggregates::read(&conn, inserted_comment.id).unwrap();
122
123     assert_eq!(0, comment_aggs_after_dislike.score);
124     assert_eq!(1, comment_aggs_after_dislike.upvotes);
125     assert_eq!(1, comment_aggs_after_dislike.downvotes);
126
127     // Remove the first comment like
128     CommentLike::remove(&conn, inserted_person.id, inserted_comment.id).unwrap();
129     let after_like_remove = CommentAggregates::read(&conn, inserted_comment.id).unwrap();
130     assert_eq!(-1, after_like_remove.score);
131     assert_eq!(0, after_like_remove.upvotes);
132     assert_eq!(1, after_like_remove.downvotes);
133
134     // Remove the parent post
135     Post::delete(&conn, inserted_post.id).unwrap();
136
137     // Should be none found, since the post was deleted
138     let after_delete = CommentAggregates::read(&conn, inserted_comment.id);
139     assert!(after_delete.is_err());
140
141     // This should delete all the associated rows, and fire triggers
142     Person::delete(&conn, another_inserted_person.id).unwrap();
143     let person_num_deleted = Person::delete(&conn, inserted_person.id).unwrap();
144     assert_eq!(1, person_num_deleted);
145
146     // Delete the community
147     let community_num_deleted = Community::delete(&conn, inserted_community.id).unwrap();
148     assert_eq!(1, community_num_deleted);
149   }
150 }