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