Return content of removed comments for admins (ref #5232) (#5245)

* Return content of removed comments for admins (ref #5232)

* fmt

* remove dbg
This commit is contained in:
Nutomic 2024-12-02 22:06:39 +00:00 committed by Felix Ableitner
parent db88ba3cbb
commit cd7759bba4
3 changed files with 57 additions and 12 deletions

View file

@ -156,7 +156,6 @@ test("Delete a comment", async () => {
commentRes.comment_view.comment.id, commentRes.comment_view.comment.id,
); );
expect(deleteCommentRes.comment_view.comment.deleted).toBe(true); expect(deleteCommentRes.comment_view.comment.deleted).toBe(true);
expect(deleteCommentRes.comment_view.comment.content).toBe("");
// Make sure that comment is undefined on beta // Make sure that comment is undefined on beta
await waitUntil( await waitUntil(
@ -255,7 +254,6 @@ test("Remove a comment from admin and community on different instance", async ()
betaComment.comment.id, betaComment.comment.id,
); );
expect(removeCommentRes.comment_view.comment.removed).toBe(true); expect(removeCommentRes.comment_view.comment.removed).toBe(true);
expect(removeCommentRes.comment_view.comment.content).toBe("");
// Comment text is also hidden from list // Comment text is also hidden from list
let listComments = await getComments( let listComments = await getComments(
@ -264,7 +262,6 @@ test("Remove a comment from admin and community on different instance", async ()
); );
expect(listComments.comments.length).toBe(1); expect(listComments.comments.length).toBe(1);
expect(listComments.comments[0].comment.removed).toBe(true); expect(listComments.comments[0].comment.removed).toBe(true);
expect(listComments.comments[0].comment.content).toBe("");
// Make sure its not removed on alpha // Make sure its not removed on alpha
let refetchedPostComments = await getComments( let refetchedPostComments = await getComments(

View file

@ -83,7 +83,7 @@ pub async fn get_conn<'a, 'b: 'a>(pool: &'a mut DbPool<'b>) -> Result<DbConn<'a>
}) })
} }
impl<'a> Deref for DbConn<'a> { impl Deref for DbConn<'_> {
type Target = AsyncPgConnection; type Target = AsyncPgConnection;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -94,7 +94,7 @@ impl<'a> Deref for DbConn<'a> {
} }
} }
impl<'a> DerefMut for DbConn<'a> { impl DerefMut for DbConn<'_> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
match self { match self {
DbConn::Pool(conn) => conn.deref_mut(), DbConn::Pool(conn) => conn.deref_mut(),

View file

@ -365,6 +365,7 @@ impl CommentView {
comment_id: CommentId, comment_id: CommentId,
my_local_user: Option<&'a LocalUser>, my_local_user: Option<&'a LocalUser>,
) -> Result<Option<Self>, Error> { ) -> Result<Option<Self>, Error> {
let is_admin = my_local_user.map(|u| u.admin).unwrap_or(false);
// If a person is given, then my_vote (res.9), if None, should be 0, not null // If a person is given, then my_vote (res.9), if None, should be 0, not null
// Necessary to differentiate between other person's votes // Necessary to differentiate between other person's votes
if let Ok(Some(res)) = queries().read(pool, (comment_id, my_local_user)).await { if let Ok(Some(res)) = queries().read(pool, (comment_id, my_local_user)).await {
@ -375,7 +376,7 @@ impl CommentView {
if res.comment.deleted || res.comment.removed { if res.comment.deleted || res.comment.removed {
new_view.comment.content = String::new(); new_view.comment.content = String::new();
} }
Ok(Some(new_view)) Ok(Some(handle_deleted(res, is_admin)))
} else { } else {
Ok(None) Ok(None)
} }
@ -402,22 +403,25 @@ pub struct CommentQuery<'a> {
impl<'a> CommentQuery<'a> { impl<'a> CommentQuery<'a> {
pub async fn list(self, pool: &mut DbPool<'_>) -> Result<Vec<CommentView>, Error> { pub async fn list(self, pool: &mut DbPool<'_>) -> Result<Vec<CommentView>, Error> {
let is_admin = self.local_user.map(|u| u.admin).unwrap_or(false);
Ok( Ok(
queries() queries()
.list(pool, self) .list(pool, self)
.await? .await?
.into_iter() .into_iter()
.map(|mut c| { .map(|c| handle_deleted(c, is_admin))
if c.comment.deleted || c.comment.removed {
c.comment.content = String::new();
}
c
})
.collect(), .collect(),
) )
} }
} }
fn handle_deleted(mut c: CommentView, is_admin: bool) -> CommentView {
if !is_admin && (c.comment.deleted || c.comment.removed) {
c.comment.content = String::new();
}
c
}
#[cfg(test)] #[cfg(test)]
#[allow(clippy::indexing_slicing)] #[allow(clippy::indexing_slicing)]
mod tests { mod tests {
@ -1232,4 +1236,48 @@ mod tests {
cleanup(data, pool).await cleanup(data, pool).await
} }
#[tokio::test]
#[serial]
async fn comment_removed() -> LemmyResult<()> {
let pool = &build_db_pool_for_tests().await;
let pool = &mut pool.into();
let mut data = init_data(pool).await?;
// Mark a comment as removed
let form = CommentUpdateForm {
removed: Some(true),
..Default::default()
};
Comment::update(pool, data.inserted_comment_0.id, &form).await?;
// Read as normal user, content is cleared
data.timmy_local_user_view.local_user.admin = false;
let comment_listing = CommentQuery {
community_id: Some(data.inserted_community.id),
local_user: Some(&data.timmy_local_user_view.local_user),
sort: Some(CommentSortType::Old),
..Default::default()
}
.list(pool)
.await?;
assert_eq!("", comment_listing[0].comment.content);
// Read as admin, content is returned
data.timmy_local_user_view.local_user.admin = true;
let comment_listing = CommentQuery {
community_id: Some(data.inserted_community.id),
local_user: Some(&data.timmy_local_user_view.local_user),
sort: Some(CommentSortType::Old),
..Default::default()
}
.list(pool)
.await?;
assert_eq!(
data.inserted_comment_0.content,
comment_listing[0].comment.content
);
cleanup(data, pool).await
}
} }