fix(stacks): name the body field in the stack-create required error (#1289)

The create endpoint reads the new stack name from the body field
stackName, but a missing or non-string value returned "Stack name is
required and must be a string", which points at a value problem and
leaves anyone scripting against the stacks API unsure which field to
fix. Name the field in the message so the cause is unambiguous, and add
regression coverage for the missing and non-string cases.
This commit is contained in:
Anso
2026-06-02 19:53:45 -04:00
committed by GitHub
parent b2cae92a92
commit 653be3296b
2 changed files with 46 additions and 1 deletions
@@ -0,0 +1,45 @@
/**
* Validation tests for POST /api/stacks (create).
*
* The create endpoint reads the new stack name from the body field `stackName`.
* When that field is missing or not a string it must reject with a 400 whose
* message names the field, so an operator or a script automating against the
* stacks API can see they sent the wrong field rather than a badly typed value.
* These cases short-circuit before any FileSystemService call, but the route
* gates on the `stack:create` permission first, so the test logs in as the
* seeded admin to reach the validation branch.
*/
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import request from 'supertest';
import { setupTestDb, cleanupTestDb, loginAsTestAdmin } from './helpers/setupTestDb';
let tmpDir: string;
let app: import('express').Express;
let authCookie: string;
beforeAll(async () => {
tmpDir = await setupTestDb();
({ app } = await import('../index'));
authCookie = await loginAsTestAdmin(app);
});
afterAll(() => {
cleanupTestDb(tmpDir);
});
describe('POST /api/stacks required-field validation', () => {
it('rejects a missing stackName with a 400 that names the field', async () => {
const res = await request(app).post('/api/stacks').set('Cookie', authCookie).send({});
expect(res.status).toBe(400);
expect(res.body.error).toMatch(/Field 'stackName' is required/);
});
it('rejects a non-string stackName with the same field-named 400', async () => {
const res = await request(app)
.post('/api/stacks')
.set('Cookie', authCookie)
.send({ stackName: 123 });
expect(res.status).toBe(400);
expect(res.body.error).toMatch(/Field 'stackName' is required/);
});
});
+1 -1
View File
@@ -618,7 +618,7 @@ stacksRouter.post('/', async (req: Request, res: Response) => {
try {
const { stackName } = req.body;
if (!stackName || typeof stackName !== 'string') {
return res.status(400).json({ error: 'Stack name is required and must be a string' });
return res.status(400).json({ error: "Field 'stackName' is required and must be a string" });
}
if (!isValidStackName(stackName)) {
return res.status(400).json({ error: 'Stack name can only contain alphanumeric characters, hyphens, and underscores' });