mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(post transfer): publish trash with public key
This commit is contained in:
@@ -165,6 +165,31 @@ describe('PostTransferModal', () => {
|
||||
expect(options).toContainEqual({ text: TRASH_BOARD_TITLE, value: TRASH_BOARD_ADDRESS });
|
||||
});
|
||||
|
||||
it('publishes hidden trash board transfers with the board public key identity', async () => {
|
||||
await renderTransferModal();
|
||||
|
||||
const select = document.body.querySelector<HTMLSelectElement>('select');
|
||||
expect(select).not.toBeNull();
|
||||
await act(async () => {
|
||||
select!.value = TRASH_BOARD_ADDRESS;
|
||||
select!.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
});
|
||||
|
||||
const form = document.body.querySelector<HTMLFormElement>('form');
|
||||
expect(form).not.toBeNull();
|
||||
await act(async () => {
|
||||
form!.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
|
||||
await Promise.resolve();
|
||||
});
|
||||
|
||||
const [publishOptions] = testState.publishCommentMock.mock.calls[0] as [Record<string, unknown>, string];
|
||||
expect(publishOptions).toMatchObject({
|
||||
communityAddress: TRASH_BOARD_PUBLIC_KEY,
|
||||
communityPublicKey: TRASH_BOARD_PUBLIC_KEY,
|
||||
});
|
||||
expect(publishOptions).not.toHaveProperty('communityName');
|
||||
});
|
||||
|
||||
it('resolves the hidden trash board when it is the transfer source', async () => {
|
||||
await renderTransferModal({ ...baseComment, communityAddress: TRASH_BOARD_ADDRESS });
|
||||
|
||||
@@ -192,6 +217,11 @@ describe('PostTransferModal', () => {
|
||||
});
|
||||
|
||||
const [sourceModerationOptions] = testState.publishCommentModerationMock.mock.calls[1] as [{ commentModeration: { reason: string } }, string];
|
||||
expect(sourceModerationOptions).toMatchObject({
|
||||
communityAddress: TRASH_BOARD_PUBLIC_KEY,
|
||||
communityPublicKey: TRASH_BOARD_PUBLIC_KEY,
|
||||
});
|
||||
expect(sourceModerationOptions).not.toHaveProperty('communityName');
|
||||
expect(sourceModerationOptions.commentModeration.reason).toContain('/trash/');
|
||||
expect(sourceModerationOptions.commentModeration.reason).toContain('(the rules)');
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
getInitialTransferFields,
|
||||
getTargetTransferModerationFlairs,
|
||||
getTransferBoardReference,
|
||||
getTransferPublishIdentity,
|
||||
getTransferPublishPayload,
|
||||
getTransferSourceBoardReference,
|
||||
getTransferSourceBoardRulesLink,
|
||||
@@ -344,7 +345,9 @@ const PostTransferModal = ({ comment, onClose, onTransferStateChange, onTransfer
|
||||
try {
|
||||
await createAccount(temporaryAccountName);
|
||||
temporaryAccountCreated = true;
|
||||
const payload = getTransferPublishPayload(comment, selectedFields, resolvedTargetBoardAddress);
|
||||
const targetPublishIdentity = getTransferPublishIdentity(resolvedTargetBoard, resolvedTargetBoardAddress);
|
||||
const sourcePublishIdentity = sourceCommunityAddress ? getTransferPublishIdentity(sourceBoard, sourceCommunityAddress) : undefined;
|
||||
const payload = getTransferPublishPayload(comment, selectedFields, resolvedTargetBoardAddress, resolvedTargetBoard);
|
||||
await publishComment(
|
||||
{
|
||||
...payload,
|
||||
@@ -371,11 +374,14 @@ const PostTransferModal = ({ comment, onClose, onTransferStateChange, onTransfer
|
||||
if (!targetCommentCid) {
|
||||
throw new Error('Transferred post was accepted, but no target CID was returned.');
|
||||
}
|
||||
if (!sourcePublishIdentity) {
|
||||
throw new Error('Transferred post was accepted, but no source board was resolved.');
|
||||
}
|
||||
|
||||
// Queue the target marker first so a target moderation failure does not remove the original post.
|
||||
await publishCommentModeration({
|
||||
commentCid: targetCommentCid,
|
||||
communityAddress: resolvedTargetBoardAddress,
|
||||
...targetPublishIdentity,
|
||||
commentModeration: {
|
||||
flairs: getTargetTransferModerationFlairs(comment, selectedFields),
|
||||
},
|
||||
@@ -383,7 +389,7 @@ const PostTransferModal = ({ comment, onClose, onTransferStateChange, onTransfer
|
||||
});
|
||||
await publishCommentModeration({
|
||||
commentCid: sourceCommentCid,
|
||||
communityAddress: sourceCommunityAddress,
|
||||
...sourcePublishIdentity,
|
||||
commentModeration: getTransferSourceModeration(
|
||||
comment,
|
||||
getTransferBoardReference(resolvedTargetBoard, resolvedTargetBoardAddress),
|
||||
|
||||
@@ -3,13 +3,14 @@ import {
|
||||
canTransferComment,
|
||||
getTargetTransferModerationFlairs,
|
||||
getTransferPublishPayload,
|
||||
getTransferPublishIdentity,
|
||||
getTransferSourceBoardReference,
|
||||
getTransferSourceBoardRulesLink,
|
||||
getTransferSourceModeration,
|
||||
hasTransferredCommentMarker,
|
||||
TRANSFERRED_COMMENT_FLAIR,
|
||||
} from '../comment-transfer';
|
||||
import { TRASH_BOARD_ADDRESS, TRASH_BOARD_CODE, TRASH_BOARD_TITLE } from '../special-boards';
|
||||
import { TRASH_BOARD_ADDRESS, TRASH_BOARD_CODE, TRASH_BOARD_PUBLIC_KEY, TRASH_BOARD_TITLE } from '../special-boards';
|
||||
|
||||
describe('comment-transfer', () => {
|
||||
const selectedFields = {
|
||||
@@ -58,6 +59,36 @@ describe('comment-transfer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('uses the public key identity when publishing transfers to a special board', () => {
|
||||
expect(getTransferPublishIdentity({ address: 'tech-posting.eth', directoryCode: 'g' }, 'tech-posting.eth')).toEqual({
|
||||
communityAddress: 'tech-posting.eth',
|
||||
});
|
||||
expect(getTransferPublishIdentity({ address: TRASH_BOARD_ADDRESS, directoryCode: TRASH_BOARD_CODE, publicKey: TRASH_BOARD_PUBLIC_KEY }, TRASH_BOARD_ADDRESS)).toEqual(
|
||||
{
|
||||
communityAddress: TRASH_BOARD_PUBLIC_KEY,
|
||||
communityPublicKey: TRASH_BOARD_PUBLIC_KEY,
|
||||
},
|
||||
);
|
||||
|
||||
const payload = getTransferPublishPayload(
|
||||
{
|
||||
cid: 'source',
|
||||
communityAddress: 'music-posting.eth',
|
||||
content: 'wrong board',
|
||||
} as never,
|
||||
selectedFields,
|
||||
TRASH_BOARD_ADDRESS,
|
||||
{ address: TRASH_BOARD_ADDRESS, directoryCode: TRASH_BOARD_CODE, publicKey: TRASH_BOARD_PUBLIC_KEY },
|
||||
);
|
||||
|
||||
expect(payload).toMatchObject({
|
||||
communityAddress: TRASH_BOARD_PUBLIC_KEY,
|
||||
communityPublicKey: TRASH_BOARD_PUBLIC_KEY,
|
||||
content: 'wrong board',
|
||||
});
|
||||
expect(payload).not.toHaveProperty('communityName');
|
||||
});
|
||||
|
||||
it('copies selected comment body text verbatim while still ignoring blank bodies', () => {
|
||||
expect(
|
||||
getTransferPublishPayload(
|
||||
|
||||
@@ -10,9 +10,16 @@ export type PostTransferFields = Record<PostTransferField, boolean>;
|
||||
export type TransferBoardLike = {
|
||||
address?: string;
|
||||
directoryCode?: string;
|
||||
publicKey?: string;
|
||||
title?: string;
|
||||
};
|
||||
|
||||
export type TransferPublishIdentity = {
|
||||
communityAddress: string;
|
||||
communityPublicKey?: string;
|
||||
communityName?: string;
|
||||
};
|
||||
|
||||
export const TRANSFERRED_COMMENT_FLAIR_TEXT = '5chan:transferred';
|
||||
export const TRANSFERRED_COMMENT_FLAIR = { text: TRANSFERRED_COMMENT_FLAIR_TEXT } as const;
|
||||
export const TRANSFER_FIELD_KEYS: PostTransferField[] = ['displayName', 'title', 'content', 'link', 'spoiler', 'flairs'];
|
||||
@@ -63,9 +70,30 @@ export const getAvailableTransferFields = (comment: Comment): PostTransferField[
|
||||
|
||||
export const hasSelectedTransferFields = (fields: PostTransferFields, availableFields: PostTransferField[]) => availableFields.some((field) => fields[field]);
|
||||
|
||||
export const getTransferPublishPayload = (comment: Comment, fields: PostTransferFields, targetBoardAddress: string): Record<string, unknown> => {
|
||||
export const getTransferPublishIdentity = (targetBoard: TransferBoardLike | undefined, targetBoardAddress: string): TransferPublishIdentity => {
|
||||
const boardAddress = getTextField(targetBoard?.address) ?? targetBoardAddress;
|
||||
const publicKey = getTextField(targetBoard?.publicKey);
|
||||
|
||||
if (publicKey && isSpecialBoardCode(targetBoard?.directoryCode)) {
|
||||
return {
|
||||
communityAddress: publicKey,
|
||||
communityPublicKey: publicKey,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
communityAddress: boardAddress,
|
||||
};
|
||||
};
|
||||
|
||||
export const getTransferPublishPayload = (
|
||||
comment: Comment,
|
||||
fields: PostTransferFields,
|
||||
targetBoardAddress: string,
|
||||
targetBoard?: TransferBoardLike,
|
||||
): Record<string, unknown> => {
|
||||
const payload: Record<string, unknown> = {
|
||||
communityAddress: targetBoardAddress,
|
||||
...getTransferPublishIdentity(targetBoard, targetBoardAddress),
|
||||
};
|
||||
const displayName = getCommentDisplayName(comment);
|
||||
const title = getTextField(comment.title);
|
||||
|
||||
@@ -3,6 +3,7 @@ export interface SpecialBoard {
|
||||
aliases?: string[];
|
||||
directoryCode: string;
|
||||
nsfw?: boolean;
|
||||
publicKey?: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
@@ -14,14 +15,15 @@ export const TRASH_BOARD_TITLE = '/trash/ - Off-topic';
|
||||
export const SPECIAL_BOARDS: SpecialBoard[] = [
|
||||
{
|
||||
address: TRASH_BOARD_ADDRESS,
|
||||
aliases: [TRASH_BOARD_PUBLIC_KEY, 'off-topic.eth'],
|
||||
aliases: ['off-topic.eth'],
|
||||
directoryCode: TRASH_BOARD_CODE,
|
||||
nsfw: true,
|
||||
publicKey: TRASH_BOARD_PUBLIC_KEY,
|
||||
title: TRASH_BOARD_TITLE,
|
||||
},
|
||||
];
|
||||
|
||||
const getSpecialBoardLookupAddresses = (board: SpecialBoard): string[] => [board.address, ...(board.aliases ?? [])];
|
||||
const getSpecialBoardLookupAddresses = (board: SpecialBoard): string[] => [board.address, ...(board.publicKey ? [board.publicKey] : []), ...(board.aliases ?? [])];
|
||||
|
||||
export const getSpecialBoardByCode = (code: string | undefined): SpecialBoard | undefined =>
|
||||
code ? SPECIAL_BOARDS.find((board) => board.directoryCode === code) : undefined;
|
||||
|
||||
Reference in New Issue
Block a user