true, 'booking.whole_vehicle_enabled' => true, ]); $service = new BookingService; foreach (VehicleOption::cases() as $option) { expect(fn () => $service->validateSelections([new VehicleSelectionData($option)])) ->not->toThrow(InvalidVehicleSelectionException::class); } }); test('front seat and back seat can be selected together in one booking', function () { config(['booking.back_seat_enabled' => true]); $service = new BookingService; expect(fn () => $service->validateSelections([ new VehicleSelectionData(VehicleOption::FrontSeat, 1), new VehicleSelectionData(VehicleOption::BackSeat, 2), ]))->not->toThrow(InvalidVehicleSelectionException::class); }); test('requesting more passengers than the configured max is rejected', function (VehicleOption $option) { config(["booking.{$option->value}_max_per_booking" => 1]); $service = new BookingService; expect(fn () => $service->validateSelections([new VehicleSelectionData($option, 2)])) ->toThrow(InvalidVehicleSelectionException::class); })->with([ 'front_seat' => [VehicleOption::FrontSeat], 'back_seat' => [VehicleOption::BackSeat], 'whole_vehicle' => [VehicleOption::WholeVehicle], ]); test('requesting passengers up to the configured max passes', function (VehicleOption $option) { config(["booking.{$option->value}_max_per_booking" => 2]); $service = new BookingService; expect(fn () => $service->validateSelections([new VehicleSelectionData($option, 2)])) ->not->toThrow(InvalidVehicleSelectionException::class); })->with([ 'front_seat' => [VehicleOption::FrontSeat], 'back_seat' => [VehicleOption::BackSeat], 'whole_vehicle' => [VehicleOption::WholeVehicle], ]); test('an option is rejected when disabled via config', function (VehicleOption $option) { config(["booking.{$option->value}_enabled" => false]); $service = new BookingService; expect(fn () => $service->validateSelections([new VehicleSelectionData($option)])) ->toThrow(InvalidVehicleSelectionException::class, "Vehicle option [{$option->value}] is not currently available for booking."); })->with([ 'front_seat' => [VehicleOption::FrontSeat], 'back_seat' => [VehicleOption::BackSeat], 'whole_vehicle' => [VehicleOption::WholeVehicle], ]); test('exceeding the max produces the expected message', function () { config(['booking.front_seat_max_per_booking' => 1]); $service = new BookingService; expect(fn () => $service->validateSelections([new VehicleSelectionData(VehicleOption::FrontSeat, 2)])) ->toThrow(InvalidVehicleSelectionException::class, 'Vehicle option [front_seat] passenger count [2] exceeds the max of [1] per booking.'); }); test('the same vehicle option cannot be selected twice in one booking', function () { config(['booking.back_seat_enabled' => true]); $service = new BookingService; expect(fn () => $service->validateSelections([ new VehicleSelectionData(VehicleOption::BackSeat, 1), new VehicleSelectionData(VehicleOption::BackSeat, 1), ]))->toThrow(InvalidVehicleSelectionException::class); }); test('whole vehicle cannot be combined with another vehicle option', function () { config([ 'booking.back_seat_enabled' => true, 'booking.whole_vehicle_enabled' => true, ]); $service = new BookingService; expect(fn () => $service->validateSelections([ new VehicleSelectionData(VehicleOption::WholeVehicle), new VehicleSelectionData(VehicleOption::BackSeat), ]))->toThrow(InvalidVehicleSelectionException::class); });