feat: persist postcodes.io fallback results into local DB
This commit is contained in:
@@ -47,6 +47,11 @@ class PostcodeService
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function normalisePostcode(string $value): string
|
||||
{
|
||||
return strtoupper(preg_replace('/\s+/', '', $value));
|
||||
}
|
||||
|
||||
private function isFullPostcode(string $query): bool
|
||||
{
|
||||
return (bool) preg_match('/^[A-Z]{1,2}[0-9][0-9A-Z]?\s*[0-9][A-Z]{2}$/i', $query);
|
||||
@@ -59,7 +64,7 @@ class PostcodeService
|
||||
|
||||
private function lookupLocalPostcode(string $postcode): ?LocationResult
|
||||
{
|
||||
$normalised = strtoupper(preg_replace('/\s+/', '', $postcode));
|
||||
$normalised = $this->normalisePostcode($postcode);
|
||||
|
||||
$row = Postcode::find($normalised);
|
||||
|
||||
@@ -105,7 +110,7 @@ class PostcodeService
|
||||
|
||||
private function lookupPostcode(string $postcode): ?LocationResult
|
||||
{
|
||||
$normalised = strtoupper(preg_replace('/\s+/', '', $postcode));
|
||||
$normalised = $this->normalisePostcode($postcode);
|
||||
$url = self::BASE_URL.'/postcodes/'.$normalised;
|
||||
|
||||
try {
|
||||
@@ -117,12 +122,23 @@ class PostcodeService
|
||||
|
||||
$data = $response->json('result');
|
||||
|
||||
return new LocationResult(
|
||||
$result = new LocationResult(
|
||||
query: $postcode,
|
||||
displayName: $data['postcode'],
|
||||
lat: $data['latitude'],
|
||||
lng: $data['longitude'],
|
||||
);
|
||||
|
||||
Postcode::updateOrCreate(
|
||||
['postcode' => $normalised],
|
||||
[
|
||||
'outcode' => substr($normalised, 0, strlen($normalised) - 3),
|
||||
'lat' => $data['latitude'],
|
||||
'lng' => $data['longitude'],
|
||||
],
|
||||
);
|
||||
|
||||
return $result;
|
||||
} catch (Throwable $e) {
|
||||
Log::error('PostcodeService: postcode lookup failed', [
|
||||
'postcode' => $postcode,
|
||||
@@ -147,12 +163,22 @@ class PostcodeService
|
||||
|
||||
$data = $response->json('result');
|
||||
|
||||
return new LocationResult(
|
||||
$result = new LocationResult(
|
||||
query: $outcode,
|
||||
displayName: $data['outcode'],
|
||||
lat: $data['latitude'],
|
||||
lng: $data['longitude'],
|
||||
);
|
||||
|
||||
Outcode::updateOrCreate(
|
||||
['outcode' => $normalised],
|
||||
[
|
||||
'lat' => $data['latitude'],
|
||||
'lng' => $data['longitude'],
|
||||
],
|
||||
);
|
||||
|
||||
return $result;
|
||||
} catch (Throwable $e) {
|
||||
Log::error('PostcodeService: outcode lookup failed', [
|
||||
'outcode' => $outcode,
|
||||
|
||||
@@ -216,3 +216,48 @@ it('resolves an outcode from local DB without calling HTTP', function (): void {
|
||||
|
||||
Http::assertNothingSent();
|
||||
});
|
||||
|
||||
// --- HTTP fallback persistence ---
|
||||
|
||||
it('persists a full postcode resolved via HTTP fallback', function (): void {
|
||||
Http::fake([
|
||||
'*/postcodes/SW1A1AA' => Http::response([
|
||||
'status' => 200,
|
||||
'result' => [
|
||||
'postcode' => 'SW1A 1AA',
|
||||
'latitude' => 51.501009,
|
||||
'longitude' => -0.141588,
|
||||
],
|
||||
]),
|
||||
]);
|
||||
|
||||
$this->service->resolve('SW1A 1AA');
|
||||
|
||||
$row = Postcode::find('SW1A1AA');
|
||||
|
||||
expect($row)->not->toBeNull()
|
||||
->and($row->outcode)->toBe('SW1A')
|
||||
->and((float) $row->lat)->toBe(51.501009)
|
||||
->and((float) $row->lng)->toBe(-0.141588);
|
||||
});
|
||||
|
||||
it('persists an outcode resolved via HTTP fallback', function (): void {
|
||||
Http::fake([
|
||||
'*/outcodes/PE7' => Http::response([
|
||||
'status' => 200,
|
||||
'result' => [
|
||||
'outcode' => 'PE7',
|
||||
'latitude' => 52.536397,
|
||||
'longitude' => -0.210181,
|
||||
],
|
||||
]),
|
||||
]);
|
||||
|
||||
$this->service->resolve('PE7');
|
||||
|
||||
$row = Outcode::find('PE7');
|
||||
|
||||
expect($row)->not->toBeNull()
|
||||
->and((float) $row->lat)->toBe(52.536397)
|
||||
->and((float) $row->lng)->toBe(-0.210181);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user