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