mirror of
https://github.com/LemmyNet/lemmy
synced 2024-11-10 06:54:12 +00:00
update moderator view (#3820)
* update api tests for new moderator view * chage moderator view to be a listing type in get posts Note: Internally, the listing type is called ListingType.ModeratorView, but it's called "Moderator View" in the api endpoint * fix formatting * add support for moderator view to list comments * add api test for moderator view when listing comments * fix api test formatting * retry tests * don't filter out blocked users and communities when using moderator view * fix cargo tests failing * fix formatting * fix previous merge * Adding ModeratorView to listing_type_enums * Fixing fmt. * Adding a default to ListingType. * Upgrading to use new lemmy-js-client. --------- Co-authored-by: Nutomic <me@nutomic.com> Co-authored-by: Dessalines <dessalines@users.noreply.github.com> Co-authored-by: Dessalines <tyhou13@gmx.com>
This commit is contained in:
parent
c93bde9799
commit
384e55f0e4
12 changed files with 140 additions and 30 deletions
|
@ -19,7 +19,7 @@
|
|||
"eslint": "^8.40.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"lemmy-js-client": "0.19.0-rc.2",
|
||||
"lemmy-js-client": "0.19.0-rc.3",
|
||||
"prettier": "^3.0.0",
|
||||
"ts-jest": "^29.1.0",
|
||||
"typescript": "^5.0.4"
|
||||
|
|
|
@ -21,6 +21,8 @@ import {
|
|||
registerUser,
|
||||
API,
|
||||
getPosts,
|
||||
getComments,
|
||||
createComment,
|
||||
getCommunityByName,
|
||||
} from "./shared";
|
||||
|
||||
|
@ -245,12 +247,17 @@ test("moderator view", async () => {
|
|||
client: alpha.client,
|
||||
};
|
||||
expect(otherUser.auth).not.toBe("");
|
||||
|
||||
let otherCommunity = (await createCommunity(otherUser)).community_view;
|
||||
expect(otherCommunity.community.name).toBeDefined();
|
||||
let otherPost = (await createPost(otherUser, otherCommunity.community.id))
|
||||
.post_view;
|
||||
expect(otherPost.post.id).toBeDefined();
|
||||
|
||||
let otherComment = (await createComment(otherUser, otherPost.post.id))
|
||||
.comment_view;
|
||||
expect(otherComment.comment.id).toBeDefined();
|
||||
|
||||
// create a community and post on alpha
|
||||
let alphaCommunity = (await createCommunity(alpha)).community_view;
|
||||
expect(alphaCommunity.community.name).toBeDefined();
|
||||
|
@ -258,27 +265,56 @@ test("moderator view", async () => {
|
|||
.post_view;
|
||||
expect(alphaPost.post.id).toBeDefined();
|
||||
|
||||
let alphaComment = (await createComment(otherUser, alphaPost.post.id))
|
||||
.comment_view;
|
||||
expect(alphaComment.comment.id).toBeDefined();
|
||||
|
||||
// other user also posts on alpha's community
|
||||
let otherAlphaPost = (
|
||||
await createPost(otherUser, alphaCommunity.community.id)
|
||||
).post_view;
|
||||
expect(otherAlphaPost.post.id).toBeDefined();
|
||||
|
||||
// alpha lists posts on home page, should contain all posts that were made
|
||||
let posts = (await getPosts(alpha)).posts;
|
||||
let otherAlphaComment = (
|
||||
await createComment(otherUser, otherAlphaPost.post.id)
|
||||
).comment_view;
|
||||
expect(otherAlphaComment.comment.id).toBeDefined();
|
||||
|
||||
// alpha lists posts and comments on home page, should contain all posts that were made
|
||||
let posts = (await getPosts(alpha, "All")).posts;
|
||||
expect(posts).toBeDefined();
|
||||
let postIds = posts.map(post => post.post.id);
|
||||
|
||||
let comments = (await getComments(alpha, undefined, "All")).comments;
|
||||
expect(comments).toBeDefined();
|
||||
let commentIds = comments.map(comment => comment.comment.id);
|
||||
|
||||
expect(postIds).toContain(otherPost.post.id);
|
||||
expect(commentIds).toContain(otherComment.comment.id);
|
||||
|
||||
expect(postIds).toContain(alphaPost.post.id);
|
||||
expect(commentIds).toContain(alphaComment.comment.id);
|
||||
|
||||
expect(postIds).toContain(otherAlphaPost.post.id);
|
||||
expect(commentIds).toContain(otherAlphaComment.comment.id);
|
||||
|
||||
// in moderator view, alpha should not see otherPost, wich was posted on a community alpha doesn't moderate
|
||||
posts = (await getPosts(alpha, true)).posts;
|
||||
posts = (await getPosts(alpha, "ModeratorView")).posts;
|
||||
expect(posts).toBeDefined();
|
||||
postIds = posts.map(post => post.post.id);
|
||||
|
||||
comments = (await getComments(alpha, undefined, "ModeratorView")).comments;
|
||||
expect(comments).toBeDefined();
|
||||
commentIds = comments.map(comment => comment.comment.id);
|
||||
|
||||
expect(postIds).not.toContain(otherPost.post.id);
|
||||
expect(commentIds).not.toContain(otherComment.comment.id);
|
||||
|
||||
expect(postIds).toContain(alphaPost.post.id);
|
||||
expect(commentIds).toContain(alphaComment.comment.id);
|
||||
|
||||
expect(postIds).toContain(otherAlphaPost.post.id);
|
||||
expect(commentIds).toContain(otherAlphaComment.comment.id);
|
||||
});
|
||||
|
||||
test("Get community for different casing on domain", async () => {
|
||||
|
|
|
@ -4,7 +4,6 @@ import {
|
|||
GetUnreadCount,
|
||||
GetUnreadCountResponse,
|
||||
LemmyHttp,
|
||||
LocalUser,
|
||||
} from "lemmy-js-client";
|
||||
import { CreatePost } from "lemmy-js-client/dist/types/CreatePost";
|
||||
import { DeletePost } from "lemmy-js-client/dist/types/DeletePost";
|
||||
|
@ -69,6 +68,7 @@ import { GetPostsResponse } from "lemmy-js-client/dist/types/GetPostsResponse";
|
|||
import { GetPosts } from "lemmy-js-client/dist/types/GetPosts";
|
||||
import { GetPersonDetailsResponse } from "lemmy-js-client/dist/types/GetPersonDetailsResponse";
|
||||
import { GetPersonDetails } from "lemmy-js-client/dist/types/GetPersonDetails";
|
||||
import { ListingType } from "lemmy-js-client/dist/types/ListingType";
|
||||
|
||||
export interface API {
|
||||
client: LemmyHttp;
|
||||
|
@ -201,7 +201,9 @@ export async function setupLogins() {
|
|||
try {
|
||||
await createCommunity(alpha, "main");
|
||||
await createCommunity(beta, "main");
|
||||
} catch (_) {}
|
||||
} catch (_) {
|
||||
console.log("Communities already exist");
|
||||
}
|
||||
}
|
||||
|
||||
export async function createPost(
|
||||
|
@ -321,11 +323,12 @@ export async function getPost(
|
|||
|
||||
export async function getComments(
|
||||
api: API,
|
||||
post_id: number,
|
||||
post_id?: number,
|
||||
listingType: ListingType = "All",
|
||||
): Promise<GetCommentsResponse> {
|
||||
let form: GetComments = {
|
||||
post_id: post_id,
|
||||
type_: "All",
|
||||
type_: listingType,
|
||||
sort: "New",
|
||||
auth: api.auth,
|
||||
};
|
||||
|
@ -798,11 +801,11 @@ export async function listCommentReports(
|
|||
|
||||
export function getPosts(
|
||||
api: API,
|
||||
moderator_view = false,
|
||||
listingType?: ListingType,
|
||||
): Promise<GetPostsResponse> {
|
||||
let form: GetPosts = {
|
||||
moderator_view,
|
||||
auth: api.auth,
|
||||
type_: listingType,
|
||||
};
|
||||
return api.client.getPosts(form);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"noImplicitAny": true,
|
||||
"lib": ["es2017", "es7", "es6", "dom"],
|
||||
"outDir": "./dist",
|
||||
"target": "ES5",
|
||||
"target": "ES2015",
|
||||
"strictNullChecks": true,
|
||||
"moduleResolution": "Node"
|
||||
},
|
||||
|
|
|
@ -2174,10 +2174,10 @@ kleur@^3.0.3:
|
|||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
||||
|
||||
lemmy-js-client@0.19.0-rc.2:
|
||||
version "0.19.0-rc.2"
|
||||
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-rc.2.tgz#c3cb511b27f92538909a2b91a0f8527b1abad958"
|
||||
integrity sha512-FXuf8s7bpBVkHL/OGWDb/0aGIrJ7uv3d4Xt1h6zmNDhw6MmmuD8RXgCHiS2jqhxjAEp96Dpl1NFXbpmKpix7tQ==
|
||||
lemmy-js-client@0.19.0-rc.3:
|
||||
version "0.19.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-rc.3.tgz#1efbfd5ce492319227a41cb020fc1cf9b2e7c075"
|
||||
integrity sha512-RmibQ3+YTvqsQ89II2I29pfPmVAWiSObGAU9Nc/AGYfyvaCya7f5+TirKwHdKA2eWDWLOTnD4rm6WgcgAwvhWw==
|
||||
dependencies:
|
||||
cross-fetch "^3.1.5"
|
||||
form-data "^4.0.0"
|
||||
|
|
|
@ -77,7 +77,6 @@ pub struct GetPosts {
|
|||
pub saved_only: Option<bool>,
|
||||
pub liked_only: Option<bool>,
|
||||
pub disliked_only: Option<bool>,
|
||||
pub moderator_view: Option<bool>,
|
||||
pub auth: Option<Sensitive<String>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -43,8 +43,6 @@ pub async fn list_posts(
|
|||
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
|
||||
}
|
||||
|
||||
let moderator_view = data.moderator_view.unwrap_or_default();
|
||||
|
||||
let listing_type = Some(listing_type_with_default(
|
||||
data.type_,
|
||||
&local_site,
|
||||
|
@ -59,7 +57,6 @@ pub async fn list_posts(
|
|||
saved_only,
|
||||
liked_only,
|
||||
disliked_only,
|
||||
moderator_view,
|
||||
page,
|
||||
limit,
|
||||
..Default::default()
|
||||
|
|
|
@ -44,7 +44,9 @@ use strum_macros::{Display, EnumString};
|
|||
#[cfg(feature = "full")]
|
||||
use ts_rs::TS;
|
||||
|
||||
#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(
|
||||
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default,
|
||||
)]
|
||||
#[cfg_attr(feature = "full", derive(DbEnum, TS))]
|
||||
#[cfg_attr(
|
||||
feature = "full",
|
||||
|
@ -54,6 +56,7 @@ use ts_rs::TS;
|
|||
#[cfg_attr(feature = "full", ts(export))]
|
||||
/// The post sort types. See here for descriptions: https://join-lemmy.org/docs/en/users/03-votes-and-ranking.html
|
||||
pub enum SortType {
|
||||
#[default]
|
||||
Active,
|
||||
Hot,
|
||||
New,
|
||||
|
@ -99,7 +102,9 @@ pub enum PersonSortType {
|
|||
PostCount,
|
||||
}
|
||||
|
||||
#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(
|
||||
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default,
|
||||
)]
|
||||
#[cfg_attr(feature = "full", derive(DbEnum, TS))]
|
||||
#[cfg_attr(
|
||||
feature = "full",
|
||||
|
@ -112,9 +117,12 @@ pub enum ListingType {
|
|||
/// Content from your own site, as well as all connected / federated sites.
|
||||
All,
|
||||
/// Content from your site only.
|
||||
#[default]
|
||||
Local,
|
||||
/// Content only from communities you've subscribed to.
|
||||
Subscribed,
|
||||
/// Content that you can moderate (because you are a moderator of the community it is posted to)
|
||||
ModeratorView,
|
||||
}
|
||||
|
||||
#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
|
@ -22,6 +22,7 @@ use lemmy_db_schema::{
|
|||
community,
|
||||
community_block,
|
||||
community_follower,
|
||||
community_moderator,
|
||||
community_person_ban,
|
||||
local_user_language,
|
||||
person,
|
||||
|
@ -101,6 +102,14 @@ fn queries<'a>() -> Queries<
|
|||
.and(comment_like::person_id.eq(person_id_join)),
|
||||
),
|
||||
)
|
||||
.left_join(
|
||||
community_moderator::table.on(
|
||||
post::id
|
||||
.eq(comment::post_id)
|
||||
.and(post::community_id.eq(community_moderator::community_id))
|
||||
.and(community_moderator::person_id.eq(person_id_join)),
|
||||
),
|
||||
)
|
||||
};
|
||||
|
||||
let selection = (
|
||||
|
@ -186,6 +195,9 @@ fn queries<'a>() -> Queries<
|
|||
.or(community_follower::person_id.eq(person_id_join)),
|
||||
)
|
||||
}
|
||||
ListingType::ModeratorView => {
|
||||
query = query.filter(community_moderator::person_id.is_not_null());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +234,9 @@ fn queries<'a>() -> Queries<
|
|||
query = query.filter(person::bot_account.eq(false));
|
||||
};
|
||||
|
||||
if options.local_user.is_some() {
|
||||
if options.local_user.is_some()
|
||||
&& options.listing_type.unwrap_or_default() != ListingType::ModeratorView
|
||||
{
|
||||
// Filter out the rows with missing languages
|
||||
query = query.filter(local_user_language::language_id.is_not_null());
|
||||
|
||||
|
|
|
@ -258,6 +258,9 @@ fn queries<'a>() -> Queries<
|
|||
.or(community_follower::person_id.eq(person_id_join)),
|
||||
)
|
||||
}
|
||||
ListingType::ModeratorView => {
|
||||
query = query.filter(community_moderator::person_id.is_not_null());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,10 +298,6 @@ fn queries<'a>() -> Queries<
|
|||
if options.saved_only {
|
||||
query = query.filter(post_saved::id.is_not_null());
|
||||
}
|
||||
|
||||
if options.moderator_view {
|
||||
query = query.filter(community_moderator::person_id.is_not_null());
|
||||
}
|
||||
// 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 !options
|
||||
|
@ -318,16 +317,17 @@ fn queries<'a>() -> Queries<
|
|||
query = query.filter(post_like::score.eq(-1));
|
||||
}
|
||||
|
||||
if options.local_user.is_some() {
|
||||
// Dont filter blocks or missing languages for moderator view type
|
||||
if options.local_user.is_some()
|
||||
&& options.listing_type.unwrap_or_default() != ListingType::ModeratorView
|
||||
{
|
||||
// Filter out the rows with missing languages
|
||||
query = query.filter(local_user_language::language_id.is_not_null());
|
||||
|
||||
// Don't show blocked communities or persons
|
||||
query = query.filter(community_block::person_id.is_null());
|
||||
if !options.moderator_view {
|
||||
query = query.filter(person_block::person_id.is_null());
|
||||
}
|
||||
}
|
||||
let now = diesel::dsl::now.into_sql::<Timestamptz>();
|
||||
|
||||
query = match options.sort.unwrap_or(SortType::Hot) {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
ALTER TABLE local_user
|
||||
ALTER default_listing_type DROP DEFAULT;
|
||||
|
||||
ALTER TABLE local_site
|
||||
ALTER default_post_listing_type DROP DEFAULT;
|
||||
|
||||
UPDATE
|
||||
local_user
|
||||
SET
|
||||
default_listing_type = 'Local'
|
||||
WHERE
|
||||
default_listing_type = 'ModeratorView';
|
||||
|
||||
UPDATE
|
||||
local_site
|
||||
SET
|
||||
default_post_listing_type = 'Local'
|
||||
WHERE
|
||||
default_post_listing_type = 'ModeratorView';
|
||||
|
||||
-- rename the old enum
|
||||
ALTER TYPE listing_type_enum RENAME TO listing_type_enum__;
|
||||
|
||||
-- create the new enum
|
||||
CREATE TYPE listing_type_enum AS ENUM (
|
||||
'All',
|
||||
'Local',
|
||||
'Subscribed'
|
||||
);
|
||||
|
||||
-- alter all your enum columns
|
||||
ALTER TABLE local_user
|
||||
ALTER COLUMN default_listing_type TYPE listing_type_enum
|
||||
USING default_listing_type::text::listing_type_enum;
|
||||
|
||||
ALTER TABLE local_site
|
||||
ALTER COLUMN default_post_listing_type TYPE listing_type_enum
|
||||
USING default_post_listing_type::text::listing_type_enum;
|
||||
|
||||
-- Add back in the default
|
||||
ALTER TABLE local_user
|
||||
ALTER default_listing_type SET DEFAULT 'Local';
|
||||
|
||||
ALTER TABLE local_site
|
||||
ALTER default_post_listing_type SET DEFAULT 'Local';
|
||||
|
||||
-- drop the old enum
|
||||
DROP TYPE listing_type_enum__;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
-- Update the listing_type_enum
|
||||
ALTER TYPE listing_type_enum
|
||||
ADD VALUE 'ModeratorView';
|
||||
|
Loading…
Reference in a new issue