X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fdb_views%2Fsrc%2Fpost_view.rs;h=1d85df3c83e0ea6cd51817d7f378556fd528915c;hb=ced3aa5bd8bc78fb7a1a98bd839531255b773a9c;hp=466713e1d3eb3db9f60146cf98f4a4e96feaf555;hpb=88215bfbc98b70595035426c06cfe67f4a9ab0ab;p=lemmy.git diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index 466713e1..1d85df3c 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -1,4 +1,4 @@ -use crate::structs::PostView; +use crate::structs::{LocalUserView, PostView}; use diesel::{ debug_query, dsl::{now, IntervalDsl}, @@ -34,7 +34,6 @@ use lemmy_db_schema::{ }, source::{ community::{Community, CommunityFollower, CommunityPersonBan}, - local_user::LocalUser, person::Person, person_block::PersonBlock, post::{Post, PostRead, PostSaved}, @@ -149,9 +148,18 @@ impl PostView { if !is_mod_or_admin.unwrap_or(false) { query = query .filter(community::removed.eq(false)) - .filter(community::deleted.eq(false)) .filter(post::removed.eq(false)) - .filter(post::deleted.eq(false)); + // users can see their own deleted posts + .filter( + community::deleted + .eq(false) + .or(post::creator_id.eq(person_id_join)), + ) + .filter( + post::deleted + .eq(false) + .or(post::creator_id.eq(person_id_join)), + ); } let ( @@ -198,12 +206,11 @@ pub struct PostQuery<'a> { pub sort: Option, pub creator_id: Option, pub community_id: Option, - pub local_user: Option<&'a LocalUser>, + pub local_user: Option<&'a LocalUserView>, pub search_term: Option, pub url_search: Option, pub saved_only: Option, - /// Used to show deleted or removed posts for admins - pub is_mod_or_admin: Option, + pub is_profile_view: Option, pub page: Option, pub limit: Option, } @@ -213,8 +220,11 @@ impl<'a> PostQuery<'a> { let conn = &mut get_conn(pool).await?; // The left join below will return None in this case - let person_id_join = self.local_user.map(|l| l.person_id).unwrap_or(PersonId(-1)); - let local_user_id_join = self.local_user.map(|l| l.id).unwrap_or(LocalUserId(-1)); + let person_id_join = self.local_user.map(|l| l.person.id).unwrap_or(PersonId(-1)); + let local_user_id_join = self + .local_user + .map(|l| l.local_user.id) + .unwrap_or(LocalUserId(-1)); let mut query = post::table .inner_join(person::table) @@ -301,16 +311,23 @@ impl<'a> PostQuery<'a> { )) .into_boxed(); - // Hide deleted and removed for non-admins or mods - // TODO This eventually needs to show posts where you are the creator - if !self.is_mod_or_admin.unwrap_or(false) { + let is_profile_view = self.is_profile_view.unwrap_or(false); + let is_creator = self.creator_id == self.local_user.map(|l| l.person.id); + // only show deleted posts to creator + if is_creator { query = query - .filter(community::removed.eq(false)) .filter(community::deleted.eq(false)) - .filter(post::removed.eq(false)) .filter(post::deleted.eq(false)); } + let is_admin = self.local_user.map(|l| l.person.admin).unwrap_or(false); + // only show removed posts to admin when viewing user profile + if !(is_profile_view && is_admin) { + query = query + .filter(community::removed.eq(false)) + .filter(post::removed.eq(false)); + } + if self.community_id.is_none() { query = query.then_order_by(post_aggregates::featured_local.desc()); } else if let Some(community_id) = self.community_id { @@ -358,13 +375,21 @@ impl<'a> PostQuery<'a> { ); } - if !self.local_user.map(|l| l.show_nsfw).unwrap_or(false) { + if !self + .local_user + .map(|l| l.local_user.show_nsfw) + .unwrap_or(false) + { query = query .filter(post::nsfw.eq(false)) .filter(community::nsfw.eq(false)); }; - if !self.local_user.map(|l| l.show_bot_accounts).unwrap_or(true) { + if !self + .local_user + .map(|l| l.local_user.show_bot_accounts) + .unwrap_or(true) + { query = query.filter(person::bot_account.eq(false)); }; @@ -373,7 +398,11 @@ impl<'a> PostQuery<'a> { } // Only hide the read posts, if the saved_only is false. Otherwise ppl with the hide_read // setting wont be able to see saved posts. - else if !self.local_user.map(|l| l.show_read_posts).unwrap_or(true) { + else if !self + .local_user + .map(|l| l.local_user.show_read_posts) + .unwrap_or(true) + { query = query.filter(post_read::post_id.is_null()); } @@ -387,8 +416,12 @@ impl<'a> PostQuery<'a> { } query = match self.sort.unwrap_or(SortType::Hot) { - SortType::Active => query.then_order_by(post_aggregates::hot_rank_active.desc()), - SortType::Hot => query.then_order_by(post_aggregates::hot_rank.desc()), + SortType::Active => query + .then_order_by(post_aggregates::hot_rank_active.desc()) + .then_order_by(post_aggregates::published.desc()), + SortType::Hot => query + .then_order_by(post_aggregates::hot_rank.desc()) + .then_order_by(post_aggregates::published.desc()), SortType::New => query.then_order_by(post_aggregates::published.desc()), SortType::Old => query.then_order_by(post_aggregates::published.asc()), SortType::NewComments => query.then_order_by(post_aggregates::newest_comment_time.desc()), @@ -473,7 +506,13 @@ impl JoinView for PostView { #[cfg(test)] mod tests { - use crate::post_view::{PostQuery, PostView}; + #![allow(clippy::unwrap_used)] + #![allow(clippy::indexing_slicing)] + + use crate::{ + post_view::{PostQuery, PostView}, + structs::LocalUserView, + }; use lemmy_db_schema::{ aggregates::structs::PostAggregates, impls::actor_language::UNDETERMINED_ID, @@ -498,8 +537,7 @@ mod tests { struct Data { inserted_instance: Instance, - inserted_person: Person, - inserted_local_user: LocalUser, + local_user_view: LocalUserView, inserted_blocked_person: Person, inserted_bot: Person, inserted_community: Community, @@ -588,11 +626,15 @@ mod tests { .build(); let _inserted_bot_post = Post::create(pool, &new_bot_post).await.unwrap(); + let local_user_view = LocalUserView { + local_user: inserted_local_user, + person: inserted_person, + counts: Default::default(), + }; Data { inserted_instance, - inserted_person, - inserted_local_user, + local_user_view, inserted_blocked_person, inserted_bot, inserted_community, @@ -605,20 +647,21 @@ mod tests { async fn post_listing_with_person() { let pool = &build_db_pool_for_tests().await; let pool = &mut pool.into(); - let data = init_data(pool).await; + let mut data = init_data(pool).await; let local_user_form = LocalUserUpdateForm::builder() .show_bot_accounts(Some(false)) .build(); let inserted_local_user = - LocalUser::update(pool, data.inserted_local_user.id, &local_user_form) + LocalUser::update(pool, data.local_user_view.local_user.id, &local_user_form) .await .unwrap(); + data.local_user_view.local_user = inserted_local_user; let read_post_listing = PostQuery { sort: (Some(SortType::New)), community_id: (Some(data.inserted_community.id)), - local_user: (Some(&inserted_local_user)), + local_user: (Some(&data.local_user_view)), ..Default::default() } .list(pool) @@ -628,7 +671,7 @@ mod tests { let post_listing_single_with_person = PostView::read( pool, data.inserted_post.id, - Some(data.inserted_person.id), + Some(data.local_user_view.person.id), None, ) .await @@ -650,14 +693,15 @@ mod tests { .show_bot_accounts(Some(true)) .build(); let inserted_local_user = - LocalUser::update(pool, data.inserted_local_user.id, &local_user_form) + LocalUser::update(pool, data.local_user_view.local_user.id, &local_user_form) .await .unwrap(); + data.local_user_view.local_user = inserted_local_user; let post_listings_with_bots = PostQuery { sort: (Some(SortType::New)), community_id: (Some(data.inserted_community.id)), - local_user: (Some(&inserted_local_user)), + local_user: (Some(&data.local_user_view)), ..Default::default() } .list(pool) @@ -715,7 +759,7 @@ mod tests { let data = init_data(pool).await; let community_block = CommunityBlockForm { - person_id: data.inserted_person.id, + person_id: data.local_user_view.person.id, community_id: data.inserted_community.id, }; CommunityBlock::block(pool, &community_block).await.unwrap(); @@ -723,7 +767,7 @@ mod tests { let read_post_listings_with_person_after_block = PostQuery { sort: (Some(SortType::New)), community_id: (Some(data.inserted_community.id)), - local_user: (Some(&data.inserted_local_user)), + local_user: (Some(&data.local_user_view)), ..Default::default() } .list(pool) @@ -743,11 +787,11 @@ mod tests { async fn post_listing_like() { let pool = &build_db_pool_for_tests().await; let pool = &mut pool.into(); - let data = init_data(pool).await; + let mut data = init_data(pool).await; let post_like_form = PostLikeForm { post_id: data.inserted_post.id, - person_id: data.inserted_person.id, + person_id: data.local_user_view.person.id, score: 1, }; @@ -756,7 +800,7 @@ mod tests { let expected_post_like = PostLike { id: inserted_post_like.id, post_id: data.inserted_post.id, - person_id: data.inserted_person.id, + person_id: data.local_user_view.person.id, published: inserted_post_like.published, score: 1, }; @@ -765,7 +809,7 @@ mod tests { let post_listing_single_with_person = PostView::read( pool, data.inserted_post.id, - Some(data.inserted_person.id), + Some(data.local_user_view.person.id), None, ) .await @@ -781,14 +825,15 @@ mod tests { .show_bot_accounts(Some(false)) .build(); let inserted_local_user = - LocalUser::update(pool, data.inserted_local_user.id, &local_user_form) + LocalUser::update(pool, data.local_user_view.local_user.id, &local_user_form) .await .unwrap(); + data.local_user_view.local_user = inserted_local_user; let read_post_listing = PostQuery { sort: (Some(SortType::New)), community_id: (Some(data.inserted_community.id)), - local_user: (Some(&inserted_local_user)), + local_user: (Some(&data.local_user_view)), ..Default::default() } .list(pool) @@ -798,9 +843,10 @@ mod tests { assert_eq!(expected_post_with_upvote, read_post_listing[0]); - let like_removed = PostLike::remove(pool, data.inserted_person.id, data.inserted_post.id) - .await - .unwrap(); + let like_removed = + PostLike::remove(pool, data.local_user_view.person.id, data.inserted_post.id) + .await + .unwrap(); assert_eq!(1, like_removed); cleanup(data, pool).await; } @@ -818,7 +864,7 @@ mod tests { .unwrap(); let post_spanish = PostInsertForm::builder() .name("asffgdsc".to_string()) - .creator_id(data.inserted_person.id) + .creator_id(data.local_user_view.person.id) .community_id(data.inserted_community.id) .language_id(Some(spanish_id)) .build(); @@ -827,7 +873,7 @@ mod tests { let post_listings_all = PostQuery { sort: (Some(SortType::New)), - local_user: (Some(&data.inserted_local_user)), + local_user: (Some(&data.local_user_view)), ..Default::default() } .list(pool) @@ -841,13 +887,13 @@ mod tests { .await .unwrap() .unwrap(); - LocalUserLanguage::update(pool, vec![french_id], data.inserted_local_user.id) + LocalUserLanguage::update(pool, vec![french_id], data.local_user_view.local_user.id) .await .unwrap(); let post_listing_french = PostQuery { sort: (Some(SortType::New)), - local_user: (Some(&data.inserted_local_user)), + local_user: (Some(&data.local_user_view)), ..Default::default() } .list(pool) @@ -863,13 +909,13 @@ mod tests { LocalUserLanguage::update( pool, vec![french_id, UNDETERMINED_ID], - data.inserted_local_user.id, + data.local_user_view.local_user.id, ) .await .unwrap(); let post_listings_french_und = PostQuery { sort: (Some(SortType::New)), - local_user: (Some(&data.inserted_local_user)), + local_user: (Some(&data.local_user_view)), ..Default::default() } .list(pool) @@ -889,55 +935,103 @@ mod tests { #[tokio::test] #[serial] - async fn post_listings_deleted() { + async fn post_listings_removed() { let pool = &build_db_pool_for_tests().await; let pool = &mut pool.into(); - let data = init_data(pool).await; + let mut data = init_data(pool).await; - // Delete the post + // Remove the post Post::update( pool, data.inserted_post.id, - &PostUpdateForm::builder().deleted(Some(true)).build(), + &PostUpdateForm::builder().removed(Some(true)).build(), ) .await .unwrap(); - // Make sure you don't see the deleted post in the results + // Make sure you don't see the removed post in the results let post_listings_no_admin = PostQuery { - sort: (Some(SortType::New)), - local_user: (Some(&data.inserted_local_user)), - is_mod_or_admin: (Some(false)), + sort: Some(SortType::New), + local_user: Some(&data.local_user_view), ..Default::default() } .list(pool) .await .unwrap(); - assert_eq!(1, post_listings_no_admin.len()); - // Make sure they see both + // Removed post is shown to admins on profile page + data.local_user_view.person.admin = true; let post_listings_is_admin = PostQuery { - sort: (Some(SortType::New)), - local_user: (Some(&data.inserted_local_user)), - is_mod_or_admin: (Some(true)), + sort: Some(SortType::New), + local_user: Some(&data.local_user_view), + is_profile_view: Some(true), ..Default::default() } .list(pool) .await .unwrap(); - assert_eq!(2, post_listings_is_admin.len()); cleanup(data, pool).await; } + #[tokio::test] + #[serial] + async fn post_listings_deleted() { + let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); + let data = init_data(pool).await; + + // Delete the post + Post::update( + pool, + data.inserted_post.id, + &PostUpdateForm::builder().deleted(Some(true)).build(), + ) + .await + .unwrap(); + + // Make sure you don't see the deleted post in the results + let post_listings_no_creator = PostQuery { + sort: Some(SortType::New), + ..Default::default() + } + .list(pool) + .await + .unwrap(); + let not_contains_deleted = post_listings_no_creator + .iter() + .map(|p| p.post.id) + .all(|p| p != data.inserted_post.id); + assert!(not_contains_deleted); + + // Deleted post is shown to creator + let post_listings_is_creator = PostQuery { + sort: Some(SortType::New), + local_user: Some(&data.local_user_view), + ..Default::default() + } + .list(pool) + .await + .unwrap(); + let contains_deleted = post_listings_is_creator + .iter() + .map(|p| p.post.id) + .any(|p| p == data.inserted_post.id); + assert!(contains_deleted); + + cleanup(data, pool).await; + } + async fn cleanup(data: Data, pool: &mut DbPool<'_>) { let num_deleted = Post::delete(pool, data.inserted_post.id).await.unwrap(); Community::delete(pool, data.inserted_community.id) .await .unwrap(); - Person::delete(pool, data.inserted_person.id).await.unwrap(); + Person::delete(pool, data.local_user_view.person.id) + .await + .unwrap(); Person::delete(pool, data.inserted_bot.id).await.unwrap(); Person::delete(pool, data.inserted_blocked_person.id) .await @@ -950,7 +1044,7 @@ mod tests { async fn expected_post_view(data: &Data, pool: &mut DbPool<'_>) -> PostView { let (inserted_person, inserted_community, inserted_post) = ( - &data.inserted_person, + &data.local_user_view.person, &data.inserted_community, &data.inserted_post, );