]> Untitled Git - lemmy.git/blob - crates/db_queries/src/aggregates/community_aggregates.rs
3fb891c11ee6e1b764e3130495faf17824db8ce0
[lemmy.git] / crates / db_queries / src / aggregates / community_aggregates.rs
1 use diesel::{result::Error, *};
2 use lemmy_db_schema::schema::community_aggregates;
3 use serde::Serialize;
4
5 #[derive(Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Clone)]
6 #[table_name = "community_aggregates"]
7 pub struct CommunityAggregates {
8   pub id: i32,
9   pub community_id: i32,
10   pub subscribers: i64,
11   pub posts: i64,
12   pub comments: i64,
13   pub published: chrono::NaiveDateTime,
14 }
15
16 impl CommunityAggregates {
17   pub fn read(conn: &PgConnection, community_id: i32) -> Result<Self, Error> {
18     community_aggregates::table
19       .filter(community_aggregates::community_id.eq(community_id))
20       .first::<Self>(conn)
21   }
22 }
23
24 #[cfg(test)]
25 mod tests {
26   use crate::{
27     aggregates::community_aggregates::CommunityAggregates,
28     establish_unpooled_connection,
29     Crud,
30     Followable,
31     ListingType,
32     SortType,
33   };
34   use lemmy_db_schema::source::{
35     comment::{Comment, CommentForm},
36     community::{Community, CommunityFollower, CommunityFollowerForm, CommunityForm},
37     post::{Post, PostForm},
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_community_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_community_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_community_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 another_community = CommunityForm {
126       name: "TIL_community_agg_2".into(),
127       creator_id: inserted_user.id,
128       title: "nada".to_owned(),
129       description: None,
130       category_id: 1,
131       nsfw: false,
132       removed: None,
133       deleted: None,
134       updated: None,
135       actor_id: None,
136       local: true,
137       private_key: None,
138       public_key: None,
139       last_refreshed_at: None,
140       published: None,
141       icon: None,
142       banner: None,
143     };
144
145     let another_inserted_community = Community::create(&conn, &another_community).unwrap();
146
147     let first_user_follow = CommunityFollowerForm {
148       community_id: inserted_community.id,
149       user_id: inserted_user.id,
150       pending: false,
151     };
152
153     CommunityFollower::follow(&conn, &first_user_follow).unwrap();
154
155     let second_user_follow = CommunityFollowerForm {
156       community_id: inserted_community.id,
157       user_id: another_inserted_user.id,
158       pending: false,
159     };
160
161     CommunityFollower::follow(&conn, &second_user_follow).unwrap();
162
163     let another_community_follow = CommunityFollowerForm {
164       community_id: another_inserted_community.id,
165       user_id: inserted_user.id,
166       pending: false,
167     };
168
169     CommunityFollower::follow(&conn, &another_community_follow).unwrap();
170
171     let new_post = PostForm {
172       name: "A test post".into(),
173       url: None,
174       body: None,
175       creator_id: inserted_user.id,
176       community_id: inserted_community.id,
177       removed: None,
178       deleted: None,
179       locked: None,
180       stickied: None,
181       nsfw: false,
182       updated: None,
183       embed_title: None,
184       embed_description: None,
185       embed_html: None,
186       thumbnail_url: None,
187       ap_id: None,
188       local: true,
189       published: None,
190     };
191
192     let inserted_post = Post::create(&conn, &new_post).unwrap();
193
194     let comment_form = CommentForm {
195       content: "A test comment".into(),
196       creator_id: inserted_user.id,
197       post_id: inserted_post.id,
198       removed: None,
199       deleted: None,
200       read: None,
201       parent_id: None,
202       published: None,
203       updated: None,
204       ap_id: None,
205       local: true,
206     };
207
208     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
209
210     let child_comment_form = CommentForm {
211       content: "A test comment".into(),
212       creator_id: inserted_user.id,
213       post_id: inserted_post.id,
214       removed: None,
215       deleted: None,
216       read: None,
217       parent_id: Some(inserted_comment.id),
218       published: None,
219       updated: None,
220       ap_id: None,
221       local: true,
222     };
223
224     let _inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
225
226     let community_aggregates_before_delete =
227       CommunityAggregates::read(&conn, inserted_community.id).unwrap();
228
229     assert_eq!(2, community_aggregates_before_delete.subscribers);
230     assert_eq!(1, community_aggregates_before_delete.posts);
231     assert_eq!(2, community_aggregates_before_delete.comments);
232
233     // Test the other community
234     let another_community_aggs =
235       CommunityAggregates::read(&conn, another_inserted_community.id).unwrap();
236     assert_eq!(1, another_community_aggs.subscribers);
237     assert_eq!(0, another_community_aggs.posts);
238     assert_eq!(0, another_community_aggs.comments);
239
240     // Unfollow test
241     CommunityFollower::unfollow(&conn, &second_user_follow).unwrap();
242     let after_unfollow = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
243     assert_eq!(1, after_unfollow.subscribers);
244
245     // Follow again just for the later tests
246     CommunityFollower::follow(&conn, &second_user_follow).unwrap();
247     let after_follow_again = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
248     assert_eq!(2, after_follow_again.subscribers);
249
250     // Remove a parent comment (the comment count should also be 0)
251     Post::delete(&conn, inserted_post.id).unwrap();
252     let after_parent_post_delete = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
253     assert_eq!(0, after_parent_post_delete.comments);
254     assert_eq!(0, after_parent_post_delete.posts);
255
256     // Remove the 2nd user
257     User_::delete(&conn, another_inserted_user.id).unwrap();
258     let after_user_delete = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
259     assert_eq!(1, after_user_delete.subscribers);
260
261     // This should delete all the associated rows, and fire triggers
262     let user_num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
263     assert_eq!(1, user_num_deleted);
264
265     // Should be none found, since the creator was deleted
266     let after_delete = CommunityAggregates::read(&conn, inserted_community.id);
267     assert!(after_delete.is_err());
268   }
269 }