]> Untitled Git - lemmy.git/blob - crates/db_schema/src/aggregates/community_aggregates.rs
Cache & Optimize Woodpecker CI (#3450)
[lemmy.git] / crates / db_schema / src / aggregates / community_aggregates.rs
1 use crate::{
2   aggregates::structs::CommunityAggregates,
3   newtypes::CommunityId,
4   schema::community_aggregates,
5   utils::{get_conn, DbPool},
6 };
7 use diesel::{result::Error, ExpressionMethods, QueryDsl};
8 use diesel_async::RunQueryDsl;
9
10 impl CommunityAggregates {
11   pub async fn read(pool: &mut DbPool<'_>, community_id: CommunityId) -> Result<Self, Error> {
12     let conn = &mut get_conn(pool).await?;
13     community_aggregates::table
14       .filter(community_aggregates::community_id.eq(community_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::community_aggregates::CommunityAggregates,
27     source::{
28       comment::{Comment, CommentInsertForm},
29       community::{Community, CommunityFollower, CommunityFollowerForm, CommunityInsertForm},
30       instance::Instance,
31       person::{Person, PersonInsertForm},
32       post::{Post, PostInsertForm},
33     },
34     traits::{Crud, Followable},
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_community_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_community_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_community_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 another_community = CommunityInsertForm::builder()
75       .name("TIL_community_agg_2".into())
76       .title("nada".to_owned())
77       .public_key("pubkey".to_string())
78       .instance_id(inserted_instance.id)
79       .build();
80
81     let another_inserted_community = Community::create(pool, &another_community).await.unwrap();
82
83     let first_person_follow = CommunityFollowerForm {
84       community_id: inserted_community.id,
85       person_id: inserted_person.id,
86       pending: false,
87     };
88
89     CommunityFollower::follow(pool, &first_person_follow)
90       .await
91       .unwrap();
92
93     let second_person_follow = CommunityFollowerForm {
94       community_id: inserted_community.id,
95       person_id: another_inserted_person.id,
96       pending: false,
97     };
98
99     CommunityFollower::follow(pool, &second_person_follow)
100       .await
101       .unwrap();
102
103     let another_community_follow = CommunityFollowerForm {
104       community_id: another_inserted_community.id,
105       person_id: inserted_person.id,
106       pending: false,
107     };
108
109     CommunityFollower::follow(pool, &another_community_follow)
110       .await
111       .unwrap();
112
113     let new_post = PostInsertForm::builder()
114       .name("A test post".into())
115       .creator_id(inserted_person.id)
116       .community_id(inserted_community.id)
117       .build();
118
119     let inserted_post = Post::create(pool, &new_post).await.unwrap();
120
121     let comment_form = CommentInsertForm::builder()
122       .content("A test comment".into())
123       .creator_id(inserted_person.id)
124       .post_id(inserted_post.id)
125       .build();
126
127     let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap();
128
129     let child_comment_form = CommentInsertForm::builder()
130       .content("A test comment".into())
131       .creator_id(inserted_person.id)
132       .post_id(inserted_post.id)
133       .build();
134
135     let _inserted_child_comment =
136       Comment::create(pool, &child_comment_form, Some(&inserted_comment.path))
137         .await
138         .unwrap();
139
140     let community_aggregates_before_delete = CommunityAggregates::read(pool, inserted_community.id)
141       .await
142       .unwrap();
143
144     assert_eq!(2, community_aggregates_before_delete.subscribers);
145     assert_eq!(1, community_aggregates_before_delete.posts);
146     assert_eq!(2, community_aggregates_before_delete.comments);
147
148     // Test the other community
149     let another_community_aggs = CommunityAggregates::read(pool, another_inserted_community.id)
150       .await
151       .unwrap();
152     assert_eq!(1, another_community_aggs.subscribers);
153     assert_eq!(0, another_community_aggs.posts);
154     assert_eq!(0, another_community_aggs.comments);
155
156     // Unfollow test
157     CommunityFollower::unfollow(pool, &second_person_follow)
158       .await
159       .unwrap();
160     let after_unfollow = CommunityAggregates::read(pool, inserted_community.id)
161       .await
162       .unwrap();
163     assert_eq!(1, after_unfollow.subscribers);
164
165     // Follow again just for the later tests
166     CommunityFollower::follow(pool, &second_person_follow)
167       .await
168       .unwrap();
169     let after_follow_again = CommunityAggregates::read(pool, inserted_community.id)
170       .await
171       .unwrap();
172     assert_eq!(2, after_follow_again.subscribers);
173
174     // Remove a parent post (the comment count should also be 0)
175     Post::delete(pool, inserted_post.id).await.unwrap();
176     let after_parent_post_delete = CommunityAggregates::read(pool, inserted_community.id)
177       .await
178       .unwrap();
179     assert_eq!(0, after_parent_post_delete.comments);
180     assert_eq!(0, after_parent_post_delete.posts);
181
182     // Remove the 2nd person
183     Person::delete(pool, another_inserted_person.id)
184       .await
185       .unwrap();
186     let after_person_delete = CommunityAggregates::read(pool, inserted_community.id)
187       .await
188       .unwrap();
189     assert_eq!(1, after_person_delete.subscribers);
190
191     // This should delete all the associated rows, and fire triggers
192     let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap();
193     assert_eq!(1, person_num_deleted);
194
195     // Delete the community
196     let community_num_deleted = Community::delete(pool, inserted_community.id)
197       .await
198       .unwrap();
199     assert_eq!(1, community_num_deleted);
200
201     let another_community_num_deleted = Community::delete(pool, another_inserted_community.id)
202       .await
203       .unwrap();
204     assert_eq!(1, another_community_num_deleted);
205
206     // Should be none found, since the creator was deleted
207     let after_delete = CommunityAggregates::read(pool, inserted_community.id).await;
208     assert!(after_delete.is_err());
209   }
210 }