artisan('postcodes:import', ['--file' => $path]) ->assertSuccessful(); expect(Postcode::count())->toBe(2) ->and(Postcode::find('SW1A1AA')->outcode)->toBe('SW1A') ->and(Postcode::find('M11AD')->outcode)->toBe('M1'); }); it('skips terminated postcodes', function (): void { $csv = <<<'CSV' pcd,pcds,doterm,lat,long "SW1A1AA","SW1A 1AA","",51.501009,-0.141588 "OLD1AA","OLD 1AA","202301",50.000000,-1.000000 CSV; $path = writeOnspdFixture($csv); $this->artisan('postcodes:import', ['--file' => $path])->assertSuccessful(); expect(Postcode::count())->toBe(1) ->and(Postcode::find('OLD1AA'))->toBeNull(); }); it('skips rows with blank coordinates', function (): void { $csv = <<<'CSV' pcd,pcds,doterm,lat,long "SW1A1AA","SW1A 1AA","",51.501009,-0.141588 "BT11AA","BT1 1AA","",, CSV; $path = writeOnspdFixture($csv); $this->artisan('postcodes:import', ['--file' => $path])->assertSuccessful(); expect(Postcode::count())->toBe(1) ->and(Postcode::find('BT11AA'))->toBeNull(); }); it('derives outcode centroids as the average of member postcodes', function (): void { $csv = <<<'CSV' pcd,pcds,doterm,lat,long "PE71AA","PE7 1AA","",52.500000,-0.200000 "PE71AB","PE7 1AB","",52.600000,-0.220000 "M11AD","M1 1AD","",53.480957,-2.237428 CSV; $path = writeOnspdFixture($csv); $this->artisan('postcodes:import', ['--file' => $path])->assertSuccessful(); $pe7 = Outcode::find('PE7'); expect($pe7)->not->toBeNull() ->and(round((float) $pe7->lat, 6))->toBe(52.550000) ->and(round((float) $pe7->lng, 6))->toBe(-0.210000) ->and(Outcode::find('M1'))->not->toBeNull(); });