mirror of https://github.com/LemmyNet/lemmy.git
Clean up reporting (#1776)
* First untested pass at reporting. * Adding unit tests for post and comment report views * Fix clippy * Adding counts, creator_banned, and unresolved_only * Adding my_vote to report views * Fixing unit tests.add_user_agent
parent
240de006db
commit
b18c744f63
|
@ -3,7 +3,6 @@ use actix_web::web::Data;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
blocking,
|
blocking,
|
||||||
check_community_ban,
|
check_community_ban,
|
||||||
collect_moderated_communities,
|
|
||||||
comment::*,
|
comment::*,
|
||||||
get_local_user_view_from_jwt,
|
get_local_user_view_from_jwt,
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
|
@ -15,22 +14,18 @@ use lemmy_db_views::{
|
||||||
comment_view::CommentView,
|
comment_view::CommentView,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
|
||||||
messages::{SendModRoomMessage, SendUserRoomMessage},
|
|
||||||
LemmyContext,
|
|
||||||
UserOperation,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Creates a comment report and notifies the moderators of the community
|
/// Creates a comment report and notifies the moderators of the community
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for CreateCommentReport {
|
impl Perform for CreateCommentReport {
|
||||||
type Response = CreateCommentReportResponse;
|
type Response = CommentReportResponse;
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<CreateCommentReportResponse, LemmyError> {
|
) -> Result<CommentReportResponse, LemmyError> {
|
||||||
let data: &CreateCommentReport = self;
|
let data: &CreateCommentReport = self;
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||||
|
@ -66,18 +61,18 @@ impl Perform for CreateCommentReport {
|
||||||
.await?
|
.await?
|
||||||
.map_err(|_| ApiError::err("couldnt_create_report"))?;
|
.map_err(|_| ApiError::err("couldnt_create_report"))?;
|
||||||
|
|
||||||
let res = CreateCommentReportResponse { success: true };
|
let comment_report_view = blocking(context.pool(), move |conn| {
|
||||||
|
CommentReportView::read(conn, report.id, person_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
context.chat_server().do_send(SendUserRoomMessage {
|
let res = CommentReportResponse {
|
||||||
op: UserOperation::CreateCommentReport,
|
comment_report_view,
|
||||||
response: res.clone(),
|
};
|
||||||
local_recipient_id: local_user_view.local_user.id,
|
|
||||||
websocket_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
context.chat_server().do_send(SendModRoomMessage {
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
op: UserOperation::CreateCommentReport,
|
op: UserOperation::CreateCommentReport,
|
||||||
response: report,
|
response: res.clone(),
|
||||||
community_id: comment_view.community.id,
|
community_id: comment_view.community.id,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
});
|
});
|
||||||
|
@ -89,20 +84,21 @@ impl Perform for CreateCommentReport {
|
||||||
/// Resolves or unresolves a comment report and notifies the moderators of the community
|
/// Resolves or unresolves a comment report and notifies the moderators of the community
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for ResolveCommentReport {
|
impl Perform for ResolveCommentReport {
|
||||||
type Response = ResolveCommentReportResponse;
|
type Response = CommentReportResponse;
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<ResolveCommentReportResponse, LemmyError> {
|
) -> Result<CommentReportResponse, LemmyError> {
|
||||||
let data: &ResolveCommentReport = self;
|
let data: &ResolveCommentReport = self;
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||||
|
|
||||||
let report_id = data.report_id;
|
let report_id = data.report_id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
let report = blocking(context.pool(), move |conn| {
|
let report = blocking(context.pool(), move |conn| {
|
||||||
CommentReportView::read(conn, report_id)
|
CommentReportView::read(conn, report_id, person_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
@ -123,9 +119,13 @@ impl Perform for ResolveCommentReport {
|
||||||
};
|
};
|
||||||
|
|
||||||
let report_id = data.report_id;
|
let report_id = data.report_id;
|
||||||
let res = ResolveCommentReportResponse {
|
let comment_report_view = blocking(context.pool(), move |conn| {
|
||||||
report_id,
|
CommentReportView::read(conn, report_id, person_id)
|
||||||
resolved,
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
let res = CommentReportResponse {
|
||||||
|
comment_report_view,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.chat_server().do_send(SendModRoomMessage {
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
|
@ -148,36 +148,29 @@ impl Perform for ListCommentReports {
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
websocket_id: Option<ConnectionId>,
|
_websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<ListCommentReportsResponse, LemmyError> {
|
) -> Result<ListCommentReportsResponse, LemmyError> {
|
||||||
let data: &ListCommentReports = self;
|
let data: &ListCommentReports = self;
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let community_id = data.community;
|
let community_id = data.community_id;
|
||||||
let community_ids =
|
let unresolved_only = data.unresolved_only;
|
||||||
collect_moderated_communities(person_id, community_id, context.pool()).await?;
|
|
||||||
|
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let comments = blocking(context.pool(), move |conn| {
|
let comment_reports = blocking(context.pool(), move |conn| {
|
||||||
CommentReportQueryBuilder::create(conn)
|
CommentReportQueryBuilder::create(conn, person_id)
|
||||||
.community_ids(community_ids)
|
.community_id(community_id)
|
||||||
|
.unresolved_only(unresolved_only)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.list()
|
.list()
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let res = ListCommentReportsResponse { comments };
|
let res = ListCommentReportsResponse { comment_reports };
|
||||||
|
|
||||||
context.chat_server().do_send(SendUserRoomMessage {
|
|
||||||
op: UserOperation::ListCommentReports,
|
|
||||||
response: res.clone(),
|
|
||||||
local_recipient_id: local_user_view.local_user.id,
|
|
||||||
websocket_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ use captcha::{gen, Difficulty};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
blocking,
|
blocking,
|
||||||
collect_moderated_communities,
|
|
||||||
get_local_user_view_from_jwt,
|
get_local_user_view_from_jwt,
|
||||||
is_admin,
|
is_admin,
|
||||||
password_length_check,
|
password_length_check,
|
||||||
|
@ -67,7 +66,7 @@ use lemmy_utils::{
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
messages::{CaptchaItem, SendAllMessage, SendUserRoomMessage},
|
messages::{CaptchaItem, SendAllMessage},
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
UserOperation,
|
UserOperation,
|
||||||
};
|
};
|
||||||
|
@ -816,52 +815,31 @@ impl Perform for GetReportCount {
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
websocket_id: Option<ConnectionId>,
|
_websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<GetReportCountResponse, LemmyError> {
|
) -> Result<GetReportCountResponse, LemmyError> {
|
||||||
let data: &GetReportCount = self;
|
let data: &GetReportCount = self;
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let community_id = data.community;
|
let community_id = data.community_id;
|
||||||
let community_ids =
|
|
||||||
collect_moderated_communities(person_id, community_id, context.pool()).await?;
|
|
||||||
|
|
||||||
let res = {
|
|
||||||
if community_ids.is_empty() {
|
|
||||||
GetReportCountResponse {
|
|
||||||
community: None,
|
|
||||||
comment_reports: 0,
|
|
||||||
post_reports: 0,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let ids = community_ids.clone();
|
|
||||||
let comment_reports = blocking(context.pool(), move |conn| {
|
let comment_reports = blocking(context.pool(), move |conn| {
|
||||||
CommentReportView::get_report_count(conn, &ids)
|
CommentReportView::get_report_count(conn, person_id, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let ids = community_ids.clone();
|
|
||||||
let post_reports = blocking(context.pool(), move |conn| {
|
let post_reports = blocking(context.pool(), move |conn| {
|
||||||
PostReportView::get_report_count(conn, &ids)
|
PostReportView::get_report_count(conn, person_id, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
GetReportCountResponse {
|
let res = GetReportCountResponse {
|
||||||
community: data.community,
|
community_id,
|
||||||
comment_reports,
|
comment_reports,
|
||||||
post_reports,
|
post_reports,
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
context.chat_server().do_send(SendUserRoomMessage {
|
|
||||||
op: UserOperation::GetReportCount,
|
|
||||||
response: res.clone(),
|
|
||||||
local_recipient_id: local_user_view.local_user.id,
|
|
||||||
websocket_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,14 @@ use actix_web::web::Data;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
blocking,
|
blocking,
|
||||||
check_community_ban,
|
check_community_ban,
|
||||||
collect_moderated_communities,
|
|
||||||
get_local_user_view_from_jwt,
|
get_local_user_view_from_jwt,
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
post::{
|
post::{
|
||||||
CreatePostReport,
|
CreatePostReport,
|
||||||
CreatePostReportResponse,
|
|
||||||
ListPostReports,
|
ListPostReports,
|
||||||
ListPostReportsResponse,
|
ListPostReportsResponse,
|
||||||
|
PostReportResponse,
|
||||||
ResolvePostReport,
|
ResolvePostReport,
|
||||||
ResolvePostReportResponse,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use lemmy_db_queries::Reportable;
|
use lemmy_db_queries::Reportable;
|
||||||
|
@ -22,22 +20,18 @@ use lemmy_db_views::{
|
||||||
post_view::PostView,
|
post_view::PostView,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
|
||||||
messages::{SendModRoomMessage, SendUserRoomMessage},
|
|
||||||
LemmyContext,
|
|
||||||
UserOperation,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Creates a post report and notifies the moderators of the community
|
/// Creates a post report and notifies the moderators of the community
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for CreatePostReport {
|
impl Perform for CreatePostReport {
|
||||||
type Response = CreatePostReportResponse;
|
type Response = PostReportResponse;
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<CreatePostReportResponse, LemmyError> {
|
) -> Result<PostReportResponse, LemmyError> {
|
||||||
let data: &CreatePostReport = self;
|
let data: &CreatePostReport = self;
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||||
|
@ -75,18 +69,16 @@ impl Perform for CreatePostReport {
|
||||||
.await?
|
.await?
|
||||||
.map_err(|_| ApiError::err("couldnt_create_report"))?;
|
.map_err(|_| ApiError::err("couldnt_create_report"))?;
|
||||||
|
|
||||||
let res = CreatePostReportResponse { success: true };
|
let post_report_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostReportView::read(conn, report.id, person_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
context.chat_server().do_send(SendUserRoomMessage {
|
let res = PostReportResponse { post_report_view };
|
||||||
op: UserOperation::CreatePostReport,
|
|
||||||
response: res.clone(),
|
|
||||||
local_recipient_id: local_user_view.local_user.id,
|
|
||||||
websocket_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
context.chat_server().do_send(SendModRoomMessage {
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
op: UserOperation::CreatePostReport,
|
op: UserOperation::CreatePostReport,
|
||||||
response: report,
|
response: res.clone(),
|
||||||
community_id: post_view.community.id,
|
community_id: post_view.community.id,
|
||||||
websocket_id,
|
websocket_id,
|
||||||
});
|
});
|
||||||
|
@ -98,20 +90,21 @@ impl Perform for CreatePostReport {
|
||||||
/// Resolves or unresolves a post report and notifies the moderators of the community
|
/// Resolves or unresolves a post report and notifies the moderators of the community
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for ResolvePostReport {
|
impl Perform for ResolvePostReport {
|
||||||
type Response = ResolvePostReportResponse;
|
type Response = PostReportResponse;
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<ResolvePostReportResponse, LemmyError> {
|
) -> Result<PostReportResponse, LemmyError> {
|
||||||
let data: &ResolvePostReport = self;
|
let data: &ResolvePostReport = self;
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||||
|
|
||||||
let report_id = data.report_id;
|
let report_id = data.report_id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
let report = blocking(context.pool(), move |conn| {
|
let report = blocking(context.pool(), move |conn| {
|
||||||
PostReportView::read(conn, report_id)
|
PostReportView::read(conn, report_id, person_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
@ -127,15 +120,17 @@ impl Perform for ResolvePostReport {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = ResolvePostReportResponse {
|
|
||||||
report_id,
|
|
||||||
resolved: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
if blocking(context.pool(), resolve_fun).await?.is_err() {
|
if blocking(context.pool(), resolve_fun).await?.is_err() {
|
||||||
return Err(ApiError::err("couldnt_resolve_report").into());
|
return Err(ApiError::err("couldnt_resolve_report").into());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let post_report_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostReportView::read(conn, report_id, person_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
let res = PostReportResponse { post_report_view };
|
||||||
|
|
||||||
context.chat_server().do_send(SendModRoomMessage {
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
op: UserOperation::ResolvePostReport,
|
op: UserOperation::ResolvePostReport,
|
||||||
response: res.clone(),
|
response: res.clone(),
|
||||||
|
@ -156,36 +151,29 @@ impl Perform for ListPostReports {
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
websocket_id: Option<ConnectionId>,
|
_websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<ListPostReportsResponse, LemmyError> {
|
) -> Result<ListPostReportsResponse, LemmyError> {
|
||||||
let data: &ListPostReports = self;
|
let data: &ListPostReports = self;
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let community_id = data.community;
|
let community_id = data.community_id;
|
||||||
let community_ids =
|
let unresolved_only = data.unresolved_only;
|
||||||
collect_moderated_communities(person_id, community_id, context.pool()).await?;
|
|
||||||
|
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let posts = blocking(context.pool(), move |conn| {
|
let post_reports = blocking(context.pool(), move |conn| {
|
||||||
PostReportQueryBuilder::create(conn)
|
PostReportQueryBuilder::create(conn, person_id)
|
||||||
.community_ids(community_ids)
|
.community_id(community_id)
|
||||||
|
.unresolved_only(unresolved_only)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.list()
|
.list()
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let res = ListPostReportsResponse { posts };
|
let res = ListPostReportsResponse { post_reports };
|
||||||
|
|
||||||
context.chat_server().do_send(SendUserRoomMessage {
|
|
||||||
op: UserOperation::ListPostReports,
|
|
||||||
response: res.clone(),
|
|
||||||
local_recipient_id: local_user_view.local_user.id,
|
|
||||||
websocket_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use lemmy_db_schema::{CommentId, CommunityId, LocalUserId, PostId};
|
use lemmy_db_schema::{CommentId, CommentReportId, CommunityId, LocalUserId, PostId};
|
||||||
use lemmy_db_views::{comment_report_view::CommentReportView, comment_view::CommentView};
|
use lemmy_db_views::{comment_report_view::CommentReportView, comment_view::CommentView};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -79,42 +79,37 @@ pub struct GetCommentsResponse {
|
||||||
pub comments: Vec<CommentView>,
|
pub comments: Vec<CommentView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct CreateCommentReport {
|
pub struct CreateCommentReport {
|
||||||
pub comment_id: CommentId,
|
pub comment_id: CommentId,
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Clone)]
|
||||||
pub struct CreateCommentReportResponse {
|
pub struct CommentReportResponse {
|
||||||
pub success: bool,
|
pub comment_report_view: CommentReportView,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Deserialize)]
|
||||||
pub struct ResolveCommentReport {
|
pub struct ResolveCommentReport {
|
||||||
pub report_id: i32,
|
pub report_id: CommentReportId,
|
||||||
pub resolved: bool,
|
pub resolved: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Deserialize)]
|
||||||
pub struct ResolveCommentReportResponse {
|
|
||||||
// TODO this should probably return the view
|
|
||||||
pub report_id: i32,
|
|
||||||
pub resolved: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
|
||||||
pub struct ListCommentReports {
|
pub struct ListCommentReports {
|
||||||
pub page: Option<i64>,
|
pub page: Option<i64>,
|
||||||
pub limit: Option<i64>,
|
pub limit: Option<i64>,
|
||||||
|
/// Only shows the unresolved reports
|
||||||
|
pub unresolved_only: Option<bool>,
|
||||||
/// if no community is given, it returns reports for all communities moderated by the auth user
|
/// if no community is given, it returns reports for all communities moderated by the auth user
|
||||||
pub community: Option<CommunityId>,
|
pub community_id: Option<CommunityId>,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Clone, Debug)]
|
#[derive(Serialize)]
|
||||||
pub struct ListCommentReportsResponse {
|
pub struct ListCommentReportsResponse {
|
||||||
pub comments: Vec<CommentReportView>,
|
pub comment_reports: Vec<CommentReportView>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,7 @@ pub mod websocket;
|
||||||
use crate::site::FederatedInstances;
|
use crate::site::FederatedInstances;
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use lemmy_db_queries::{
|
use lemmy_db_queries::{
|
||||||
source::{
|
source::{community::Community_, person_block::PersonBlock_, site::Site_},
|
||||||
community::{CommunityModerator_, Community_},
|
|
||||||
person_block::PersonBlock_,
|
|
||||||
site::Site_,
|
|
||||||
},
|
|
||||||
Crud,
|
Crud,
|
||||||
DbPool,
|
DbPool,
|
||||||
Readable,
|
Readable,
|
||||||
|
@ -20,7 +16,7 @@ use lemmy_db_queries::{
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
comment::Comment,
|
comment::Comment,
|
||||||
community::{Community, CommunityModerator},
|
community::Community,
|
||||||
person::Person,
|
person::Person,
|
||||||
person_block::PersonBlock,
|
person_block::PersonBlock,
|
||||||
person_mention::{PersonMention, PersonMentionForm},
|
person_mention::{PersonMention, PersonMentionForm},
|
||||||
|
@ -384,31 +380,6 @@ pub async fn check_downvotes_enabled(score: i16, pool: &DbPool) -> Result<(), Le
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of communities that the user moderates
|
|
||||||
/// or if a community_id is supplied validates the user is a moderator
|
|
||||||
/// of that community and returns the community id in a vec
|
|
||||||
///
|
|
||||||
/// * `person_id` - the person id of the moderator
|
|
||||||
/// * `community_id` - optional community id to check for moderator privileges
|
|
||||||
/// * `pool` - the diesel db pool
|
|
||||||
pub async fn collect_moderated_communities(
|
|
||||||
person_id: PersonId,
|
|
||||||
community_id: Option<CommunityId>,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<Vec<CommunityId>, LemmyError> {
|
|
||||||
if let Some(community_id) = community_id {
|
|
||||||
// if the user provides a community_id, just check for mod/admin privileges
|
|
||||||
is_mod_or_admin(pool, person_id, community_id).await?;
|
|
||||||
Ok(vec![community_id])
|
|
||||||
} else {
|
|
||||||
let ids = blocking(pool, move |conn: &'_ _| {
|
|
||||||
CommunityModerator::get_person_moderated_communities(conn, person_id)
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
Ok(ids)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn build_federated_instances(
|
pub async fn build_federated_instances(
|
||||||
pool: &DbPool,
|
pool: &DbPool,
|
||||||
federation_config: &FederationConfig,
|
federation_config: &FederationConfig,
|
||||||
|
|
|
@ -253,15 +253,15 @@ pub struct PrivateMessageResponse {
|
||||||
pub private_message_view: PrivateMessageView,
|
pub private_message_view: PrivateMessageView,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Deserialize)]
|
||||||
pub struct GetReportCount {
|
pub struct GetReportCount {
|
||||||
pub community: Option<CommunityId>,
|
pub community_id: Option<CommunityId>,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Clone)]
|
||||||
pub struct GetReportCountResponse {
|
pub struct GetReportCountResponse {
|
||||||
pub community: Option<CommunityId>,
|
pub community_id: Option<CommunityId>,
|
||||||
pub comment_reports: i64,
|
pub comment_reports: i64,
|
||||||
pub post_reports: i64,
|
pub post_reports: i64,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use lemmy_db_schema::{CommunityId, PostId};
|
use lemmy_db_schema::{CommunityId, PostId, PostReportId};
|
||||||
use lemmy_db_views::{
|
use lemmy_db_views::{
|
||||||
comment_view::CommentView,
|
comment_view::CommentView,
|
||||||
post_report_view::PostReportView,
|
post_report_view::PostReportView,
|
||||||
|
@ -112,42 +112,39 @@ pub struct SavePost {
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct CreatePostReport {
|
pub struct CreatePostReport {
|
||||||
pub post_id: PostId,
|
pub post_id: PostId,
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Clone)]
|
||||||
pub struct CreatePostReportResponse {
|
pub struct PostReportResponse {
|
||||||
pub success: bool,
|
pub post_report_view: PostReportView,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Deserialize)]
|
||||||
pub struct ResolvePostReport {
|
pub struct ResolvePostReport {
|
||||||
pub report_id: i32,
|
pub report_id: PostReportId,
|
||||||
pub resolved: bool,
|
pub resolved: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Deserialize)]
|
||||||
pub struct ResolvePostReportResponse {
|
|
||||||
pub report_id: i32,
|
|
||||||
pub resolved: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
|
||||||
pub struct ListPostReports {
|
pub struct ListPostReports {
|
||||||
pub page: Option<i64>,
|
pub page: Option<i64>,
|
||||||
pub limit: Option<i64>,
|
pub limit: Option<i64>,
|
||||||
pub community: Option<CommunityId>,
|
/// Only shows the unresolved reports
|
||||||
|
pub unresolved_only: Option<bool>,
|
||||||
|
/// if no community is given, it returns reports for all communities moderated by the auth user
|
||||||
|
pub community_id: Option<CommunityId>,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Clone, Debug)]
|
#[derive(Serialize)]
|
||||||
pub struct ListPostReportsResponse {
|
pub struct ListPostReportsResponse {
|
||||||
pub posts: Vec<PostReportView>,
|
pub post_reports: Vec<PostReportView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
|
|
|
@ -131,13 +131,22 @@ pub trait Readable {
|
||||||
|
|
||||||
pub trait Reportable {
|
pub trait Reportable {
|
||||||
type Form;
|
type Form;
|
||||||
|
type IdType;
|
||||||
fn report(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
|
fn report(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
fn resolve(conn: &PgConnection, report_id: i32, resolver_id: PersonId) -> Result<usize, Error>
|
fn resolve(
|
||||||
|
conn: &PgConnection,
|
||||||
|
report_id: Self::IdType,
|
||||||
|
resolver_id: PersonId,
|
||||||
|
) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
fn unresolve(conn: &PgConnection, report_id: i32, resolver_id: PersonId) -> Result<usize, Error>
|
fn unresolve(
|
||||||
|
conn: &PgConnection,
|
||||||
|
report_id: Self::IdType,
|
||||||
|
resolver_id: PersonId,
|
||||||
|
) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@ use diesel::{dsl::*, result::Error, *};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
naive_now,
|
naive_now,
|
||||||
source::comment_report::{CommentReport, CommentReportForm},
|
source::comment_report::{CommentReport, CommentReportForm},
|
||||||
|
CommentReportId,
|
||||||
PersonId,
|
PersonId,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Reportable for CommentReport {
|
impl Reportable for CommentReport {
|
||||||
type Form = CommentReportForm;
|
type Form = CommentReportForm;
|
||||||
|
type IdType = CommentReportId;
|
||||||
/// creates a comment report and returns it
|
/// creates a comment report and returns it
|
||||||
///
|
///
|
||||||
/// * `conn` - the postgres connection
|
/// * `conn` - the postgres connection
|
||||||
|
@ -26,7 +28,7 @@ impl Reportable for CommentReport {
|
||||||
/// * `by_resolver_id` - the id of the user resolving the report
|
/// * `by_resolver_id` - the id of the user resolving the report
|
||||||
fn resolve(
|
fn resolve(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
report_id: i32,
|
report_id: Self::IdType,
|
||||||
by_resolver_id: PersonId,
|
by_resolver_id: PersonId,
|
||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
use lemmy_db_schema::schema::comment_report::dsl::*;
|
use lemmy_db_schema::schema::comment_report::dsl::*;
|
||||||
|
@ -46,7 +48,7 @@ impl Reportable for CommentReport {
|
||||||
/// * `by_resolver_id` - the id of the user unresolving the report
|
/// * `by_resolver_id` - the id of the user unresolving the report
|
||||||
fn unresolve(
|
fn unresolve(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
report_id: i32,
|
report_id: Self::IdType,
|
||||||
by_resolver_id: PersonId,
|
by_resolver_id: PersonId,
|
||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
use lemmy_db_schema::schema::comment_report::dsl::*;
|
use lemmy_db_schema::schema::comment_report::dsl::*;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use crate::Reportable;
|
use crate::Reportable;
|
||||||
use diesel::{dsl::*, result::Error, *};
|
use diesel::{dsl::*, result::Error, *};
|
||||||
use lemmy_db_schema::{naive_now, source::post_report::*, PersonId};
|
use lemmy_db_schema::{naive_now, source::post_report::*, PersonId, PostReportId};
|
||||||
|
|
||||||
impl Reportable for PostReport {
|
impl Reportable for PostReport {
|
||||||
type Form = PostReportForm;
|
type Form = PostReportForm;
|
||||||
|
type IdType = PostReportId;
|
||||||
|
|
||||||
/// creates a post report and returns it
|
/// creates a post report and returns it
|
||||||
///
|
///
|
||||||
/// * `conn` - the postgres connection
|
/// * `conn` - the postgres connection
|
||||||
|
@ -22,7 +24,7 @@ impl Reportable for PostReport {
|
||||||
/// * `by_resolver_id` - the id of the user resolving the report
|
/// * `by_resolver_id` - the id of the user resolving the report
|
||||||
fn resolve(
|
fn resolve(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
report_id: i32,
|
report_id: Self::IdType,
|
||||||
by_resolver_id: PersonId,
|
by_resolver_id: PersonId,
|
||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
use lemmy_db_schema::schema::post_report::dsl::*;
|
use lemmy_db_schema::schema::post_report::dsl::*;
|
||||||
|
@ -42,7 +44,7 @@ impl Reportable for PostReport {
|
||||||
/// * `by_resolver_id` - the id of the user unresolving the report
|
/// * `by_resolver_id` - the id of the user unresolving the report
|
||||||
fn unresolve(
|
fn unresolve(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
report_id: i32,
|
report_id: Self::IdType,
|
||||||
by_resolver_id: PersonId,
|
by_resolver_id: PersonId,
|
||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
use lemmy_db_schema::schema::post_report::dsl::*;
|
use lemmy_db_schema::schema::post_report::dsl::*;
|
||||||
|
|
|
@ -73,6 +73,12 @@ pub struct PersonBlockId(i32);
|
||||||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
|
||||||
pub struct CommunityBlockId(i32);
|
pub struct CommunityBlockId(i32);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
|
||||||
|
pub struct CommentReportId(i32);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
|
||||||
|
pub struct PostReportId(i32);
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, FromSqlRow)]
|
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, FromSqlRow)]
|
||||||
#[sql_type = "Text"]
|
#[sql_type = "Text"]
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
use crate::{schema::comment_report, source::comment::Comment, CommentId, PersonId};
|
use crate::{
|
||||||
|
schema::comment_report,
|
||||||
|
source::comment::Comment,
|
||||||
|
CommentId,
|
||||||
|
CommentReportId,
|
||||||
|
PersonId,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -7,7 +13,7 @@ use serde::{Deserialize, Serialize};
|
||||||
#[belongs_to(Comment)]
|
#[belongs_to(Comment)]
|
||||||
#[table_name = "comment_report"]
|
#[table_name = "comment_report"]
|
||||||
pub struct CommentReport {
|
pub struct CommentReport {
|
||||||
pub id: i32,
|
pub id: CommentReportId,
|
||||||
pub creator_id: PersonId,
|
pub creator_id: PersonId,
|
||||||
pub comment_id: CommentId,
|
pub comment_id: CommentId,
|
||||||
pub original_comment_text: String,
|
pub original_comment_text: String,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{schema::post_report, source::post::Post, DbUrl, PersonId, PostId};
|
use crate::{schema::post_report, source::post::Post, DbUrl, PersonId, PostId, PostReportId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||||
#[belongs_to(Post)]
|
#[belongs_to(Post)]
|
||||||
#[table_name = "post_report"]
|
#[table_name = "post_report"]
|
||||||
pub struct PostReport {
|
pub struct PostReport {
|
||||||
pub id: i32,
|
pub id: PostReportId,
|
||||||
pub creator_id: PersonId,
|
pub creator_id: PersonId,
|
||||||
pub post_id: PostId,
|
pub post_id: PostId,
|
||||||
pub original_post_name: String,
|
pub original_post_name: String,
|
||||||
|
|
|
@ -1,15 +1,35 @@
|
||||||
use diesel::{result::Error, *};
|
use diesel::{result::Error, *};
|
||||||
use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec};
|
use lemmy_db_queries::{
|
||||||
|
aggregates::comment_aggregates::CommentAggregates,
|
||||||
|
limit_and_offset,
|
||||||
|
MaybeOptional,
|
||||||
|
ToSafe,
|
||||||
|
ViewToVec,
|
||||||
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
schema::{comment, comment_report, community, person, person_alias_1, person_alias_2, post},
|
schema::{
|
||||||
|
comment,
|
||||||
|
comment_aggregates,
|
||||||
|
comment_like,
|
||||||
|
comment_report,
|
||||||
|
community,
|
||||||
|
community_moderator,
|
||||||
|
community_person_ban,
|
||||||
|
person,
|
||||||
|
person_alias_1,
|
||||||
|
person_alias_2,
|
||||||
|
post,
|
||||||
|
},
|
||||||
source::{
|
source::{
|
||||||
comment::Comment,
|
comment::Comment,
|
||||||
comment_report::CommentReport,
|
comment_report::CommentReport,
|
||||||
community::{Community, CommunitySafe},
|
community::{Community, CommunityPersonBan, CommunitySafe},
|
||||||
person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2},
|
person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2},
|
||||||
post::Post,
|
post::Post,
|
||||||
},
|
},
|
||||||
|
CommentReportId,
|
||||||
CommunityId,
|
CommunityId,
|
||||||
|
PersonId,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -21,6 +41,9 @@ pub struct CommentReportView {
|
||||||
pub community: CommunitySafe,
|
pub community: CommunitySafe,
|
||||||
pub creator: PersonSafe,
|
pub creator: PersonSafe,
|
||||||
pub comment_creator: PersonSafeAlias1,
|
pub comment_creator: PersonSafeAlias1,
|
||||||
|
pub counts: CommentAggregates,
|
||||||
|
pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
|
||||||
|
pub my_vote: Option<i16>, // Left join to CommentLike
|
||||||
pub resolver: Option<PersonSafeAlias2>,
|
pub resolver: Option<PersonSafeAlias2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +54,9 @@ type CommentReportViewTuple = (
|
||||||
CommunitySafe,
|
CommunitySafe,
|
||||||
PersonSafe,
|
PersonSafe,
|
||||||
PersonSafeAlias1,
|
PersonSafeAlias1,
|
||||||
|
CommentAggregates,
|
||||||
|
Option<CommunityPersonBan>,
|
||||||
|
Option<i16>,
|
||||||
Option<PersonSafeAlias2>,
|
Option<PersonSafeAlias2>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -38,15 +64,46 @@ impl CommentReportView {
|
||||||
/// returns the CommentReportView for the provided report_id
|
/// returns the CommentReportView for the provided report_id
|
||||||
///
|
///
|
||||||
/// * `report_id` - the report id to obtain
|
/// * `report_id` - the report id to obtain
|
||||||
pub fn read(conn: &PgConnection, report_id: i32) -> Result<Self, Error> {
|
pub fn read(
|
||||||
let (comment_report, comment, post, community, creator, comment_creator, resolver) =
|
conn: &PgConnection,
|
||||||
comment_report::table
|
report_id: CommentReportId,
|
||||||
|
my_person_id: PersonId,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let (
|
||||||
|
comment_report,
|
||||||
|
comment,
|
||||||
|
post,
|
||||||
|
community,
|
||||||
|
creator,
|
||||||
|
comment_creator,
|
||||||
|
counts,
|
||||||
|
creator_banned_from_community,
|
||||||
|
comment_like,
|
||||||
|
resolver,
|
||||||
|
) = comment_report::table
|
||||||
.find(report_id)
|
.find(report_id)
|
||||||
.inner_join(comment::table)
|
.inner_join(comment::table)
|
||||||
.inner_join(post::table.on(comment::post_id.eq(post::id)))
|
.inner_join(post::table.on(comment::post_id.eq(post::id)))
|
||||||
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
||||||
.inner_join(person::table.on(comment_report::creator_id.eq(person::id)))
|
.inner_join(person::table.on(comment_report::creator_id.eq(person::id)))
|
||||||
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
||||||
|
.inner_join(
|
||||||
|
comment_aggregates::table.on(comment_report::comment_id.eq(comment_aggregates::comment_id)),
|
||||||
|
)
|
||||||
|
.left_join(
|
||||||
|
community_person_ban::table.on(
|
||||||
|
community::id
|
||||||
|
.eq(community_person_ban::community_id)
|
||||||
|
.and(community_person_ban::person_id.eq(comment::creator_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.left_join(
|
||||||
|
comment_like::table.on(
|
||||||
|
comment::id
|
||||||
|
.eq(comment_like::comment_id)
|
||||||
|
.and(comment_like::person_id.eq(my_person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
.left_join(
|
.left_join(
|
||||||
person_alias_2::table.on(comment_report::resolver_id.eq(person_alias_2::id.nullable())),
|
person_alias_2::table.on(comment_report::resolver_id.eq(person_alias_2::id.nullable())),
|
||||||
)
|
)
|
||||||
|
@ -57,10 +114,19 @@ impl CommentReportView {
|
||||||
Community::safe_columns_tuple(),
|
Community::safe_columns_tuple(),
|
||||||
Person::safe_columns_tuple(),
|
Person::safe_columns_tuple(),
|
||||||
PersonAlias1::safe_columns_tuple(),
|
PersonAlias1::safe_columns_tuple(),
|
||||||
|
comment_aggregates::all_columns,
|
||||||
|
community_person_ban::all_columns.nullable(),
|
||||||
|
comment_like::score.nullable(),
|
||||||
PersonAlias2::safe_columns_tuple().nullable(),
|
PersonAlias2::safe_columns_tuple().nullable(),
|
||||||
))
|
))
|
||||||
.first::<CommentReportViewTuple>(conn)?;
|
.first::<CommentReportViewTuple>(conn)?;
|
||||||
|
|
||||||
|
let my_vote = if comment_like.is_none() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
comment_like
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
comment_report,
|
comment_report,
|
||||||
comment,
|
comment,
|
||||||
|
@ -68,6 +134,9 @@ impl CommentReportView {
|
||||||
community,
|
community,
|
||||||
creator,
|
creator,
|
||||||
comment_creator,
|
comment_creator,
|
||||||
|
counts,
|
||||||
|
creator_banned_from_community: creator_banned_from_community.is_some(),
|
||||||
|
my_vote,
|
||||||
resolver,
|
resolver,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -76,46 +145,60 @@ impl CommentReportView {
|
||||||
///
|
///
|
||||||
/// * `community_ids` - a Vec<i32> of community_ids to get a count for
|
/// * `community_ids` - a Vec<i32> of community_ids to get a count for
|
||||||
/// TODO this eq_any is a bad way to do this, would be better to join to communitymoderator
|
/// TODO this eq_any is a bad way to do this, would be better to join to communitymoderator
|
||||||
|
/// TODO FIX THIS NOW
|
||||||
/// for a person id
|
/// for a person id
|
||||||
pub fn get_report_count(
|
pub fn get_report_count(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
community_ids: &[CommunityId],
|
my_person_id: PersonId,
|
||||||
|
community_id: Option<CommunityId>,
|
||||||
) -> Result<i64, Error> {
|
) -> Result<i64, Error> {
|
||||||
use diesel::dsl::*;
|
use diesel::dsl::*;
|
||||||
comment_report::table
|
|
||||||
|
let mut query = comment_report::table
|
||||||
.inner_join(comment::table)
|
.inner_join(comment::table)
|
||||||
.inner_join(post::table.on(comment::post_id.eq(post::id)))
|
.inner_join(post::table.on(comment::post_id.eq(post::id)))
|
||||||
.filter(
|
// Test this join
|
||||||
comment_report::resolved
|
.inner_join(
|
||||||
.eq(false)
|
community_moderator::table.on(
|
||||||
.and(post::community_id.eq_any(community_ids)),
|
community_moderator::community_id
|
||||||
|
.eq(post::community_id)
|
||||||
|
.and(community_moderator::person_id.eq(my_person_id)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.select(count(comment_report::id))
|
.filter(comment_report::resolved.eq(false))
|
||||||
.first::<i64>(conn)
|
.into_boxed();
|
||||||
|
|
||||||
|
if let Some(community_id) = community_id {
|
||||||
|
query = query.filter(post::community_id.eq(community_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
query.select(count(comment_report::id)).first::<i64>(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CommentReportQueryBuilder<'a> {
|
pub struct CommentReportQueryBuilder<'a> {
|
||||||
conn: &'a PgConnection,
|
conn: &'a PgConnection,
|
||||||
community_ids: Option<Vec<CommunityId>>, // TODO bad way to do this
|
my_person_id: PersonId,
|
||||||
|
community_id: Option<CommunityId>,
|
||||||
page: Option<i64>,
|
page: Option<i64>,
|
||||||
limit: Option<i64>,
|
limit: Option<i64>,
|
||||||
resolved: Option<bool>,
|
unresolved_only: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CommentReportQueryBuilder<'a> {
|
impl<'a> CommentReportQueryBuilder<'a> {
|
||||||
pub fn create(conn: &'a PgConnection) -> Self {
|
pub fn create(conn: &'a PgConnection, my_person_id: PersonId) -> Self {
|
||||||
CommentReportQueryBuilder {
|
CommentReportQueryBuilder {
|
||||||
conn,
|
conn,
|
||||||
community_ids: None,
|
my_person_id,
|
||||||
|
community_id: None,
|
||||||
page: None,
|
page: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
resolved: Some(false),
|
unresolved_only: Some(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn community_ids<T: MaybeOptional<Vec<CommunityId>>>(mut self, community_ids: T) -> Self {
|
pub fn community_id<T: MaybeOptional<CommunityId>>(mut self, community_id: T) -> Self {
|
||||||
self.community_ids = community_ids.get_optional();
|
self.community_id = community_id.get_optional();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +212,8 @@ impl<'a> CommentReportQueryBuilder<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolved<T: MaybeOptional<bool>>(mut self, resolved: T) -> Self {
|
pub fn unresolved_only<T: MaybeOptional<bool>>(mut self, unresolved_only: T) -> Self {
|
||||||
self.resolved = resolved.get_optional();
|
self.unresolved_only = unresolved_only.get_optional();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +224,31 @@ impl<'a> CommentReportQueryBuilder<'a> {
|
||||||
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
||||||
.inner_join(person::table.on(comment_report::creator_id.eq(person::id)))
|
.inner_join(person::table.on(comment_report::creator_id.eq(person::id)))
|
||||||
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
||||||
|
// Test this join
|
||||||
|
.inner_join(
|
||||||
|
community_moderator::table.on(
|
||||||
|
community_moderator::community_id
|
||||||
|
.eq(post::community_id)
|
||||||
|
.and(community_moderator::person_id.eq(self.my_person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.inner_join(
|
||||||
|
comment_aggregates::table.on(comment_report::comment_id.eq(comment_aggregates::comment_id)),
|
||||||
|
)
|
||||||
|
.left_join(
|
||||||
|
community_person_ban::table.on(
|
||||||
|
community::id
|
||||||
|
.eq(community_person_ban::community_id)
|
||||||
|
.and(community_person_ban::person_id.eq(comment::creator_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.left_join(
|
||||||
|
comment_like::table.on(
|
||||||
|
comment::id
|
||||||
|
.eq(comment_like::comment_id)
|
||||||
|
.and(comment_like::person_id.eq(self.my_person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
.left_join(
|
.left_join(
|
||||||
person_alias_2::table.on(comment_report::resolver_id.eq(person_alias_2::id.nullable())),
|
person_alias_2::table.on(comment_report::resolver_id.eq(person_alias_2::id.nullable())),
|
||||||
)
|
)
|
||||||
|
@ -151,16 +259,19 @@ impl<'a> CommentReportQueryBuilder<'a> {
|
||||||
Community::safe_columns_tuple(),
|
Community::safe_columns_tuple(),
|
||||||
Person::safe_columns_tuple(),
|
Person::safe_columns_tuple(),
|
||||||
PersonAlias1::safe_columns_tuple(),
|
PersonAlias1::safe_columns_tuple(),
|
||||||
|
comment_aggregates::all_columns,
|
||||||
|
community_person_ban::all_columns.nullable(),
|
||||||
|
comment_like::score.nullable(),
|
||||||
PersonAlias2::safe_columns_tuple().nullable(),
|
PersonAlias2::safe_columns_tuple().nullable(),
|
||||||
))
|
))
|
||||||
.into_boxed();
|
.into_boxed();
|
||||||
|
|
||||||
if let Some(comm_ids) = self.community_ids {
|
if let Some(community_id) = self.community_id {
|
||||||
query = query.filter(post::community_id.eq_any(comm_ids));
|
query = query.filter(post::community_id.eq(community_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(resolved_flag) = self.resolved {
|
if self.unresolved_only.unwrap_or(false) {
|
||||||
query = query.filter(comment_report::resolved.eq(resolved_flag));
|
query = query.filter(comment_report::resolved.eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (limit, offset) = limit_and_offset(self.page, self.limit);
|
let (limit, offset) = limit_and_offset(self.page, self.limit);
|
||||||
|
@ -187,8 +298,281 @@ impl ViewToVec for CommentReportView {
|
||||||
community: a.3.to_owned(),
|
community: a.3.to_owned(),
|
||||||
creator: a.4.to_owned(),
|
creator: a.4.to_owned(),
|
||||||
comment_creator: a.5.to_owned(),
|
comment_creator: a.5.to_owned(),
|
||||||
resolver: a.6.to_owned(),
|
counts: a.6.to_owned(),
|
||||||
|
creator_banned_from_community: a.7.is_some(),
|
||||||
|
my_vote: a.8,
|
||||||
|
resolver: a.9.to_owned(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<Self>>()
|
.collect::<Vec<Self>>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::comment_report_view::{CommentReportQueryBuilder, CommentReportView};
|
||||||
|
use lemmy_db_queries::{
|
||||||
|
aggregates::comment_aggregates::CommentAggregates,
|
||||||
|
establish_unpooled_connection,
|
||||||
|
Crud,
|
||||||
|
Joinable,
|
||||||
|
Reportable,
|
||||||
|
};
|
||||||
|
use lemmy_db_schema::source::{comment::*, comment_report::*, community::*, person::*, post::*};
|
||||||
|
use serial_test::serial;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[serial]
|
||||||
|
fn test_crud() {
|
||||||
|
let conn = establish_unpooled_connection();
|
||||||
|
|
||||||
|
let new_person = PersonForm {
|
||||||
|
name: "timmy_crv".into(),
|
||||||
|
..PersonForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_timmy = Person::create(&conn, &new_person).unwrap();
|
||||||
|
|
||||||
|
let new_person_2 = PersonForm {
|
||||||
|
name: "sara_crv".into(),
|
||||||
|
..PersonForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_sara = Person::create(&conn, &new_person_2).unwrap();
|
||||||
|
|
||||||
|
// Add a third person, since new ppl can only report something once.
|
||||||
|
let new_person_3 = PersonForm {
|
||||||
|
name: "jessica_crv".into(),
|
||||||
|
..PersonForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_jessica = Person::create(&conn, &new_person_3).unwrap();
|
||||||
|
|
||||||
|
let new_community = CommunityForm {
|
||||||
|
name: "test community crv".to_string(),
|
||||||
|
title: "nada".to_owned(),
|
||||||
|
..CommunityForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_community = Community::create(&conn, &new_community).unwrap();
|
||||||
|
|
||||||
|
// Make timmy a mod
|
||||||
|
let timmy_moderator_form = CommunityModeratorForm {
|
||||||
|
community_id: inserted_community.id,
|
||||||
|
person_id: inserted_timmy.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let _inserted_moderator = CommunityModerator::join(&conn, &timmy_moderator_form).unwrap();
|
||||||
|
|
||||||
|
let new_post = PostForm {
|
||||||
|
name: "A test post crv".into(),
|
||||||
|
creator_id: inserted_timmy.id,
|
||||||
|
community_id: inserted_community.id,
|
||||||
|
..PostForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_post = Post::create(&conn, &new_post).unwrap();
|
||||||
|
|
||||||
|
let comment_form = CommentForm {
|
||||||
|
content: "A test comment 32".into(),
|
||||||
|
creator_id: inserted_timmy.id,
|
||||||
|
post_id: inserted_post.id,
|
||||||
|
..CommentForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
|
||||||
|
|
||||||
|
// sara reports
|
||||||
|
let sara_report_form = CommentReportForm {
|
||||||
|
creator_id: inserted_sara.id,
|
||||||
|
comment_id: inserted_comment.id,
|
||||||
|
original_comment_text: "this was it at time of creation".into(),
|
||||||
|
reason: "from sara".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_sara_report = CommentReport::report(&conn, &sara_report_form).unwrap();
|
||||||
|
|
||||||
|
// jessica reports
|
||||||
|
let jessica_report_form = CommentReportForm {
|
||||||
|
creator_id: inserted_jessica.id,
|
||||||
|
comment_id: inserted_comment.id,
|
||||||
|
original_comment_text: "this was it at time of creation".into(),
|
||||||
|
reason: "from jessica".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_jessica_report = CommentReport::report(&conn, &jessica_report_form).unwrap();
|
||||||
|
|
||||||
|
let agg = CommentAggregates::read(&conn, inserted_comment.id).unwrap();
|
||||||
|
|
||||||
|
let read_jessica_report_view =
|
||||||
|
CommentReportView::read(&conn, inserted_jessica_report.id, inserted_timmy.id).unwrap();
|
||||||
|
let expected_jessica_report_view = CommentReportView {
|
||||||
|
comment_report: inserted_jessica_report.to_owned(),
|
||||||
|
comment: inserted_comment.to_owned(),
|
||||||
|
post: inserted_post,
|
||||||
|
community: CommunitySafe {
|
||||||
|
id: inserted_community.id,
|
||||||
|
name: inserted_community.name,
|
||||||
|
icon: None,
|
||||||
|
removed: false,
|
||||||
|
deleted: false,
|
||||||
|
nsfw: false,
|
||||||
|
actor_id: inserted_community.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
title: inserted_community.title,
|
||||||
|
description: None,
|
||||||
|
updated: None,
|
||||||
|
banner: None,
|
||||||
|
published: inserted_community.published,
|
||||||
|
},
|
||||||
|
creator: PersonSafe {
|
||||||
|
id: inserted_jessica.id,
|
||||||
|
name: inserted_jessica.name,
|
||||||
|
display_name: None,
|
||||||
|
published: inserted_jessica.published,
|
||||||
|
avatar: None,
|
||||||
|
actor_id: inserted_jessica.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
banned: false,
|
||||||
|
deleted: false,
|
||||||
|
admin: false,
|
||||||
|
bot_account: false,
|
||||||
|
bio: None,
|
||||||
|
banner: None,
|
||||||
|
updated: None,
|
||||||
|
inbox_url: inserted_jessica.inbox_url.to_owned(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
matrix_user_id: None,
|
||||||
|
},
|
||||||
|
comment_creator: PersonSafeAlias1 {
|
||||||
|
id: inserted_timmy.id,
|
||||||
|
name: inserted_timmy.name.to_owned(),
|
||||||
|
display_name: None,
|
||||||
|
published: inserted_timmy.published,
|
||||||
|
avatar: None,
|
||||||
|
actor_id: inserted_timmy.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
banned: false,
|
||||||
|
deleted: false,
|
||||||
|
admin: false,
|
||||||
|
bot_account: false,
|
||||||
|
bio: None,
|
||||||
|
banner: None,
|
||||||
|
updated: None,
|
||||||
|
inbox_url: inserted_timmy.inbox_url.to_owned(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
matrix_user_id: None,
|
||||||
|
},
|
||||||
|
creator_banned_from_community: false,
|
||||||
|
counts: CommentAggregates {
|
||||||
|
id: agg.id,
|
||||||
|
comment_id: inserted_comment.id,
|
||||||
|
score: 0,
|
||||||
|
upvotes: 0,
|
||||||
|
downvotes: 0,
|
||||||
|
published: agg.published,
|
||||||
|
},
|
||||||
|
my_vote: None,
|
||||||
|
resolver: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(read_jessica_report_view, expected_jessica_report_view);
|
||||||
|
|
||||||
|
let mut expected_sara_report_view = expected_jessica_report_view.clone();
|
||||||
|
expected_sara_report_view.comment_report = inserted_sara_report;
|
||||||
|
expected_sara_report_view.creator = PersonSafe {
|
||||||
|
id: inserted_sara.id,
|
||||||
|
name: inserted_sara.name,
|
||||||
|
display_name: None,
|
||||||
|
published: inserted_sara.published,
|
||||||
|
avatar: None,
|
||||||
|
actor_id: inserted_sara.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
banned: false,
|
||||||
|
deleted: false,
|
||||||
|
admin: false,
|
||||||
|
bot_account: false,
|
||||||
|
bio: None,
|
||||||
|
banner: None,
|
||||||
|
updated: None,
|
||||||
|
inbox_url: inserted_sara.inbox_url.to_owned(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
matrix_user_id: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Do a batch read of timmys reports
|
||||||
|
let reports = CommentReportQueryBuilder::create(&conn, inserted_timmy.id)
|
||||||
|
.list()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
reports,
|
||||||
|
[
|
||||||
|
expected_sara_report_view.to_owned(),
|
||||||
|
expected_jessica_report_view.to_owned()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Make sure the counts are correct
|
||||||
|
let report_count = CommentReportView::get_report_count(&conn, inserted_timmy.id, None).unwrap();
|
||||||
|
assert_eq!(2, report_count);
|
||||||
|
|
||||||
|
// Try to resolve the report
|
||||||
|
CommentReport::resolve(&conn, inserted_jessica_report.id, inserted_timmy.id).unwrap();
|
||||||
|
let read_jessica_report_view_after_resolve =
|
||||||
|
CommentReportView::read(&conn, inserted_jessica_report.id, inserted_timmy.id).unwrap();
|
||||||
|
|
||||||
|
let mut expected_jessica_report_view_after_resolve = expected_jessica_report_view;
|
||||||
|
expected_jessica_report_view_after_resolve
|
||||||
|
.comment_report
|
||||||
|
.resolved = true;
|
||||||
|
expected_jessica_report_view_after_resolve
|
||||||
|
.comment_report
|
||||||
|
.resolver_id = Some(inserted_timmy.id);
|
||||||
|
expected_jessica_report_view_after_resolve
|
||||||
|
.comment_report
|
||||||
|
.updated = read_jessica_report_view_after_resolve
|
||||||
|
.comment_report
|
||||||
|
.updated;
|
||||||
|
expected_jessica_report_view_after_resolve.resolver = Some(PersonSafeAlias2 {
|
||||||
|
id: inserted_timmy.id,
|
||||||
|
name: inserted_timmy.name.to_owned(),
|
||||||
|
display_name: None,
|
||||||
|
published: inserted_timmy.published,
|
||||||
|
avatar: None,
|
||||||
|
actor_id: inserted_timmy.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
banned: false,
|
||||||
|
deleted: false,
|
||||||
|
admin: false,
|
||||||
|
bot_account: false,
|
||||||
|
bio: None,
|
||||||
|
banner: None,
|
||||||
|
updated: None,
|
||||||
|
inbox_url: inserted_timmy.inbox_url.to_owned(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
matrix_user_id: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
read_jessica_report_view_after_resolve,
|
||||||
|
expected_jessica_report_view_after_resolve
|
||||||
|
);
|
||||||
|
|
||||||
|
// Do a batch read of timmys reports
|
||||||
|
// It should only show saras, which is unresolved
|
||||||
|
let reports_after_resolve = CommentReportQueryBuilder::create(&conn, inserted_timmy.id)
|
||||||
|
.list()
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(reports_after_resolve[0], expected_sara_report_view);
|
||||||
|
|
||||||
|
// Make sure the counts are correct
|
||||||
|
let report_count_after_resolved =
|
||||||
|
CommentReportView::get_report_count(&conn, inserted_timmy.id, None).unwrap();
|
||||||
|
assert_eq!(1, report_count_after_resolved);
|
||||||
|
|
||||||
|
Person::delete(&conn, inserted_timmy.id).unwrap();
|
||||||
|
Person::delete(&conn, inserted_sara.id).unwrap();
|
||||||
|
Person::delete(&conn, inserted_jessica.id).unwrap();
|
||||||
|
Community::delete(&conn, inserted_community.id).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,33 @@
|
||||||
use diesel::{result::Error, *};
|
use diesel::{result::Error, *};
|
||||||
use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec};
|
use lemmy_db_queries::{
|
||||||
|
aggregates::post_aggregates::PostAggregates,
|
||||||
|
limit_and_offset,
|
||||||
|
MaybeOptional,
|
||||||
|
ToSafe,
|
||||||
|
ViewToVec,
|
||||||
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
schema::{community, person, person_alias_1, person_alias_2, post, post_report},
|
schema::{
|
||||||
|
community,
|
||||||
|
community_moderator,
|
||||||
|
community_person_ban,
|
||||||
|
person,
|
||||||
|
person_alias_1,
|
||||||
|
person_alias_2,
|
||||||
|
post,
|
||||||
|
post_aggregates,
|
||||||
|
post_like,
|
||||||
|
post_report,
|
||||||
|
},
|
||||||
source::{
|
source::{
|
||||||
community::{Community, CommunitySafe},
|
community::{Community, CommunityPersonBan, CommunitySafe},
|
||||||
person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2},
|
person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2},
|
||||||
post::Post,
|
post::Post,
|
||||||
post_report::PostReport,
|
post_report::PostReport,
|
||||||
},
|
},
|
||||||
CommunityId,
|
CommunityId,
|
||||||
|
PersonId,
|
||||||
|
PostReportId,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -19,6 +38,9 @@ pub struct PostReportView {
|
||||||
pub community: CommunitySafe,
|
pub community: CommunitySafe,
|
||||||
pub creator: PersonSafe,
|
pub creator: PersonSafe,
|
||||||
pub post_creator: PersonSafeAlias1,
|
pub post_creator: PersonSafeAlias1,
|
||||||
|
pub creator_banned_from_community: bool,
|
||||||
|
pub my_vote: Option<i16>,
|
||||||
|
pub counts: PostAggregates,
|
||||||
pub resolver: Option<PersonSafeAlias2>,
|
pub resolver: Option<PersonSafeAlias2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +50,9 @@ type PostReportViewTuple = (
|
||||||
CommunitySafe,
|
CommunitySafe,
|
||||||
PersonSafe,
|
PersonSafe,
|
||||||
PersonSafeAlias1,
|
PersonSafeAlias1,
|
||||||
|
Option<CommunityPersonBan>,
|
||||||
|
Option<i16>,
|
||||||
|
PostAggregates,
|
||||||
Option<PersonSafeAlias2>,
|
Option<PersonSafeAlias2>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -35,13 +60,42 @@ impl PostReportView {
|
||||||
/// returns the PostReportView for the provided report_id
|
/// returns the PostReportView for the provided report_id
|
||||||
///
|
///
|
||||||
/// * `report_id` - the report id to obtain
|
/// * `report_id` - the report id to obtain
|
||||||
pub fn read(conn: &PgConnection, report_id: i32) -> Result<Self, Error> {
|
pub fn read(
|
||||||
let (post_report, post, community, creator, post_creator, resolver) = post_report::table
|
conn: &PgConnection,
|
||||||
|
report_id: PostReportId,
|
||||||
|
my_person_id: PersonId,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let (
|
||||||
|
post_report,
|
||||||
|
post,
|
||||||
|
community,
|
||||||
|
creator,
|
||||||
|
post_creator,
|
||||||
|
creator_banned_from_community,
|
||||||
|
post_like,
|
||||||
|
counts,
|
||||||
|
resolver,
|
||||||
|
) = post_report::table
|
||||||
.find(report_id)
|
.find(report_id)
|
||||||
.inner_join(post::table)
|
.inner_join(post::table)
|
||||||
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
||||||
.inner_join(person::table.on(post_report::creator_id.eq(person::id)))
|
.inner_join(person::table.on(post_report::creator_id.eq(person::id)))
|
||||||
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
||||||
|
.left_join(
|
||||||
|
community_person_ban::table.on(
|
||||||
|
post::community_id
|
||||||
|
.eq(community_person_ban::community_id)
|
||||||
|
.and(community_person_ban::person_id.eq(post::creator_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.left_join(
|
||||||
|
post_like::table.on(
|
||||||
|
post::id
|
||||||
|
.eq(post_like::post_id)
|
||||||
|
.and(post_like::person_id.eq(my_person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.inner_join(post_aggregates::table.on(post_report::post_id.eq(post_aggregates::post_id)))
|
||||||
.left_join(
|
.left_join(
|
||||||
person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())),
|
person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())),
|
||||||
)
|
)
|
||||||
|
@ -51,16 +105,24 @@ impl PostReportView {
|
||||||
Community::safe_columns_tuple(),
|
Community::safe_columns_tuple(),
|
||||||
Person::safe_columns_tuple(),
|
Person::safe_columns_tuple(),
|
||||||
PersonAlias1::safe_columns_tuple(),
|
PersonAlias1::safe_columns_tuple(),
|
||||||
|
community_person_ban::all_columns.nullable(),
|
||||||
|
post_like::score.nullable(),
|
||||||
|
post_aggregates::all_columns,
|
||||||
PersonAlias2::safe_columns_tuple().nullable(),
|
PersonAlias2::safe_columns_tuple().nullable(),
|
||||||
))
|
))
|
||||||
.first::<PostReportViewTuple>(conn)?;
|
.first::<PostReportViewTuple>(conn)?;
|
||||||
|
|
||||||
|
let my_vote = if post_like.is_none() { None } else { post_like };
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
post_report,
|
post_report,
|
||||||
post,
|
post,
|
||||||
community,
|
community,
|
||||||
creator,
|
creator,
|
||||||
post_creator,
|
post_creator,
|
||||||
|
creator_banned_from_community: creator_banned_from_community.is_some(),
|
||||||
|
my_vote,
|
||||||
|
counts,
|
||||||
resolver,
|
resolver,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -72,42 +134,54 @@ impl PostReportView {
|
||||||
/// for a person id
|
/// for a person id
|
||||||
pub fn get_report_count(
|
pub fn get_report_count(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
community_ids: &[CommunityId],
|
my_person_id: PersonId,
|
||||||
|
community_id: Option<CommunityId>,
|
||||||
) -> Result<i64, Error> {
|
) -> Result<i64, Error> {
|
||||||
use diesel::dsl::*;
|
use diesel::dsl::*;
|
||||||
post_report::table
|
let mut query = post_report::table
|
||||||
.inner_join(post::table)
|
.inner_join(post::table)
|
||||||
.filter(
|
// Test this join
|
||||||
post_report::resolved
|
.inner_join(
|
||||||
.eq(false)
|
community_moderator::table.on(
|
||||||
.and(post::community_id.eq_any(community_ids)),
|
community_moderator::community_id
|
||||||
|
.eq(post::community_id)
|
||||||
|
.and(community_moderator::person_id.eq(my_person_id)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.select(count(post_report::id))
|
.filter(post_report::resolved.eq(false))
|
||||||
.first::<i64>(conn)
|
.into_boxed();
|
||||||
|
|
||||||
|
if let Some(community_id) = community_id {
|
||||||
|
query = query.filter(post::community_id.eq(community_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
query.select(count(post_report::id)).first::<i64>(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PostReportQueryBuilder<'a> {
|
pub struct PostReportQueryBuilder<'a> {
|
||||||
conn: &'a PgConnection,
|
conn: &'a PgConnection,
|
||||||
community_ids: Option<Vec<CommunityId>>, // TODO bad way to do this
|
my_person_id: PersonId,
|
||||||
|
community_id: Option<CommunityId>,
|
||||||
page: Option<i64>,
|
page: Option<i64>,
|
||||||
limit: Option<i64>,
|
limit: Option<i64>,
|
||||||
resolved: Option<bool>,
|
unresolved_only: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PostReportQueryBuilder<'a> {
|
impl<'a> PostReportQueryBuilder<'a> {
|
||||||
pub fn create(conn: &'a PgConnection) -> Self {
|
pub fn create(conn: &'a PgConnection, my_person_id: PersonId) -> Self {
|
||||||
PostReportQueryBuilder {
|
PostReportQueryBuilder {
|
||||||
conn,
|
conn,
|
||||||
community_ids: None,
|
my_person_id,
|
||||||
|
community_id: None,
|
||||||
page: None,
|
page: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
resolved: Some(false),
|
unresolved_only: Some(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn community_ids<T: MaybeOptional<Vec<CommunityId>>>(mut self, community_ids: T) -> Self {
|
pub fn community_id<T: MaybeOptional<CommunityId>>(mut self, community_id: T) -> Self {
|
||||||
self.community_ids = community_ids.get_optional();
|
self.community_id = community_id.get_optional();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,8 +195,8 @@ impl<'a> PostReportQueryBuilder<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolved<T: MaybeOptional<bool>>(mut self, resolved: T) -> Self {
|
pub fn unresolved_only<T: MaybeOptional<bool>>(mut self, unresolved_only: T) -> Self {
|
||||||
self.resolved = resolved.get_optional();
|
self.unresolved_only = unresolved_only.get_optional();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +206,29 @@ impl<'a> PostReportQueryBuilder<'a> {
|
||||||
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
||||||
.inner_join(person::table.on(post_report::creator_id.eq(person::id)))
|
.inner_join(person::table.on(post_report::creator_id.eq(person::id)))
|
||||||
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
||||||
|
// Test this join
|
||||||
|
.inner_join(
|
||||||
|
community_moderator::table.on(
|
||||||
|
community_moderator::community_id
|
||||||
|
.eq(post::community_id)
|
||||||
|
.and(community_moderator::person_id.eq(self.my_person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.left_join(
|
||||||
|
community_person_ban::table.on(
|
||||||
|
post::community_id
|
||||||
|
.eq(community_person_ban::community_id)
|
||||||
|
.and(community_person_ban::person_id.eq(post::creator_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.left_join(
|
||||||
|
post_like::table.on(
|
||||||
|
post::id
|
||||||
|
.eq(post_like::post_id)
|
||||||
|
.and(post_like::person_id.eq(self.my_person_id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.inner_join(post_aggregates::table.on(post_report::post_id.eq(post_aggregates::post_id)))
|
||||||
.left_join(
|
.left_join(
|
||||||
person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())),
|
person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())),
|
||||||
)
|
)
|
||||||
|
@ -141,16 +238,19 @@ impl<'a> PostReportQueryBuilder<'a> {
|
||||||
Community::safe_columns_tuple(),
|
Community::safe_columns_tuple(),
|
||||||
Person::safe_columns_tuple(),
|
Person::safe_columns_tuple(),
|
||||||
PersonAlias1::safe_columns_tuple(),
|
PersonAlias1::safe_columns_tuple(),
|
||||||
|
community_person_ban::all_columns.nullable(),
|
||||||
|
post_like::score.nullable(),
|
||||||
|
post_aggregates::all_columns,
|
||||||
PersonAlias2::safe_columns_tuple().nullable(),
|
PersonAlias2::safe_columns_tuple().nullable(),
|
||||||
))
|
))
|
||||||
.into_boxed();
|
.into_boxed();
|
||||||
|
|
||||||
if let Some(comm_ids) = self.community_ids {
|
if let Some(community_id) = self.community_id {
|
||||||
query = query.filter(post::community_id.eq_any(comm_ids));
|
query = query.filter(post::community_id.eq(community_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(resolved_flag) = self.resolved {
|
if self.unresolved_only.unwrap_or(false) {
|
||||||
query = query.filter(post_report::resolved.eq(resolved_flag));
|
query = query.filter(post_report::resolved.eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (limit, offset) = limit_and_offset(self.page, self.limit);
|
let (limit, offset) = limit_and_offset(self.page, self.limit);
|
||||||
|
@ -176,8 +276,283 @@ impl ViewToVec for PostReportView {
|
||||||
community: a.2.to_owned(),
|
community: a.2.to_owned(),
|
||||||
creator: a.3.to_owned(),
|
creator: a.3.to_owned(),
|
||||||
post_creator: a.4.to_owned(),
|
post_creator: a.4.to_owned(),
|
||||||
resolver: a.5.to_owned(),
|
creator_banned_from_community: a.5.is_some(),
|
||||||
|
my_vote: a.6,
|
||||||
|
counts: a.7.to_owned(),
|
||||||
|
resolver: a.8.to_owned(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<Self>>()
|
.collect::<Vec<Self>>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::post_report_view::{PostReportQueryBuilder, PostReportView};
|
||||||
|
use lemmy_db_queries::{
|
||||||
|
aggregates::post_aggregates::PostAggregates,
|
||||||
|
establish_unpooled_connection,
|
||||||
|
Crud,
|
||||||
|
Joinable,
|
||||||
|
Reportable,
|
||||||
|
};
|
||||||
|
use lemmy_db_schema::source::{
|
||||||
|
community::*,
|
||||||
|
person::*,
|
||||||
|
post::*,
|
||||||
|
post_report::{PostReport, PostReportForm},
|
||||||
|
};
|
||||||
|
use serial_test::serial;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[serial]
|
||||||
|
fn test_crud() {
|
||||||
|
let conn = establish_unpooled_connection();
|
||||||
|
|
||||||
|
let new_person = PersonForm {
|
||||||
|
name: "timmy_prv".into(),
|
||||||
|
..PersonForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_timmy = Person::create(&conn, &new_person).unwrap();
|
||||||
|
|
||||||
|
let new_person_2 = PersonForm {
|
||||||
|
name: "sara_prv".into(),
|
||||||
|
..PersonForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_sara = Person::create(&conn, &new_person_2).unwrap();
|
||||||
|
|
||||||
|
// Add a third person, since new ppl can only report something once.
|
||||||
|
let new_person_3 = PersonForm {
|
||||||
|
name: "jessica_prv".into(),
|
||||||
|
..PersonForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_jessica = Person::create(&conn, &new_person_3).unwrap();
|
||||||
|
|
||||||
|
let new_community = CommunityForm {
|
||||||
|
name: "test community prv".to_string(),
|
||||||
|
title: "nada".to_owned(),
|
||||||
|
..CommunityForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_community = Community::create(&conn, &new_community).unwrap();
|
||||||
|
|
||||||
|
// Make timmy a mod
|
||||||
|
let timmy_moderator_form = CommunityModeratorForm {
|
||||||
|
community_id: inserted_community.id,
|
||||||
|
person_id: inserted_timmy.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let _inserted_moderator = CommunityModerator::join(&conn, &timmy_moderator_form).unwrap();
|
||||||
|
|
||||||
|
let new_post = PostForm {
|
||||||
|
name: "A test post crv".into(),
|
||||||
|
creator_id: inserted_timmy.id,
|
||||||
|
community_id: inserted_community.id,
|
||||||
|
..PostForm::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_post = Post::create(&conn, &new_post).unwrap();
|
||||||
|
|
||||||
|
// sara reports
|
||||||
|
let sara_report_form = PostReportForm {
|
||||||
|
creator_id: inserted_sara.id,
|
||||||
|
post_id: inserted_post.id,
|
||||||
|
original_post_name: "Orig post".into(),
|
||||||
|
original_post_url: None,
|
||||||
|
original_post_body: None,
|
||||||
|
reason: "from sara".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_sara_report = PostReport::report(&conn, &sara_report_form).unwrap();
|
||||||
|
|
||||||
|
// jessica reports
|
||||||
|
let jessica_report_form = PostReportForm {
|
||||||
|
creator_id: inserted_jessica.id,
|
||||||
|
post_id: inserted_post.id,
|
||||||
|
original_post_name: "Orig post".into(),
|
||||||
|
original_post_url: None,
|
||||||
|
original_post_body: None,
|
||||||
|
reason: "from jessica".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_jessica_report = PostReport::report(&conn, &jessica_report_form).unwrap();
|
||||||
|
|
||||||
|
let agg = PostAggregates::read(&conn, inserted_post.id).unwrap();
|
||||||
|
|
||||||
|
let read_jessica_report_view =
|
||||||
|
PostReportView::read(&conn, inserted_jessica_report.id, inserted_timmy.id).unwrap();
|
||||||
|
let expected_jessica_report_view = PostReportView {
|
||||||
|
post_report: inserted_jessica_report.to_owned(),
|
||||||
|
post: inserted_post.to_owned(),
|
||||||
|
community: CommunitySafe {
|
||||||
|
id: inserted_community.id,
|
||||||
|
name: inserted_community.name,
|
||||||
|
icon: None,
|
||||||
|
removed: false,
|
||||||
|
deleted: false,
|
||||||
|
nsfw: false,
|
||||||
|
actor_id: inserted_community.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
title: inserted_community.title,
|
||||||
|
description: None,
|
||||||
|
updated: None,
|
||||||
|
banner: None,
|
||||||
|
published: inserted_community.published,
|
||||||
|
},
|
||||||
|
creator: PersonSafe {
|
||||||
|
id: inserted_jessica.id,
|
||||||
|
name: inserted_jessica.name,
|
||||||
|
display_name: None,
|
||||||
|
published: inserted_jessica.published,
|
||||||
|
avatar: None,
|
||||||
|
actor_id: inserted_jessica.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
banned: false,
|
||||||
|
deleted: false,
|
||||||
|
admin: false,
|
||||||
|
bot_account: false,
|
||||||
|
bio: None,
|
||||||
|
banner: None,
|
||||||
|
updated: None,
|
||||||
|
inbox_url: inserted_jessica.inbox_url.to_owned(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
matrix_user_id: None,
|
||||||
|
},
|
||||||
|
post_creator: PersonSafeAlias1 {
|
||||||
|
id: inserted_timmy.id,
|
||||||
|
name: inserted_timmy.name.to_owned(),
|
||||||
|
display_name: None,
|
||||||
|
published: inserted_timmy.published,
|
||||||
|
avatar: None,
|
||||||
|
actor_id: inserted_timmy.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
banned: false,
|
||||||
|
deleted: false,
|
||||||
|
admin: false,
|
||||||
|
bot_account: false,
|
||||||
|
bio: None,
|
||||||
|
banner: None,
|
||||||
|
updated: None,
|
||||||
|
inbox_url: inserted_timmy.inbox_url.to_owned(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
matrix_user_id: None,
|
||||||
|
},
|
||||||
|
creator_banned_from_community: false,
|
||||||
|
my_vote: None,
|
||||||
|
counts: PostAggregates {
|
||||||
|
id: agg.id,
|
||||||
|
post_id: inserted_post.id,
|
||||||
|
comments: 0,
|
||||||
|
score: 0,
|
||||||
|
upvotes: 0,
|
||||||
|
downvotes: 0,
|
||||||
|
stickied: false,
|
||||||
|
published: agg.published,
|
||||||
|
newest_comment_time_necro: inserted_post.published,
|
||||||
|
newest_comment_time: inserted_post.published,
|
||||||
|
},
|
||||||
|
resolver: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(read_jessica_report_view, expected_jessica_report_view);
|
||||||
|
|
||||||
|
let mut expected_sara_report_view = expected_jessica_report_view.clone();
|
||||||
|
expected_sara_report_view.post_report = inserted_sara_report;
|
||||||
|
expected_sara_report_view.my_vote = None;
|
||||||
|
expected_sara_report_view.creator = PersonSafe {
|
||||||
|
id: inserted_sara.id,
|
||||||
|
name: inserted_sara.name,
|
||||||
|
display_name: None,
|
||||||
|
published: inserted_sara.published,
|
||||||
|
avatar: None,
|
||||||
|
actor_id: inserted_sara.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
banned: false,
|
||||||
|
deleted: false,
|
||||||
|
admin: false,
|
||||||
|
bot_account: false,
|
||||||
|
bio: None,
|
||||||
|
banner: None,
|
||||||
|
updated: None,
|
||||||
|
inbox_url: inserted_sara.inbox_url.to_owned(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
matrix_user_id: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Do a batch read of timmys reports
|
||||||
|
let reports = PostReportQueryBuilder::create(&conn, inserted_timmy.id)
|
||||||
|
.list()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
reports,
|
||||||
|
[
|
||||||
|
expected_sara_report_view.to_owned(),
|
||||||
|
expected_jessica_report_view.to_owned()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Make sure the counts are correct
|
||||||
|
let report_count = PostReportView::get_report_count(&conn, inserted_timmy.id, None).unwrap();
|
||||||
|
assert_eq!(2, report_count);
|
||||||
|
|
||||||
|
// Try to resolve the report
|
||||||
|
PostReport::resolve(&conn, inserted_jessica_report.id, inserted_timmy.id).unwrap();
|
||||||
|
let read_jessica_report_view_after_resolve =
|
||||||
|
PostReportView::read(&conn, inserted_jessica_report.id, inserted_timmy.id).unwrap();
|
||||||
|
|
||||||
|
let mut expected_jessica_report_view_after_resolve = expected_jessica_report_view;
|
||||||
|
expected_jessica_report_view_after_resolve
|
||||||
|
.post_report
|
||||||
|
.resolved = true;
|
||||||
|
expected_jessica_report_view_after_resolve
|
||||||
|
.post_report
|
||||||
|
.resolver_id = Some(inserted_timmy.id);
|
||||||
|
expected_jessica_report_view_after_resolve
|
||||||
|
.post_report
|
||||||
|
.updated = read_jessica_report_view_after_resolve.post_report.updated;
|
||||||
|
expected_jessica_report_view_after_resolve.resolver = Some(PersonSafeAlias2 {
|
||||||
|
id: inserted_timmy.id,
|
||||||
|
name: inserted_timmy.name.to_owned(),
|
||||||
|
display_name: None,
|
||||||
|
published: inserted_timmy.published,
|
||||||
|
avatar: None,
|
||||||
|
actor_id: inserted_timmy.actor_id.to_owned(),
|
||||||
|
local: true,
|
||||||
|
banned: false,
|
||||||
|
deleted: false,
|
||||||
|
admin: false,
|
||||||
|
bot_account: false,
|
||||||
|
bio: None,
|
||||||
|
banner: None,
|
||||||
|
updated: None,
|
||||||
|
inbox_url: inserted_timmy.inbox_url.to_owned(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
matrix_user_id: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
read_jessica_report_view_after_resolve,
|
||||||
|
expected_jessica_report_view_after_resolve
|
||||||
|
);
|
||||||
|
|
||||||
|
// Do a batch read of timmys reports
|
||||||
|
// It should only show saras, which is unresolved
|
||||||
|
let reports_after_resolve = PostReportQueryBuilder::create(&conn, inserted_timmy.id)
|
||||||
|
.list()
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(reports_after_resolve[0], expected_sara_report_view);
|
||||||
|
|
||||||
|
// Make sure the counts are correct
|
||||||
|
let report_count_after_resolved =
|
||||||
|
PostReportView::get_report_count(&conn, inserted_timmy.id, None).unwrap();
|
||||||
|
assert_eq!(1, report_count_after_resolved);
|
||||||
|
|
||||||
|
Person::delete(&conn, inserted_timmy.id).unwrap();
|
||||||
|
Person::delete(&conn, inserted_sara.id).unwrap();
|
||||||
|
Person::delete(&conn, inserted_jessica.id).unwrap();
|
||||||
|
Community::delete(&conn, inserted_community.id).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue