]> Untitled Git - lemmy.git/blob - crates/db_schema/src/aggregates/site_aggregates.rs
1fe90e0fe69d2ac8fcda28a727e723ea56d22c4f
[lemmy.git] / crates / db_schema / src / aggregates / site_aggregates.rs
1 use crate::{
2   aggregates::structs::SiteAggregates,
3   schema::site_aggregates,
4   utils::{get_conn, DbPool},
5 };
6 use diesel::result::Error;
7 use diesel_async::RunQueryDsl;
8
9 impl SiteAggregates {
10   pub async fn read(pool: &mut DbPool<'_>) -> Result<Self, Error> {
11     let conn = &mut get_conn(pool).await?;
12     site_aggregates::table.first::<Self>(conn).await
13   }
14 }
15
16 #[cfg(test)]
17 mod tests {
18   use crate::{
19     aggregates::site_aggregates::SiteAggregates,
20     source::{
21       comment::{Comment, CommentInsertForm},
22       community::{Community, CommunityInsertForm, CommunityUpdateForm},
23       instance::Instance,
24       person::{Person, PersonInsertForm},
25       post::{Post, PostInsertForm},
26       site::{Site, SiteInsertForm},
27     },
28     traits::Crud,
29     utils::{build_db_pool_for_tests, DbPool},
30   };
31   use serial_test::serial;
32
33   async fn prepare_site_with_community(
34     pool: &mut DbPool<'_>,
35   ) -> (Instance, Person, Site, Community) {
36     let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string())
37       .await
38       .unwrap();
39
40     let new_person = PersonInsertForm::builder()
41       .name("thommy_site_agg".into())
42       .public_key("pubkey".to_string())
43       .instance_id(inserted_instance.id)
44       .build();
45
46     let inserted_person = Person::create(pool, &new_person).await.unwrap();
47
48     let site_form = SiteInsertForm::builder()
49       .name("test_site".into())
50       .instance_id(inserted_instance.id)
51       .build();
52
53     let inserted_site = Site::create(pool, &site_form).await.unwrap();
54
55     let new_community = CommunityInsertForm::builder()
56       .name("TIL_site_agg".into())
57       .title("nada".to_owned())
58       .public_key("pubkey".to_string())
59       .instance_id(inserted_instance.id)
60       .build();
61
62     let inserted_community = Community::create(pool, &new_community).await.unwrap();
63     (
64       inserted_instance,
65       inserted_person,
66       inserted_site,
67       inserted_community,
68     )
69   }
70
71   #[tokio::test]
72   #[serial]
73   async fn test_crud() {
74     let pool = &build_db_pool_for_tests().await;
75     let pool = &mut pool.into();
76
77     let (inserted_instance, inserted_person, inserted_site, inserted_community) =
78       prepare_site_with_community(pool).await;
79
80     let new_post = PostInsertForm::builder()
81       .name("A test post".into())
82       .creator_id(inserted_person.id)
83       .community_id(inserted_community.id)
84       .build();
85
86     // Insert two of those posts
87     let inserted_post = Post::create(pool, &new_post).await.unwrap();
88     let _inserted_post_again = Post::create(pool, &new_post).await.unwrap();
89
90     let comment_form = CommentInsertForm::builder()
91       .content("A test comment".into())
92       .creator_id(inserted_person.id)
93       .post_id(inserted_post.id)
94       .build();
95
96     // Insert two of those comments
97     let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap();
98
99     let child_comment_form = CommentInsertForm::builder()
100       .content("A test comment".into())
101       .creator_id(inserted_person.id)
102       .post_id(inserted_post.id)
103       .build();
104
105     let _inserted_child_comment =
106       Comment::create(pool, &child_comment_form, Some(&inserted_comment.path))
107         .await
108         .unwrap();
109
110     let site_aggregates_before_delete = SiteAggregates::read(pool).await.unwrap();
111
112     // TODO: this is unstable, sometimes it returns 0 users, sometimes 1
113     //assert_eq!(0, site_aggregates_before_delete.users);
114     assert_eq!(1, site_aggregates_before_delete.communities);
115     assert_eq!(2, site_aggregates_before_delete.posts);
116     assert_eq!(2, site_aggregates_before_delete.comments);
117
118     // Try a post delete
119     Post::delete(pool, inserted_post.id).await.unwrap();
120     let site_aggregates_after_post_delete = SiteAggregates::read(pool).await.unwrap();
121     assert_eq!(1, site_aggregates_after_post_delete.posts);
122     assert_eq!(0, site_aggregates_after_post_delete.comments);
123
124     // This shouuld delete all the associated rows, and fire triggers
125     let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap();
126     assert_eq!(1, person_num_deleted);
127
128     // Delete the community
129     let community_num_deleted = Community::delete(pool, inserted_community.id)
130       .await
131       .unwrap();
132     assert_eq!(1, community_num_deleted);
133
134     // Site should still exist, it can without a site creator.
135     let after_delete_creator = SiteAggregates::read(pool).await;
136     assert!(after_delete_creator.is_ok());
137
138     Site::delete(pool, inserted_site.id).await.unwrap();
139     let after_delete_site = SiteAggregates::read(pool).await;
140     assert!(after_delete_site.is_err());
141
142     Instance::delete(pool, inserted_instance.id).await.unwrap();
143   }
144
145   #[tokio::test]
146   #[serial]
147   async fn test_soft_delete() {
148     let pool = &build_db_pool_for_tests().await;
149     let pool = &mut pool.into();
150
151     let (inserted_instance, inserted_person, inserted_site, inserted_community) =
152       prepare_site_with_community(pool).await;
153
154     let site_aggregates_before = SiteAggregates::read(pool).await.unwrap();
155     assert_eq!(1, site_aggregates_before.communities);
156
157     Community::update(
158       pool,
159       inserted_community.id,
160       &CommunityUpdateForm::builder().deleted(Some(true)).build(),
161     )
162     .await
163     .unwrap();
164
165     let site_aggregates_after_delete = SiteAggregates::read(pool).await.unwrap();
166     assert_eq!(0, site_aggregates_after_delete.communities);
167
168     Community::update(
169       pool,
170       inserted_community.id,
171       &CommunityUpdateForm::builder().deleted(Some(false)).build(),
172     )
173     .await
174     .unwrap();
175
176     Community::update(
177       pool,
178       inserted_community.id,
179       &CommunityUpdateForm::builder().removed(Some(true)).build(),
180     )
181     .await
182     .unwrap();
183
184     let site_aggregates_after_remove = SiteAggregates::read(pool).await.unwrap();
185     assert_eq!(0, site_aggregates_after_remove.communities);
186
187     Community::update(
188       pool,
189       inserted_community.id,
190       &CommunityUpdateForm::builder().deleted(Some(true)).build(),
191     )
192     .await
193     .unwrap();
194
195     let site_aggregates_after_remove_delete = SiteAggregates::read(pool).await.unwrap();
196     assert_eq!(0, site_aggregates_after_remove_delete.communities);
197
198     Community::delete(pool, inserted_community.id)
199       .await
200       .unwrap();
201     Site::delete(pool, inserted_site.id).await.unwrap();
202     Person::delete(pool, inserted_person.id).await.unwrap();
203     Instance::delete(pool, inserted_instance.id).await.unwrap();
204   }
205 }