]> Untitled Git - lemmy.git/blob - lemmy_db_queries/src/aggregates/post_aggregates.rs
6c1dbed27f8c342440cdd49df6f836583c28fd1d
[lemmy.git] / lemmy_db_queries / src / aggregates / post_aggregates.rs
1 use diesel::{result::Error, *};
2 use lemmy_db_schema::schema::post_aggregates;
3 use serde::Serialize;
4
5 #[derive(Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Clone)]
6 #[table_name = "post_aggregates"]
7 pub struct PostAggregates {
8   pub id: i32,
9   pub post_id: i32,
10   pub comments: i64,
11   pub score: i64,
12   pub upvotes: i64,
13   pub downvotes: i64,
14   pub published: chrono::NaiveDateTime,
15   pub newest_comment_time: chrono::NaiveDateTime,
16 }
17
18 impl PostAggregates {
19   pub fn read(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
20     post_aggregates::table
21       .filter(post_aggregates::post_id.eq(post_id))
22       .first::<Self>(conn)
23   }
24 }
25
26 #[cfg(test)]
27 mod tests {
28   use crate::{
29     aggregates::post_aggregates::PostAggregates,
30     establish_unpooled_connection,
31     Crud,
32     Likeable,
33     ListingType,
34     SortType,
35   };
36   use lemmy_db_schema::source::{
37     comment::{Comment, CommentForm},
38     community::{Community, CommunityForm},
39     post::{Post, PostForm, PostLike, PostLikeForm},
40     user::{UserForm, User_},
41   };
42
43   #[test]
44   fn test_crud() {
45     let conn = establish_unpooled_connection();
46
47     let new_user = UserForm {
48       name: "thommy_community_agg".into(),
49       preferred_username: None,
50       password_encrypted: "nope".into(),
51       email: None,
52       matrix_user_id: None,
53       avatar: None,
54       banner: None,
55       admin: false,
56       banned: Some(false),
57       published: None,
58       updated: None,
59       show_nsfw: false,
60       theme: "browser".into(),
61       default_sort_type: SortType::Hot as i16,
62       default_listing_type: ListingType::Subscribed as i16,
63       lang: "browser".into(),
64       show_avatars: true,
65       send_notifications_to_email: false,
66       actor_id: None,
67       bio: None,
68       local: true,
69       private_key: None,
70       public_key: None,
71       last_refreshed_at: None,
72     };
73
74     let inserted_user = User_::create(&conn, &new_user).unwrap();
75
76     let another_user = UserForm {
77       name: "jerry_community_agg".into(),
78       preferred_username: None,
79       password_encrypted: "nope".into(),
80       email: None,
81       matrix_user_id: None,
82       avatar: None,
83       banner: None,
84       admin: false,
85       banned: Some(false),
86       published: None,
87       updated: None,
88       show_nsfw: false,
89       theme: "browser".into(),
90       default_sort_type: SortType::Hot as i16,
91       default_listing_type: ListingType::Subscribed as i16,
92       lang: "browser".into(),
93       show_avatars: true,
94       send_notifications_to_email: false,
95       actor_id: None,
96       bio: None,
97       local: true,
98       private_key: None,
99       public_key: None,
100       last_refreshed_at: None,
101     };
102
103     let another_inserted_user = User_::create(&conn, &another_user).unwrap();
104
105     let new_community = CommunityForm {
106       name: "TIL_community_agg".into(),
107       creator_id: inserted_user.id,
108       title: "nada".to_owned(),
109       description: None,
110       category_id: 1,
111       nsfw: false,
112       removed: None,
113       deleted: None,
114       updated: None,
115       actor_id: None,
116       local: true,
117       private_key: None,
118       public_key: None,
119       last_refreshed_at: None,
120       published: None,
121       icon: None,
122       banner: None,
123     };
124
125     let inserted_community = Community::create(&conn, &new_community).unwrap();
126
127     let new_post = PostForm {
128       name: "A test post".into(),
129       url: None,
130       body: None,
131       creator_id: inserted_user.id,
132       community_id: inserted_community.id,
133       removed: None,
134       deleted: None,
135       locked: None,
136       stickied: None,
137       nsfw: false,
138       updated: None,
139       embed_title: None,
140       embed_description: None,
141       embed_html: None,
142       thumbnail_url: None,
143       ap_id: None,
144       local: true,
145       published: None,
146     };
147
148     let inserted_post = Post::create(&conn, &new_post).unwrap();
149
150     let comment_form = CommentForm {
151       content: "A test comment".into(),
152       creator_id: inserted_user.id,
153       post_id: inserted_post.id,
154       removed: None,
155       deleted: None,
156       read: None,
157       parent_id: None,
158       published: None,
159       updated: None,
160       ap_id: None,
161       local: true,
162     };
163
164     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
165
166     let child_comment_form = CommentForm {
167       content: "A test comment".into(),
168       creator_id: inserted_user.id,
169       post_id: inserted_post.id,
170       removed: None,
171       deleted: None,
172       read: None,
173       parent_id: Some(inserted_comment.id),
174       published: None,
175       updated: None,
176       ap_id: None,
177       local: true,
178     };
179
180     let _inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
181
182     let post_like = PostLikeForm {
183       post_id: inserted_post.id,
184       user_id: inserted_user.id,
185       score: 1,
186     };
187
188     PostLike::like(&conn, &post_like).unwrap();
189
190     let post_aggs_before_delete = PostAggregates::read(&conn, inserted_post.id).unwrap();
191
192     assert_eq!(2, post_aggs_before_delete.comments);
193     assert_eq!(1, post_aggs_before_delete.score);
194     assert_eq!(1, post_aggs_before_delete.upvotes);
195     assert_eq!(0, post_aggs_before_delete.downvotes);
196
197     // Add a post dislike from the other user
198     let post_dislike = PostLikeForm {
199       post_id: inserted_post.id,
200       user_id: another_inserted_user.id,
201       score: -1,
202     };
203
204     PostLike::like(&conn, &post_dislike).unwrap();
205
206     let post_aggs_after_dislike = PostAggregates::read(&conn, inserted_post.id).unwrap();
207
208     assert_eq!(2, post_aggs_after_dislike.comments);
209     assert_eq!(0, post_aggs_after_dislike.score);
210     assert_eq!(1, post_aggs_after_dislike.upvotes);
211     assert_eq!(1, post_aggs_after_dislike.downvotes);
212
213     // Remove the parent comment
214     Comment::delete(&conn, inserted_comment.id).unwrap();
215     let after_comment_delete = PostAggregates::read(&conn, inserted_post.id).unwrap();
216     assert_eq!(0, after_comment_delete.comments);
217     assert_eq!(0, after_comment_delete.score);
218     assert_eq!(1, after_comment_delete.upvotes);
219     assert_eq!(1, after_comment_delete.downvotes);
220
221     // Remove the first post like
222     PostLike::remove(&conn, inserted_user.id, inserted_post.id).unwrap();
223     let after_like_remove = PostAggregates::read(&conn, inserted_post.id).unwrap();
224     assert_eq!(0, after_like_remove.comments);
225     assert_eq!(-1, after_like_remove.score);
226     assert_eq!(0, after_like_remove.upvotes);
227     assert_eq!(1, after_like_remove.downvotes);
228
229     // This should delete all the associated rows, and fire triggers
230     User_::delete(&conn, another_inserted_user.id).unwrap();
231     let user_num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
232     assert_eq!(1, user_num_deleted);
233
234     // Should be none found, since the creator was deleted
235     let after_delete = PostAggregates::read(&conn, inserted_post.id);
236     assert!(after_delete.is_err());
237   }
238 }