From 5d48ee3dc8942104af6c586c22e5b9faea68d10f Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 24 Oct 2023 08:37:03 -0400 Subject: [PATCH] Add creator_is_moderator to Comment and PostViews. Fixes #3347 (#4087) * Add creator_is_moderator to Comment and PostViews. Fixes #3347 * Fixing community_moderator join. * Addressing PR comments. --- crates/db_schema/src/lib.rs | 4 +-- crates/db_views/src/comment_view.rs | 45 +++++++++++++++++++++++++++-- crates/db_views/src/post_view.rs | 43 +++++++++++++++++++++++++-- crates/db_views/src/structs.rs | 2 ++ 4 files changed, 88 insertions(+), 6 deletions(-) diff --git a/crates/db_schema/src/lib.rs b/crates/db_schema/src/lib.rs index 5b908f356..1aa0e4e88 100644 --- a/crates/db_schema/src/lib.rs +++ b/crates/db_schema/src/lib.rs @@ -30,8 +30,8 @@ pub mod newtypes; pub mod schema; #[cfg(feature = "full")] pub mod aliases { - use crate::schema::person; - diesel::alias!(person as person1: Person1, person as person2: Person2); + use crate::schema::{community_moderator, person}; + diesel::alias!(person as person1: Person1, person as person2: Person2, community_moderator as community_moderator1: CommunityModerator1); } pub mod source; #[cfg(feature = "full")] diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index 98536fb8f..99f046cdf 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -12,6 +12,7 @@ use diesel::{ use diesel_async::RunQueryDsl; use diesel_ltree::{nlevel, subpath, Ltree, LtreeExtensions}; use lemmy_db_schema::{ + aliases, newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId}, schema::{ comment, @@ -90,6 +91,17 @@ fn queries<'a>() -> Queries< .and(community_moderator::person_id.eq(person_id_join)), ), ) + .left_join( + aliases::community_moderator1.on( + community::id + .eq(aliases::community_moderator1.field(community_moderator::community_id)) + .and( + aliases::community_moderator1 + .field(community_moderator::person_id) + .eq(comment::creator_id), + ), + ), + ) }; let selection = ( @@ -99,6 +111,10 @@ fn queries<'a>() -> Queries< community::all_columns, comment_aggregates::all_columns, community_person_ban::id.nullable().is_not_null(), + aliases::community_moderator1 + .field(community_moderator::id) + .nullable() + .is_not_null(), CommunityFollower::select_subscribed_type(), comment_saved::id.nullable().is_not_null(), person_block::id.nullable().is_not_null(), @@ -338,7 +354,7 @@ mod tests { source::{ actor_language::LocalUserLanguage, comment::{Comment, CommentInsertForm, CommentLike, CommentLikeForm, CommentUpdateForm}, - community::{Community, CommunityInsertForm}, + community::{Community, CommunityInsertForm, CommunityModerator, CommunityModeratorForm}, instance::Instance, language::Language, local_user::{LocalUser, LocalUserInsertForm}, @@ -346,7 +362,7 @@ mod tests { person_block::{PersonBlock, PersonBlockForm}, post::{Post, PostInsertForm}, }, - traits::{Blockable, Crud, Likeable}, + traits::{Blockable, Crud, Joinable, Likeable}, utils::build_db_pool_for_tests, SubscribedType, }; @@ -779,6 +795,30 @@ mod tests { cleanup(data, pool).await; } + #[tokio::test] + #[serial] + async fn test_creator_is_moderator() { + let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); + let data = init_data(pool).await; + + // Make one of the inserted persons a moderator + let person_id = data.inserted_person_2.id; + let community_id = data.inserted_community.id; + let form = CommunityModeratorForm { + community_id, + person_id, + }; + CommunityModerator::join(pool, &form).await.unwrap(); + + // Make sure that they come back as a mod in the list + let comments = CommentQuery::default().list(pool).await.unwrap(); + + assert!(comments[1].creator_is_moderator); + + cleanup(data, pool).await; + } + async fn cleanup(data: Data, pool: &mut DbPool<'_>) { CommentLike::remove( pool, @@ -814,6 +854,7 @@ mod tests { .unwrap(); CommentView { creator_banned_from_community: false, + creator_is_moderator: false, my_vote: None, subscribed: SubscribedType::NotSubscribed, saved: false, diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index c3da47ac9..51213abb2 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -107,6 +107,13 @@ fn queries<'a>() -> Queries< .and(community_person_ban::person_id.eq(post_aggregates::creator_id)), ), ); + let creator_is_moderator = exists( + community_moderator::table.filter( + post_aggregates::community_id + .eq(community_moderator::community_id) + .and(community_moderator::person_id.eq(post_aggregates::creator_id)), + ), + ); let is_saved = |person_id| { exists( @@ -226,6 +233,7 @@ fn queries<'a>() -> Queries< person::all_columns, community::all_columns, is_creator_banned_from_community, + creator_is_moderator, post_aggregates::all_columns, subscribed_type_selection, is_saved_selection, @@ -705,7 +713,7 @@ mod tests { newtypes::LanguageId, source::{ actor_language::LocalUserLanguage, - community::{Community, CommunityInsertForm}, + community::{Community, CommunityInsertForm, CommunityModerator, CommunityModeratorForm}, community_block::{CommunityBlock, CommunityBlockForm}, instance::Instance, instance_block::{InstanceBlock, InstanceBlockForm}, @@ -715,7 +723,7 @@ mod tests { person_block::{PersonBlock, PersonBlockForm}, post::{Post, PostInsertForm, PostLike, PostLikeForm, PostUpdateForm}, }, - traits::{Blockable, Crud, Likeable}, + traits::{Blockable, Crud, Joinable, Likeable}, utils::{build_db_pool_for_tests, DbPool}, SortType, SubscribedType, @@ -1063,6 +1071,36 @@ mod tests { cleanup(data, pool).await; } + #[tokio::test] + #[serial] + async fn creator_is_moderator() { + let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); + let data = init_data(pool).await; + + // Make one of the inserted persons a moderator + let person_id = data.local_user_view.person.id; + let community_id = data.inserted_community.id; + let form = CommunityModeratorForm { + community_id, + person_id, + }; + CommunityModerator::join(pool, &form).await.unwrap(); + + let post_listing = PostQuery { + sort: (Some(SortType::New)), + community_id: (Some(data.inserted_community.id)), + local_user: (Some(&data.local_user_view)), + ..Default::default() + } + .list(pool) + .await + .unwrap(); + + assert!(post_listing[1].creator_is_moderator); + cleanup(data, pool).await; + } + #[tokio::test] #[serial] async fn post_listing_person_language() { @@ -1396,6 +1434,7 @@ mod tests { last_refreshed_at: inserted_person.last_refreshed_at, }, creator_banned_from_community: false, + creator_is_moderator: false, community: Community { id: inserted_community.id, name: inserted_community.name.clone(), diff --git a/crates/db_views/src/structs.rs b/crates/db_views/src/structs.rs index 10847b053..2f65bb78f 100644 --- a/crates/db_views/src/structs.rs +++ b/crates/db_views/src/structs.rs @@ -56,6 +56,7 @@ pub struct CommentView { pub community: Community, pub counts: CommentAggregates, pub creator_banned_from_community: bool, + pub creator_is_moderator: bool, pub subscribed: SubscribedType, pub saved: bool, pub creator_blocked: bool, @@ -107,6 +108,7 @@ pub struct PostView { pub creator: Person, pub community: Community, pub creator_banned_from_community: bool, + pub creator_is_moderator: bool, pub counts: PostAggregates, pub subscribed: SubscribedType, pub saved: bool,