Cap articles.content at 10000 characters, with coverage
PocketBase silently enforced its own default max on unbounded text fields, which broke saving a real production article longer than that. Make the limit explicit and generous enough for the content this blog actually publishes, and add a test asserting the exact boundary.
This commit is contained in:
@@ -18,7 +18,7 @@ migrate((app) => {
|
||||
fields: [
|
||||
{ type: 'text', name: 'title', required: true, max: 160 },
|
||||
{ type: 'text', name: 'slug', required: true, max: 160, pattern: '^[a-z0-9]+(-[a-z0-9]+)*$' },
|
||||
{ type: 'text', name: 'content', required: true },
|
||||
{ type: 'text', name: 'content', required: true, max: 10000 },
|
||||
{
|
||||
type: 'file',
|
||||
name: 'cover',
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { afterAll, describe, expect, it } from 'vitest'
|
||||
import { startTestPocketbase } from '../support/pocketbase'
|
||||
|
||||
// Exercises the PocketBase collection schema directly (pb_migrations), not the
|
||||
// Nitro /content/* endpoints — this is about what the CMS itself accepts.
|
||||
const pb = await startTestPocketbase()
|
||||
|
||||
afterAll(async () => {
|
||||
await pb.stop()
|
||||
})
|
||||
|
||||
async function createArticle(content: string) {
|
||||
return fetch(`${pb.url}/api/collections/articles/records`, {
|
||||
method: 'POST',
|
||||
headers: { Authorization: pb.token, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
title: 'Vincolo lunghezza contenuto',
|
||||
slug: 'vincolo-lunghezza-contenuto',
|
||||
content,
|
||||
publishedAt: '2025-01-01 00:00:00',
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
describe('articles.content max length', () => {
|
||||
it('accepts content up to 10000 characters', async () => {
|
||||
const response = await createArticle('a'.repeat(10000))
|
||||
expect(response.status).toBe(200)
|
||||
})
|
||||
|
||||
it('rejects content over 10000 characters', async () => {
|
||||
const response = await createArticle('a'.repeat(10001))
|
||||
expect(response.status).toBe(400)
|
||||
const body = await response.json()
|
||||
expect(body.data.content.code).toBe('validation_max_text_constraint')
|
||||
})
|
||||
})
|
||||
@@ -83,6 +83,8 @@ export interface TestCategory {
|
||||
|
||||
export interface TestPocketbase {
|
||||
url: string
|
||||
/** Superuser auth token, for tests that need to create/inspect records beyond the seeded fixtures. */
|
||||
token: string
|
||||
categories: TestCategory[]
|
||||
articles: TestArticle[]
|
||||
stop(): Promise<void>
|
||||
@@ -155,6 +157,7 @@ export async function startTestPocketbase(options: StartOptions = {}): Promise<T
|
||||
|
||||
return {
|
||||
url,
|
||||
token,
|
||||
categories,
|
||||
articles,
|
||||
async stop() {
|
||||
|
||||
Reference in New Issue
Block a user