]> Untitled Git - lemmy.git/blob - crates/db_queries/src/aggregates/community_aggregates.rs
Add both (De)Serialize to all models (#1851)
[lemmy.git] / crates / db_queries / src / aggregates / community_aggregates.rs
1 use diesel::{result::Error, *};
2 use lemmy_db_schema::{schema::community_aggregates, CommunityId};
3 use serde::{Deserialize, Serialize};
4
5 #[derive(
6   Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone,
7 )]
8 #[table_name = "community_aggregates"]
9 pub struct CommunityAggregates {
10   pub id: i32,
11   pub community_id: CommunityId,
12   pub subscribers: i64,
13   pub posts: i64,
14   pub comments: i64,
15   pub published: chrono::NaiveDateTime,
16   pub users_active_day: i64,
17   pub users_active_week: i64,
18   pub users_active_month: i64,
19   pub users_active_half_year: i64,
20 }
21
22 impl CommunityAggregates {
23   pub fn read(conn: &PgConnection, community_id: CommunityId) -> Result<Self, Error> {
24     community_aggregates::table
25       .filter(community_aggregates::community_id.eq(community_id))
26       .first::<Self>(conn)
27   }
28 }
29
30 #[cfg(test)]
31 mod tests {
32   use crate::{
33     aggregates::community_aggregates::CommunityAggregates,
34     establish_unpooled_connection,
35     Crud,
36     Followable,
37   };
38   use lemmy_db_schema::source::{
39     comment::{Comment, CommentForm},
40     community::{Community, CommunityFollower, CommunityFollowerForm, CommunityForm},
41     person::{Person, PersonForm},
42     post::{Post, PostForm},
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_person = PersonForm {
52       name: "thommy_community_agg".into(),
53       ..PersonForm::default()
54     };
55
56     let inserted_person = Person::create(&conn, &new_person).unwrap();
57
58     let another_person = PersonForm {
59       name: "jerry_community_agg".into(),
60       ..PersonForm::default()
61     };
62
63     let another_inserted_person = Person::create(&conn, &another_person).unwrap();
64
65     let new_community = CommunityForm {
66       name: "TIL_community_agg".into(),
67       title: "nada".to_owned(),
68       ..CommunityForm::default()
69     };
70
71     let inserted_community = Community::create(&conn, &new_community).unwrap();
72
73     let another_community = CommunityForm {
74       name: "TIL_community_agg_2".into(),
75       title: "nada".to_owned(),
76       ..CommunityForm::default()
77     };
78
79     let another_inserted_community = Community::create(&conn, &another_community).unwrap();
80
81     let first_person_follow = CommunityFollowerForm {
82       community_id: inserted_community.id,
83       person_id: inserted_person.id,
84       pending: false,
85     };
86
87     CommunityFollower::follow(&conn, &first_person_follow).unwrap();
88
89     let second_person_follow = CommunityFollowerForm {
90       community_id: inserted_community.id,
91       person_id: another_inserted_person.id,
92       pending: false,
93     };
94
95     CommunityFollower::follow(&conn, &second_person_follow).unwrap();
96
97     let another_community_follow = CommunityFollowerForm {
98       community_id: another_inserted_community.id,
99       person_id: inserted_person.id,
100       pending: false,
101     };
102
103     CommunityFollower::follow(&conn, &another_community_follow).unwrap();
104
105     let new_post = PostForm {
106       name: "A test post".into(),
107       creator_id: inserted_person.id,
108       community_id: inserted_community.id,
109       ..PostForm::default()
110     };
111
112     let inserted_post = Post::create(&conn, &new_post).unwrap();
113
114     let comment_form = CommentForm {
115       content: "A test comment".into(),
116       creator_id: inserted_person.id,
117       post_id: inserted_post.id,
118       ..CommentForm::default()
119     };
120
121     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
122
123     let child_comment_form = CommentForm {
124       content: "A test comment".into(),
125       creator_id: inserted_person.id,
126       post_id: inserted_post.id,
127       parent_id: Some(inserted_comment.id),
128       ..CommentForm::default()
129     };
130
131     let _inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
132
133     let community_aggregates_before_delete =
134       CommunityAggregates::read(&conn, inserted_community.id).unwrap();
135
136     assert_eq!(2, community_aggregates_before_delete.subscribers);
137     assert_eq!(1, community_aggregates_before_delete.posts);
138     assert_eq!(2, community_aggregates_before_delete.comments);
139
140     // Test the other community
141     let another_community_aggs =
142       CommunityAggregates::read(&conn, another_inserted_community.id).unwrap();
143     assert_eq!(1, another_community_aggs.subscribers);
144     assert_eq!(0, another_community_aggs.posts);
145     assert_eq!(0, another_community_aggs.comments);
146
147     // Unfollow test
148     CommunityFollower::unfollow(&conn, &second_person_follow).unwrap();
149     let after_unfollow = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
150     assert_eq!(1, after_unfollow.subscribers);
151
152     // Follow again just for the later tests
153     CommunityFollower::follow(&conn, &second_person_follow).unwrap();
154     let after_follow_again = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
155     assert_eq!(2, after_follow_again.subscribers);
156
157     // Remove a parent comment (the comment count should also be 0)
158     Post::delete(&conn, inserted_post.id).unwrap();
159     let after_parent_post_delete = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
160     assert_eq!(0, after_parent_post_delete.comments);
161     assert_eq!(0, after_parent_post_delete.posts);
162
163     // Remove the 2nd person
164     Person::delete(&conn, another_inserted_person.id).unwrap();
165     let after_person_delete = CommunityAggregates::read(&conn, inserted_community.id).unwrap();
166     assert_eq!(1, after_person_delete.subscribers);
167
168     // This should delete all the associated rows, and fire triggers
169     let person_num_deleted = Person::delete(&conn, inserted_person.id).unwrap();
170     assert_eq!(1, person_num_deleted);
171
172     // Delete the community
173     let community_num_deleted = Community::delete(&conn, inserted_community.id).unwrap();
174     assert_eq!(1, community_num_deleted);
175
176     let another_community_num_deleted =
177       Community::delete(&conn, another_inserted_community.id).unwrap();
178     assert_eq!(1, another_community_num_deleted);
179
180     // Should be none found, since the creator was deleted
181     let after_delete = CommunityAggregates::read(&conn, inserted_community.id);
182     assert!(after_delete.is_err());
183   }
184 }