create([ 'real_stock' => 10, 'reserved_stock' => 2, ]); $reservation = StockReservation::query()->create([ 'status' => StockReservation::STATUS_ACTIVE, 'expires_at' => now()->subMinute(), ]); StockReservationLine::query()->create([ 'stock_reservation_id' => $reservation->id, 'inventory_id' => $inventory->id, 'quantity' => 2, 'tracks_inventory' => true, ]); $result = app(ExpireStockReservationsService::class)->expireOverdue(); $this->assertSame([ 'purchases' => 0, 'cart_reservations' => 0, 'orphan_reservations' => 1, 'failed' => 0, ], $result); $this->assertDatabaseHas('stock_reservations', [ 'id' => $reservation->id, 'status' => StockReservation::STATUS_EXPIRED, 'expires_at' => null, ]); $this->assertDatabaseHas('inventories', [ 'id' => $inventory->id, 'reserved_stock' => 0, ]); } public function test_one_failed_reservation_does_not_stop_the_remaining_batch(): void { $first = StockReservation::query()->create([ 'status' => StockReservation::STATUS_ACTIVE, 'expires_at' => now()->subMinutes(2), ]); $second = StockReservation::query()->create([ 'status' => StockReservation::STATUS_ACTIVE, 'expires_at' => now()->subMinute(), ]); $reservations = \Mockery::mock(StockReservationService::class); $reservations->shouldReceive('expire') ->twice() ->andReturnUsing(function (StockReservation $reservation) use ($first): void { if ($reservation->is($first)) { throw new RuntimeException('Broken reservation.'); } $reservation->update([ 'status' => StockReservation::STATUS_EXPIRED, 'expires_at' => null, 'expired_at' => now(), ]); }); $service = new ExpireStockReservationsService( \Mockery::mock(ReleaseCheckoutService::class), $reservations, ); $result = $service->expireOverdue(); $this->assertSame([ 'purchases' => 0, 'cart_reservations' => 0, 'orphan_reservations' => 1, 'failed' => 1, ], $result); $this->assertDatabaseHas('stock_reservations', [ 'id' => $first->id, 'status' => StockReservation::STATUS_ACTIVE, ]); $this->assertDatabaseHas('stock_reservations', [ 'id' => $second->id, 'status' => StockReservation::STATUS_EXPIRED, ]); } }