create(['status' => BookingStatus::Confirmed]); $updated = (new AssignDriverAction)->handle($booking, new AssignDriverData( driverName: 'U Aung', driverPhone: '+959111222333', carPlateNumber: 'YGN-1234', carModel: 'Tesla Model Y', )); expect($updated->driver_name)->toBe('U Aung') ->and($updated->driver_phone)->toBe('+959111222333') ->and($updated->car_plate_number)->toBe('YGN-1234') ->and($updated->car_model)->toBe('Tesla Model Y') ->and($booking->refresh()->driver_name)->toBe('U Aung'); }); test('car_model is optional', function () { $booking = Booking::factory()->create(['status' => BookingStatus::Confirmed]); $updated = (new AssignDriverAction)->handle($booking, new AssignDriverData( driverName: 'U Aung', driverPhone: '+959111222333', carPlateNumber: 'YGN-1234', )); expect($updated->car_model)->toBeNull(); }); test('it guards against assigning a driver to a pending_payment booking', function () { $booking = Booking::factory()->create(['status' => BookingStatus::PendingPayment]); expect(fn () => (new AssignDriverAction)->handle($booking, new AssignDriverData( driverName: 'U Aung', driverPhone: '+959111222333', carPlateNumber: 'YGN-1234', )))->toThrow(DriverAssignmentNotAllowedException::class); expect($booking->refresh()->driver_name)->toBeNull(); }); test('it guards against assigning a driver to a cancelled booking', function () { $booking = Booking::factory()->create(['status' => BookingStatus::Cancelled]); expect(fn () => (new AssignDriverAction)->handle($booking, new AssignDriverData( driverName: 'U Aung', driverPhone: '+959111222333', carPlateNumber: 'YGN-1234', )))->toThrow(DriverAssignmentNotAllowedException::class); }); test('reassigning a different driver on a still-confirmed booking overwrites the previous values', function () { $booking = Booking::factory()->create([ 'status' => BookingStatus::Confirmed, 'driver_name' => 'U Aung', 'driver_phone' => '+959111222333', 'car_plate_number' => 'YGN-1234', ]); (new AssignDriverAction)->handle($booking, new AssignDriverData( driverName: 'Daw Hla', driverPhone: '+959444555666', carPlateNumber: 'YGN-5678', )); expect($booking->refresh()->driver_name)->toBe('Daw Hla') ->and($booking->car_plate_number)->toBe('YGN-5678'); }); test('a round trip: assigning a driver to the outbound leg does not touch the linked return leg', function () { $outbound = Booking::factory()->create(['status' => BookingStatus::Confirmed]); $return = Booking::factory()->create([ 'status' => BookingStatus::Confirmed, 'is_return_leg' => true, 'linked_booking_id' => $outbound->id, ]); $outbound->update(['linked_booking_id' => $return->id]); (new AssignDriverAction)->handle($outbound, new AssignDriverData( driverName: 'U Aung', driverPhone: '+959111222333', carPlateNumber: 'YGN-1234', )); // Each leg has its own independent driver/vehicle slot — the return leg // can get a completely different (or no-yet-assigned) vehicle, per the // "next available vehicle" business rule (domain.md §2b). expect($outbound->refresh()->driver_name)->toBe('U Aung') ->and($return->refresh()->driver_name)->toBeNull(); });