mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
feat(admin): require a resolution and fix panel layout and copy (#3335)
This commit is contained in:
1 parent
4db13b0375
commit
6534ee4300
57 files changed
+1186
-255
No files matched your search
@@ -31,6 +31,9 @@ export function mapGuildToAdminResponse(guild: Guild, ownerUser?: User | null):
|
||||
banner: guild.bannerHash,
|
||||
member_count: guild.memberCount,
|
||||
nsfw_level: guild.nsfwLevel,
|
||||
nsfw: guild.nsfw,
|
||||
content_warning_level: guild.contentWarningLevel as 0 | 1,
|
||||
content_warning_text: guild.contentWarningText,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -48,6 +51,9 @@ export function mapGuildsToAdminResponse(guilds: Array<Guild>, ownerMap?: Map<st
|
||||
banner: guild.bannerHash,
|
||||
member_count: guild.memberCount,
|
||||
nsfw_level: guild.nsfwLevel,
|
||||
nsfw: guild.nsfw,
|
||||
content_warning_level: guild.contentWarningLevel as 0 | 1,
|
||||
content_warning_text: guild.contentWarningText,
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -60,6 +60,9 @@ export class AdminGuildLookupService {
|
||||
verification_level: guild.verificationLevel,
|
||||
mfa_level: guild.mfaLevel,
|
||||
nsfw_level: guild.nsfwLevel,
|
||||
nsfw: guild.nsfw,
|
||||
content_warning_level: guild.contentWarningLevel as 0 | 1,
|
||||
content_warning_text: guild.contentWarningText,
|
||||
explicit_content_filter: guild.explicitContentFilter,
|
||||
default_message_notifications: guild.defaultMessageNotifications,
|
||||
afk_channel_id: guild.afkChannelId?.toString() ?? null,
|
||||
@@ -76,6 +79,9 @@ export class AdminGuildLookupService {
|
||||
position: c.position,
|
||||
parent_id: c.parentId?.toString() ?? null,
|
||||
nsfw: c.isNsfw,
|
||||
nsfw_override: c.nsfwOverride,
|
||||
content_warning_level: c.contentWarningLevel as 0 | 1,
|
||||
content_warning_text: c.contentWarningText,
|
||||
url: c.url,
|
||||
})),
|
||||
roles: roles.map((r) => ({
|
||||
|
||||
@@ -16,6 +16,19 @@ interface AdminGuildDetail {
|
||||
} | null;
|
||||
}
|
||||
|
||||
interface AdminGuildWarningDetail {
|
||||
guild: {
|
||||
nsfw: boolean;
|
||||
content_warning_level: number;
|
||||
content_warning_text: string | null;
|
||||
channels: Array<{
|
||||
nsfw_override: boolean | null;
|
||||
content_warning_level: number;
|
||||
content_warning_text: string | null;
|
||||
}>;
|
||||
} | null;
|
||||
}
|
||||
|
||||
interface AdminGuildUpdate {
|
||||
guild: {
|
||||
id: string;
|
||||
@@ -98,6 +111,30 @@ describe('Admin guild routes', () => {
|
||||
'owner_id',
|
||||
]);
|
||||
});
|
||||
test('GET /admin/guilds/{guild_id} returns the adult content and content warning state', async () => {
|
||||
const admin = await createTestAccount(harness);
|
||||
await setUserACLs(harness, admin, ['admin:authenticate', 'guild:lookup', 'guild:update:settings']);
|
||||
const guild = await createGuild(harness, admin.token, `Warning Lookup Guild ${Date.now()}`);
|
||||
const before = await createBuilder<AdminGuildWarningDetail>(harness, `${admin.token}`)
|
||||
.get(`/admin/guilds/${guild.id}`)
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.execute();
|
||||
expect(before.guild).toMatchObject({nsfw: false, content_warning_level: 0, content_warning_text: null});
|
||||
expect(before.guild?.channels.length).toBeGreaterThan(0);
|
||||
for (const channel of before.guild?.channels ?? []) {
|
||||
expect(channel).toMatchObject({nsfw_override: null, content_warning_level: 0, content_warning_text: null});
|
||||
}
|
||||
await createBuilder(harness, `${admin.token}`)
|
||||
.patch(`/admin/guilds/${guild.id}`)
|
||||
.body({nsfw: true, content_warning_level: 1, content_warning_text: 'Graphic content'})
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.execute();
|
||||
const after = await createBuilder<AdminGuildWarningDetail>(harness, `${admin.token}`)
|
||||
.get(`/admin/guilds/${guild.id}`)
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.execute();
|
||||
expect(after.guild).toMatchObject({nsfw: true, content_warning_level: 1, content_warning_text: 'Graphic content'});
|
||||
});
|
||||
test('PATCH /admin/guilds/{guild_id} requires the ACL selected by every supplied field', async () => {
|
||||
const admin = await createTestAccount(harness);
|
||||
await setUserACLs(harness, admin, ['admin:authenticate', 'guild:update:settings']);
|
||||
|
||||
@@ -223,6 +223,36 @@ export const ReportAdminAuditCases: ReadonlyArray<AdminAuditCoverageCase> = [
|
||||
};
|
||||
},
|
||||
},
|
||||
...(['actioned', 'no_violation', 'duplicate'] as const).map(
|
||||
(resolution): AdminAuditCoverageCase => ({
|
||||
method: 'PATCH',
|
||||
route: '/admin/reports/:report_id',
|
||||
name: `resolution ${resolution}`,
|
||||
async prepare(context) {
|
||||
const {reportId} = await fileUserReport(context);
|
||||
return {
|
||||
request: {
|
||||
path: `/admin/reports/${reportId}`,
|
||||
body: {status: 'resolved', resolution, notify_reporter: false},
|
||||
},
|
||||
expected: {
|
||||
action: 'resolve_report',
|
||||
targetType: 'report',
|
||||
targetId: reportId,
|
||||
metadata: {
|
||||
report_id: reportId,
|
||||
report_type: '1',
|
||||
notify_reporter: 'false',
|
||||
reporter_dm_sent: 'true',
|
||||
reporter_email_sent: 'true',
|
||||
reporter_dsa_email_sent: 'false',
|
||||
resolution,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
}),
|
||||
),
|
||||
{
|
||||
method: 'POST',
|
||||
route: '/admin/reports/:report_id/legal-hold',
|
||||
|
||||
@@ -146,6 +146,22 @@ describe('moderation activity events', () => {
|
||||
expect(resolved?.meta.ip).toBeNull();
|
||||
});
|
||||
|
||||
test.each(['actioned', 'no_violation', 'duplicate'] as const)(
|
||||
'a staff resolve with %s publishes that outcome even when the account is under enforcement',
|
||||
async (resolution) => {
|
||||
const {reported, reportId} = await fileReport();
|
||||
await createBuilder(harness, admin.token)
|
||||
.put(`/admin/users/${reported.userId}/ban`)
|
||||
.body({duration_hours: 24, notify_user: false})
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.execute();
|
||||
await resolve(reportId, {resolution});
|
||||
expect(publisher.of('report_resolved').map((event) => event.data)).toEqual([
|
||||
expect.objectContaining({report_id: reportId, outcome: resolution, resolved_by: 'staff'}),
|
||||
]);
|
||||
},
|
||||
);
|
||||
|
||||
test('without a chosen outcome the reported account state decides between actioned and unspecified', async () => {
|
||||
const first = await fileReport();
|
||||
await resolve(first.reportId, {});
|
||||
|
||||
Reference in new issue
Block a user