[rooms] unset cloning on copy

This commit is contained in:
Devin Zuczek
2026-09-22 10:25:15 -04:00
parent c46341b331
commit 2dc374ab70
3 changed files with 38 additions and 6 deletions
+1 -1
View File
@@ -1719,7 +1719,7 @@ const app = new Hono<App>()
'caller. Cloning is the only way to make a room, so the per-account room cap is',
'enforced here — it counts the rooms the account created, minus their auto-provisioned',
'dorm (`MAX_ROOMS_PER_ACCOUNT`; 0 lifts the cap). The clone starts with no tags,',
'`IsRRO` cleared, and PRIVATE accessibility — a new room is unpublished until its',
'zeroed `Stats`, `IsRRO`/`IsDeveloperOwned`/`CloningAllowed` cleared, and PRIVATE accessibility — a new room is unpublished until its',
'owner sets its accessibility, so it never lands in the public feeds on creation.',
'',
'Rejections — a blank or taken name, the cap, a source that disallows cloning — are',
@@ -1309,11 +1309,20 @@ describe('rooms endpoints', () => {
CreatorAccountId: number
Tags?: Array<{ Tag: string }>
IsRRO: boolean
IsDeveloperOwned: boolean
CloningAllowed: boolean
Accessibility: number
Roles: Array<{ AccountId: number; Role: number; InvitedRole: number }>
Stats: Record<string, number>
} | null
}
// Give the source every flag and counter the clone must NOT inherit.
await env.DB.prepare(
`UPDATE room SET data = json_set(data, '$.IsDeveloperOwned', json('true'),
'$.CloningAllowed', json('true'), '$.Stats.VisitorCount', 42) WHERE room_id = 24`
).run()
// Clone MakerRoom (base, RoomId 24) → a fresh room owned by the caller (801).
const ok = await post(24, 'MyMakerClone')
expect(ok.success).toBe(true)
@@ -1327,6 +1336,16 @@ describe('rooms endpoints', () => {
expect(ok.value!.Tags).toEqual([])
// IsRRO is cleared so the client doesn't render a virtual "RRO" tag on the clone.
expect(ok.value!.IsRRO).toBe(false)
// Nor is it developer-owned, and the new owner opts it into cloning themselves.
expect(ok.value!.IsDeveloperOwned).toBe(false)
expect(ok.value!.CloningAllowed).toBe(false)
// No engagement carries over — not even the blob-stored VisitorCount.
expect(ok.value!.Stats).toEqual({
CheerCount: 0,
FavoriteCount: 0,
VisitorCount: 0,
VisitCount: 0,
})
// A new room is unpublished: Private (0), never the source's visibility.
expect(ok.value!.Accessibility).toBe(0)
// Ownership is reset to the cloner: sole owner (Role 255), and none of the
@@ -1338,8 +1357,16 @@ describe('rooms endpoints', () => {
// It persists and is fetchable by its new id.
const fetched = (await (await SELF.fetch(`${ORIGIN}/rooms/${ok.value!.RoomId}`)).json()) as {
Name: string
Tags: unknown[]
IsDeveloperOwned: boolean
CloningAllowed: boolean
Stats: Record<string, number>
}
expect(fetched.Name).toBe('MyMakerClone')
expect(fetched.Tags).toEqual([])
expect(fetched.IsDeveloperOwned).toBe(false)
expect(fetched.CloningAllowed).toBe(false)
expect(fetched.Stats.VisitorCount).toBe(0)
// Duplicate name is rejected.
const dup = await post(24, 'MyMakerClone')