REST API
Buggy Bookings โ Find the Defects
RequestValidateHard
Description
A booking API whose documentation and behaviour disagree in five places. The job is not to automate it โ it is to prove what is wrong.
Test Scenario
// This challenge inverts the usual exercise: assert the API is WRONG.
// Five defects are reachable from a plain HTTP client. One is shown here.
// Defect: a record is lost between page 1 and page 2.
const seen = new Set();
let page = 1;
while (page <= 4) {
const res = await request.get(`/api/v1/buggy/bookings?page=${page}&limit=3`);
const body = await res.json();
for (const booking of body.data) {
seen.add(booking.id);
}
page++;
}
const total = (await (await request.get('/api/v1/buggy/bookings')).json()).meta.total;
// Walking every page should reach every record. It does not.
expect(seen.size).toBe(total);
// Defect: PUT reports success but drops one field.
const created = await (await request.post('/api/v1/buggy/bookings', {
data: { name: 'Test User', email: 't@example.com', nights: 2, notes: 'original' },
})).json();
const put = await request.put(`/api/v1/buggy/bookings/${created.data.id}`, {
data: { name: 'Test User', email: 't@example.com', nights: 2, notes: 'updated' },
});
// The write response says the change landed...
expect((await put.json()).data.notes).toBe('updated');
// ...but reading it back disagrees. Never assert on the write response alone.
const readBack = await (await request.get(`/api/v1/buggy/bookings/${created.data.id}`)).json();
expect(readBack.data.notes).toBe('updated');Endpoint
/api/v1/buggy/bookingsTesting Tips
- โขEvery happy-path test passes here โ start from the documented contract and look for where reality departs from it
- โขPaging is documented as 1-based and contiguous: walk every page and compare the union against total
- โขPUT is documented to replace the whole record โ never trust the write response, always read it back
- โขDELETE is documented as 204 and idempotent: check the status, and check what a second delete returns
- โขnights is documented as a positive integer โ try a string, a float and a boolean
- โขDELETE /api/v1/buggy/bookings?reset=true reseeds the store; the data also reseeds itself every 10 minutes
// Playwright API Testing - RESTimport { test, expect } from '@playwright/test';test('REST API request', async ({ request }) => {const response = await request.get('/api/v1/resource');expect(response.ok()).toBeTruthy();expect(response.status()).toBe(200);const data = await response.json();expect(data).toBeDefined();});
Challenge ID: rest-buggy-bookings
2 frameworks available
API Playground
Send requests and inspect responses
Endpoint: /api/v1/buggy/bookings
Press Enter to send