This skill should be used when the user is testing HTTP API routes, working with authentication strategies, or writing integration tests. It covers framework-agnostic HTTP API route testing patterns, JWT cookie authentication, and other common auth patterns.
From hugin-coworknpx claudepluginhub michelve/hugin-marketplace --plugin hugin-coworkThis skill uses the workspace's default tool permissions.
examples/authentication-testing.mdexamples/http-method-patterns.mdreferences/response-validation.mdresources/api-integration-testing.mdresources/authentication-testing.mdresources/http-testing-fundamentals.mdSearches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Guides agent creation for Claude Code plugins with file templates, frontmatter specs (name, description, model), triggering examples, system prompts, and best practices.
!`cat package.json 2>/dev/null || echo '{"error": "No package.json found."}'`
This skill provides guidance for testing HTTP API routes and endpoints. Primary examples use Express with TypeScript, but patterns adapt to other frameworks.
Unit Tests
Integration Tests
End-to-End Tests
See authentication-testing.md for JWT cookie and bearer token authentication test patterns.
See http-method-patterns.md for GET, POST, PUT/PATCH, and DELETE request test examples.
See response-validation.md for status code testing and response schema validation patterns.
describe("Error Handling", () => {
it("should return structured error response", async () => {
const response = await request(app).post("/api/users").send({ invalid: "data" });
expect(response.status).toBe(400);
expect(response.body).toEqual({
error: expect.any(String),
message: expect.any(String),
errors: expect.any(Array),
});
});
it("should handle database errors gracefully", async () => {
mockDatabase.findOne.mockRejectedValue(new Error("Connection lost"));
const response = await request(app).get("/api/users/123");
expect(response.status).toBe(500);
expect(response.body.error).toBe("Internal Server Error");
});
it("should sanitize error messages in production", async () => {
process.env.NODE_ENV = "production";
const response = await request(app).get("/api/error-prone-route");
expect(response.status).toBe(500);
expect(response.body.message).not.toContain("stack trace");
expect(response.body.message).not.toContain("SQL");
});
});
describe("API Tests", () => {
let testDatabase;
beforeAll(async () => {
// Initialize test database
testDatabase = await initTestDatabase();
});
afterAll(async () => {
// Clean up test database
await testDatabase.close();
});
beforeEach(async () => {
// Seed test data
await testDatabase.seed();
});
afterEach(async () => {
// Clear test data
await testDatabase.clear();
});
// Tests...
});
While this skill provides framework-agnostic patterns, here are common testing libraries per framework:
ā Don't share state between tests
// Bad
let userId;
it("creates user", async () => {
const response = await request(app).post("/api/users").send(userData);
userId = response.body.id; // Shared state!
});
it("deletes user", async () => {
await request(app).delete(`/api/users/${userId}`); // Depends on previous test
});
ā Do create fresh state for each test
// Good
it("creates user", async () => {
const response = await request(app).post("/api/users").send(userData);
expect(response.status).toBe(201);
});
it("deletes user", async () => {
const user = await createTestUser();
const response = await request(app).delete(`/api/users/${user.id}`);
expect(response.status).toBe(204);
});
See the resources/ directory for more detailed guides:
http-testing-fundamentals.md - Deep dive into HTTP testing conceptsauthentication-testing.md - Authentication strategies and edge casesapi-integration-testing.md - Integration testing patterns and toolsTest Structure
describe('Resource Name', () => {
describe('HTTP Method /path', () => {
it('should describe expected behavior', async () => {
// Arrange
const testData = {...};
// Act
const response = await request(app)
.method('/path')
.set('Cookie', authCookie)
.send(testData);
// Assert
expect(response.status).toBe(expectedStatus);
expect(response.body).toMatchObject(expectedData);
});
});
});
Authentication Pattern
let authCookie: string;
beforeEach(async () => {
const response = await request(app)
.post('/api/auth/login')
.send({ email: 'test@example.com', password: 'password123' });
authCookie = response.headers['set-cookie'][0];
});
// Use authCookie in protected route tests
.set('Cookie', authCookie)