]> Untitled Git - lemmy.git/blob - crates/db_queries/src/aggregates/post_aggregates.rs
Moving matrix_user_id to person table. #1438
[lemmy.git] / crates / db_queries / src / aggregates / post_aggregates.rs
1 use diesel::{result::Error, *};
2 use lemmy_db_schema::{schema::post_aggregates, PostId};
3 use serde::Serialize;
4
5 #[derive(Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Clone)]
6 #[table_name = "post_aggregates"]
7 pub struct PostAggregates {
8   pub id: i32,
9   pub post_id: PostId,
10   pub comments: i64,
11   pub score: i64,
12   pub upvotes: i64,
13   pub downvotes: i64,
14   pub stickied: bool,
15   pub published: chrono::NaiveDateTime,
16   pub newest_comment_time_necro: chrono::NaiveDateTime, // A newest comment time, limited to 2 days, to prevent necrobumping
17   pub newest_comment_time: chrono::NaiveDateTime,
18 }
19
20 impl PostAggregates {
21   pub fn read(conn: &PgConnection, post_id: PostId) -> Result<Self, Error> {
22     post_aggregates::table
23       .filter(post_aggregates::post_id.eq(post_id))
24       .first::<Self>(conn)
25   }
26 }
27
28 #[cfg(test)]
29 mod tests {
30   use crate::{
31     aggregates::post_aggregates::PostAggregates,
32     establish_unpooled_connection,
33     Crud,
34     Likeable,
35   };
36   use lemmy_db_schema::source::{
37     comment::{Comment, CommentForm},
38     community::{Community, CommunityForm},
39     person::{Person, PersonForm},
40     post::{Post, PostForm, PostLike, PostLikeForm},
41   };
42   use serial_test::serial;
43
44   #[test]
45   #[serial]
46   fn test_crud() {
47     let conn = establish_unpooled_connection();
48
49     let new_person = PersonForm {
50       name: "thommy_community_agg".into(),
51       preferred_username: None,
52       avatar: None,
53       banner: None,
54       banned: None,
55       deleted: None,
56       published: None,
57       updated: None,
58       actor_id: None,
59       bio: None,
60       local: None,
61       private_key: None,
62       public_key: None,
63       last_refreshed_at: None,
64       inbox_url: None,
65       shared_inbox_url: None,
66       matrix_user_id: None,
67     };
68
69     let inserted_person = Person::create(&conn, &new_person).unwrap();
70
71     let another_person = PersonForm {
72       name: "jerry_community_agg".into(),
73       preferred_username: None,
74       avatar: None,
75       banner: None,
76       banned: None,
77       deleted: None,
78       published: None,
79       updated: None,
80       actor_id: None,
81       bio: None,
82       local: None,
83       private_key: None,
84       public_key: None,
85       last_refreshed_at: None,
86       inbox_url: None,
87       shared_inbox_url: None,
88       matrix_user_id: None,
89     };
90
91     let another_inserted_person = Person::create(&conn, &another_person).unwrap();
92
93     let new_community = CommunityForm {
94       name: "TIL_community_agg".into(),
95       creator_id: inserted_person.id,
96       title: "nada".to_owned(),
97       description: None,
98       nsfw: false,
99       removed: None,
100       deleted: None,
101       updated: None,
102       actor_id: None,
103       local: true,
104       private_key: None,
105       public_key: None,
106       last_refreshed_at: None,
107       published: None,
108       icon: None,
109       banner: None,
110       followers_url: None,
111       inbox_url: None,
112       shared_inbox_url: None,
113     };
114
115     let inserted_community = Community::create(&conn, &new_community).unwrap();
116
117     let new_post = PostForm {
118       name: "A test post".into(),
119       url: None,
120       body: None,
121       creator_id: inserted_person.id,
122       community_id: inserted_community.id,
123       removed: None,
124       deleted: None,
125       locked: None,
126       stickied: None,
127       nsfw: false,
128       updated: None,
129       embed_title: None,
130       embed_description: None,
131       embed_html: None,
132       thumbnail_url: None,
133       ap_id: None,
134       local: true,
135       published: None,
136     };
137
138     let inserted_post = Post::create(&conn, &new_post).unwrap();
139
140     let comment_form = CommentForm {
141       content: "A test comment".into(),
142       creator_id: inserted_person.id,
143       post_id: inserted_post.id,
144       removed: None,
145       deleted: None,
146       read: None,
147       parent_id: None,
148       published: None,
149       updated: None,
150       ap_id: None,
151       local: true,
152     };
153
154     let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
155
156     let child_comment_form = CommentForm {
157       content: "A test comment".into(),
158       creator_id: inserted_person.id,
159       post_id: inserted_post.id,
160       removed: None,
161       deleted: None,
162       read: None,
163       parent_id: Some(inserted_comment.id),
164       published: None,
165       updated: None,
166       ap_id: None,
167       local: true,
168     };
169
170     let _inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
171
172     let post_like = PostLikeForm {
173       post_id: inserted_post.id,
174       person_id: inserted_person.id,
175       score: 1,
176     };
177
178     PostLike::like(&conn, &post_like).unwrap();
179
180     let post_aggs_before_delete = PostAggregates::read(&conn, inserted_post.id).unwrap();
181
182     assert_eq!(2, post_aggs_before_delete.comments);
183     assert_eq!(1, post_aggs_before_delete.score);
184     assert_eq!(1, post_aggs_before_delete.upvotes);
185     assert_eq!(0, post_aggs_before_delete.downvotes);
186
187     // Add a post dislike from the other person
188     let post_dislike = PostLikeForm {
189       post_id: inserted_post.id,
190       person_id: another_inserted_person.id,
191       score: -1,
192     };
193
194     PostLike::like(&conn, &post_dislike).unwrap();
195
196     let post_aggs_after_dislike = PostAggregates::read(&conn, inserted_post.id).unwrap();
197
198     assert_eq!(2, post_aggs_after_dislike.comments);
199     assert_eq!(0, post_aggs_after_dislike.score);
200     assert_eq!(1, post_aggs_after_dislike.upvotes);
201     assert_eq!(1, post_aggs_after_dislike.downvotes);
202
203     // Remove the parent comment
204     Comment::delete(&conn, inserted_comment.id).unwrap();
205     let after_comment_delete = PostAggregates::read(&conn, inserted_post.id).unwrap();
206     assert_eq!(0, after_comment_delete.comments);
207     assert_eq!(0, after_comment_delete.score);
208     assert_eq!(1, after_comment_delete.upvotes);
209     assert_eq!(1, after_comment_delete.downvotes);
210
211     // Remove the first post like
212     PostLike::remove(&conn, inserted_person.id, inserted_post.id).unwrap();
213     let after_like_remove = PostAggregates::read(&conn, inserted_post.id).unwrap();
214     assert_eq!(0, after_like_remove.comments);
215     assert_eq!(-1, after_like_remove.score);
216     assert_eq!(0, after_like_remove.upvotes);
217     assert_eq!(1, after_like_remove.downvotes);
218
219     // This should delete all the associated rows, and fire triggers
220     Person::delete(&conn, another_inserted_person.id).unwrap();
221     let person_num_deleted = Person::delete(&conn, inserted_person.id).unwrap();
222     assert_eq!(1, person_num_deleted);
223
224     // Should be none found, since the creator was deleted
225     let after_delete = PostAggregates::read(&conn, inserted_post.id);
226     assert!(after_delete.is_err());
227   }
228 }