Adding tests for person, post, and community.

This commit is contained in:
Dessalines 2024-12-18 22:57:59 -05:00
parent 389083418c
commit 48283a1ed9
2 changed files with 234 additions and 35 deletions

View file

@ -150,7 +150,7 @@ impl SearchCombinedQuery {
// The post // The post
.left_join(post::table.on(post_join)) .left_join(post::table.on(post_join))
// The item creator // The item creator
.inner_join(person::table.on(item_creator_join)) .left_join(person::table.on(item_creator_join))
// The community // The community
.left_join(community::table.on(community_join)) .left_join(community::table.on(community_join))
.left_join(actions_alias( .left_join(actions_alias(
@ -176,7 +176,7 @@ impl SearchCombinedQuery {
person_aggregates::table person_aggregates::table
.on(search_combined::person_id.eq(person_aggregates::person_id.nullable())), .on(search_combined::person_id.eq(person_aggregates::person_id.nullable())),
) )
.inner_join(post_aggregates::table.on(post::id.eq(post_aggregates::post_id))) .left_join(post_aggregates::table.on(post::id.eq(post_aggregates::post_id)))
.left_join( .left_join(
comment_aggregates::table comment_aggregates::table
.on(search_combined::comment_id.eq(comment_aggregates::comment_id.nullable())), .on(search_combined::comment_id.eq(comment_aggregates::comment_id.nullable())),
@ -214,7 +214,7 @@ impl SearchCombinedQuery {
// Person // Person
person_aggregates::all_columns.nullable(), person_aggregates::all_columns.nullable(),
// // Shared // // Shared
person::all_columns, person::all_columns.nullable(),
local_user::admin.nullable().is_not_null(), local_user::admin.nullable().is_not_null(),
creator_community_actions creator_community_actions
.field(community_actions::became_moderator) .field(community_actions::became_moderator)
@ -311,11 +311,21 @@ impl SearchCombinedQuery {
match self.listing_type.unwrap_or_default() { match self.listing_type.unwrap_or_default() {
ListingType::Subscribed => query = query.filter(is_subscribed), ListingType::Subscribed => query = query.filter(is_subscribed),
ListingType::Local => { ListingType::Local => {
query = query query = query.filter(
.filter(community::local.eq(true)) community::local
.filter(community::hidden.eq(false).or(is_subscribed)); .eq(true)
.and(community::hidden.eq(false).or(is_subscribed))
.or(search_combined::person_id.is_not_null().and(person::local)),
);
}
ListingType::All => {
query = query.filter(
community::hidden
.eq(false)
.or(is_subscribed)
.or(search_combined::person_id.is_not_null()),
)
} }
ListingType::All => query = query.filter(community::hidden.eq(false).or(is_subscribed)),
ListingType::ModeratorView => { ListingType::ModeratorView => {
query = query.filter(community_actions::became_moderator.is_not_null()); query = query.filter(community_actions::became_moderator.is_not_null());
} }
@ -325,14 +335,14 @@ impl SearchCombinedQuery {
// TODO need null checks for this? // TODO need null checks for this?
query = query.filter(not( query = query.filter(not(
comment::removed comment::removed
.or(comment::deleted) .and(comment::deleted)
.or(post::removed) .and(post::removed)
.or(post::deleted) .and(post::deleted)
.or(community::removed) .and(community::removed)
.or(community::deleted) .and(community::deleted)
.or(community::removed) .and(community::removed)
.or(community::deleted) .and(community::deleted)
.or(person::deleted), .and(person::deleted),
)); ));
let mut query = PaginatedQueryBuilder::new(query); let mut query = PaginatedQueryBuilder::new(query);
@ -367,9 +377,10 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
// Use for a short alias // Use for a short alias
let v = self.clone(); let v = self.clone();
if let (Some(post), Some(counts), Some(community), Some(unread_comments)) = ( if let (Some(post), Some(counts), Some(creator), Some(community), Some(unread_comments)) = (
v.post.clone(), v.post.clone(),
v.post_counts, v.post_counts,
v.item_creator.clone(),
v.community.clone(), v.community.clone(),
v.post_unread_comments, v.post_unread_comments,
) { ) {
@ -378,7 +389,7 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
community, community,
counts, counts,
unread_comments, unread_comments,
creator: v.item_creator, creator,
creator_banned_from_community: v.item_creator_banned_from_community, creator_banned_from_community: v.item_creator_banned_from_community,
creator_is_moderator: v.item_creator_is_moderator, creator_is_moderator: v.item_creator_is_moderator,
creator_is_admin: v.item_creator_is_admin, creator_is_admin: v.item_creator_is_admin,
@ -391,15 +402,19 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
image_details: v.image_details, image_details: v.image_details,
banned_from_community: v.banned_from_community, banned_from_community: v.banned_from_community,
})) }))
} else if let (Some(comment), Some(counts), Some(post), Some(community)) = } else if let (Some(comment), Some(counts), Some(creator), Some(post), Some(community)) = (
(v.comment, v.comment_counts, v.post, v.community.clone()) v.comment,
{ v.comment_counts,
v.item_creator.clone(),
v.post,
v.community.clone(),
) {
Some(SearchCombinedView::Comment(CommentView { Some(SearchCombinedView::Comment(CommentView {
comment, comment,
counts, counts,
post, post,
community, community,
creator: v.item_creator, creator,
creator_banned_from_community: v.item_creator_banned_from_community, creator_banned_from_community: v.item_creator_banned_from_community,
creator_is_moderator: v.item_creator_is_moderator, creator_is_moderator: v.item_creator_is_moderator,
creator_is_admin: v.item_creator_is_admin, creator_is_admin: v.item_creator_is_admin,
@ -417,9 +432,9 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
blocked: v.community_blocked, blocked: v.community_blocked,
banned_from_community: v.banned_from_community, banned_from_community: v.banned_from_community,
})) }))
} else if let Some(counts) = v.item_creator_counts { } else if let (Some(person), Some(counts)) = (v.item_creator, v.item_creator_counts) {
Some(SearchCombinedView::Person(PersonView { Some(SearchCombinedView::Person(PersonView {
person: v.item_creator, person,
counts, counts,
is_admin: v.item_creator_is_admin, is_admin: v.item_creator_is_admin,
})) }))
@ -445,10 +460,12 @@ mod tests {
}, },
traits::Crud, traits::Crud,
utils::{build_db_pool_for_tests, DbPool}, utils::{build_db_pool_for_tests, DbPool},
SearchType,
}; };
use lemmy_utils::error::LemmyResult; use lemmy_utils::error::LemmyResult;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use serial_test::serial; use serial_test::serial;
use url::Url;
struct Data { struct Data {
instance: Instance, instance: Instance,
@ -473,12 +490,15 @@ mod tests {
let sara_form = PersonInsertForm::test_form(instance.id, "sara_pcv"); let sara_form = PersonInsertForm::test_form(instance.id, "sara_pcv");
let sara = Person::create(pool, &sara_form).await?; let sara = Person::create(pool, &sara_form).await?;
let community_form = CommunityInsertForm::new( let community_form = CommunityInsertForm {
description: Some("ask lemmy things".into()),
..CommunityInsertForm::new(
instance.id, instance.id,
"asklemmy".to_string(), "asklemmy".to_string(),
"Ask Lemmy".to_owned(), "Ask Lemmy".to_owned(),
"pubkey".to_string(), "pubkey".to_string(),
); )
};
let community = Community::create(pool, &community_form).await?; let community = Community::create(pool, &community_form).await?;
let community_form_2 = CommunityInsertForm::new( let community_form_2 = CommunityInsertForm::new(
@ -489,13 +509,17 @@ mod tests {
); );
let community_2 = Community::create(pool, &community_form_2).await?; let community_2 = Community::create(pool, &community_form_2).await?;
let timmy_post_form = PostInsertForm::new("timmy post prv".into(), timmy.id, community.id); let timmy_post_form = PostInsertForm {
body: Some("postbody inside here".into()),
url: Some(Url::parse("https://google.com")?.into()),
..PostInsertForm::new("timmy post prv".into(), timmy.id, community.id)
};
let timmy_post = Post::create(pool, &timmy_post_form).await?; let timmy_post = Post::create(pool, &timmy_post_form).await?;
let timmy_post_form_2 = PostInsertForm::new("timmy post prv 2".into(), timmy.id, community.id); let timmy_post_form_2 = PostInsertForm::new("timmy post prv 2".into(), timmy.id, community.id);
let timmy_post_2 = Post::create(pool, &timmy_post_form_2).await?; let timmy_post_2 = Post::create(pool, &timmy_post_form_2).await?;
let sara_post_form = PostInsertForm::new("sara post prv".into(), sara.id, community.id); let sara_post_form = PostInsertForm::new("sara post prv".into(), sara.id, community_2.id);
let sara_post = Post::create(pool, &sara_post_form).await?; let sara_post = Post::create(pool, &sara_post_form).await?;
let timmy_comment_form = let timmy_comment_form =
@ -533,13 +557,18 @@ mod tests {
#[tokio::test] #[tokio::test]
#[serial] #[serial]
async fn community_search() -> LemmyResult<()> { async fn community() -> LemmyResult<()> {
let pool = &build_db_pool_for_tests(); let pool = &build_db_pool_for_tests();
let pool = &mut pool.into(); let pool = &mut pool.into();
let data = init_data(pool).await?; let data = init_data(pool).await?;
// Community search // Community search
let community_search = SearchCombinedQuery::default().list(pool, &None).await?; let community_search = SearchCombinedQuery {
type_: Some(SearchType::Communities),
..Default::default()
}
.list(pool, &None)
.await?;
assert_length!(2, community_search); assert_length!(2, community_search);
// Make sure the types are correct // Make sure the types are correct
@ -558,6 +587,7 @@ mod tests {
// Filtered by id // Filtered by id
let community_search_by_id = SearchCombinedQuery { let community_search_by_id = SearchCombinedQuery {
community_id: Some(data.community.id), community_id: Some(data.community.id),
type_: Some(SearchType::Communities),
..Default::default() ..Default::default()
} }
.list(pool, &None) .list(pool, &None)
@ -566,7 +596,8 @@ mod tests {
// Using a term // Using a term
let community_search_by_name = SearchCombinedQuery { let community_search_by_name = SearchCombinedQuery {
search_term: Some("Ask".into()), search_term: Some("things".into()),
type_: Some(SearchType::Communities),
..Default::default() ..Default::default()
} }
.list(pool, &None) .list(pool, &None)
@ -580,6 +611,174 @@ mod tests {
panic!("wrong type"); panic!("wrong type");
} }
// Test title only search to make sure 'ask lemmy things' doesn't get returned
// Using a term
let community_search_title_only = SearchCombinedQuery {
search_term: Some("things".into()),
type_: Some(SearchType::Communities),
title_only: Some(true),
..Default::default()
}
.list(pool, &None)
.await?;
assert!(community_search_title_only.is_empty());
cleanup(data, pool).await?;
Ok(())
}
#[tokio::test]
#[serial]
async fn person() -> LemmyResult<()> {
let pool = &build_db_pool_for_tests();
let pool = &mut pool.into();
let data = init_data(pool).await?;
// Person search
let person_search = SearchCombinedQuery {
type_: Some(SearchType::Users),
..Default::default()
}
.list(pool, &None)
.await?;
assert_length!(2, person_search);
// Make sure the types are correct
if let SearchCombinedView::Person(v) = &person_search[0] {
assert_eq!(data.sara.id, v.person.id);
} else {
panic!("wrong type");
}
if let SearchCombinedView::Person(v) = &person_search[1] {
assert_eq!(data.timmy.id, v.person.id);
} else {
panic!("wrong type");
}
// Filtered by creator_id
let person_search_by_id = SearchCombinedQuery {
creator_id: Some(data.sara.id),
type_: Some(SearchType::Users),
..Default::default()
}
.list(pool, &None)
.await?;
assert_length!(1, person_search_by_id);
if let SearchCombinedView::Person(v) = &person_search_by_id[0] {
assert_eq!(data.sara.id, v.person.id);
} else {
panic!("wrong type");
}
// Using a term
let person_search_by_name = SearchCombinedQuery {
search_term: Some("tim".into()),
type_: Some(SearchType::Users),
..Default::default()
}
.list(pool, &None)
.await?;
assert_length!(1, person_search_by_name);
if let SearchCombinedView::Person(v) = &person_search_by_name[0] {
assert_eq!(data.timmy.id, v.person.id);
} else {
panic!("wrong type");
}
cleanup(data, pool).await?;
Ok(())
}
#[tokio::test]
#[serial]
async fn post() -> LemmyResult<()> {
let pool = &build_db_pool_for_tests();
let pool = &mut pool.into();
let data = init_data(pool).await?;
// post search
let post_search = SearchCombinedQuery {
type_: Some(SearchType::Posts),
..Default::default()
}
.list(pool, &None)
.await?;
assert_length!(3, post_search);
// Make sure the types are correct
if let SearchCombinedView::Post(v) = &post_search[0] {
assert_eq!(data.sara_post.id, v.post.id);
assert_eq!(data.community_2.id, v.community.id);
} else {
panic!("wrong type");
}
if let SearchCombinedView::Post(v) = &post_search[1] {
assert_eq!(data.timmy_post_2.id, v.post.id);
assert_eq!(data.community.id, v.community.id);
} else {
panic!("wrong type");
}
if let SearchCombinedView::Post(v) = &post_search[2] {
assert_eq!(data.timmy_post.id, v.post.id);
assert_eq!(data.community.id, v.community.id);
} else {
panic!("wrong type");
}
// Filtered by id
let post_search_by_community = SearchCombinedQuery {
community_id: Some(data.community.id),
type_: Some(SearchType::Posts),
..Default::default()
}
.list(pool, &None)
.await?;
assert_length!(2, post_search_by_community);
// Using a term
let post_search_by_name = SearchCombinedQuery {
search_term: Some("sara".into()),
type_: Some(SearchType::Posts),
..Default::default()
}
.list(pool, &None)
.await?;
assert_length!(1, post_search_by_name);
// Test title only search to make sure 'postbody' doesn't show up
// Using a term
let post_search_title_only = SearchCombinedQuery {
search_term: Some("postbody".into()),
type_: Some(SearchType::Posts),
title_only: Some(true),
..Default::default()
}
.list(pool, &None)
.await?;
assert!(post_search_title_only.is_empty());
// Test title only search to make sure 'postbody' doesn't show up
// Using a term
let post_search_url_only = SearchCombinedQuery {
search_term: data.timmy_post.url.as_ref().map(|u| u.to_string()),
type_: Some(SearchType::Posts),
post_url_only: Some(true),
..Default::default()
}
.list(pool, &None)
.await?;
assert_length!(1, post_search_url_only);
cleanup(data, pool).await?; cleanup(data, pool).await?;
Ok(()) Ok(())

View file

@ -932,7 +932,7 @@ pub struct SearchCombinedViewInternal {
// Person // Person
pub item_creator_counts: Option<PersonAggregates>, pub item_creator_counts: Option<PersonAggregates>,
// Shared // Shared
pub item_creator: Person, pub item_creator: Option<Person>,
pub item_creator_is_admin: bool, pub item_creator_is_admin: bool,
pub item_creator_is_moderator: bool, pub item_creator_is_moderator: bool,
pub item_creator_banned_from_community: bool, pub item_creator_banned_from_community: bool,