lemmy/crates/db_schema/src/aggregates/community_aggregates.rs
Nutomic d9e7f0100a
Dont upsert Instance row every apub fetch (#2771)
This is not necessary because the domain cant change, so we only
need to insert if no row exists for this domain.

Also fetch instance actor when parsing person, not only community

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
2023-02-28 21:36:57 -05:00

206 lines
6.5 KiB
Rust

use crate::{
aggregates::structs::CommunityAggregates,
newtypes::CommunityId,
schema::community_aggregates,
utils::{get_conn, DbPool},
};
use diesel::{result::Error, ExpressionMethods, QueryDsl};
use diesel_async::RunQueryDsl;
impl CommunityAggregates {
pub async fn read(pool: &DbPool, community_id: CommunityId) -> Result<Self, Error> {
let conn = &mut get_conn(pool).await?;
community_aggregates::table
.filter(community_aggregates::community_id.eq(community_id))
.first::<Self>(conn)
.await
}
}
#[cfg(test)]
mod tests {
use crate::{
aggregates::community_aggregates::CommunityAggregates,
source::{
comment::{Comment, CommentInsertForm},
community::{Community, CommunityFollower, CommunityFollowerForm, CommunityInsertForm},
instance::Instance,
person::{Person, PersonInsertForm},
post::{Post, PostInsertForm},
},
traits::{Crud, Followable},
utils::build_db_pool_for_tests,
};
use serial_test::serial;
#[tokio::test]
#[serial]
async fn test_crud() {
let pool = &build_db_pool_for_tests().await;
let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string())
.await
.unwrap();
let new_person = PersonInsertForm::builder()
.name("thommy_community_agg".into())
.public_key("pubkey".to_string())
.instance_id(inserted_instance.id)
.build();
let inserted_person = Person::create(pool, &new_person).await.unwrap();
let another_person = PersonInsertForm::builder()
.name("jerry_community_agg".into())
.public_key("pubkey".to_string())
.instance_id(inserted_instance.id)
.build();
let another_inserted_person = Person::create(pool, &another_person).await.unwrap();
let new_community = CommunityInsertForm::builder()
.name("TIL_community_agg".into())
.title("nada".to_owned())
.public_key("pubkey".to_string())
.instance_id(inserted_instance.id)
.build();
let inserted_community = Community::create(pool, &new_community).await.unwrap();
let another_community = CommunityInsertForm::builder()
.name("TIL_community_agg_2".into())
.title("nada".to_owned())
.public_key("pubkey".to_string())
.instance_id(inserted_instance.id)
.build();
let another_inserted_community = Community::create(pool, &another_community).await.unwrap();
let first_person_follow = CommunityFollowerForm {
community_id: inserted_community.id,
person_id: inserted_person.id,
pending: false,
};
CommunityFollower::follow(pool, &first_person_follow)
.await
.unwrap();
let second_person_follow = CommunityFollowerForm {
community_id: inserted_community.id,
person_id: another_inserted_person.id,
pending: false,
};
CommunityFollower::follow(pool, &second_person_follow)
.await
.unwrap();
let another_community_follow = CommunityFollowerForm {
community_id: another_inserted_community.id,
person_id: inserted_person.id,
pending: false,
};
CommunityFollower::follow(pool, &another_community_follow)
.await
.unwrap();
let new_post = PostInsertForm::builder()
.name("A test post".into())
.creator_id(inserted_person.id)
.community_id(inserted_community.id)
.build();
let inserted_post = Post::create(pool, &new_post).await.unwrap();
let comment_form = CommentInsertForm::builder()
.content("A test comment".into())
.creator_id(inserted_person.id)
.post_id(inserted_post.id)
.build();
let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap();
let child_comment_form = CommentInsertForm::builder()
.content("A test comment".into())
.creator_id(inserted_person.id)
.post_id(inserted_post.id)
.build();
let _inserted_child_comment =
Comment::create(pool, &child_comment_form, Some(&inserted_comment.path))
.await
.unwrap();
let community_aggregates_before_delete = CommunityAggregates::read(pool, inserted_community.id)
.await
.unwrap();
assert_eq!(2, community_aggregates_before_delete.subscribers);
assert_eq!(1, community_aggregates_before_delete.posts);
assert_eq!(2, community_aggregates_before_delete.comments);
// Test the other community
let another_community_aggs = CommunityAggregates::read(pool, another_inserted_community.id)
.await
.unwrap();
assert_eq!(1, another_community_aggs.subscribers);
assert_eq!(0, another_community_aggs.posts);
assert_eq!(0, another_community_aggs.comments);
// Unfollow test
CommunityFollower::unfollow(pool, &second_person_follow)
.await
.unwrap();
let after_unfollow = CommunityAggregates::read(pool, inserted_community.id)
.await
.unwrap();
assert_eq!(1, after_unfollow.subscribers);
// Follow again just for the later tests
CommunityFollower::follow(pool, &second_person_follow)
.await
.unwrap();
let after_follow_again = CommunityAggregates::read(pool, inserted_community.id)
.await
.unwrap();
assert_eq!(2, after_follow_again.subscribers);
// Remove a parent comment (the comment count should also be 0)
Post::delete(pool, inserted_post.id).await.unwrap();
let after_parent_post_delete = CommunityAggregates::read(pool, inserted_community.id)
.await
.unwrap();
assert_eq!(0, after_parent_post_delete.comments);
assert_eq!(0, after_parent_post_delete.posts);
// Remove the 2nd person
Person::delete(pool, another_inserted_person.id)
.await
.unwrap();
let after_person_delete = CommunityAggregates::read(pool, inserted_community.id)
.await
.unwrap();
assert_eq!(1, after_person_delete.subscribers);
// This should delete all the associated rows, and fire triggers
let person_num_deleted = Person::delete(pool, inserted_person.id).await.unwrap();
assert_eq!(1, person_num_deleted);
// Delete the community
let community_num_deleted = Community::delete(pool, inserted_community.id)
.await
.unwrap();
assert_eq!(1, community_num_deleted);
let another_community_num_deleted = Community::delete(pool, another_inserted_community.id)
.await
.unwrap();
assert_eq!(1, another_community_num_deleted);
// Should be none found, since the creator was deleted
let after_delete = CommunityAggregates::read(pool, inserted_community.id).await;
assert!(after_delete.is_err());
}
}