Merge branch 'master' of github.com:bitsocialnet/5chan

# Conflicts:
#	public/translations/ar/default.json
#	public/translations/bn/default.json
#	public/translations/cs/default.json
#	public/translations/da/default.json
#	public/translations/de/default.json
#	public/translations/el/default.json
#	public/translations/en/default.json
#	public/translations/es/default.json
#	public/translations/fa/default.json
#	public/translations/fi/default.json
#	public/translations/fil/default.json
#	public/translations/fr/default.json
#	public/translations/he/default.json
#	public/translations/hi/default.json
#	public/translations/hu/default.json
#	public/translations/id/default.json
#	public/translations/it/default.json
#	public/translations/ja/default.json
#	public/translations/ko/default.json
#	public/translations/mr/default.json
#	public/translations/nl/default.json
#	public/translations/no/default.json
#	public/translations/pl/default.json
#	public/translations/pt/default.json
#	public/translations/ro/default.json
#	public/translations/ru/default.json
#	public/translations/sq/default.json
#	public/translations/sv/default.json
#	public/translations/te/default.json
#	public/translations/th/default.json
#	public/translations/tr/default.json
#	public/translations/uk/default.json
#	public/translations/ur/default.json
#	public/translations/vi/default.json
#	public/translations/zh/default.json
This commit is contained in:
Tommaso Casaburi
2026-05-24 23:18:28 +07:00
66 changed files with 1293 additions and 74 deletions
@@ -20,7 +20,7 @@ const testState = vi.hoisted(() => ({
directories: [
{ address: 'music-posting.eth', features: {}, title: '/mu/ - Music' },
{ address: 'mod.eth', features: {}, title: '/mod/ - Moderation' },
] as Array<{ address: string; features?: Record<string, unknown>; title?: string }>,
] as Array<{ address: string; directoryCode?: string; features?: Record<string, unknown>; title?: string }>,
editedComment: undefined as { commentModeration?: { archived?: boolean }; deleted?: boolean; locked?: boolean; postCid?: string; removed?: boolean } | undefined,
gifFrameStatus: 'idle' as 'idle' | 'ready',
handleUploadMock: vi.fn(),
@@ -426,6 +426,7 @@ describe('PostForm', () => {
testState.comments = {};
testState.directories = [
{ address: 'music-posting.eth', features: {}, title: '/mu/ - Music' },
{ address: 'politically-incorrect.bso', directoryCode: 'pol', features: { hasFlags: true }, title: '/pol/ - Politically Incorrect' },
{ address: 'random-nsfw.bso', features: {}, title: '/b/ - Random' },
{ address: 'silly-stuff.bso', features: {}, title: '/s5s/ - Silly Stuff' },
{ address: 'traditional-games.bso', features: {}, title: '/tg/ - Traditional Games' },
@@ -606,6 +607,59 @@ describe('PostForm', () => {
expect(testState.publishedPostOptions?.content).toBeUndefined();
});
it('shows a 4chan-style flag field on flag boards and publishes the default geographic request', async () => {
testState.resolvedCommunityAddress = 'politically-incorrect.bso';
await renderPostForm('/pol');
await clickByText(container, 'start_new_thread');
const table = container.querySelector('table');
const flagSelect = table?.querySelector<HTMLSelectElement>('select[aria-label="flag"]');
const textarea = table?.querySelector<HTMLTextAreaElement>('textarea');
expect(flagSelect).toBeTruthy();
expect(flagSelect?.value).toBe('country:auto');
expect(
Array.from(flagSelect?.options || [])
.slice(0, 4)
.map((option) => option.textContent),
).toEqual(['Geographic Location', 'Anarcho-Capitalist', 'Anarchist', 'Black Nationalist']);
await dispatchInput(textarea as HTMLTextAreaElement, 'flagged post');
await clickByText(table as HTMLTableElement, 'post');
expect(testState.publishPostMock).toHaveBeenCalledWith({
content: 'flagged post',
challengeRequest: {
challengeAnswers: ['bitsocial-flags:5chan:flag:country:auto'],
},
flairs: [{ type: 'country', code: 'auto', text: 'flag:country:auto' }],
});
});
it('publishes selected political flags from the post form', async () => {
testState.resolvedCommunityAddress = 'politically-incorrect.bso';
await renderPostForm('/pol');
await clickByText(container, 'start_new_thread');
const table = container.querySelector('table');
const flagSelect = table?.querySelector<HTMLSelectElement>('select[aria-label="flag"]');
const textarea = table?.querySelector<HTMLTextAreaElement>('textarea');
await dispatchChange(flagSelect as HTMLSelectElement, 'pol:AC');
await dispatchInput(textarea as HTMLTextAreaElement, 'memeflag post');
await clickByText(table as HTMLTableElement, 'post');
expect(testState.publishPostMock).toHaveBeenCalledWith({
content: 'memeflag post',
challengeRequest: {
challengeAnswers: ['bitsocial-flags:5chan:flag:pol:AC'],
},
flairs: [{ type: 'pol', code: 'AC', text: 'flag:pol:AC' }],
});
});
it('validates unsupported options and stores fortune output in post content', async () => {
const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.25);
testState.resolvedCommunityAddress = 'random-nsfw.bso';