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