🏨 Hotel Booking Wiki

The Hotel Booking application is a multi-resource property management system designed for QA practice. It covers the full hospitality lifecycle β€” from adding properties and defining room types to creating bookings with dynamic pricing, updating booking statuses, and submitting guest reviews.

A unique feature is the QA Chaos Lab, which injects intentional failures into API responses to simulate real-world instability: network delays, data corruption, race conditions, and permission issues. This makes Hotel the ideal app for resilience and negative testing.

Key Characteristics

Quick Start

Step 1
Add Property
Name, city, country, star rating
β†’
Step 2
Add Room Type
Bed type, price, capacity, rooms
β†’
Step 3
Create Booking
Guest details, dates, guests/rooms
β†’
Step 4
Progress Status
PENDING β†’ CONFIRMED β†’ CHECKED_IN β†’ CHECKED_OUT
β†’
Step 5
Submit Review
Only after CHECKED_OUT
Authentication: All API calls require Authorization: qac_live_<your_api_key> in the request header. Get your key from the Profile page.

UI Overview

The Hotel interface is a single-page application with four tabs: Properties, Room Types, Bookings, and Reviews. A hotel banner image appears at the top of each tab. The top navigation provides access to the QA Chaos Lab, API Docs, Data Viewer, and Profile.

Properties Tab

Contains an Add New Property form with fields: Property Name*, City*, Country*, Star Rating (1–5 dropdown), Address*, Postal Code, Phone, Email, Check-In Time (default 03:00 PM), Check-Out Time (default 11:00 AM), Description textarea, and Cancellation Policy textarea (default: "Free cancellation up to 24 hours before check-in").

Below the form: My Properties table with columns β€” Name, City, Country, Rating (star icons), Status (ACTIVE badge), and Actions (DELETE button in red).

Room Types Tab

Contains an Add Room Type form: Select Property* (dropdown), Room Type Name*, Bed Type* (Single/Double/Queen/King/Twin), Max Occupancy*, Room Size (sqm), Price Per Night ($)*, Total Rooms*, Description, Amenities (comma-separated, e.g. "WiFi, TV, AC, Mini Bar").

Below: Room Types table β€” Property, Room Type, Bed Type, Max Occupancy, Price/Night, Total Rooms, Status (AVAILABLE badge), Actions (DELETE).

Bookings Tab

Stats dashboard at top: Total Bookings, Pending, Confirmed, Checked In, Total Revenue (in dollars).

Create New Booking form: Property*, Room Type* (filtered by selected property), Guest Name*, Guest Email*, Guest Phone*, Check-In Date*, Check-Out Date*, Number of Guests*, Number of Rooms (default 1), Special Requests textarea.

All Bookings section with Filter by Status dropdown (All Statuses). Table columns: Confirmation #, Guest, Property, Room Type, Check-In, Check-Out, Guests, Total Amount, Status, Actions.

Reviews Tab

Guest Reviews table: Guest, Property, Rating, Comment, Date. The + ADD REVIEW button (top right) opens the review submission form. Reviews require a completed (CHECKED_OUT) booking.

Top Navigation

ItemDescription
🎲 Chaos (cyan badge)Opens the QA Chaos Lab modal β€” toggles chaos for the session
πŸ“– API DocsLinks to Swagger UI with full API reference
πŸ” Data ViewerRead-only table view of all hotel data
← ProfileReturns to main profile/apps page
β˜€οΈ / πŸŒ™Dark/light theme toggle

QA Chaos Lab

The Chaos Lab is a unique testing feature that randomly injects failures into Hotel API responses. It is controlled per-user and does not affect other users. Click the 🎲 Chaos button in the top nav to open the modal.

Configuration

Pack A

Network Instability

Simulates network delays, timeouts, and connection issues. Returns 1xx, 5xx, and 503 errors for random requests.

Pack B

Data Validation Errors

Corrupts API responses: removes fields, breaks JSON structure, changes data types, injects null values.

Pack C

Race Conditions

Corrupts data BEFORE/AFTER one rule triggers: string→numbers swaps, drops fields, swaps values unexpectedly.

Pack D

Security & Permissions

Tests authentication boundaries, access control, permission escalation, and security edge cases.

QA note: When Chaos is active, normal API calls may return unexpected errors. Test your client's error handling, retry logic, and graceful degradation under chaos conditions.

Property Flow

Properties are the top-level resource. All other resources (room types, bookings, reviews) belong to a property. Properties can be active or inactive.

Room Types Flow

Room types define the inventory under a property. They set the price, capacity, and availability used when creating bookings.

Booking Flow

Bookings represent guest reservations. The total amount is auto-calculated and the confirmation number is auto-generated.

Booking Lifecycle

PENDING β†’ CONFIRMED β†’ CHECKED_IN β†’ CHECKED_OUT
PENDING / CONFIRMED β†’ CANCELLED PENDING / CONFIRMED β†’ NO_SHOW

Business Rules

Review Flow

Guests can leave a review only after their booking reaches CHECKED_OUT status. Only one review per booking is permitted.

API – Properties

Base path: /api/hotel/properties

POST /api/hotel/properties Create a new property
FieldTypeRequiredNotes
namestringrequiredProperty name
addressstringrequiredStreet address
citystringrequiredCity
countrystringrequiredCountry
star_ratingintegeroptional1–5
postal_codestringoptional
phonestringoptional
emailstringoptional
check_in_timestringoptionalDefault: 15:00:00
check_out_timestringoptionalDefault: 11:00:00
descriptionstringoptional
cancellation_policystringoptionalDefault: "Free cancellation up to 24 hours before check-in"

Returns: 201 with created property object. 400 if required fields missing or star_rating out of range.

GET /api/hotel/properties List all properties
Query ParamTypeNotes
is_activebooleanFilter by active/inactive
citystringCase-insensitive partial match

Returns: 200 with array of properties, ordered by created_at DESC.

GET /api/hotel/properties/:id Get property by ID

Returns: 200 with property object. 404 if not found or not owned by the authenticated user.

PUT /api/hotel/properties/:id Update a property

Updatable fields: name, description, address, city, country, postal_code, phone, email, star_rating, check_in_time, check_out_time, cancellation_policy, is_active.

Returns 400 if no valid fields provided. Unknown fields are silently ignored.

DELETE /api/hotel/properties/:id Delete a property

Returns: 200 with deleted property. 404 if not found.

API – Room Types

Base path: /api/hotel/room-types

POST /api/hotel/room-types Add a room type to a property
FieldTypeRequiredNotes
property_iduuidrequiredMust be owned by authenticated user
namestringrequirede.g. "Deluxe Suite"
max_occupancyintegerrequiredβ‰₯ 1
bed_typestringrequiredSingle, Double, Queen, King, Twin
price_per_nightnumberrequiredβ‰₯ 0
total_roomsintegerrequiredβ‰₯ 1
room_size_sqmnumberoptional
descriptionstringoptional
amenitiesarrayoptionale.g. ["WiFi","TV","AC"]
GET /api/hotel/room-types List all room types
Query ParamNotes
property_idFilter by property UUID
is_availabletrue/false

Ordered by price_per_night ASC.

GET /api/hotel/room-types/:id Get room type by ID

Returns: 200 with room type. 404 if not found or property not owned by authenticated user.

PUT /api/hotel/room-types/:id Update a room type

Updatable: name, description, max_occupancy, bed_type, room_size_sqm, amenities, price_per_night, total_rooms, images, is_available. Returns 400 if no valid fields provided.

DELETE /api/hotel/room-types/:id Delete a room type

Returns 200 with deleted room type object. 404 if not found.

GET /api/hotel/availability Check room availability for dates
Query ParamRequiredNotes
property_idrequiredUUID
room_type_idrequiredUUID
check_in_daterequiredYYYY-MM-DD
check_out_daterequiredYYYY-MM-DD

API – Bookings

Base path: /api/hotel/bookings

POST /api/hotel/bookings Create a booking
FieldTypeRequiredNotes
property_iduuidrequired
room_type_iduuidrequiredMust belong to property
guest_namestringrequired
guest_emailstringrequired
guest_phonestringrequired
check_in_datedaterequiredYYYY-MM-DD
check_out_datedaterequiredMust be after check-in
number_of_guestsintegerrequiredβ‰₯ 1
number_of_roomsintegeroptionalDefault: 1
special_requestsstringoptional

Total amount is auto-calculated: price_per_night Γ— number_of_rooms Γ— nights. Confirmation number auto-generated.

GET /api/hotel/bookings List all bookings
Query ParamNotes
property_idFilter by property
statusPENDING, CONFIRMED, CHECKED_IN, CHECKED_OUT, CANCELLED, NO_SHOW
check_in_dateFilter bookings with check-in on or after this date
check_out_dateFilter bookings with check-out on or before this date
PATCH /api/hotel/bookings/:id/status Update booking status

Body: { "status": "CONFIRMED", "cancellation_reason": "..." }

Valid statuses: PENDING, CONFIRMED, CHECKED_IN, CHECKED_OUT, CANCELLED, NO_SHOW

Sets confirmed_at when status becomes CONFIRMED. Sets cancelled_at when status becomes CANCELLED.

DELETE /api/hotel/bookings/:id Delete a booking

Returns 200 with deleted booking object. 404 if not found.

POST /api/hotel/reset Reset all hotel data to template state

Deletes all user's hotel data and repopulates from template. Returns counts of deleted and created resources.

API – Reviews

Base path: /api/hotel/reviews

POST /api/hotel/reviews Submit a guest review
FieldTypeRequiredNotes
booking_iduuidrequiredBooking must be CHECKED_OUT
property_iduuidrequired
ratingintegerrequired1–5
cleanliness_ratingintegeroptional1–5
service_ratingintegeroptional1–5
location_ratingintegeroptional1–5
value_ratingintegeroptional1–5
commentstringoptional

Returns 400 if booking is not CHECKED_OUT or if a review already exists for the booking.

GET /api/hotel/reviews List all reviews
Query ParamNotes
property_idFilter by property UUID

Ordered by created_at DESC. Includes guest name and property name in the response.

Test Cases

Properties

TC-PROP-001 Create property with all required fields Expected Pass
  1. Send POST /api/hotel/properties with name, address, city, country
Response: 201 with property object containing generated id and is_active: true
TC-PROP-002 Create property with star_rating = 6 (out of range) Expected Fail
  1. Send POST /api/hotel/properties with valid required fields and star_rating: 6
Response: 400 β€” star rating must be between 1 and 5
TC-PROP-003 Create property missing required field (no city) Expected Fail
  1. Send POST /api/hotel/properties with name, address, country β€” omit city
Response: 400 β€” Name, address, city, and country are required
TC-PROP-004 Set property is_active to false via PUT Expected Pass
  1. Create a property
  2. PUT /api/hotel/properties/:id with { "is_active": false }
  3. GET /api/hotel/properties?is_active=false
Returned list includes the deactivated property. GET with is_active=true excludes it.
TC-PROP-005 Update property with no valid fields Expected Fail
  1. PUT /api/hotel/properties/:id with body { "unknown_field": "value" }
Response: 400 β€” No valid fields to update

Room Types

TC-ROOM-001 Create room type with price_per_night = 0 Expected Pass
  1. POST /api/hotel/room-types with valid fields and price_per_night: 0
Response: 201 β€” zero price is allowed (free rooms)
TC-ROOM-002 Create room type with negative price Expected Fail
  1. POST /api/hotel/room-types with price_per_night: -50
Response: 400 β€” Invalid values for max occupancy, price, or total rooms
TC-ROOM-003 Create room type for a property not owned by user Expected Fail
  1. POST /api/hotel/room-types with a valid property_id that belongs to a different user
Response: 404 β€” Property not found
TC-ROOM-004 Mark room type as unavailable, then try booking it Expected Fail
  1. PUT /api/hotel/room-types/:id with { "is_available": false }
  2. POST /api/hotel/bookings referencing that room type
Response: 400 β€” Room type is not available for booking

Bookings

TC-BOOK-001 Create booking and verify total amount calculation Expected Pass
  1. Create a room type with price_per_night: 100
  2. POST booking with same-day dates spanning 3 nights, number_of_rooms: 2
Response: 201 β€” total_amount = 100 Γ— 2 Γ— 3 = 600
TC-BOOK-002 Create booking with check-out = check-in (same day) Expected Fail
  1. POST /api/hotel/bookings with check_in_date = check_out_date
Response: 400 β€” Check-out date must be after check-in date
TC-BOOK-003 Create booking with check-out before check-in Expected Fail
  1. POST booking where check_out_date < check_in_date
Response: 400 β€” Check-out date must be after check-in date
TC-BOOK-004 Progress booking through full lifecycle Expected Pass
  1. Create booking β†’ status: PENDING
  2. PATCH status β†’ CONFIRMED (confirmed_at is set)
  3. PATCH status β†’ CHECKED_IN
  4. PATCH status β†’ CHECKED_OUT
Each step returns 200 with updated status. After CHECKED_OUT, booking is eligible for a review.
TC-BOOK-005 Cancel booking and include cancellation_reason Expected Pass
  1. PATCH /api/hotel/bookings/:id/status with { "status": "CANCELLED", "cancellation_reason": "Guest request" }
Response: 200 β€” cancelled_at timestamp set, cancellation_reason stored
TC-BOOK-006 Submit booking with invalid status value Expected Fail
  1. PATCH /api/hotel/bookings/:id/status with { "status": "DONE" }
Response: 400 β€” Invalid status

Reviews

TC-REV-001 Submit review for a CHECKED_OUT booking Expected Pass
  1. Complete full booking lifecycle to CHECKED_OUT
  2. POST /api/hotel/reviews with booking_id, property_id, rating: 4
Response: 201 with review object
TC-REV-002 Submit review for a PENDING booking Expected Fail
  1. Create a booking (status: PENDING)
  2. POST /api/hotel/reviews with that booking_id
Response: 400 β€” Booking not found or not checked out yet
TC-REV-003 Submit duplicate review for same booking Expected Fail
  1. Submit a successful review for a CHECKED_OUT booking
  2. POST the same booking_id + property_id again
Response: 400 β€” Review already exists for this booking
TC-REV-004 Submit review with rating = 0 (below minimum) Expected Fail
  1. POST /api/hotel/reviews with rating: 0 for a valid CHECKED_OUT booking
Response: 400 β€” Rating must be between 1 and 5

UI Test Cases

TC-UI-001 Add New Property form renders all required fields Expected Pass
  1. Navigate to Hotel app β†’ Properties tab
  2. Verify form contains: Property Name*, City*, Country*, Star Rating dropdown, Address*, Postal Code, Phone, Email, Check-In Time, Check-Out Time, Description, Cancellation Policy
All fields visible. Required fields marked with *. Star Rating shows "Select" placeholder. Check-In defaults to 03:00 PM, Check-Out to 11:00 AM.
TC-UI-002 Submit Add Property form with empty required fields Expected Fail
  1. Leave Property Name, City, Country, and Address blank
  2. Click ADD PROPERTY
Error displayed. Property not added to the table below.
TC-UI-003 My Properties table shows correct columns and data Expected Pass
  1. Add a property
  2. Verify table shows: Name, City, Country, Rating (stars), Status (ACTIVE badge), Actions (DELETE)
Star rating renders as star icons (e.g. β˜…β˜…β˜… for 3). Status shows green ACTIVE badge.
TC-UI-004 Room Types: Select Property dropdown populates from created properties Expected Pass
  1. Add 2 properties
  2. Navigate to Room Types tab
  3. Click Select Property dropdown
Dropdown lists both created properties by name.
TC-UI-005 Room Types table shows AVAILABLE status badge Expected Pass
  1. Add a room type
  2. Verify the Room Types table row shows AVAILABLE badge in Status column
Green AVAILABLE badge displayed. Table shows Property, Room Type, Bed Type, Max Occupancy, Price/Night, Total Rooms, Status, Actions.
TC-UI-006 Bookings stats dashboard shows zero values initially Expected Pass
  1. Navigate to Bookings tab with no bookings created
Stats bar shows: Total Bookings: 0, Pending: 0, Confirmed: 0, Checked In: 0, Total Revenue: $0.00
TC-UI-007 Create Booking: Room Type updates when Property changes Expected Pass
  1. Select Property A in Create New Booking form
  2. Note Room Type options
  3. Change Property to Property B
Room Type dropdown updates to show only room types for the newly selected property.
TC-UI-008 Filter bookings by status in All Bookings section Expected Pass
  1. Create bookings with different statuses
  2. Use Filter by Status dropdown in All Bookings section
  3. Select "CONFIRMED"
Table shows only CONFIRMED bookings. Selecting "All Statuses" shows all bookings again.
TC-UI-009 Reviews tab: Guest Reviews table is empty initially Expected Pass
  1. Navigate to Reviews tab with no reviews submitted
Guest Reviews table shows column headers (Guest, Property, Rating, Comment, Date) but no rows. + ADD REVIEW button visible in top right.
TC-UI-010 QA Chaos Lab modal opens and closes correctly Expected Pass
  1. Click 🎲 Chaos button in top nav
  2. Verify modal opens with: session toggle, intensity slider, random seed input, 4 chaos pack checkboxes
  3. Click X to close
Modal appears centered. All chaos packs (A, B, C, D) shown with descriptions. Closing returns to normal app state.
TC-UI-011 Chaos intensity slider accepts values 0–100% Expected Pass
  1. Open Chaos modal
  2. Drag intensity slider to 0%
  3. Drag to 100%
  4. Set to 50%
Slider moves smoothly. Label updates with the current percentage. Default shown as 50%.
TC-UI-012 DELETE property button removes it from table Expected Pass
  1. Add a property
  2. Click DELETE button in its table row
  3. Confirm deletion prompt if shown
Property removed from My Properties table immediately. Row count decrements.

QA Tasks

Hands-on challenges designed for manual testing, API automation, and chaos resilience testing.

#1 Full Booking Lifecycle Manual

Create a property β†’ add a room type β†’ make a booking β†’ progress it through PENDING β†’ CONFIRMED β†’ CHECKED_IN β†’ CHECKED_OUT β†’ submit a review. Verify the total amount calculation is correct at each step.

#2 Booking Date Boundary Testing Automation

Automate a suite of booking date edge cases: same-day check-out, check-out before check-in, 1-night stays, and multi-month stays. Assert correct 400/201 responses and validate calculated amounts.

#3 Chaos: Network Instability Resilience Chaos

Enable Chaos Pack A at 75% intensity. Perform a booking creation workflow and observe how many requests fail. Verify your client retries on 5xx errors and surfaces friendly error messages on timeout.

#4 Review Gate Enforcement Automation

Attempt to POST a review for bookings in each non-CHECKED_OUT status (PENDING, CONFIRMED, CHECKED_IN, CANCELLED, NO_SHOW). Verify all return 400. Only CHECKED_OUT allows a review.

#5 Star Rating Boundary Exploration Manual

Create properties with star_rating: 0, 1, 3, 5, and 6. Document which values succeed and which fail. Try updating an existing property's star rating to out-of-range values via PUT.

#6 Cross-User Isolation Test Automation

Use two different API keys. Create a property with User A. Attempt to create a room type under that property with User B's key. Document the response. Try to fetch User A's bookings with User B. Assert no data leaks across users.

#7 Chaos: Data Corruption Detection Chaos

Enable Pack B (Data Validation Errors) at 100% intensity. Run GET /api/hotel/properties and GET /api/hotel/bookings repeatedly. Document all response anomalies: missing fields, wrong types, broken JSON. Test whether your parser/client handles them gracefully.

#8 Room Availability and Booking Conflict Manual

Disable a room type via PUT (is_available: false), then attempt to book it. Restore it (is_available: true) and book again successfully. Use the availability check endpoint to query before booking.

#9 Reset Data and Verify Template State Manual

Delete all properties manually. Then call POST /api/hotel/reset. Verify the response reports created properties and room types. Check the Properties tab in UI and confirm template data is restored.

#10 Chaos: Reproduce Scenario with Seed Chaos

Enable chaos and note the Random Seed value displayed. Perform 5 API operations and note which ones failed. Reset the seed to the same value. Repeat the same 5 operations and verify the same failures occur β€” chaos is reproducible with the same seed.