115 - Read Belga API url from config and sync the feed row via migration
This commit is contained in:
parent
7d745b036a
commit
1140e527f1
4 changed files with 85 additions and 15 deletions
|
|
@ -7,15 +7,13 @@
|
|||
class BelgaHomepageParserAdapter implements HomepageParserInterface
|
||||
{
|
||||
/**
|
||||
* Must stay in sync with config('feed.providers.belga.languages.en.url').
|
||||
* Nothing calls getHomepageUrl() at runtime — the fetcher uses $feed->url,
|
||||
* seeded from that config value — so drift here would go unnoticed.
|
||||
* Belga is English-only for now (#124). The unused $language argument keeps
|
||||
* the constructor compatible with HomepageParserFactory, which passes one
|
||||
* positionally to every homepage parser.
|
||||
*
|
||||
* @phpstan-ignore constructor.unusedParameter
|
||||
*/
|
||||
private const API_URL = 'https://capi.belga.press/belgapress/api/public/pressreleases?offset=1&count=6&search=&start=&end=&newsroomId=70&language=EN';
|
||||
|
||||
public function __construct(
|
||||
private string $language = 'en',
|
||||
) {}
|
||||
public function __construct(string $language = 'en') {}
|
||||
|
||||
public function canParse(string $url): bool
|
||||
{
|
||||
|
|
@ -29,7 +27,9 @@ public function extractArticleUrls(string $html): array
|
|||
|
||||
public function getHomepageUrl(): string
|
||||
{
|
||||
return str_replace('language=EN', 'language='.strtoupper($this->language), self::API_URL);
|
||||
$url = config('feed.providers.belga.languages.en.url');
|
||||
|
||||
return is_string($url) ? $url : '';
|
||||
}
|
||||
|
||||
public function getSourceName(): string
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
'type' => 'website',
|
||||
'is_active' => true,
|
||||
'languages' => [
|
||||
'en' => ['url' => 'https://capi.belga.press/belgapress/api/public/pressreleases?offset=1&count=6&search=&start=&end=&newsroomId=70&language=EN'],
|
||||
'en' => ['url' => 'https://capi.belga.press/belgapress/api/public/pressreleases?offset=1&count=50&search=&start=&end=&newsroomId=70&language=EN'],
|
||||
],
|
||||
'parsers' => [
|
||||
'homepage' => BelgaHomepageParserAdapter::class,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* Belga retired its public RSS feed, so the provider switched to website
|
||||
* discovery against their public JSON API (see #115).
|
||||
*
|
||||
* System feeds are maintained by the platform, not the end user, so their
|
||||
* stored url/type are updated through migrations rather than the UI.
|
||||
*
|
||||
* Keyed on `provider`, never on the previous url: environments are at
|
||||
* different points in this feed's history (some on the dead RSS url, some
|
||||
* already on an earlier API url), and a url-keyed update would silently
|
||||
* match nothing on most of them.
|
||||
*
|
||||
* `feeds.url` is unique while `feeds.provider` is not, so a blanket update
|
||||
* across several belga rows would collide. CreateFeedAction looks feeds up by
|
||||
* url, so a config url change can leave a second belga row behind: adopt the
|
||||
* one already on the target url and deactivate the superseded ones.
|
||||
*
|
||||
* Superseded rows are deactivated rather than deleted — routes.feed_id
|
||||
* cascades on delete, so removing a feed would take its routing rules with it.
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$url = config('feed.providers.belga.languages.en.url');
|
||||
|
||||
if (! is_string($url) || $url === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$keepId = DB::table('feeds')->where('provider', 'belga')->where('url', $url)->min('id')
|
||||
?? DB::table('feeds')->where('provider', 'belga')->min('id');
|
||||
|
||||
if ($keepId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('feeds')
|
||||
->where('provider', 'belga')
|
||||
->where('id', '!=', $keepId)
|
||||
->update([
|
||||
'is_active' => false,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
DB::table('feeds')
|
||||
->where('id', $keepId)
|
||||
->update([
|
||||
'type' => 'website',
|
||||
'url' => $url,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// No rollback: the previous RSS endpoint 404s, so restoring it would
|
||||
// only reinstate a feed that silently yields no articles.
|
||||
}
|
||||
};
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use App\Services\Parsers\BelgaHomepageParser;
|
||||
use App\Services\Parsers\BelgaHomepageParserAdapter;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class BelgaHomepageParserTest extends TestCase
|
||||
{
|
||||
|
|
@ -98,10 +98,14 @@ public function test_adapter_delegates_and_reports_source(): void
|
|||
$this->assertSame('Belga News Agency', $adapter->getSourceName());
|
||||
}
|
||||
|
||||
public function test_adapter_uppercases_language_in_api_url(): void
|
||||
public function test_adapter_url_comes_from_config(): void
|
||||
{
|
||||
$this->assertStringContainsString('language=EN', (new BelgaHomepageParserAdapter('en'))->getHomepageUrl());
|
||||
$this->assertStringContainsString('language=NL', (new BelgaHomepageParserAdapter('nl'))->getHomepageUrl());
|
||||
config(['feed.providers.belga.languages.en.url' => 'https://example.test/pressreleases?count=7']);
|
||||
|
||||
$this->assertSame(
|
||||
'https://example.test/pressreleases?count=7',
|
||||
(new BelgaHomepageParserAdapter('en'))->getHomepageUrl()
|
||||
);
|
||||
}
|
||||
|
||||
public function test_adapter_api_url_pins_load_bearing_query_params(): void
|
||||
|
|
@ -111,6 +115,7 @@ public function test_adapter_api_url_pins_load_bearing_query_params(): void
|
|||
$this->assertStringStartsWith('https://capi.belga.press/belgapress/api/public/pressreleases?', $url);
|
||||
$this->assertStringContainsString('newsroomId=70', $url);
|
||||
$this->assertStringContainsString('offset=1', $url);
|
||||
$this->assertStringContainsString('count=6', $url);
|
||||
$this->assertStringContainsString('count=50', $url);
|
||||
$this->assertStringContainsString('language=EN', $url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue