Add language tags for comments

This commit is contained in:
Felix Ableitner 2022-08-22 22:55:10 +02:00 committed by Dessalines
parent a6dc6804aa
commit 3d0d8796ad
14 changed files with 352 additions and 279 deletions

View file

@ -22,6 +22,10 @@
} }
], ],
"distinguished": false, "distinguished": false,
"language": {
"identifier": "fr",
"name": "Français"
},
"published": "2021-03-01T13:42:43.966208+00:00", "published": "2021-03-01T13:42:43.966208+00:00",
"updated": "2021-03-01T13:43:03.955787+00:00" "updated": "2021-03-01T13:43:03.955787+00:00"
} }

View file

@ -4,7 +4,10 @@ use crate::{
local_instance, local_instance,
mentions::collect_non_local_mentions, mentions::collect_non_local_mentions,
objects::{read_from_string_or_source, verify_is_remote_object}, objects::{read_from_string_or_source, verify_is_remote_object},
protocol::{objects::note::Note, Source}, protocol::{
objects::{note::Note, LanguageTag},
Source,
},
PostOrComment, PostOrComment,
}; };
use activitypub_federation::{ use activitypub_federation::{
@ -20,6 +23,7 @@ use lemmy_db_schema::{
source::{ source::{
comment::{Comment, CommentForm}, comment::{Comment, CommentForm},
community::Community, community::Community,
language::Language,
person::Person, person::Person,
post::Post, post::Post,
}, },
@ -105,6 +109,11 @@ impl ApubObject for ApubComment {
} else { } else {
ObjectId::<PostOrComment>::new(post.ap_id) ObjectId::<PostOrComment>::new(post.ap_id)
}; };
let language = self.language_id;
let language = blocking(context.pool(), move |conn| {
Language::read_from_id(conn, language)
})
.await??;
let maa = let maa =
collect_non_local_mentions(&self, ObjectId::new(community.actor_id), context, &mut 0).await?; collect_non_local_mentions(&self, ObjectId::new(community.actor_id), context, &mut 0).await?;
@ -122,6 +131,7 @@ impl ApubObject for ApubComment {
updated: self.updated.map(convert_datetime), updated: self.updated.map(convert_datetime),
tag: maa.tags, tag: maa.tags,
distinguished: Some(self.distinguished), distinguished: Some(self.distinguished),
language: LanguageTag::new(language),
}; };
Ok(note) Ok(note)
@ -176,6 +186,12 @@ impl ApubObject for ApubComment {
let content = read_from_string_or_source(&note.content, &note.media_type, &note.source); let content = read_from_string_or_source(&note.content, &note.media_type, &note.source);
let content_slurs_removed = remove_slurs(&content, &context.settings().slur_regex()); let content_slurs_removed = remove_slurs(&content, &context.settings().slur_regex());
let language = note.language.map(|l| l.identifier);
let language = blocking(context.pool(), move |conn| {
Language::read_id_from_code_opt(conn, language.as_deref())
})
.await??;
let form = CommentForm { let form = CommentForm {
creator_id: creator.id, creator_id: creator.id,
post_id: post.id, post_id: post.id,
@ -187,6 +203,7 @@ impl ApubObject for ApubComment {
ap_id: Some(note.id.into()), ap_id: Some(note.id.into()),
distinguished: note.distinguished, distinguished: note.distinguished,
local: Some(false), local: Some(false),
language_id: language,
}; };
let parent_comment_path = parent_comment.map(|t| t.0.path); let parent_comment_path = parent_comment.map(|t| t.0.path);
let comment = blocking(context.pool(), move |conn| { let comment = blocking(context.pool(), move |conn| {

View file

@ -4,7 +4,10 @@ use crate::{
local_instance, local_instance,
objects::{read_from_string_or_source_opt, verify_is_remote_object}, objects::{read_from_string_or_source_opt, verify_is_remote_object},
protocol::{ protocol::{
objects::page::{Attachment, AttributedTo, LanguageTag, Page, PageType}, objects::{
page::{Attachment, AttributedTo, Page, PageType},
LanguageTag,
},
ImageObject, ImageObject,
Source, Source,
}, },

View file

@ -1,3 +1,4 @@
use lemmy_db_schema::source::language::Language;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use url::Url; use url::Url;
@ -15,6 +16,27 @@ pub struct Endpoints {
pub shared_inbox: Url, pub shared_inbox: Url,
} }
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct LanguageTag {
pub(crate) identifier: String,
pub(crate) name: String,
}
impl LanguageTag {
pub(crate) fn new(lang: Language) -> Option<LanguageTag> {
// undetermined
if lang.code == "und" {
None
} else {
Some(LanguageTag {
identifier: lang.code,
name: lang.name,
})
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::protocol::{ use crate::protocol::{

View file

@ -3,7 +3,7 @@ use crate::{
local_instance, local_instance,
mentions::MentionOrValue, mentions::MentionOrValue,
objects::{comment::ApubComment, person::ApubPerson, post::ApubPost}, objects::{comment::ApubComment, person::ApubPerson, post::ApubPost},
protocol::Source, protocol::{objects::LanguageTag, Source},
}; };
use activitypub_federation::{ use activitypub_federation::{
core::object_id::ObjectId, core::object_id::ObjectId,
@ -46,6 +46,7 @@ pub struct Note {
pub(crate) tag: Vec<MentionOrValue>, pub(crate) tag: Vec<MentionOrValue>,
// lemmy extension // lemmy extension
pub(crate) distinguished: Option<bool>, pub(crate) distinguished: Option<bool>,
pub(crate) language: Option<LanguageTag>,
} }
impl Note { impl Note {

View file

@ -2,7 +2,7 @@ use crate::{
fetcher::user_or_community::{PersonOrGroupType, UserOrCommunity}, fetcher::user_or_community::{PersonOrGroupType, UserOrCommunity},
local_instance, local_instance,
objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost}, objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
protocol::{ImageObject, Source}, protocol::{objects::LanguageTag, ImageObject, Source},
}; };
use activitypub_federation::{ use activitypub_federation::{
core::object_id::ObjectId, core::object_id::ObjectId,
@ -16,7 +16,7 @@ use activitypub_federation::{
use activitystreams_kinds::{link::LinkType, object::ImageType}; use activitystreams_kinds::{link::LinkType, object::ImageType};
use chrono::{DateTime, FixedOffset}; use chrono::{DateTime, FixedOffset};
use itertools::Itertools; use itertools::Itertools;
use lemmy_db_schema::{newtypes::DbUrl, source::language::Language}; use lemmy_db_schema::newtypes::DbUrl;
use lemmy_utils::error::LemmyError; use lemmy_utils::error::LemmyError;
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -65,26 +65,6 @@ pub struct Page {
pub(crate) language: Option<LanguageTag>, pub(crate) language: Option<LanguageTag>,
} }
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct LanguageTag {
pub(crate) identifier: String,
pub(crate) name: String,
}
impl LanguageTag {
pub(crate) fn new(lang: Language) -> Option<LanguageTag> {
// undetermined
if lang.code == "und" {
None
} else {
Some(LanguageTag {
identifier: lang.code,
name: lang.name,
})
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub(crate) struct Link { pub(crate) struct Link {

View file

@ -278,6 +278,7 @@ impl DeleteableOrRemoveable for Comment {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{ use crate::{
newtypes::LanguageId,
source::{ source::{
comment::*, comment::*,
community::{Community, CommunityForm}, community::{Community, CommunityForm},
@ -343,6 +344,7 @@ mod tests {
ap_id: inserted_comment.ap_id.to_owned(), ap_id: inserted_comment.ap_id.to_owned(),
distinguished: false, distinguished: false,
local: true, local: true,
language_id: LanguageId::default(),
}; };
let child_comment_form = CommentForm { let child_comment_form = CommentForm {

View file

@ -27,6 +27,7 @@ table! {
local -> Bool, local -> Bool,
path -> Ltree, path -> Ltree,
distinguished -> Bool, distinguished -> Bool,
language_id -> Int4,
} }
} }
@ -729,6 +730,7 @@ joinable!(registration_application -> person (admin_id));
joinable!(mod_hide_community -> person (mod_person_id)); joinable!(mod_hide_community -> person (mod_person_id));
joinable!(mod_hide_community -> community (community_id)); joinable!(mod_hide_community -> community (community_id));
joinable!(post -> language (language_id)); joinable!(post -> language (language_id));
joinable!(comment -> language (language_id));
joinable!(local_user_language -> language (language_id)); joinable!(local_user_language -> language (language_id));
joinable!(local_user_language -> local_user (local_user_id)); joinable!(local_user_language -> local_user (local_user_id));

View file

@ -1,4 +1,4 @@
use crate::newtypes::{CommentId, DbUrl, LtreeDef, PersonId, PostId}; use crate::newtypes::{CommentId, DbUrl, LanguageId, LtreeDef, PersonId, PostId};
use diesel_ltree::Ltree; use diesel_ltree::Ltree;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -23,6 +23,7 @@ pub struct Comment {
#[serde(with = "LtreeDef")] #[serde(with = "LtreeDef")]
pub path: Ltree, pub path: Ltree,
pub distinguished: bool, pub distinguished: bool,
pub language_id: LanguageId,
} }
#[derive(Clone, Default)] #[derive(Clone, Default)]
@ -39,6 +40,7 @@ pub struct CommentForm {
pub ap_id: Option<DbUrl>, pub ap_id: Option<DbUrl>,
pub local: Option<bool>, pub local: Option<bool>,
pub distinguished: Option<bool>, pub distinguished: Option<bool>,
pub language_id: Option<LanguageId>,
} }
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]

View file

@ -3,18 +3,10 @@ use diesel::{dsl::*, result::Error, *};
use diesel_ltree::{nlevel, subpath, Ltree, LtreeExtensions}; use diesel_ltree::{nlevel, subpath, Ltree, LtreeExtensions};
use lemmy_db_schema::{ use lemmy_db_schema::{
aggregates::structs::CommentAggregates, aggregates::structs::CommentAggregates,
newtypes::{CommentId, CommunityId, DbUrl, PersonId, PostId}, newtypes::{CommentId, CommunityId, DbUrl, LocalUserId, PersonId, PostId},
schema::{ schema::{
comment, comment, comment_aggregates, comment_like, comment_saved, community, community_block,
comment_aggregates, community_follower, community_person_ban, language, local_user_language, person, person_block,
comment_like,
comment_saved,
community,
community_block,
community_follower,
community_person_ban,
person,
person_block,
post, post,
}, },
source::{ source::{
@ -27,8 +19,7 @@ use lemmy_db_schema::{
}, },
traits::{ToSafe, ViewToVec}, traits::{ToSafe, ViewToVec},
utils::{functions::hot_rank, fuzzy_search, limit_and_offset_unlimited}, utils::{functions::hot_rank, fuzzy_search, limit_and_offset_unlimited},
CommentSortType, CommentSortType, ListingType,
ListingType,
}; };
use typed_builder::TypedBuilder; use typed_builder::TypedBuilder;
@ -174,6 +165,7 @@ impl<'a> CommentQuery<'a> {
// The left join below will return None in this case // 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 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 mut query = comment::table let mut query = comment::table
.inner_join(person::table) .inner_join(person::table)
@ -227,6 +219,14 @@ impl<'a> CommentQuery<'a> {
.and(comment_like::person_id.eq(person_id_join)), .and(comment_like::person_id.eq(person_id_join)),
), ),
) )
.inner_join(language::table)
.left_join(
local_user_language::table.on(
post::language_id
.eq(local_user_language::language_id)
.and(local_user_language::local_user_id.eq(local_user_id_join)),
),
)
.select(( .select((
comment::all_columns, comment::all_columns,
Person::safe_columns_tuple(), Person::safe_columns_tuple(),
@ -295,8 +295,11 @@ impl<'a> CommentQuery<'a> {
query = query.filter(person::bot_account.eq(false)); query = query.filter(person::bot_account.eq(false));
}; };
// Don't show blocked communities or persons
if self.local_user.is_some() { if self.local_user.is_some() {
// Filter out the rows with missing languages
query = query.filter(local_user_language::id.is_not_null());
// Don't show blocked communities or persons
query = query.filter(community_block::person_id.is_null()); query = query.filter(community_block::person_id.is_null());
query = query.filter(person_block::person_id.is_null()); query = query.filter(person_block::person_id.is_null());
} }
@ -373,13 +376,10 @@ mod tests {
use crate::comment_view::*; use crate::comment_view::*;
use lemmy_db_schema::{ use lemmy_db_schema::{
aggregates::structs::CommentAggregates, aggregates::structs::CommentAggregates,
newtypes::LanguageId,
source::{ source::{
comment::*, comment::*, community::*, local_user::LocalUserForm, person::*,
community::*, person_block::PersonBlockForm, post::*,
local_user::LocalUserForm,
person::*,
person_block::PersonBlockForm,
post::*,
}, },
traits::{Blockable, Crud, Likeable}, traits::{Blockable, Crud, Likeable},
utils::establish_unpooled_connection, utils::establish_unpooled_connection,
@ -387,11 +387,18 @@ mod tests {
}; };
use serial_test::serial; use serial_test::serial;
#[test] struct Data {
#[serial] inserted_comment_0: Comment,
fn test_crud() { inserted_comment_1: Comment,
let conn = establish_unpooled_connection(); inserted_comment_2: Comment,
inserted_post: Post,
inserted_person: Person,
inserted_local_user: LocalUser,
inserted_person_2: Person,
inserted_community: Community,
}
fn init_data(conn: &PgConnection) -> Data {
let new_person = PersonForm { let new_person = PersonForm {
name: "timmy".into(), name: "timmy".into(),
public_key: Some("pubkey".to_string()), public_key: Some("pubkey".to_string()),
@ -510,117 +517,43 @@ mod tests {
target_id: inserted_person_2.id, target_id: inserted_person_2.id,
published: inserted_block.published, published: inserted_block.published,
}; };
assert_eq!(expected_block, inserted_block); assert_eq!(expected_block, inserted_block);
Data {
inserted_comment_0,
inserted_comment_1,
inserted_comment_2,
inserted_post,
inserted_person,
inserted_local_user,
inserted_person_2,
inserted_community,
}
}
#[test]
#[serial]
fn test_crud() {
let conn = establish_unpooled_connection();
let data = init_data(&conn);
let comment_like_form = CommentLikeForm { let comment_like_form = CommentLikeForm {
comment_id: inserted_comment_0.id, comment_id: data.inserted_comment_0.id,
post_id: inserted_post.id, post_id: data.inserted_post.id,
person_id: inserted_person.id, person_id: data.inserted_person.id,
score: 1, score: 1,
}; };
let _inserted_comment_like = CommentLike::like(&conn, &comment_like_form).unwrap(); let _inserted_comment_like = CommentLike::like(&conn, &comment_like_form).unwrap();
let agg = CommentAggregates::read(&conn, inserted_comment_0.id).unwrap(); let expected_comment_view_no_person = expected_comment_view(&data, &conn);
let top_path = inserted_comment_0.to_owned().path;
let expected_comment_view_no_person = CommentView {
creator_banned_from_community: false,
my_vote: None,
subscribed: SubscribedType::NotSubscribed,
saved: false,
creator_blocked: false,
comment: Comment {
id: inserted_comment_0.id,
content: "Comment 0".into(),
creator_id: inserted_person.id,
post_id: inserted_post.id,
removed: false,
deleted: false,
published: inserted_comment_0.published,
ap_id: inserted_comment_0.ap_id,
updated: None,
local: true,
distinguished: false,
path: top_path,
},
creator: PersonSafe {
id: inserted_person.id,
name: "timmy".into(),
display_name: None,
published: inserted_person.published,
avatar: None,
actor_id: inserted_person.actor_id.to_owned(),
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
updated: None,
inbox_url: inserted_person.inbox_url.to_owned(),
shared_inbox_url: None,
matrix_user_id: None,
ban_expires: None,
},
post: Post {
id: inserted_post.id,
name: inserted_post.name.to_owned(),
creator_id: inserted_person.id,
url: None,
body: None,
published: inserted_post.published,
updated: None,
community_id: inserted_community.id,
removed: false,
deleted: false,
locked: false,
stickied: false,
nsfw: false,
embed_title: None,
embed_description: None,
embed_video_url: None,
thumbnail_url: None,
ap_id: inserted_post.ap_id.to_owned(),
local: true,
language_id: Default::default(),
},
community: CommunitySafe {
id: inserted_community.id,
name: "test community 5".to_string(),
icon: None,
removed: false,
deleted: false,
nsfw: false,
actor_id: inserted_community.actor_id.to_owned(),
local: true,
title: "nada".to_owned(),
description: None,
updated: None,
banner: None,
hidden: false,
posting_restricted_to_mods: false,
published: inserted_community.published,
},
counts: CommentAggregates {
id: agg.id,
comment_id: inserted_comment_0.id,
score: 1,
upvotes: 1,
downvotes: 0,
published: agg.published,
child_count: 5,
},
};
let mut expected_comment_view_with_person = expected_comment_view_no_person.to_owned(); let mut expected_comment_view_with_person = expected_comment_view_no_person.to_owned();
expected_comment_view_with_person.my_vote = Some(1); expected_comment_view_with_person.my_vote = Some(1);
let read_comment_views_no_person = CommentQuery::builder() let read_comment_views_no_person = CommentQuery::builder()
.conn(&conn) .conn(&conn)
.post_id(Some(inserted_post.id)) .post_id(Some(data.inserted_post.id))
.build() .build()
.list() .list()
.unwrap(); .unwrap();
@ -632,8 +565,8 @@ mod tests {
let read_comment_views_with_person = CommentQuery::builder() let read_comment_views_with_person = CommentQuery::builder()
.conn(&conn) .conn(&conn)
.post_id(Some(inserted_post.id)) .post_id(Some(data.inserted_post.id))
.local_user(Some(&inserted_local_user)) .local_user(Some(&data.inserted_local_user))
.build() .build()
.list() .list()
.unwrap(); .unwrap();
@ -646,25 +579,38 @@ mod tests {
// Make sure its 1, not showing the blocked comment // Make sure its 1, not showing the blocked comment
assert_eq!(5, read_comment_views_with_person.len()); assert_eq!(5, read_comment_views_with_person.len());
let read_comment_from_blocked_person = let read_comment_from_blocked_person = CommentView::read(
CommentView::read(&conn, inserted_comment_1.id, Some(inserted_person.id)).unwrap(); &conn,
data.inserted_comment_1.id,
Some(data.inserted_person.id),
)
.unwrap();
// Make sure block set the creator blocked // Make sure block set the creator blocked
assert!(read_comment_from_blocked_person.creator_blocked); assert!(read_comment_from_blocked_person.creator_blocked);
let top_path = inserted_comment_0.path; cleanup(data, &conn);
}
#[test]
#[serial]
fn test_comment_tree() {
let conn = establish_unpooled_connection();
let data = init_data(&conn);
let top_path = data.inserted_comment_0.path.clone();
let read_comment_views_top_path = CommentQuery::builder() let read_comment_views_top_path = CommentQuery::builder()
.conn(&conn) .conn(&conn)
.post_id(Some(inserted_post.id)) .post_id(Some(data.inserted_post.id))
.parent_path(Some(top_path)) .parent_path(Some(top_path))
.build() .build()
.list() .list()
.unwrap(); .unwrap();
let child_path = inserted_comment_1.to_owned().path; let child_path = data.inserted_comment_1.path.clone();
let read_comment_views_child_path = CommentQuery::builder() let read_comment_views_child_path = CommentQuery::builder()
.conn(&conn) .conn(&conn)
.post_id(Some(inserted_post.id)) .post_id(Some(data.inserted_post.id))
.parent_path(Some(child_path)) .parent_path(Some(child_path))
.build() .build()
.list() .list()
@ -679,12 +625,12 @@ mod tests {
.into_iter() .into_iter()
.map(|c| c.comment) .map(|c| c.comment)
.collect::<Vec<Comment>>(); .collect::<Vec<Comment>>();
assert!(child_comments.contains(&inserted_comment_1)); assert!(child_comments.contains(&data.inserted_comment_1));
assert!(!child_comments.contains(&inserted_comment_2)); assert!(!child_comments.contains(&data.inserted_comment_2));
let read_comment_views_top_max_depth = CommentQuery::builder() let read_comment_views_top_max_depth = CommentQuery::builder()
.conn(&conn) .conn(&conn)
.post_id(Some(inserted_post.id)) .post_id(Some(data.inserted_post.id))
.max_depth(Some(1)) .max_depth(Some(1))
.build() .build()
.list() .list()
@ -692,15 +638,15 @@ mod tests {
// Make sure a depth limited one only has the top comment // Make sure a depth limited one only has the top comment
assert_eq!( assert_eq!(
expected_comment_view_no_person, expected_comment_view(&data, &conn),
read_comment_views_top_max_depth[0] read_comment_views_top_max_depth[0]
); );
assert_eq!(1, read_comment_views_top_max_depth.len()); assert_eq!(1, read_comment_views_top_max_depth.len());
let child_path = inserted_comment_1.path; let child_path = data.inserted_comment_1.path.clone();
let read_comment_views_parent_max_depth = CommentQuery::builder() let read_comment_views_parent_max_depth = CommentQuery::builder()
.conn(&conn) .conn(&conn)
.post_id(Some(inserted_post.id)) .post_id(Some(data.inserted_post.id))
.parent_path(Some(child_path)) .parent_path(Some(child_path))
.max_depth(Some(1)) .max_depth(Some(1))
.sort(Some(CommentSortType::New)) .sort(Some(CommentSortType::New))
@ -715,17 +661,110 @@ mod tests {
.eq("Comment 3")); .eq("Comment 3"));
assert_eq!(3, read_comment_views_parent_max_depth.len()); assert_eq!(3, read_comment_views_parent_max_depth.len());
// Delete everything cleanup(data, &conn);
let like_removed = }
CommentLike::remove(&conn, inserted_person.id, inserted_comment_0.id).unwrap();
let num_deleted = Comment::delete(&conn, inserted_comment_0.id).unwrap();
Comment::delete(&conn, inserted_comment_1.id).unwrap();
Post::delete(&conn, inserted_post.id).unwrap();
Community::delete(&conn, inserted_community.id).unwrap();
Person::delete(&conn, inserted_person.id).unwrap();
Person::delete(&conn, inserted_person_2.id).unwrap();
assert_eq!(1, num_deleted); fn cleanup(data: Data, conn: &PgConnection) {
assert_eq!(1, like_removed); CommentLike::remove(&conn, data.inserted_person.id, data.inserted_comment_0.id).unwrap();
Comment::delete(&conn, data.inserted_comment_0.id).unwrap();
Comment::delete(&conn, data.inserted_comment_1.id).unwrap();
Post::delete(&conn, data.inserted_post.id).unwrap();
Community::delete(&conn, data.inserted_community.id).unwrap();
Person::delete(&conn, data.inserted_person.id).unwrap();
Person::delete(&conn, data.inserted_person_2.id).unwrap();
}
fn expected_comment_view(data: &Data, conn: &PgConnection) -> CommentView {
let agg = CommentAggregates::read(&conn, data.inserted_comment_0.id).unwrap();
CommentView {
creator_banned_from_community: false,
my_vote: None,
subscribed: SubscribedType::NotSubscribed,
saved: false,
creator_blocked: false,
comment: Comment {
id: data.inserted_comment_0.id,
content: "Comment 0".into(),
creator_id: data.inserted_person.id,
post_id: data.inserted_post.id,
removed: false,
deleted: false,
published: data.inserted_comment_0.published,
ap_id: data.inserted_comment_0.ap_id.clone(),
updated: None,
local: true,
distinguished: false,
path: data.inserted_comment_0.to_owned().path,
language_id: LanguageId(0),
},
creator: PersonSafe {
id: data.inserted_person.id,
name: "timmy".into(),
display_name: None,
published: data.inserted_person.published,
avatar: None,
actor_id: data.inserted_person.actor_id.to_owned(),
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
updated: None,
inbox_url: data.inserted_person.inbox_url.to_owned(),
shared_inbox_url: None,
matrix_user_id: None,
ban_expires: None,
},
post: Post {
id: data.inserted_post.id,
name: data.inserted_post.name.to_owned(),
creator_id: data.inserted_person.id,
url: None,
body: None,
published: data.inserted_post.published,
updated: None,
community_id: data.inserted_community.id,
removed: false,
deleted: false,
locked: false,
stickied: false,
nsfw: false,
embed_title: None,
embed_description: None,
embed_video_url: None,
thumbnail_url: None,
ap_id: data.inserted_post.ap_id.to_owned(),
local: true,
language_id: Default::default(),
},
community: CommunitySafe {
id: data.inserted_community.id,
name: "test community 5".to_string(),
icon: None,
removed: false,
deleted: false,
nsfw: false,
actor_id: data.inserted_community.actor_id.to_owned(),
local: true,
title: "nada".to_owned(),
description: None,
updated: None,
banner: None,
hidden: false,
posting_restricted_to_mods: false,
published: data.inserted_community.published,
},
counts: CommentAggregates {
id: agg.id,
comment_id: data.inserted_comment_0.id,
score: 1,
upvotes: 1,
downvotes: 0,
published: agg.published,
child_count: 5,
},
}
} }
} }

View file

@ -555,109 +555,6 @@ mod tests {
} }
} }
fn cleanup(data: Data, conn: &PgConnection) {
let num_deleted = Post::delete(conn, data.inserted_post.id).unwrap();
Community::delete(conn, data.inserted_community.id).unwrap();
Person::delete(conn, data.inserted_person.id).unwrap();
Person::delete(conn, data.inserted_bot.id).unwrap();
Person::delete(conn, data.inserted_blocked_person.id).unwrap();
assert_eq!(1, num_deleted);
}
fn expected_post_listing(data: &Data, conn: &PgConnection) -> PostView {
let (inserted_person, inserted_community, inserted_post) = (
&data.inserted_person,
&data.inserted_community,
&data.inserted_post,
);
let agg = PostAggregates::read(conn, inserted_post.id).unwrap();
PostView {
post: Post {
id: inserted_post.id,
name: inserted_post.name.clone(),
creator_id: inserted_person.id,
url: None,
body: None,
published: inserted_post.published,
updated: None,
community_id: inserted_community.id,
removed: false,
deleted: false,
locked: false,
stickied: false,
nsfw: false,
embed_title: None,
embed_description: None,
embed_video_url: None,
thumbnail_url: None,
ap_id: inserted_post.ap_id.to_owned(),
local: true,
language_id: LanguageId(47),
},
my_vote: None,
creator: PersonSafe {
id: inserted_person.id,
name: inserted_person.name.clone(),
display_name: None,
published: inserted_person.published,
avatar: None,
actor_id: inserted_person.actor_id.to_owned(),
local: true,
admin: false,
bot_account: false,
banned: false,
deleted: false,
bio: None,
banner: None,
updated: None,
inbox_url: inserted_person.inbox_url.to_owned(),
shared_inbox_url: None,
matrix_user_id: None,
ban_expires: None,
},
creator_banned_from_community: false,
community: CommunitySafe {
id: inserted_community.id,
name: inserted_community.name.clone(),
icon: None,
removed: false,
deleted: false,
nsfw: false,
actor_id: inserted_community.actor_id.to_owned(),
local: true,
title: "nada".to_owned(),
description: None,
updated: None,
banner: None,
hidden: false,
posting_restricted_to_mods: false,
published: inserted_community.published,
},
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,
},
subscribed: SubscribedType::NotSubscribed,
read: false,
saved: false,
creator_blocked: false,
language: Language {
id: LanguageId(47),
code: "fr".to_string(),
name: "Français".to_string(),
},
}
}
#[test] #[test]
#[serial] #[serial]
fn post_listing_with_person() { fn post_listing_with_person() {
@ -683,7 +580,7 @@ mod tests {
let post_listing_single_with_person = let post_listing_single_with_person =
PostView::read(&conn, data.inserted_post.id, Some(data.inserted_person.id)).unwrap(); PostView::read(&conn, data.inserted_post.id, Some(data.inserted_person.id)).unwrap();
let mut expected_post_listing_with_user = expected_post_listing(&data, &conn); let mut expected_post_listing_with_user = expected_post_view(&data, &conn);
// Should be only one person, IE the bot post, and blocked should be missing // Should be only one person, IE the bot post, and blocked should be missing
assert_eq!(1, read_post_listing.len()); assert_eq!(1, read_post_listing.len());
@ -733,7 +630,7 @@ mod tests {
let read_post_listing_single_no_person = let read_post_listing_single_no_person =
PostView::read(&conn, data.inserted_post.id, None).unwrap(); PostView::read(&conn, data.inserted_post.id, None).unwrap();
let expected_post_listing_no_person = expected_post_listing(&data, &conn); let expected_post_listing_no_person = expected_post_view(&data, &conn);
// Should be 2 posts, with the bot post, and the blocked // Should be 2 posts, with the bot post, and the blocked
assert_eq!(3, read_post_listing_multiple_no_person.len()); assert_eq!(3, read_post_listing_multiple_no_person.len());
@ -879,4 +776,107 @@ mod tests {
cleanup(data, &conn); cleanup(data, &conn);
} }
fn cleanup(data: Data, conn: &PgConnection) {
let num_deleted = Post::delete(conn, data.inserted_post.id).unwrap();
Community::delete(conn, data.inserted_community.id).unwrap();
Person::delete(conn, data.inserted_person.id).unwrap();
Person::delete(conn, data.inserted_bot.id).unwrap();
Person::delete(conn, data.inserted_blocked_person.id).unwrap();
assert_eq!(1, num_deleted);
}
fn expected_post_view(data: &Data, conn: &PgConnection) -> PostView {
let (inserted_person, inserted_community, inserted_post) = (
&data.inserted_person,
&data.inserted_community,
&data.inserted_post,
);
let agg = PostAggregates::read(conn, inserted_post.id).unwrap();
PostView {
post: Post {
id: inserted_post.id,
name: inserted_post.name.clone(),
creator_id: inserted_person.id,
url: None,
body: None,
published: inserted_post.published,
updated: None,
community_id: inserted_community.id,
removed: false,
deleted: false,
locked: false,
stickied: false,
nsfw: false,
embed_title: None,
embed_description: None,
embed_video_url: None,
thumbnail_url: None,
ap_id: inserted_post.ap_id.to_owned(),
local: true,
language_id: LanguageId(47),
},
my_vote: None,
creator: PersonSafe {
id: inserted_person.id,
name: inserted_person.name.clone(),
display_name: None,
published: inserted_person.published,
avatar: None,
actor_id: inserted_person.actor_id.to_owned(),
local: true,
admin: false,
bot_account: false,
banned: false,
deleted: false,
bio: None,
banner: None,
updated: None,
inbox_url: inserted_person.inbox_url.to_owned(),
shared_inbox_url: None,
matrix_user_id: None,
ban_expires: None,
},
creator_banned_from_community: false,
community: CommunitySafe {
id: inserted_community.id,
name: inserted_community.name.clone(),
icon: None,
removed: false,
deleted: false,
nsfw: false,
actor_id: inserted_community.actor_id.to_owned(),
local: true,
title: "nada".to_owned(),
description: None,
updated: None,
banner: None,
hidden: false,
posting_restricted_to_mods: false,
published: inserted_community.published,
},
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,
},
subscribed: SubscribedType::NotSubscribed,
read: false,
saved: false,
creator_blocked: false,
language: Language {
id: LanguageId(47),
code: "fr".to_string(),
name: "Français".to_string(),
},
}
}
} }

View file

@ -12,9 +12,8 @@ create table local_user_language (
alter table local_user rename column lang to interface_language; alter table local_user rename column lang to interface_language;
alter table post add column language_id integer references language not null default 0;
insert into language(id, code, name) values (0, 'und', 'Undetermined'); insert into language(id, code, name) values (0, 'und', 'Undetermined');
alter table post add column language_id integer references language not null default 0;
insert into language(code, name) values ('aa', 'Afaraf'); insert into language(code, name) values ('aa', 'Afaraf');
insert into language(code, name) values ('ab', 'аҧсуа бызшәа'); insert into language(code, name) values ('ab', 'аҧсуа бызшәа');
insert into language(code, name) values ('ae', 'avesta'); insert into language(code, name) values ('ae', 'avesta');

View file

@ -0,0 +1 @@
alter table comment drop column language_id;

View file

@ -0,0 +1 @@
alter table comment add column language_id integer references language not null default 0;