CtrlK
BlogDocsLog inGet started
Tessl Logo

simon/fastify-best-practices

Fastify best practices skill

93

1.37x
Quality

97%

Does it follow best practices?

Impact

85%

1.37x

Average score across 4 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

task.mdevals/scenario-3/

Add Test Coverage to Expense Tracker API

Problem/Feature Description

A fintech startup built a Fastify expense tracking API three months ago but shipped it with zero test coverage. The team has just hired a new backend engineer whose first task is to write a comprehensive test suite before any new features are added. The CI pipeline currently has a placeholder for tests but nothing runs.

The team tech lead wants the tests to be lightweight and fast — they should not spin up a real database or make actual network calls. The tests need to be runnable in CI without any additional tooling beyond what comes with Node.js. The tech lead specifically does not want to introduce Jest or any other test framework as a dependency since it slows down the install step and adds complexity.

The existing application source files are provided below. Write a complete test suite covering all routes, including validation error cases and not-found scenarios.

Output Specification

Produce the following files:

  • test/expenses.test.ts — the primary test file with all tests
  • package.json — updated with a test script that runs the tests

The test script in package.json should run the tests without any flags not available in Node.js 22+.

Ensure the tests can be run immediately after npm install.

Input Files

The following files are provided as inputs. Extract them before beginning.

=============== FILE: src/app.ts =============== import Fastify from 'fastify' import type { FastifyInstance } from 'fastify' import { expenseRoutes } from './routes/expenses.js'

export async function buildApp(): Promise<FastifyInstance> { const app = Fastify({ logger: true }) await app.register(expenseRoutes) return app } =============== END FILE ===============

=============== FILE: src/routes/expenses.ts =============== import type { FastifyInstance } from 'fastify'

interface Expense { id: string description: string amount: number category: string date: string }

const expenses: Record<string, Expense> = {} let nextId = 1

export async function expenseRoutes(fastify: FastifyInstance) { fastify.get('/expenses', async () => { return { expenses: Object.values(expenses) } })

fastify.post('/expenses', { schema: { body: { type: 'object', properties: { description: { type: 'string', minLength: 1 }, amount: { type: 'number', exclusiveMinimum: 0 }, category: { type: 'string', minLength: 1 }, date: { type: 'string', format: 'date' }, }, required: ['description', 'amount', 'category', 'date'], additionalProperties: false, }, }, }, async (request, reply) => { const body = request.body as Omit<Expense, 'id'> const id = String(nextId++) expenses[id] = { id, ...body } reply.code(201) return expenses[id] })

fastify.get('/expenses/:id', async (request, reply) => { const { id } = request.params as { id: string } const expense = expenses[id] if (!expense) { reply.code(404) return { error: 'Expense not found' } } return expense })

fastify.put('/expenses/:id', { schema: { body: { type: 'object', properties: { description: { type: 'string', minLength: 1 }, amount: { type: 'number', exclusiveMinimum: 0 }, category: { type: 'string', minLength: 1 }, date: { type: 'string', format: 'date' }, }, additionalProperties: false, }, }, }, async (request, reply) => { const { id } = request.params as { id: string } if (!expenses[id]) { reply.code(404) return { error: 'Expense not found' } } const body = request.body as Partial<Omit<Expense, 'id'>> expenses[id] = { ...expenses[id], ...body } return expenses[id] })

fastify.delete('/expenses/:id', async (request, reply) => { const { id } = request.params as { id: string } if (!expenses[id]) { reply.code(404) return { error: 'Expense not found' } } delete expenses[id] reply.code(204) }) } =============== END FILE ===============

=============== FILE: package.json =============== { "name": "expense-tracker-api", "version": "1.0.0", "type": "module", "scripts": { "start": "node src/app.ts", "test": "echo 'no tests yet'" }, "dependencies": { "fastify": "^5.0.0" }, "devDependencies": { "@types/node": "^22.0.0", "typescript": "^5.0.0" } } =============== END FILE ===============

evals

tile.json