mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 14:41:28 -07:00
update moderationblockdetails to work on both clients for now
This commit is contained in:
@@ -391,10 +391,11 @@ export const SubscriptionResponse = z.object({
|
||||
// ---- Moderation ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* `GET /api/PlayerReporting/v1/moderationBlockDetails` — always the "not blocked"
|
||||
* `GET|POST /api/PlayerReporting/v1/moderationBlockDetails` — always the "not blocked"
|
||||
* answer (no ban storage yet), mirroring the reference server's stub
|
||||
* `ReturnModerationBlockDetails()`. `ReportCategory` is `Unknown` (-1) rather than 0,
|
||||
* which is a real category, and `Message` is the empty string the reference sends.
|
||||
* which is a real category, and `Message` is null — the client distinguishes "no
|
||||
* message" from a blank one, so we send null where the reference sends an empty string.
|
||||
* `IsVoiceModAutoban`/`TimeoutStartedAt` are on the DTO but unset by that stub, so
|
||||
* they carry their C# defaults (false / null).
|
||||
*/
|
||||
|
||||
@@ -16,22 +16,27 @@ import type { App } from '../context'
|
||||
export const moderationRoutes = new Hono<App>({ strict: false })
|
||||
// Whether the caller is currently blocked (banned / timed out / host-kicked). No ban
|
||||
// storage yet, so this is always the "not blocked" answer — the reference server's
|
||||
// stub `ReturnModerationBlockDetails()` verbatim. `ReportCategory` is `Unknown` (-1),
|
||||
// not 0, which is a real category, and `Message` is the empty string that stub sends.
|
||||
// stub `ReturnModerationBlockDetails()`. `ReportCategory` is `Unknown` (-1), not 0,
|
||||
// which is a real category. `Message` is null rather than the empty string that stub
|
||||
// sends: the client distinguishes "no message" from a blank one.
|
||||
// `IsVoiceModAutoban`/`TimeoutStartedAt` are on the DTO but left unset there, so they
|
||||
// go out with their C# defaults.
|
||||
// POST with no body — the client's actual call, despite this being a pure read.
|
||||
.post(
|
||||
// POST with no body is the client's actual call, despite this being a pure read; it
|
||||
// answers GET too, so the path is reachable either way.
|
||||
.on(
|
||||
['GET', 'POST'],
|
||||
'/api/PlayerReporting/v1/moderationBlockDetails',
|
||||
describeRoute({
|
||||
tags: ['Moderation'],
|
||||
summary: 'Whether the caller is blocked',
|
||||
description:
|
||||
'Ban / timeout / host-kick state for the caller. There is no ban storage yet, so ' +
|
||||
'this is always the “not blocked” answer, matching the reference server’s stub: ' +
|
||||
'`ReportCategory` is `Unknown` (-1) rather than 0, which is a real category, and ' +
|
||||
'`Message` is an empty string. `IsVoiceModAutoban` and `TimeoutStartedAt` are on ' +
|
||||
'the DTO but unset by that stub, so they carry their defaults.',
|
||||
'this is always the “not blocked” answer, following the reference server’s stub: ' +
|
||||
'`ReportCategory` is `Unknown` (-1) rather than 0, which is a real category. ' +
|
||||
'`Message` is null rather than the empty string that stub sends — the client ' +
|
||||
'distinguishes “no message” from a blank one. `IsVoiceModAutoban` and ' +
|
||||
'`TimeoutStartedAt` are on the DTO but unset by that stub, so they carry their ' +
|
||||
'defaults.',
|
||||
responses: { 200: json(ModerationBlockDetails, 'Always “not blocked”') },
|
||||
}),
|
||||
(c) =>
|
||||
@@ -42,7 +47,7 @@ export const moderationRoutes = new Hono<App>({ strict: false })
|
||||
IsBan: false,
|
||||
IsHostKick: false,
|
||||
IsVoiceModAutoban: false,
|
||||
Message: '',
|
||||
Message: null,
|
||||
PlayerIdReporter: null,
|
||||
TimeoutStartedAt: null,
|
||||
})
|
||||
|
||||
@@ -233,27 +233,31 @@ describe('public endpoints', () => {
|
||||
expect(await res.json()).toEqual([])
|
||||
})
|
||||
|
||||
test('POST /api/PlayerReporting/v1/moderationBlockDetails reports "not blocked"', async () => {
|
||||
// The client POSTs this with no body, despite it being a pure read.
|
||||
const res = await exports.default.fetch(
|
||||
`${ORIGIN}/api/PlayerReporting/v1/moderationBlockDetails`,
|
||||
{ method: 'POST' }
|
||||
)
|
||||
expect(res.status).toBe(200)
|
||||
// The reference server's stub verbatim: ReportCategory -1 = Unknown (0 is a real
|
||||
// category) and an empty-string Message.
|
||||
expect(await res.json()).toEqual({
|
||||
ReportCategory: -1,
|
||||
Duration: 0,
|
||||
GameSessionId: 0,
|
||||
IsBan: false,
|
||||
IsHostKick: false,
|
||||
IsVoiceModAutoban: false,
|
||||
Message: '',
|
||||
PlayerIdReporter: null,
|
||||
TimeoutStartedAt: null,
|
||||
})
|
||||
})
|
||||
// The client POSTs this with no body, despite it being a pure read; the route answers
|
||||
// GET as well, and both methods serve the same body.
|
||||
test.each(['GET', 'POST'])(
|
||||
'%s /api/PlayerReporting/v1/moderationBlockDetails reports "not blocked"',
|
||||
async (method) => {
|
||||
const res = await exports.default.fetch(
|
||||
`${ORIGIN}/api/PlayerReporting/v1/moderationBlockDetails`,
|
||||
{ method }
|
||||
)
|
||||
expect(res.status).toBe(200)
|
||||
// ReportCategory -1 = Unknown (0 is a real category). Message is null, not the
|
||||
// reference stub's empty string — the client tells "no message" from a blank one.
|
||||
expect(await res.json()).toEqual({
|
||||
ReportCategory: -1,
|
||||
Duration: 0,
|
||||
GameSessionId: 0,
|
||||
IsBan: false,
|
||||
IsHostKick: false,
|
||||
IsVoiceModAutoban: false,
|
||||
Message: null,
|
||||
PlayerIdReporter: null,
|
||||
TimeoutStartedAt: null,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
// Unauthenticated by design — the client posts this before it has an account, so
|
||||
// there's no bearer token to check and nothing to attribute the id to.
|
||||
@@ -1899,6 +1903,7 @@ describe('openapi', () => {
|
||||
)
|
||||
expect([...documented].sort()).toEqual([
|
||||
'DELETE /api/images/v1/deletesaved',
|
||||
'GET /api/PlayerReporting/v1/moderationBlockDetails',
|
||||
'GET /api/PlayerReporting/v1/voteToKickReasons',
|
||||
'GET /api/activities/charades/v1/words/{activity}',
|
||||
'GET /api/announcement/v1/get',
|
||||
|
||||
Reference in New Issue
Block a user