63 lines
2.4 KiB
TypeScript
63 lines
2.4 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import { describe, it } from 'node:test'
|
|
|
|
const pageSource = readFileSync(
|
|
new URL('../src/app/(frontend)/posts/[slug]/page.tsx', import.meta.url),
|
|
'utf8',
|
|
)
|
|
|
|
const slug = process.env.ANWARPY_VIP_TEST_SLUG
|
|
const marker = process.env.ANWARPY_VIP_BODY_MARKER
|
|
const cookie = process.env.ANWARPY_VIP_COOKIE
|
|
const baseUrl = (process.env.ANWARPY_TEST_BASE_URL || 'http://127.0.0.1:3000').replace(/\/$/, '')
|
|
|
|
async function body(url, headers = {}) {
|
|
const response = await fetch(url, { headers, redirect: 'manual' })
|
|
return { status: response.status, text: await response.text() }
|
|
}
|
|
|
|
describe('VIP content query boundary', () => {
|
|
it('does not load content before entitlement is established', () => {
|
|
const pageStart = pageSource.indexOf('export default async function PostPage')
|
|
const roleCheck = pageSource.indexOf('const role = await getViewerRole()', pageStart)
|
|
const beforeRole = pageSource.slice(pageStart, roleCheck)
|
|
assert.doesNotMatch(beforeRole, /content\s*:\s*true/)
|
|
})
|
|
|
|
it('loads content only inside the unlocked branch', () => {
|
|
assert.match(
|
|
pageSource,
|
|
/const unlocked[\s\S]*if \(unlocked\) \{[\s\S]*findByID\([\s\S]*select:\s*\{\s*content:\s*true\s*\}/,
|
|
)
|
|
assert.match(pageSource, /\{unlocked \? \([\s\S]*<RichText data=\{post\.content\}/)
|
|
})
|
|
})
|
|
|
|
describe('VIP transport acceptance', () => {
|
|
it('does not expose the protected marker to anonymous HTML, RSC, or REST', {
|
|
skip: !slug || !marker,
|
|
}, async () => {
|
|
const encoded = encodeURIComponent(slug)
|
|
const [html, rsc, rest] = await Promise.all([
|
|
body(`${baseUrl}/posts/${encoded}`),
|
|
body(`${baseUrl}/posts/${encoded}?__rsc=vip-test`, { RSC: '1', Accept: 'text/x-component' }),
|
|
body(`${baseUrl}/api/posts?where%5Bslug%5D%5Bequals%5D=${encoded}&depth=0`, { Accept: 'application/json' }),
|
|
])
|
|
assert.equal(html.status, 200)
|
|
assert.ok([200, 204].includes(rsc.status))
|
|
assert.ok([200, 401, 403].includes(rest.status))
|
|
for (const response of [html, rsc, rest]) {
|
|
assert.equal(response.text.includes(marker), false)
|
|
}
|
|
})
|
|
|
|
it('exposes the protected marker to an entitled VIP session', {
|
|
skip: !slug || !marker || !cookie,
|
|
}, async () => {
|
|
const response = await body(`${baseUrl}/posts/${encodeURIComponent(slug)}`, { Cookie: cookie })
|
|
assert.equal(response.status, 200)
|
|
assert.equal(response.text.includes(marker), true)
|
|
})
|
|
})
|