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