]> Untitled Git - lemmy.git/blob - crates/db_queries/src/aggregates/community_aggregates.rs
Support plain `cargo test` and disable unused doctests for speed
[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   pub users_active_day: i64,
15   pub users_active_week: i64,
16   pub users_active_month: i64,
17   pub users_active_half_year: i64,
18 }
19
20 impl CommunityAggregates {
21   pub fn read(conn: &PgConnection, community_id: i32) -> Result<Self, Error> {
22     community_aggregates::table
23       .filter(community_aggregates::community_id.eq(community_id))
24       .first::<Self>(conn)
25   }
26 }
27
28 #[cfg(test)]
29 mod tests {
30   use crate::{
31     aggregates::community_aggregates::CommunityAggregates,
32     establish_unpooled_connection,
33     Crud,
34     Followable,
35     ListingType,
36     SortType,
37   };
38   use lemmy_db_schema::source::{
39     comment::{Comment, CommentForm},
40     community::{Community, CommunityFollower, CommunityFollowerForm, CommunityForm},
41     post::{Post, PostForm},
42     user::{UserForm, User_},
43   };
44   use serial_test::serial;
45
46   #[test]
47   #[serial]
48   fn test_crud() {
49     let conn = establish_unpooled_connection();
50
51     let new_user = UserForm {
52       name: "thommy_community_agg".into(),
53       preferred_username: None,
54       password_encrypted: "nope".into(),
55       email: None,
56       matrix_user_id: None,
57       avatar: None,
58       banner: None,
59       admin: false,
60       banned: Some(false),
61       published: None,
62       updated: None,
63       show_nsfw: false,
64       theme: "browser".into(),
65       default_sort_type: SortType::Hot as i16,
66       default_listing_type: ListingType::Subscribed as i16,
67       lang: "browser".into(),
68       show_avatars: true,
69       send_notifications_to_email: false,
70       actor_id: None,
71       bio: None,
72       local: true,
73       private_key: None,
74       public_key: None,
75       last_refreshed_at: None,
76       inbox_url: None,
77       shared_inbox_url: None,
78     };
79
80     let inserted_user = User_::create(&conn, &new_user).unwrap();
81
82     let another_user = UserForm {
83       name: "jerry_community_agg".into(),
84       preferred_username: None,
85       password_encrypted: "nope".into(),
86       email: None,
87       matrix_user_id: None,
88       avatar: None,
89       banner: None,
90       admin: false,
91       banned: Some(false),
92       published: None,
93       updated: None,
94       show_nsfw: false,
95       theme: "browser".into(),
96       default_sort_type: SortType::Hot as i16,
97       default_listing_type: ListingType::Subscribed as i16,
98       lang: "browser".into(),
99       show_avatars: true,
100       send_notifications_to_email: false,
101       actor_id: None,
102       bio: None,
103       local: true,
104       private_key: None,
105       public_key: None,
106       last_refreshed_at: None,
107       inbox_url: None,
108       shared_inbox_url: None,
109     };
110
111     let another_inserted_user = User_::create(&conn, &another_user).unwrap();
112
113     let new_community = CommunityForm {
114       name: "TIL_community_agg".into(),
115       creator_id: inserted_user.id,
116       title: "nada".to_owned(),
117       description: None,
118       nsfw: false,
119       removed: None,
120       deleted: None,
121       updated: None,
122       actor_id: None,
123       local: true,
124       private_key: None,
125       public_key: None,
126       last_refreshed_at: None,
127       published: None,
128       icon: None,
129       banner: None,
130       followers_url: None,
131       inbox_url: None,
132       shared_inbox_url: None,
133     };
134
135     let inserted_community = Community::create(&conn, &new_community).unwrap();
136
137     let another_community = CommunityForm {
138       name: "TIL_community_agg_2".into(),
139       creator_id: inserted_user.id,
140       title: "nada".to_owned(),
141       description: None,
142       nsfw: false,
143       removed: None,
144       deleted: None,
145       updated: None,
146       actor_id: None,
147       local: true,
148       private_key: None,
149       public_key: None,
150       last_refreshed_at: None,
151       published: None,
152       icon: None,
153       banner: None,
154       followers_url: None,
155       inbox_url: None,
156       shared_inbox_url: None,
157     };
158
159     let another_inserted_community = Community::create(&conn, &another_community).unwrap();
160
161     let first_user_follow = CommunityFollowerForm {
162       community_id: inserted_community.id,
163       user_id: inserted_user.id,
164       pending: false,
165     };
166
167     CommunityFollower::follow(&conn, &first_user_follow).unwrap();
168
169     let second_user_follow = CommunityFollowerForm {
170       community_id: inserted_community.id,
171       user_id: another_inserted_user.id,
172       pending: false,
173     };
174
175     CommunityFollower::follow(&conn, &second_user_follow).unwrap();
176
177     let another_community_follow = CommunityFollowerForm {
178       community_id: another_inserted_community.id,
179       user_id: inserted_user.id,
180       pending: false,
181     };
182
183     CommunityFollower::follow(&conn, &another_community_follow).unwrap();
184
185     let new_post = PostForm {
186       name: "A test post".into(),
187       url: None,
188       body: None,
189       creator_id: inserted_user.id,
190       community_id: inserted_community.id,
191       removed: None,
192       deleted: None,
193       locked: None,
194       stickied: None,
195       nsfw: false,
196       updated: None,
197       embed_title: None,
198       embed_description: None,
199       embed_html: None,
200       thumbnail_url: None,
201       ap_id: None,
202       local: true,
203       published: None,
204     };
205
206     let inserted_post = Post::create(&conn, &new_post).unwrap();
207
208     let comment_form = CommentForm {
209       content: "A test comment".into(),
210       creator_id: inserted_user.id,
211       post_id: inserted_post.id,
212       removed: None,
213       deleted: None,
214       read: None,
215       parent_id: None,
216       published: None,
217       updated: None,
218       ap_id: None,
219       local: true,
220     };
221
222     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
223
224     let child_comment_form = CommentForm {
225       content: "A test comment".into(),
226       creator_id: inserted_user.id,
227       post_id: inserted_post.id,
228       removed: None,
229       deleted: None,
230       read: None,
231       parent_id: Some(inserted_comment.id),
232       published: None,
233       updated: None,
234       ap_id: None,
235       local: true,
236     };
237
238     let _inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
239
240     let community_aggregates_before_delete =
241       CommunityAggregates::read(&conn, inserted_community.id).unwrap();
242
243     assert_eq!(2, community_aggregates_before_delete.subscribers);
244     assert_eq!(1, community_aggregates_before_delete.posts);
245     assert_eq!(2, community_aggregates_before_delete.comments);
246
247     // Test the other community
248     let another_community_aggs =
249       CommunityAggregates::read(&conn, another_inserted_community.id).unwrap();
250     assert_eq!(1, another_community_aggs.subscribers);
251     assert_eq!(0, another_community_aggs.posts);
252     assert_eq!(0, another_community_aggs.comments);
253
254     // Unfollow test
255     CommunityFollower::unfollow(&conn, &second_user_follow).unwrap();
256     let after_unfollow = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
257     assert_eq!(1, after_unfollow.subscribers);
258
259     // Follow again just for the later tests
260     CommunityFollower::follow(&conn, &second_user_follow).unwrap();
261     let after_follow_again = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
262     assert_eq!(2, after_follow_again.subscribers);
263
264     // Remove a parent comment (the comment count should also be 0)
265     Post::delete(&conn, inserted_post.id).unwrap();
266     let after_parent_post_delete = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
267     assert_eq!(0, after_parent_post_delete.comments);
268     assert_eq!(0, after_parent_post_delete.posts);
269
270     // Remove the 2nd user
271     User_::delete(&conn, another_inserted_user.id).unwrap();
272     let after_user_delete = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
273     assert_eq!(1, after_user_delete.subscribers);
274
275     // This should delete all the associated rows, and fire triggers
276     let user_num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
277     assert_eq!(1, user_num_deleted);
278
279     // Should be none found, since the creator was deleted
280     let after_delete = CommunityAggregates::read(&conn, inserted_community.id);
281     assert!(after_delete.is_err());
282   }
283 }