assertStatus(200) ->assertSeeHtml('name="search"') ->assertSeeHtml('name="fuelType"') ->assertSeeHtml('name="radius"'); }); it('validates search is required', function () { Livewire::test(StationSearch::class) ->call('findStations') ->assertHasErrors(['search' => 'required']); }); it('validates fuelType is required', function () { Livewire::test(StationSearch::class) ->set('search', 'SW1A 1AA') ->set('fuelType', '') ->call('findStations') ->assertHasErrors(['fuelType' => 'required']); }); it('populates results and meta on successful search', function () { Http::fake([ '*/api/stations*' => Http::response([ 'data' => [ [ 'station_id' => 'abc123', 'name' => 'BP Garage', 'brand' => 'BP', 'is_supermarket' => false, 'address' => '1 High Street, London', 'postcode' => 'SW1A 1AA', 'lat' => 51.5074, 'lng' => -0.1278, 'distance_km' => 1.5, 'fuel_type' => 'e10', 'price_pence' => 14390, 'price' => 143.9, 'price_updated_at' => '2026-04-05T08:00:00.000Z', 'price_classification' => 'current', 'price_classification_label' => 'Current', ], ], 'meta' => [ 'count' => 1, 'fuel_type' => 'e10', 'radius_km' => 8.05, 'lat' => 51.5010, 'lng' => -0.1415, 'lowest_pence' => 14390, 'highest_pence' => 14390, 'cheapest_price_pence' => 14390, 'avg_pence' => 14390.0, ], ], 200), ]); Livewire::test(StationSearch::class) ->set('search', 'SW1A 1AA') ->set('fuelType', 'petrol') ->set('radius', 5) ->call('findStations') ->assertSet('apiError', null) ->assertSet('results', fn (array $r) => count($r) === 1 && $r[0]['name'] === 'BP Garage') ->assertSet('meta', fn (array $m) => $m['count'] === 1); }); it('sets apiError from 422 postcode validation response', function () { Http::fake([ '*/api/stations*' => Http::response([ 'errors' => ['postcode' => ['Postcode not found.']], ], 422), ]); Livewire::test(StationSearch::class) ->set('search', 'ZZ99 9ZZ') ->set('fuelType', 'petrol') ->call('findStations') ->assertSet('results', []) ->assertSet('meta', []) ->assertSet('apiError', 'Postcode not found.'); }); it('sets generic apiError on server error', function () { Http::fake([ '*/api/stations*' => Http::response([], 500), ]); Livewire::test(StationSearch::class) ->set('search', 'SW1A 1AA') ->set('fuelType', 'petrol') ->call('findStations') ->assertSet('results', []) ->assertSet('meta', []) ->assertSet('apiError', 'Unable to fetch stations. Please try again.'); }); it('converts radius from miles to km in the outgoing API request', function () { Http::fake([ '*/api/stations*' => Http::response(['data' => [], 'meta' => ['count' => 0]], 200), ]); Livewire::test(StationSearch::class) ->set('search', 'SW1A 1AA') ->set('fuelType', 'petrol') ->set('radius', 5) ->call('findStations'); Http::assertSent(function ($request) { $data = $request->data(); return isset($data['radius']) && abs((float) $data['radius'] - 8.05) < 0.01 && isset($data['fuel_type']) && $data['fuel_type'] === 'petrol'; }); }); it('resets results and error before each new search', function () { Http::fake([ '*/api/stations*' => Http::response(['data' => [], 'meta' => ['count' => 0]], 200), ]); Livewire::test(StationSearch::class) ->set('search', 'SW1A 1AA') ->set('fuelType', 'petrol') ->set('results', [['name' => 'Old Result']]) ->set('apiError', 'Old error') ->call('findStations') ->assertSet('apiError', null) ->assertSet('results', []); });