fedi-feed-router/tests/Feature/FixBelgaFeedOffsetMigrationTest.php
myrmidex ba8513c256
All checks were successful
CI / ci (push) Successful in 2m12s
158 - Fix Belga feed offset=1 skipping newest article
2026-08-16 22:53:52 +02:00

176 lines
5.6 KiB
PHP

<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use stdClass;
use Tests\TestCase;
/**
* The migration has already run by the time RefreshDatabase hands over, so
* these tests seed a pre-migration state and invoke up() against it directly.
*/
class FixBelgaFeedOffsetMigrationTest extends TestCase
{
use RefreshDatabase;
private const OFFSET_ONE_URL = 'https://capi.belga.press/belgapress/api/public/pressreleases?offset=1&count=50&search=&start=&end=&newsroomId=70&language=EN';
private function runMigration(): void
{
$migration = require database_path('migrations/2024_01_01_000024_fix_belga_feed_offset.php');
$migration->up();
}
private function findFeed(int $id): stdClass
{
$feed = DB::table('feeds')->find($id);
$this->assertInstanceOf(stdClass::class, $feed);
return $feed;
}
private function targetUrl(): string
{
$url = config('feed.providers.belga.languages.en.url');
$this->assertIsString($url);
return $url;
}
private function seedFeed(string $url, bool $isActive = true, string $provider = 'belga', string $type = 'website'): int
{
return DB::table('feeds')->insertGetId([
'name' => 'Belga',
'provider' => $provider,
'type' => $type,
'url' => $url,
'is_active' => $isActive,
'created_at' => now(),
'updated_at' => now(),
]);
}
public function test_moves_a_feed_still_on_the_offset_one_url(): void
{
DB::table('feeds')->delete();
$id = $this->seedFeed(self::OFFSET_ONE_URL);
$this->runMigration();
$feed = $this->findFeed($id);
$this->assertSame($this->targetUrl(), $feed->url);
$this->assertSame('website', $feed->type);
$this->assertTrue((bool) $feed->is_active);
}
public function test_is_idempotent_when_the_feed_is_already_on_the_target_url(): void
{
DB::table('feeds')->delete();
$id = $this->seedFeed($this->targetUrl());
$this->runMigration();
$this->runMigration();
$this->assertSame(1, DB::table('feeds')->where('provider', 'belga')->count());
$feed = $this->findFeed($id);
$this->assertSame($this->targetUrl(), $feed->url);
$this->assertTrue((bool) $feed->is_active);
}
public function test_deactivates_superseded_rows_instead_of_colliding_on_the_unique_url(): void
{
DB::table('feeds')->delete();
$staleId = $this->seedFeed(self::OFFSET_ONE_URL);
$currentId = $this->seedFeed($this->targetUrl());
$this->runMigration();
// Both rows survive: routes.feed_id cascades on delete, so a superseded
// feed is deactivated rather than removed.
$this->assertSame(2, DB::table('feeds')->where('provider', 'belga')->count());
$current = $this->findFeed($currentId);
$this->assertTrue((bool) $current->is_active);
$this->assertSame($this->targetUrl(), $current->url);
$stale = $this->findFeed($staleId);
$this->assertFalse((bool) $stale->is_active);
}
public function test_adopts_the_oldest_row_when_none_is_on_the_target_url(): void
{
DB::table('feeds')->delete();
$oldestId = $this->seedFeed(self::OFFSET_ONE_URL);
$newerId = $this->seedFeed('https://capi.belga.press/belgapress/api/public/pressreleases?offset=1&count=6');
$this->runMigration();
// Neither row matches config, so the migration falls back to the lowest
// id — the oldest row, which is the one routes are most likely tied to.
$oldest = $this->findFeed($oldestId);
$this->assertSame($this->targetUrl(), $oldest->url);
$this->assertTrue((bool) $oldest->is_active);
$this->assertFalse((bool) $this->findFeed($newerId)->is_active);
}
public function test_leaves_other_providers_untouched(): void
{
DB::table('feeds')->delete();
$vrtId = $this->seedFeed('https://www.vrt.be/vrtnws/nl/', true, 'vrt');
// Seed a belga row too, so the migration actually runs its updates
// rather than bailing out at the "no belga feed" guard.
$this->seedFeed(self::OFFSET_ONE_URL);
$this->runMigration();
$vrt = $this->findFeed($vrtId);
$this->assertSame('https://www.vrt.be/vrtnws/nl/', $vrt->url);
$this->assertTrue((bool) $vrt->is_active);
}
public function test_down_is_a_deliberate_no_op(): void
{
DB::table('feeds')->delete();
$id = $this->seedFeed($this->targetUrl());
$migration = require database_path('migrations/2024_01_01_000024_fix_belga_feed_offset.php');
$migration->down();
// Rolling back must not restore the offset=1 url that drops the newest
// press release.
$feed = $this->findFeed($id);
$this->assertSame($this->targetUrl(), $feed->url);
$this->assertTrue((bool) $feed->is_active);
}
public function test_does_nothing_when_no_belga_feed_exists(): void
{
DB::table('feeds')->delete();
$this->runMigration();
$this->assertSame(0, DB::table('feeds')->count());
}
public function test_does_nothing_when_the_configured_url_is_missing(): void
{
DB::table('feeds')->delete();
config(['feed.providers.belga.languages.en.url' => '']);
$id = $this->seedFeed(self::OFFSET_ONE_URL);
$this->runMigration();
$feed = $this->findFeed($id);
$this->assertSame(self::OFFSET_ONE_URL, $feed->url);
}
}