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