]> Untitled Git - lemmy.git/blob - crates/db_schema/src/aggregates/person_aggregates.rs
add enable_federated_downvotes site option
[lemmy.git] / crates / db_schema / src / aggregates / person_aggregates.rs
1 use crate::{
2   aggregates::structs::PersonAggregates,
3   newtypes::PersonId,
4   schema::person_aggregates,
5   utils::{get_conn, DbPool},
6 };
7 use diesel::{result::Error, ExpressionMethods, QueryDsl};
8 use diesel_async::RunQueryDsl;
9
10 impl PersonAggregates {
11   pub async fn read(pool: &mut DbPool<'_>, person_id: PersonId) -> Result<Self, Error> {
12     let conn = &mut get_conn(pool).await?;
13     person_aggregates::table
14       .filter(person_aggregates::person_id.eq(person_id))
15       .first::<Self>(conn)
16       .await
17   }
18 }
19
20 #[cfg(test)]
21 mod tests {
22   #![allow(clippy::unwrap_used)]
23   #![allow(clippy::indexing_slicing)]
24
25   use crate::{
26     aggregates::person_aggregates::PersonAggregates,
27     source::{
28       comment::{Comment, CommentInsertForm, CommentLike, CommentLikeForm, CommentUpdateForm},
29       community::{Community, CommunityInsertForm},
30       instance::Instance,
31       person::{Person, PersonInsertForm},
32       post::{Post, PostInsertForm, PostLike, PostLikeForm},
33     },
34     traits::{Crud, Likeable},
35     utils::build_db_pool_for_tests,
36   };
37   use serial_test::serial;
38
39   #[tokio::test]
40   #[serial]
41   async fn test_crud() {
42     let pool = &build_db_pool_for_tests().await;
43     let pool = &mut pool.into();
44
45     let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string())
46       .await
47       .unwrap();
48
49     let new_person = PersonInsertForm::builder()
50       .name("thommy_user_agg".into())
51       .public_key("pubkey".to_string())
52       .instance_id(inserted_instance.id)
53       .build();
54
55     let inserted_person = Person::create(pool, &new_person).await.unwrap();
56
57     let another_person = PersonInsertForm::builder()
58       .name("jerry_user_agg".into())
59       .public_key("pubkey".to_string())
60       .instance_id(inserted_instance.id)
61       .build();
62
63     let another_inserted_person = Person::create(pool, &another_person).await.unwrap();
64
65     let new_community = CommunityInsertForm::builder()
66       .name("TIL_site_agg".into())
67       .title("nada".to_owned())
68       .public_key("pubkey".to_string())
69       .instance_id(inserted_instance.id)
70       .build();
71
72     let inserted_community = Community::create(pool, &new_community).await.unwrap();
73
74     let new_post = PostInsertForm::builder()
75       .name("A test post".into())
76       .creator_id(inserted_person.id)
77       .community_id(inserted_community.id)
78       .build();
79
80     let inserted_post = Post::create(pool, &new_post).await.unwrap();
81
82     let post_like = PostLikeForm {
83       post_id: inserted_post.id,
84       person_id: inserted_person.id,
85       score: 1,
86     };
87
88     let _inserted_post_like = PostLike::like(pool, &post_like).await.unwrap();
89
90     let comment_form = CommentInsertForm::builder()
91       .content("A test comment".into())
92       .creator_id(inserted_person.id)
93       .post_id(inserted_post.id)
94       .build();
95
96     let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap();
97
98     let mut comment_like = CommentLikeForm {
99       comment_id: inserted_comment.id,
100       person_id: inserted_person.id,
101       post_id: inserted_post.id,
102       score: 1,
103     };
104
105     let _inserted_comment_like = CommentLike::like(pool, &comment_like).await.unwrap();
106
107     let child_comment_form = CommentInsertForm::builder()
108       .content("A test comment".into())
109       .creator_id(inserted_person.id)
110       .post_id(inserted_post.id)
111       .build();
112
113     let inserted_child_comment =
114       Comment::create(pool, &child_comment_form, Some(&inserted_comment.path))
115         .await
116         .unwrap();
117
118     let child_comment_like = CommentLikeForm {
119       comment_id: inserted_child_comment.id,
120       person_id: another_inserted_person.id,
121       post_id: inserted_post.id,
122       score: 1,
123     };
124
125     let _inserted_child_comment_like = CommentLike::like(pool, &child_comment_like).await.unwrap();
126
127     let person_aggregates_before_delete = PersonAggregates::read(pool, inserted_person.id)
128       .await
129       .unwrap();
130
131     assert_eq!(1, person_aggregates_before_delete.post_count);
132     assert_eq!(1, person_aggregates_before_delete.post_score);
133     assert_eq!(2, person_aggregates_before_delete.comment_count);
134     assert_eq!(2, person_aggregates_before_delete.comment_score);
135
136     // Remove a post like
137     PostLike::remove(pool, inserted_person.id, inserted_post.id)
138       .await
139       .unwrap();
140     let after_post_like_remove = PersonAggregates::read(pool, inserted_person.id)
141       .await
142       .unwrap();
143     assert_eq!(0, after_post_like_remove.post_score);
144
145     Comment::update(
146       pool,
147       inserted_comment.id,
148       &CommentUpdateForm {
149         removed: Some(true),
150         ..Default::default()
151       },
152     )
153     .await
154     .unwrap();
155     Comment::update(
156       pool,
157       inserted_child_comment.id,
158       &CommentUpdateForm {
159         removed: Some(true),
160         ..Default::default()
161       },
162     )
163     .await
164     .unwrap();
165
166     let after_parent_comment_removed = PersonAggregates::read(pool, inserted_person.id)
167       .await
168       .unwrap();
169     assert_eq!(0, after_parent_comment_removed.comment_count);
170     // TODO: fix person aggregate comment score calculation
171     // assert_eq!(0, after_parent_comment_removed.comment_score);
172
173     // Remove a parent comment (the scores should also be removed)
174     Comment::delete(pool, inserted_comment.id).await.unwrap();
175     Comment::delete(pool, inserted_child_comment.id)
176       .await
177       .unwrap();
178     let after_parent_comment_delete = PersonAggregates::read(pool, inserted_person.id)
179       .await
180       .unwrap();
181     assert_eq!(0, after_parent_comment_delete.comment_count);
182     // TODO: fix person aggregate comment score calculation
183     // assert_eq!(0, after_parent_comment_delete.comment_score);
184
185     // Add in the two comments again, then delete the post.
186     let new_parent_comment = Comment::create(pool, &comment_form, None).await.unwrap();
187     let _new_child_comment =
188       Comment::create(pool, &child_comment_form, Some(&new_parent_comment.path))
189         .await
190         .unwrap();
191     comment_like.comment_id = new_parent_comment.id;
192     CommentLike::like(pool, &comment_like).await.unwrap();
193     let after_comment_add = PersonAggregates::read(pool, inserted_person.id)
194       .await
195       .unwrap();
196     assert_eq!(2, after_comment_add.comment_count);
197     // TODO: fix person aggregate comment score calculation
198     // assert_eq!(1, after_comment_add.comment_score);
199
200     Post::delete(pool, inserted_post.id).await.unwrap();
201     let after_post_delete = PersonAggregates::read(pool, inserted_person.id)
202       .await
203       .unwrap();
204     // TODO: fix person aggregate comment score calculation
205     // assert_eq!(0, after_post_delete.comment_score);
206     assert_eq!(0, after_post_delete.comment_count);
207     assert_eq!(0, after_post_delete.post_score);
208     assert_eq!(0, after_post_delete.post_count);
209
210     // This should delete all the associated rows, and fire triggers
211     let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap();
212     assert_eq!(1, person_num_deleted);
213     Person::delete(pool, another_inserted_person.id)
214       .await
215       .unwrap();
216
217     // Delete the community
218     let community_num_deleted = Community::delete(pool, inserted_community.id)
219       .await
220       .unwrap();
221     assert_eq!(1, community_num_deleted);
222
223     // Should be none found
224     let after_delete = PersonAggregates::read(pool, inserted_person.id).await;
225     assert!(after_delete.is_err());
226
227     Instance::delete(pool, inserted_instance.id).await.unwrap();
228   }
229 }