Add modlog entries for bulk removals. (#5050)
* Add modlog entries for bulk removals. - Added unit tests for removal / restore to api_common/utils. - Fixes #4699 * Address PR comments. * Combining remove and restore functions. * Trigger build. * Trigger build 2. * Changing allow to expect.
This commit is contained in:
parent
338344dbc5
commit
e3edc317be
8 changed files with 424 additions and 176 deletions
|
@ -92,8 +92,10 @@ pub async fn ban_from_community(
|
||||||
let remove_data = data.ban;
|
let remove_data = data.ban;
|
||||||
remove_or_restore_user_data_in_community(
|
remove_or_restore_user_data_in_community(
|
||||||
data.community_id,
|
data.community_id,
|
||||||
|
local_user_view.person.id,
|
||||||
banned_person_id,
|
banned_person_id,
|
||||||
remove_data,
|
remove_data,
|
||||||
|
&data.reason,
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{BanPerson, BanPersonResponse},
|
person::{BanPerson, BanPersonResponse},
|
||||||
send_activity::{ActivityChannel, SendActivityData},
|
send_activity::{ActivityChannel, SendActivityData},
|
||||||
utils::{check_expire_time, is_admin, remove_user_data, restore_user_data},
|
utils::{check_expire_time, is_admin, remove_or_restore_user_data},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
|
@ -66,11 +66,15 @@ pub async fn ban_from_site(
|
||||||
|
|
||||||
// Remove their data if that's desired
|
// Remove their data if that's desired
|
||||||
if data.remove_or_restore_data.unwrap_or(false) {
|
if data.remove_or_restore_data.unwrap_or(false) {
|
||||||
if data.ban {
|
let removed = data.ban;
|
||||||
remove_user_data(person.id, &context).await?;
|
remove_or_restore_user_data(
|
||||||
} else {
|
local_user_view.person.id,
|
||||||
restore_user_data(person.id, &context).await?;
|
person.id,
|
||||||
}
|
removed,
|
||||||
|
&data.reason,
|
||||||
|
&context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
|
|
|
@ -11,7 +11,7 @@ use chrono::{DateTime, Days, Local, TimeZone, Utc};
|
||||||
use enum_map::{enum_map, EnumMap};
|
use enum_map::{enum_map, EnumMap};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm},
|
aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm},
|
||||||
newtypes::{CommunityId, DbUrl, InstanceId, PersonId, PostId},
|
newtypes::{CommentId, CommunityId, DbUrl, InstanceId, PersonId, PostId},
|
||||||
source::{
|
source::{
|
||||||
comment::{Comment, CommentUpdateForm},
|
comment::{Comment, CommentUpdateForm},
|
||||||
community::{Community, CommunityModerator, CommunityUpdateForm},
|
community::{Community, CommunityModerator, CommunityUpdateForm},
|
||||||
|
@ -23,6 +23,7 @@ use lemmy_db_schema::{
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
local_site_rate_limit::LocalSiteRateLimit,
|
local_site_rate_limit::LocalSiteRateLimit,
|
||||||
local_site_url_blocklist::LocalSiteUrlBlocklist,
|
local_site_url_blocklist::LocalSiteUrlBlocklist,
|
||||||
|
moderator::{ModRemoveComment, ModRemoveCommentForm, ModRemovePost, ModRemovePostForm},
|
||||||
oauth_account::OAuthAccount,
|
oauth_account::OAuthAccount,
|
||||||
password_reset_request::PasswordResetRequest,
|
password_reset_request::PasswordResetRequest,
|
||||||
person::{Person, PersonUpdateForm},
|
person::{Person, PersonUpdateForm},
|
||||||
|
@ -667,112 +668,179 @@ pub async fn purge_image_posts_for_community(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_user_data(
|
/// Removes or restores user data.
|
||||||
|
pub async fn remove_or_restore_user_data(
|
||||||
|
mod_person_id: PersonId,
|
||||||
banned_person_id: PersonId,
|
banned_person_id: PersonId,
|
||||||
|
removed: bool,
|
||||||
|
reason: &Option<String>,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let pool = &mut context.pool();
|
let pool = &mut context.pool();
|
||||||
// Purge user images
|
|
||||||
let person = Person::read(pool, banned_person_id).await?;
|
// Only these actions are possible when removing, not restoring
|
||||||
if let Some(avatar) = person.avatar {
|
if removed {
|
||||||
purge_image_from_pictrs(&avatar, context).await.ok();
|
// Purge user images
|
||||||
}
|
let person = Person::read(pool, banned_person_id).await?;
|
||||||
if let Some(banner) = person.banner {
|
if let Some(avatar) = person.avatar {
|
||||||
purge_image_from_pictrs(&banner, context).await.ok();
|
purge_image_from_pictrs(&avatar, context).await.ok();
|
||||||
|
}
|
||||||
|
if let Some(banner) = person.banner {
|
||||||
|
purge_image_from_pictrs(&banner, context).await.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the fields to None
|
||||||
|
Person::update(
|
||||||
|
pool,
|
||||||
|
banned_person_id,
|
||||||
|
&PersonUpdateForm {
|
||||||
|
avatar: Some(None),
|
||||||
|
banner: Some(None),
|
||||||
|
bio: Some(None),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Purge image posts
|
||||||
|
purge_image_posts_for_person(banned_person_id, context).await?;
|
||||||
|
|
||||||
|
// Communities
|
||||||
|
// Remove all communities where they're the top mod
|
||||||
|
// for now, remove the communities manually
|
||||||
|
let first_mod_communities = CommunityModeratorView::get_community_first_mods(pool).await?;
|
||||||
|
|
||||||
|
// Filter to only this banned users top communities
|
||||||
|
let banned_user_first_communities: Vec<CommunityModeratorView> = first_mod_communities
|
||||||
|
.into_iter()
|
||||||
|
.filter(|fmc| fmc.moderator.id == banned_person_id)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for first_mod_community in banned_user_first_communities {
|
||||||
|
let community_id = first_mod_community.community.id;
|
||||||
|
Community::update(
|
||||||
|
pool,
|
||||||
|
community_id,
|
||||||
|
&CommunityUpdateForm {
|
||||||
|
removed: Some(removed),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Delete the community images
|
||||||
|
if let Some(icon) = first_mod_community.community.icon {
|
||||||
|
purge_image_from_pictrs(&icon, context).await.ok();
|
||||||
|
}
|
||||||
|
if let Some(banner) = first_mod_community.community.banner {
|
||||||
|
purge_image_from_pictrs(&banner, context).await.ok();
|
||||||
|
}
|
||||||
|
// Update the fields to None
|
||||||
|
Community::update(
|
||||||
|
pool,
|
||||||
|
community_id,
|
||||||
|
&CommunityUpdateForm {
|
||||||
|
icon: Some(None),
|
||||||
|
banner: Some(None),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the fields to None
|
// Posts
|
||||||
Person::update(
|
let removed_or_restored_posts =
|
||||||
|
Post::update_removed_for_creator(pool, banned_person_id, None, removed).await?;
|
||||||
|
create_modlog_entries_for_removed_or_restored_posts(
|
||||||
pool,
|
pool,
|
||||||
banned_person_id,
|
mod_person_id,
|
||||||
&PersonUpdateForm {
|
removed_or_restored_posts.iter().map(|r| r.id).collect(),
|
||||||
avatar: Some(None),
|
removed,
|
||||||
banner: Some(None),
|
reason,
|
||||||
bio: Some(None),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Posts
|
|
||||||
Post::update_removed_for_creator(pool, banned_person_id, None, true).await?;
|
|
||||||
|
|
||||||
// Purge image posts
|
|
||||||
purge_image_posts_for_person(banned_person_id, context).await?;
|
|
||||||
|
|
||||||
// Communities
|
|
||||||
// Remove all communities where they're the top mod
|
|
||||||
// for now, remove the communities manually
|
|
||||||
let first_mod_communities = CommunityModeratorView::get_community_first_mods(pool).await?;
|
|
||||||
|
|
||||||
// Filter to only this banned users top communities
|
|
||||||
let banned_user_first_communities: Vec<CommunityModeratorView> = first_mod_communities
|
|
||||||
.into_iter()
|
|
||||||
.filter(|fmc| fmc.moderator.id == banned_person_id)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for first_mod_community in banned_user_first_communities {
|
|
||||||
let community_id = first_mod_community.community.id;
|
|
||||||
Community::update(
|
|
||||||
pool,
|
|
||||||
community_id,
|
|
||||||
&CommunityUpdateForm {
|
|
||||||
removed: Some(true),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Delete the community images
|
|
||||||
if let Some(icon) = first_mod_community.community.icon {
|
|
||||||
purge_image_from_pictrs(&icon, context).await.ok();
|
|
||||||
}
|
|
||||||
if let Some(banner) = first_mod_community.community.banner {
|
|
||||||
purge_image_from_pictrs(&banner, context).await.ok();
|
|
||||||
}
|
|
||||||
// Update the fields to None
|
|
||||||
Community::update(
|
|
||||||
pool,
|
|
||||||
community_id,
|
|
||||||
&CommunityUpdateForm {
|
|
||||||
icon: Some(None),
|
|
||||||
banner: Some(None),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
Comment::update_removed_for_creator(pool, banned_person_id, true).await?;
|
let removed_or_restored_comments =
|
||||||
|
Comment::update_removed_for_creator(pool, banned_person_id, removed).await?;
|
||||||
|
create_modlog_entries_for_removed_or_restored_comments(
|
||||||
|
pool,
|
||||||
|
mod_person_id,
|
||||||
|
removed_or_restored_comments.iter().map(|r| r.id).collect(),
|
||||||
|
removed,
|
||||||
|
reason,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We can't restore their images, but we can unremove their posts and comments
|
async fn create_modlog_entries_for_removed_or_restored_posts(
|
||||||
pub async fn restore_user_data(
|
pool: &mut DbPool<'_>,
|
||||||
banned_person_id: PersonId,
|
mod_person_id: PersonId,
|
||||||
context: &LemmyContext,
|
post_ids: Vec<PostId>,
|
||||||
|
removed: bool,
|
||||||
|
reason: &Option<String>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let pool = &mut context.pool();
|
// Build the forms
|
||||||
|
let forms = post_ids
|
||||||
|
.iter()
|
||||||
|
.map(|&post_id| ModRemovePostForm {
|
||||||
|
mod_person_id,
|
||||||
|
post_id,
|
||||||
|
removed: Some(removed),
|
||||||
|
reason: reason.clone(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Posts
|
ModRemovePost::create_multiple(pool, &forms).await?;
|
||||||
Post::update_removed_for_creator(pool, banned_person_id, None, false).await?;
|
|
||||||
|
|
||||||
// Comments
|
Ok(())
|
||||||
Comment::update_removed_for_creator(pool, banned_person_id, false).await?;
|
}
|
||||||
|
|
||||||
|
async fn create_modlog_entries_for_removed_or_restored_comments(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
mod_person_id: PersonId,
|
||||||
|
comment_ids: Vec<CommentId>,
|
||||||
|
removed: bool,
|
||||||
|
reason: &Option<String>,
|
||||||
|
) -> LemmyResult<()> {
|
||||||
|
// Build the forms
|
||||||
|
let forms = comment_ids
|
||||||
|
.iter()
|
||||||
|
.map(|&comment_id| ModRemoveCommentForm {
|
||||||
|
mod_person_id,
|
||||||
|
comment_id,
|
||||||
|
removed: Some(removed),
|
||||||
|
reason: reason.clone(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
ModRemoveComment::create_multiple(pool, &forms).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_or_restore_user_data_in_community(
|
pub async fn remove_or_restore_user_data_in_community(
|
||||||
community_id: CommunityId,
|
community_id: CommunityId,
|
||||||
|
mod_person_id: PersonId,
|
||||||
banned_person_id: PersonId,
|
banned_person_id: PersonId,
|
||||||
remove: bool,
|
remove: bool,
|
||||||
|
reason: &Option<String>,
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
// Posts
|
// Posts
|
||||||
Post::update_removed_for_creator(pool, banned_person_id, Some(community_id), remove).await?;
|
let posts =
|
||||||
|
Post::update_removed_for_creator(pool, banned_person_id, Some(community_id), remove).await?;
|
||||||
|
create_modlog_entries_for_removed_or_restored_posts(
|
||||||
|
pool,
|
||||||
|
mod_person_id,
|
||||||
|
posts.iter().map(|r| r.id).collect(),
|
||||||
|
remove,
|
||||||
|
reason,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
// TODO Diesel doesn't allow updates with joins, so this has to be a loop
|
// TODO Diesel doesn't allow updates with joins, so this has to be a loop
|
||||||
|
@ -798,6 +866,15 @@ pub async fn remove_or_restore_user_data_in_community(
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_modlog_entries_for_removed_or_restored_comments(
|
||||||
|
pool,
|
||||||
|
mod_person_id,
|
||||||
|
comments.iter().map(|r| r.comment.id).collect(),
|
||||||
|
remove,
|
||||||
|
reason,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,10 +1144,20 @@ fn build_proxied_image_url(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[expect(clippy::unwrap_used)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use lemmy_db_schema::source::{
|
||||||
|
comment::CommentInsertForm,
|
||||||
|
community::CommunityInsertForm,
|
||||||
|
person::PersonInsertForm,
|
||||||
|
post::PostInsertForm,
|
||||||
|
};
|
||||||
|
use lemmy_db_views_moderator::structs::{
|
||||||
|
ModRemoveCommentView,
|
||||||
|
ModRemovePostView,
|
||||||
|
ModlogListParams,
|
||||||
|
};
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
|
@ -1092,48 +1179,42 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_limit_ban_term() {
|
fn test_limit_ban_term() -> LemmyResult<()> {
|
||||||
// Ban expires in past, should throw error
|
// Ban expires in past, should throw error
|
||||||
assert!(limit_expire_time(Utc::now() - Days::new(5)).is_err());
|
assert!(limit_expire_time(Utc::now() - Days::new(5)).is_err());
|
||||||
|
|
||||||
// Legitimate ban term, return same value
|
// Legitimate ban term, return same value
|
||||||
let fourteen_days = Utc::now() + Days::new(14);
|
let fourteen_days = Utc::now() + Days::new(14);
|
||||||
assert_eq!(
|
assert_eq!(limit_expire_time(fourteen_days)?, Some(fourteen_days));
|
||||||
limit_expire_time(fourteen_days).unwrap(),
|
|
||||||
Some(fourteen_days)
|
|
||||||
);
|
|
||||||
let nine_years = Utc::now() + Days::new(365 * 9);
|
let nine_years = Utc::now() + Days::new(365 * 9);
|
||||||
assert_eq!(limit_expire_time(nine_years).unwrap(), Some(nine_years));
|
assert_eq!(limit_expire_time(nine_years)?, Some(nine_years));
|
||||||
|
|
||||||
// Too long ban term, changes to None (permanent ban)
|
// Too long ban term, changes to None (permanent ban)
|
||||||
assert_eq!(
|
assert_eq!(limit_expire_time(Utc::now() + Days::new(365 * 11))?, None);
|
||||||
limit_expire_time(Utc::now() + Days::new(365 * 11)).unwrap(),
|
|
||||||
None
|
Ok(())
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_proxy_image_link() {
|
async fn test_proxy_image_link() -> LemmyResult<()> {
|
||||||
let context = LemmyContext::init_test_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
|
|
||||||
// image from local domain is unchanged
|
// image from local domain is unchanged
|
||||||
let local_url = Url::parse("http://lemmy-alpha/image.png").unwrap();
|
let local_url = Url::parse("http://lemmy-alpha/image.png")?;
|
||||||
let proxied =
|
let proxied =
|
||||||
proxy_image_link_internal(local_url.clone(), PictrsImageMode::ProxyAllImages, &context)
|
proxy_image_link_internal(local_url.clone(), PictrsImageMode::ProxyAllImages, &context)
|
||||||
.await
|
.await?;
|
||||||
.unwrap();
|
|
||||||
assert_eq!(&local_url, proxied.inner());
|
assert_eq!(&local_url, proxied.inner());
|
||||||
|
|
||||||
// image from remote domain is proxied
|
// image from remote domain is proxied
|
||||||
let remote_image = Url::parse("http://lemmy-beta/image.png").unwrap();
|
let remote_image = Url::parse("http://lemmy-beta/image.png")?;
|
||||||
let proxied = proxy_image_link_internal(
|
let proxied = proxy_image_link_internal(
|
||||||
remote_image.clone(),
|
remote_image.clone(),
|
||||||
PictrsImageMode::ProxyAllImages,
|
PictrsImageMode::ProxyAllImages,
|
||||||
&context,
|
&context,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Flemmy-beta%2Fimage.png",
|
"https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Flemmy-beta%2Fimage.png",
|
||||||
proxied.as_str()
|
proxied.as_str()
|
||||||
|
@ -1146,5 +1227,159 @@ mod tests {
|
||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[serial]
|
||||||
|
async fn test_mod_remove_or_restore_data() -> LemmyResult<()> {
|
||||||
|
let context = LemmyContext::init_test_context().await;
|
||||||
|
let pool = &mut context.pool();
|
||||||
|
|
||||||
|
let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string()).await?;
|
||||||
|
|
||||||
|
let new_mod = PersonInsertForm::test_form(inserted_instance.id, "modder");
|
||||||
|
let inserted_mod = Person::create(pool, &new_mod).await?;
|
||||||
|
|
||||||
|
let new_person = PersonInsertForm::test_form(inserted_instance.id, "chrimbus");
|
||||||
|
let inserted_person = Person::create(pool, &new_person).await?;
|
||||||
|
|
||||||
|
let new_community = CommunityInsertForm::new(
|
||||||
|
inserted_instance.id,
|
||||||
|
"mod_community crepes".to_string(),
|
||||||
|
"nada".to_owned(),
|
||||||
|
"pubkey".to_string(),
|
||||||
|
);
|
||||||
|
let inserted_community = Community::create(pool, &new_community).await?;
|
||||||
|
|
||||||
|
let post_form_1 = PostInsertForm::new(
|
||||||
|
"A test post tubular".into(),
|
||||||
|
inserted_person.id,
|
||||||
|
inserted_community.id,
|
||||||
|
);
|
||||||
|
let inserted_post_1 = Post::create(pool, &post_form_1).await?;
|
||||||
|
|
||||||
|
let post_form_2 = PostInsertForm::new(
|
||||||
|
"A test post radical".into(),
|
||||||
|
inserted_person.id,
|
||||||
|
inserted_community.id,
|
||||||
|
);
|
||||||
|
let inserted_post_2 = Post::create(pool, &post_form_2).await?;
|
||||||
|
|
||||||
|
let comment_form_1 = CommentInsertForm::new(
|
||||||
|
inserted_person.id,
|
||||||
|
inserted_post_1.id,
|
||||||
|
"A test comment tubular".into(),
|
||||||
|
);
|
||||||
|
let _inserted_comment_1 = Comment::create(pool, &comment_form_1, None).await?;
|
||||||
|
|
||||||
|
let comment_form_2 = CommentInsertForm::new(
|
||||||
|
inserted_person.id,
|
||||||
|
inserted_post_2.id,
|
||||||
|
"A test comment radical".into(),
|
||||||
|
);
|
||||||
|
let _inserted_comment_2 = Comment::create(pool, &comment_form_2, None).await?;
|
||||||
|
|
||||||
|
// Remove the user data
|
||||||
|
remove_or_restore_user_data(
|
||||||
|
inserted_mod.id,
|
||||||
|
inserted_person.id,
|
||||||
|
true,
|
||||||
|
&Some("a remove reason".to_string()),
|
||||||
|
&context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Verify that their posts and comments are removed.
|
||||||
|
let params = ModlogListParams {
|
||||||
|
community_id: None,
|
||||||
|
mod_person_id: None,
|
||||||
|
other_person_id: None,
|
||||||
|
post_id: None,
|
||||||
|
comment_id: None,
|
||||||
|
page: None,
|
||||||
|
limit: None,
|
||||||
|
hide_modlog_names: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Posts
|
||||||
|
let post_modlog = ModRemovePostView::list(pool, params).await?;
|
||||||
|
assert_eq!(2, post_modlog.len());
|
||||||
|
|
||||||
|
let mod_removed_posts = post_modlog
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.mod_remove_post.removed)
|
||||||
|
.collect::<Vec<bool>>();
|
||||||
|
assert_eq!(vec![true, true], mod_removed_posts);
|
||||||
|
|
||||||
|
let removed_posts = post_modlog
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.post.removed)
|
||||||
|
.collect::<Vec<bool>>();
|
||||||
|
assert_eq!(vec![true, true], removed_posts);
|
||||||
|
|
||||||
|
// Comments
|
||||||
|
let comment_modlog = ModRemoveCommentView::list(pool, params).await?;
|
||||||
|
assert_eq!(2, comment_modlog.len());
|
||||||
|
|
||||||
|
let mod_removed_comments = comment_modlog
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.mod_remove_comment.removed)
|
||||||
|
.collect::<Vec<bool>>();
|
||||||
|
assert_eq!(vec![true, true], mod_removed_comments);
|
||||||
|
|
||||||
|
let removed_comments = comment_modlog
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.comment.removed)
|
||||||
|
.collect::<Vec<bool>>();
|
||||||
|
assert_eq!(vec![true, true], removed_comments);
|
||||||
|
|
||||||
|
// Now restore the content, and make sure it got appended
|
||||||
|
remove_or_restore_user_data(
|
||||||
|
inserted_mod.id,
|
||||||
|
inserted_person.id,
|
||||||
|
false,
|
||||||
|
&Some("a restore reason".to_string()),
|
||||||
|
&context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Posts
|
||||||
|
let post_modlog = ModRemovePostView::list(pool, params).await?;
|
||||||
|
assert_eq!(4, post_modlog.len());
|
||||||
|
|
||||||
|
let mod_restored_posts = post_modlog
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.mod_remove_post.removed)
|
||||||
|
.collect::<Vec<bool>>();
|
||||||
|
assert_eq!(vec![false, false, true, true], mod_restored_posts);
|
||||||
|
|
||||||
|
let restored_posts = post_modlog
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.post.removed)
|
||||||
|
.collect::<Vec<bool>>();
|
||||||
|
// All of these will be false, cause its the current state of the post
|
||||||
|
assert_eq!(vec![false, false, false, false], restored_posts);
|
||||||
|
|
||||||
|
// Comments
|
||||||
|
let comment_modlog = ModRemoveCommentView::list(pool, params).await?;
|
||||||
|
assert_eq!(4, comment_modlog.len());
|
||||||
|
|
||||||
|
let mod_restored_comments = comment_modlog
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.mod_remove_comment.removed)
|
||||||
|
.collect::<Vec<bool>>();
|
||||||
|
assert_eq!(vec![false, false, true, true], mod_restored_comments);
|
||||||
|
|
||||||
|
let restored_comments = comment_modlog
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.comment.removed)
|
||||||
|
.collect::<Vec<bool>>();
|
||||||
|
assert_eq!(vec![false, false, false, false], restored_comments);
|
||||||
|
|
||||||
|
Instance::delete(pool, inserted_instance.id).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ use anyhow::anyhow;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
utils::{remove_or_restore_user_data_in_community, remove_user_data},
|
utils::{remove_or_restore_user_data, remove_or_restore_user_data_in_community},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
|
@ -160,6 +160,7 @@ impl ActivityHandler for BlockUser {
|
||||||
let mod_person = self.actor.dereference(context).await?;
|
let mod_person = self.actor.dereference(context).await?;
|
||||||
let blocked_person = self.object.dereference(context).await?;
|
let blocked_person = self.object.dereference(context).await?;
|
||||||
let target = self.target.dereference(context).await?;
|
let target = self.target.dereference(context).await?;
|
||||||
|
let reason = self.summary;
|
||||||
match target {
|
match target {
|
||||||
SiteOrCommunity::Site(_site) => {
|
SiteOrCommunity::Site(_site) => {
|
||||||
let blocked_person = Person::update(
|
let blocked_person = Person::update(
|
||||||
|
@ -173,14 +174,15 @@ impl ActivityHandler for BlockUser {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if self.remove_data.unwrap_or(false) {
|
if self.remove_data.unwrap_or(false) {
|
||||||
remove_user_data(blocked_person.id, context).await?;
|
remove_or_restore_user_data(mod_person.id, blocked_person.id, true, &reason, context)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write mod log
|
// write mod log
|
||||||
let form = ModBanForm {
|
let form = ModBanForm {
|
||||||
mod_person_id: mod_person.id,
|
mod_person_id: mod_person.id,
|
||||||
other_person_id: blocked_person.id,
|
other_person_id: blocked_person.id,
|
||||||
reason: self.summary,
|
reason,
|
||||||
banned: Some(true),
|
banned: Some(true),
|
||||||
expires,
|
expires,
|
||||||
};
|
};
|
||||||
|
@ -207,8 +209,10 @@ impl ActivityHandler for BlockUser {
|
||||||
if self.remove_data.unwrap_or(false) {
|
if self.remove_data.unwrap_or(false) {
|
||||||
remove_or_restore_user_data_in_community(
|
remove_or_restore_user_data_in_community(
|
||||||
community.id,
|
community.id,
|
||||||
|
mod_person.id,
|
||||||
blocked_person.id,
|
blocked_person.id,
|
||||||
true,
|
true,
|
||||||
|
&reason,
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -219,7 +223,7 @@ impl ActivityHandler for BlockUser {
|
||||||
mod_person_id: mod_person.id,
|
mod_person_id: mod_person.id,
|
||||||
other_person_id: blocked_person.id,
|
other_person_id: blocked_person.id,
|
||||||
community_id: community.id,
|
community_id: community.id,
|
||||||
reason: self.summary,
|
reason,
|
||||||
banned: Some(true),
|
banned: Some(true),
|
||||||
expires,
|
expires,
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@ use activitypub_federation::{
|
||||||
};
|
};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
utils::{remove_or_restore_user_data_in_community, restore_user_data},
|
utils::{remove_or_restore_user_data, remove_or_restore_user_data_in_community},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
|
@ -120,7 +120,8 @@ impl ActivityHandler for UndoBlockUser {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if self.restore_data.unwrap_or(false) {
|
if self.restore_data.unwrap_or(false) {
|
||||||
restore_user_data(blocked_person.id, context).await?;
|
remove_or_restore_user_data(mod_person.id, blocked_person.id, false, &None, context)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write mod log
|
// write mod log
|
||||||
|
@ -144,8 +145,10 @@ impl ActivityHandler for UndoBlockUser {
|
||||||
if self.restore_data.unwrap_or(false) {
|
if self.restore_data.unwrap_or(false) {
|
||||||
remove_or_restore_user_data_in_community(
|
remove_or_restore_user_data_in_community(
|
||||||
community.id,
|
community.id,
|
||||||
|
mod_person.id,
|
||||||
blocked_person.id,
|
blocked_person.id,
|
||||||
false,
|
false,
|
||||||
|
&None,
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
|
@ -40,12 +40,12 @@ impl Comment {
|
||||||
pub async fn update_removed_for_creator(
|
pub async fn update_removed_for_creator(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
for_creator_id: PersonId,
|
for_creator_id: PersonId,
|
||||||
new_removed: bool,
|
removed: bool,
|
||||||
) -> Result<Vec<Self>, Error> {
|
) -> Result<Vec<Self>, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
diesel::update(comment::table.filter(comment::creator_id.eq(for_creator_id)))
|
diesel::update(comment::table.filter(comment::creator_id.eq(for_creator_id)))
|
||||||
.set((
|
.set((
|
||||||
comment::removed.eq(new_removed),
|
comment::removed.eq(removed),
|
||||||
comment::updated.eq(naive_now()),
|
comment::updated.eq(naive_now()),
|
||||||
))
|
))
|
||||||
.get_results::<Self>(conn)
|
.get_results::<Self>(conn)
|
||||||
|
|
|
@ -66,6 +66,20 @@ impl Crud for ModRemovePost {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ModRemovePost {
|
||||||
|
pub async fn create_multiple(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
forms: &Vec<ModRemovePostForm>,
|
||||||
|
) -> Result<usize, Error> {
|
||||||
|
use crate::schema::mod_remove_post::dsl::mod_remove_post;
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
insert_into(mod_remove_post)
|
||||||
|
.values(forms)
|
||||||
|
.execute(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Crud for ModLockPost {
|
impl Crud for ModLockPost {
|
||||||
type InsertForm = ModLockPostForm;
|
type InsertForm = ModLockPostForm;
|
||||||
|
@ -153,6 +167,20 @@ impl Crud for ModRemoveComment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ModRemoveComment {
|
||||||
|
pub async fn create_multiple(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
forms: &Vec<ModRemoveCommentForm>,
|
||||||
|
) -> Result<usize, Error> {
|
||||||
|
use crate::schema::mod_remove_comment::dsl::mod_remove_comment;
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
insert_into(mod_remove_comment)
|
||||||
|
.values(forms)
|
||||||
|
.execute(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Crud for ModRemoveCommunity {
|
impl Crud for ModRemoveCommunity {
|
||||||
type InsertForm = ModRemoveCommunityForm;
|
type InsertForm = ModRemoveCommunityForm;
|
||||||
|
@ -465,7 +493,6 @@ impl Crud for AdminPurgeComment {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[expect(clippy::unwrap_used)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -499,26 +526,25 @@ mod tests {
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::build_db_pool_for_tests,
|
utils::build_db_pool_for_tests,
|
||||||
};
|
};
|
||||||
|
use diesel::result::Error;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_crud() {
|
async fn test_crud() -> Result<(), Error> {
|
||||||
let pool = &build_db_pool_for_tests().await;
|
let pool = &build_db_pool_for_tests().await;
|
||||||
let pool = &mut pool.into();
|
let pool = &mut pool.into();
|
||||||
|
|
||||||
let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string())
|
let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string()).await?;
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let new_mod = PersonInsertForm::test_form(inserted_instance.id, "the mod");
|
let new_mod = PersonInsertForm::test_form(inserted_instance.id, "the mod");
|
||||||
|
|
||||||
let inserted_mod = Person::create(pool, &new_mod).await.unwrap();
|
let inserted_mod = Person::create(pool, &new_mod).await?;
|
||||||
|
|
||||||
let new_person = PersonInsertForm::test_form(inserted_instance.id, "jim2");
|
let new_person = PersonInsertForm::test_form(inserted_instance.id, "jim2");
|
||||||
|
|
||||||
let inserted_person = Person::create(pool, &new_person).await.unwrap();
|
let inserted_person = Person::create(pool, &new_person).await?;
|
||||||
|
|
||||||
let new_community = CommunityInsertForm::new(
|
let new_community = CommunityInsertForm::new(
|
||||||
inserted_instance.id,
|
inserted_instance.id,
|
||||||
|
@ -527,21 +553,21 @@ mod tests {
|
||||||
"pubkey".to_string(),
|
"pubkey".to_string(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let inserted_community = Community::create(pool, &new_community).await.unwrap();
|
let inserted_community = Community::create(pool, &new_community).await?;
|
||||||
|
|
||||||
let new_post = PostInsertForm::new(
|
let new_post = PostInsertForm::new(
|
||||||
"A test post thweep".into(),
|
"A test post thweep".into(),
|
||||||
inserted_person.id,
|
inserted_person.id,
|
||||||
inserted_community.id,
|
inserted_community.id,
|
||||||
);
|
);
|
||||||
let inserted_post = Post::create(pool, &new_post).await.unwrap();
|
let inserted_post = Post::create(pool, &new_post).await?;
|
||||||
|
|
||||||
let comment_form = CommentInsertForm::new(
|
let comment_form = CommentInsertForm::new(
|
||||||
inserted_person.id,
|
inserted_person.id,
|
||||||
inserted_post.id,
|
inserted_post.id,
|
||||||
"A test comment".into(),
|
"A test comment".into(),
|
||||||
);
|
);
|
||||||
let inserted_comment = Comment::create(pool, &comment_form, None).await.unwrap();
|
let inserted_comment = Comment::create(pool, &comment_form, None).await?;
|
||||||
|
|
||||||
// Now the actual tests
|
// Now the actual tests
|
||||||
|
|
||||||
|
@ -552,12 +578,8 @@ mod tests {
|
||||||
reason: None,
|
reason: None,
|
||||||
removed: None,
|
removed: None,
|
||||||
};
|
};
|
||||||
let inserted_mod_remove_post = ModRemovePost::create(pool, &mod_remove_post_form)
|
let inserted_mod_remove_post = ModRemovePost::create(pool, &mod_remove_post_form).await?;
|
||||||
.await
|
let read_mod_remove_post = ModRemovePost::read(pool, inserted_mod_remove_post.id).await?;
|
||||||
.unwrap();
|
|
||||||
let read_mod_remove_post = ModRemovePost::read(pool, inserted_mod_remove_post.id)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let expected_mod_remove_post = ModRemovePost {
|
let expected_mod_remove_post = ModRemovePost {
|
||||||
id: inserted_mod_remove_post.id,
|
id: inserted_mod_remove_post.id,
|
||||||
post_id: inserted_post.id,
|
post_id: inserted_post.id,
|
||||||
|
@ -574,12 +596,8 @@ mod tests {
|
||||||
post_id: inserted_post.id,
|
post_id: inserted_post.id,
|
||||||
locked: None,
|
locked: None,
|
||||||
};
|
};
|
||||||
let inserted_mod_lock_post = ModLockPost::create(pool, &mod_lock_post_form)
|
let inserted_mod_lock_post = ModLockPost::create(pool, &mod_lock_post_form).await?;
|
||||||
.await
|
let read_mod_lock_post = ModLockPost::read(pool, inserted_mod_lock_post.id).await?;
|
||||||
.unwrap();
|
|
||||||
let read_mod_lock_post = ModLockPost::read(pool, inserted_mod_lock_post.id)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let expected_mod_lock_post = ModLockPost {
|
let expected_mod_lock_post = ModLockPost {
|
||||||
id: inserted_mod_lock_post.id,
|
id: inserted_mod_lock_post.id,
|
||||||
post_id: inserted_post.id,
|
post_id: inserted_post.id,
|
||||||
|
@ -596,12 +614,8 @@ mod tests {
|
||||||
featured: false,
|
featured: false,
|
||||||
is_featured_community: true,
|
is_featured_community: true,
|
||||||
};
|
};
|
||||||
let inserted_mod_feature_post = ModFeaturePost::create(pool, &mod_feature_post_form)
|
let inserted_mod_feature_post = ModFeaturePost::create(pool, &mod_feature_post_form).await?;
|
||||||
.await
|
let read_mod_feature_post = ModFeaturePost::read(pool, inserted_mod_feature_post.id).await?;
|
||||||
.unwrap();
|
|
||||||
let read_mod_feature_post = ModFeaturePost::read(pool, inserted_mod_feature_post.id)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let expected_mod_feature_post = ModFeaturePost {
|
let expected_mod_feature_post = ModFeaturePost {
|
||||||
id: inserted_mod_feature_post.id,
|
id: inserted_mod_feature_post.id,
|
||||||
post_id: inserted_post.id,
|
post_id: inserted_post.id,
|
||||||
|
@ -619,12 +633,10 @@ mod tests {
|
||||||
reason: None,
|
reason: None,
|
||||||
removed: None,
|
removed: None,
|
||||||
};
|
};
|
||||||
let inserted_mod_remove_comment = ModRemoveComment::create(pool, &mod_remove_comment_form)
|
let inserted_mod_remove_comment =
|
||||||
.await
|
ModRemoveComment::create(pool, &mod_remove_comment_form).await?;
|
||||||
.unwrap();
|
let read_mod_remove_comment =
|
||||||
let read_mod_remove_comment = ModRemoveComment::read(pool, inserted_mod_remove_comment.id)
|
ModRemoveComment::read(pool, inserted_mod_remove_comment.id).await?;
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let expected_mod_remove_comment = ModRemoveComment {
|
let expected_mod_remove_comment = ModRemoveComment {
|
||||||
id: inserted_mod_remove_comment.id,
|
id: inserted_mod_remove_comment.id,
|
||||||
comment_id: inserted_comment.id,
|
comment_id: inserted_comment.id,
|
||||||
|
@ -643,13 +655,9 @@ mod tests {
|
||||||
removed: None,
|
removed: None,
|
||||||
};
|
};
|
||||||
let inserted_mod_remove_community =
|
let inserted_mod_remove_community =
|
||||||
ModRemoveCommunity::create(pool, &mod_remove_community_form)
|
ModRemoveCommunity::create(pool, &mod_remove_community_form).await?;
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let read_mod_remove_community =
|
let read_mod_remove_community =
|
||||||
ModRemoveCommunity::read(pool, inserted_mod_remove_community.id)
|
ModRemoveCommunity::read(pool, inserted_mod_remove_community.id).await?;
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let expected_mod_remove_community = ModRemoveCommunity {
|
let expected_mod_remove_community = ModRemoveCommunity {
|
||||||
id: inserted_mod_remove_community.id,
|
id: inserted_mod_remove_community.id,
|
||||||
community_id: inserted_community.id,
|
community_id: inserted_community.id,
|
||||||
|
@ -670,13 +678,9 @@ mod tests {
|
||||||
expires: None,
|
expires: None,
|
||||||
};
|
};
|
||||||
let inserted_mod_ban_from_community =
|
let inserted_mod_ban_from_community =
|
||||||
ModBanFromCommunity::create(pool, &mod_ban_from_community_form)
|
ModBanFromCommunity::create(pool, &mod_ban_from_community_form).await?;
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let read_mod_ban_from_community =
|
let read_mod_ban_from_community =
|
||||||
ModBanFromCommunity::read(pool, inserted_mod_ban_from_community.id)
|
ModBanFromCommunity::read(pool, inserted_mod_ban_from_community.id).await?;
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let expected_mod_ban_from_community = ModBanFromCommunity {
|
let expected_mod_ban_from_community = ModBanFromCommunity {
|
||||||
id: inserted_mod_ban_from_community.id,
|
id: inserted_mod_ban_from_community.id,
|
||||||
community_id: inserted_community.id,
|
community_id: inserted_community.id,
|
||||||
|
@ -697,8 +701,8 @@ mod tests {
|
||||||
banned: None,
|
banned: None,
|
||||||
expires: None,
|
expires: None,
|
||||||
};
|
};
|
||||||
let inserted_mod_ban = ModBan::create(pool, &mod_ban_form).await.unwrap();
|
let inserted_mod_ban = ModBan::create(pool, &mod_ban_form).await?;
|
||||||
let read_mod_ban = ModBan::read(pool, inserted_mod_ban.id).await.unwrap();
|
let read_mod_ban = ModBan::read(pool, inserted_mod_ban.id).await?;
|
||||||
let expected_mod_ban = ModBan {
|
let expected_mod_ban = ModBan {
|
||||||
id: inserted_mod_ban.id,
|
id: inserted_mod_ban.id,
|
||||||
mod_person_id: inserted_mod.id,
|
mod_person_id: inserted_mod.id,
|
||||||
|
@ -717,12 +721,8 @@ mod tests {
|
||||||
community_id: inserted_community.id,
|
community_id: inserted_community.id,
|
||||||
removed: None,
|
removed: None,
|
||||||
};
|
};
|
||||||
let inserted_mod_add_community = ModAddCommunity::create(pool, &mod_add_community_form)
|
let inserted_mod_add_community = ModAddCommunity::create(pool, &mod_add_community_form).await?;
|
||||||
.await
|
let read_mod_add_community = ModAddCommunity::read(pool, inserted_mod_add_community.id).await?;
|
||||||
.unwrap();
|
|
||||||
let read_mod_add_community = ModAddCommunity::read(pool, inserted_mod_add_community.id)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let expected_mod_add_community = ModAddCommunity {
|
let expected_mod_add_community = ModAddCommunity {
|
||||||
id: inserted_mod_add_community.id,
|
id: inserted_mod_add_community.id,
|
||||||
community_id: inserted_community.id,
|
community_id: inserted_community.id,
|
||||||
|
@ -739,8 +739,8 @@ mod tests {
|
||||||
other_person_id: inserted_person.id,
|
other_person_id: inserted_person.id,
|
||||||
removed: None,
|
removed: None,
|
||||||
};
|
};
|
||||||
let inserted_mod_add = ModAdd::create(pool, &mod_add_form).await.unwrap();
|
let inserted_mod_add = ModAdd::create(pool, &mod_add_form).await?;
|
||||||
let read_mod_add = ModAdd::read(pool, inserted_mod_add.id).await.unwrap();
|
let read_mod_add = ModAdd::read(pool, inserted_mod_add.id).await?;
|
||||||
let expected_mod_add = ModAdd {
|
let expected_mod_add = ModAdd {
|
||||||
id: inserted_mod_add.id,
|
id: inserted_mod_add.id,
|
||||||
mod_person_id: inserted_mod.id,
|
mod_person_id: inserted_mod.id,
|
||||||
|
@ -749,14 +749,12 @@ mod tests {
|
||||||
when_: inserted_mod_add.when_,
|
when_: inserted_mod_add.when_,
|
||||||
};
|
};
|
||||||
|
|
||||||
Comment::delete(pool, inserted_comment.id).await.unwrap();
|
Comment::delete(pool, inserted_comment.id).await?;
|
||||||
Post::delete(pool, inserted_post.id).await.unwrap();
|
Post::delete(pool, inserted_post.id).await?;
|
||||||
Community::delete(pool, inserted_community.id)
|
Community::delete(pool, inserted_community.id).await?;
|
||||||
.await
|
Person::delete(pool, inserted_person.id).await?;
|
||||||
.unwrap();
|
Person::delete(pool, inserted_mod.id).await?;
|
||||||
Person::delete(pool, inserted_person.id).await.unwrap();
|
Instance::delete(pool, inserted_instance.id).await?;
|
||||||
Person::delete(pool, inserted_mod.id).await.unwrap();
|
|
||||||
Instance::delete(pool, inserted_instance.id).await.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(expected_mod_remove_post, read_mod_remove_post);
|
assert_eq!(expected_mod_remove_post, read_mod_remove_post);
|
||||||
assert_eq!(expected_mod_lock_post, read_mod_lock_post);
|
assert_eq!(expected_mod_lock_post, read_mod_lock_post);
|
||||||
|
@ -767,5 +765,7 @@ mod tests {
|
||||||
assert_eq!(expected_mod_ban, read_mod_ban);
|
assert_eq!(expected_mod_ban, read_mod_ban);
|
||||||
assert_eq!(expected_mod_add_community, read_mod_add_community);
|
assert_eq!(expected_mod_add_community, read_mod_add_community);
|
||||||
assert_eq!(expected_mod_add, read_mod_add);
|
assert_eq!(expected_mod_add, read_mod_add);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ impl Post {
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
for_creator_id: PersonId,
|
for_creator_id: PersonId,
|
||||||
for_community_id: Option<CommunityId>,
|
for_community_id: Option<CommunityId>,
|
||||||
new_removed: bool,
|
removed: bool,
|
||||||
) -> Result<Vec<Self>, Error> {
|
) -> Result<Vec<Self>, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ impl Post {
|
||||||
}
|
}
|
||||||
|
|
||||||
update
|
update
|
||||||
.set((post::removed.eq(new_removed), post::updated.eq(naive_now())))
|
.set((post::removed.eq(removed), post::updated.eq(naive_now())))
|
||||||
.get_results::<Self>(conn)
|
.get_results::<Self>(conn)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue