Files
5chan/src/lib/__tests__/comment-transfer.test.ts
T

150 lines
6.0 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
canMoveCommentToTrash,
canTransferComment,
getTargetTransferModerationFlairs,
getTransferPublishPayload,
getTransferSourceBoardReference,
getTransferSourceBoardRulesLink,
getTransferSourceModeration,
hasTransferredCommentMarker,
TRANSFERRED_COMMENT_FLAIR,
} from '../comment-transfer';
import { TRASH_BOARD_ADDRESS, TRASH_BOARD_CODE, TRASH_BOARD_PUBLIC_KEY, TRASH_BOARD_TITLE } from '../special-boards';
describe('comment-transfer', () => {
const selectedFields = {
displayName: false,
title: true,
content: true,
link: true,
spoiler: true,
flairs: true,
};
it('only allows available top-level posts to transfer', () => {
expect(canTransferComment({ cid: 'source' } as never)).toBe(true);
expect(canTransferComment({ cid: 'reply', parentCid: 'source' } as never)).toBe(false);
expect(canTransferComment({ cid: '' } as never)).toBe(false);
expect(canTransferComment({ cid: 'source', deleted: true } as never)).toBe(false);
expect(canTransferComment({ cid: 'source', removed: true } as never)).toBe(false);
expect(canTransferComment({ cid: 'source', commentModeration: { removed: true } } as never)).toBe(false);
expect(canTransferComment({ cid: 'source', commentModeration: { purged: true } } as never)).toBe(false);
expect(canTransferComment({ cid: 'source', archived: true } as never)).toBe(false);
expect(canTransferComment({ cid: 'source', commentModeration: { archived: true } } as never)).toBe(false);
});
it('only allows movable posts outside the trash board to move to trash', () => {
expect(canMoveCommentToTrash({ cid: 'source', communityAddress: 'music-posting.eth' } as never)).toBe(true);
expect(canMoveCommentToTrash({ cid: 'source', communityAddress: TRASH_BOARD_ADDRESS } as never)).toBe(false);
expect(canMoveCommentToTrash({ cid: 'source', communityAddress: TRASH_BOARD_PUBLIC_KEY } as never)).toBe(false);
expect(canMoveCommentToTrash({ cid: 'reply', parentCid: 'source', communityAddress: 'music-posting.eth' } as never)).toBe(false);
});
it('copies selected post fields while excluding flag and transferred flairs', () => {
const payload = getTransferPublishPayload(
{
cid: 'source',
communityAddress: 'music-posting.eth',
content: 'wrong board',
flairs: [{ text: 'flag:country:auto', type: 'country' }, { text: 'flash:loop' }, TRANSFERRED_COMMENT_FLAIR],
link: 'https://example.com/file.swf',
spoiler: true,
title: 'Flash',
} as never,
selectedFields,
'flash-posting.eth',
);
expect(payload).toMatchObject({
communityAddress: 'flash-posting.eth',
content: 'wrong board',
flairs: [{ text: 'flash:loop' }],
link: 'https://example.com/file.swf',
spoiler: true,
title: 'Flash',
});
});
it('copies selected comment body text verbatim while still ignoring blank bodies', () => {
expect(
getTransferPublishPayload(
{
cid: 'source',
communityAddress: 'music-posting.eth',
content: '\n wrong board \n',
} as never,
selectedFields,
'tech-posting.eth',
),
).toMatchObject({
communityAddress: 'tech-posting.eth',
content: '\n wrong board \n',
});
expect(
getTransferPublishPayload(
{
cid: 'source',
communityAddress: 'music-posting.eth',
content: ' ',
} as never,
selectedFields,
'tech-posting.eth',
),
).not.toHaveProperty('content');
});
it('adds the transferred marker to target moderation flairs after safe copied tags', () => {
const flairs = getTargetTransferModerationFlairs(
{
cid: 'source',
flairs: [{ text: 'flag:country:US' }, { text: 'flash:loop' }],
} as never,
selectedFields,
);
expect(flairs).toEqual([{ text: 'flash:loop' }, { text: '5chan:transferred' }]);
});
it('marks pending source comments as rejected and published source comments as removed', () => {
expect(getTransferSourceModeration({ pendingApproval: true } as never, '>>>/g/', '/mu/', '[rules](/rules#mu)')).toEqual({
approved: false,
reason: 'Moved to >>>/g/, this post did not belong to /mu/ ([rules](/rules#mu))',
});
expect(getTransferSourceModeration({ pendingApproval: false } as never, '>>>/g/', '/mu/', '[rules](/rules#mu)')).toEqual({
removed: true,
reason: 'Moved to >>>/g/, this post did not belong to /mu/ ([rules](/rules#mu))',
});
});
it('formats source board references and rules links from directory metadata', () => {
expect(getTransferSourceBoardReference({ address: 'japanese-culture.eth', directoryCode: 'jp', title: '/jp/ - Otaku Culture' }, 'fallback.eth')).toBe('/jp/');
expect(getTransferSourceBoardRulesLink({ address: 'japanese-culture.eth', directoryCode: 'jp', title: '/jp/ - Otaku Culture' })).toBe('[rules](/rules#jp)');
expect(getTransferSourceBoardReference({ address: TRASH_BOARD_ADDRESS, directoryCode: TRASH_BOARD_CODE, title: TRASH_BOARD_TITLE }, 'fallback.eth')).toBe('/trash/');
expect(getTransferSourceBoardRulesLink({ address: TRASH_BOARD_ADDRESS, directoryCode: TRASH_BOARD_CODE, title: TRASH_BOARD_TITLE })).toBe('the rules');
expect(getTransferSourceBoardReference(undefined, 'source-board.eth')).toBe('source-board.eth');
expect(getTransferSourceBoardRulesLink(undefined)).toBe('the rules');
});
it('only treats moderation/update flairs as the transferred marker', () => {
expect(hasTransferredCommentMarker({ flairs: [{ text: '5chan:transferred' }] })).toBe(false);
expect(
hasTransferredCommentMarker({
raw: {
commentUpdate: {
flairs: [{ text: '5chan:transferred' }],
},
},
}),
).toBe(true);
expect(
hasTransferredCommentMarker({
commentModeration: {
flairs: [{ text: '5chan:transferred' }],
},
}),
).toBe(true);
});
});