150 lines
4.5 KiB
PHP
150 lines
4.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Lvl0\FediDiscover\Tests\Feature;
|
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Lvl0\FediDiscover\Actions\PollFediverseAction;
|
|
use Lvl0\FediDiscover\Clients\FediverseClientInterface;
|
|
use Lvl0\FediDiscover\Config\InstanceType;
|
|
use Lvl0\FediDiscover\Models\Instance;
|
|
use Mockery;
|
|
use RuntimeException;
|
|
use Tests\TestCase;
|
|
|
|
class PollInstancesCommandTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
// Bind a no-op stub so the command can resolve PollFediverseAction
|
|
// from the container without making real HTTP calls.
|
|
$stub = Mockery::mock(FediverseClientInterface::class);
|
|
$stub->shouldReceive('fetchPostsSince')->andReturn(collect());
|
|
|
|
$this->app->bind(FediverseClientInterface::class, fn () => $stub);
|
|
}
|
|
|
|
public function test_it_exits_zero_when_there_are_no_enabled_instances(): void
|
|
{
|
|
$this->artisan('fedi-discover:poll')
|
|
->assertExitCode(0);
|
|
}
|
|
|
|
public function test_it_calls_the_action_for_each_enabled_instance_and_skips_disabled(): void
|
|
{
|
|
$enabled1 = Instance::create([
|
|
'type' => InstanceType::Mastodon,
|
|
'url' => 'https://mastodon.social',
|
|
'enabled' => true,
|
|
'interval_seconds' => 600,
|
|
]);
|
|
|
|
$enabled2 = Instance::create([
|
|
'type' => InstanceType::Mastodon,
|
|
'url' => 'https://fosstodon.org',
|
|
'enabled' => true,
|
|
'interval_seconds' => 600,
|
|
]);
|
|
|
|
Instance::create([
|
|
'type' => InstanceType::Mastodon,
|
|
'url' => 'https://disabled.example',
|
|
'enabled' => false,
|
|
'interval_seconds' => 600,
|
|
]);
|
|
|
|
$calledWith = [];
|
|
|
|
$action = Mockery::mock(PollFediverseAction::class);
|
|
$action->shouldReceive('execute')
|
|
->twice()
|
|
->withArgs(function (Instance $instance) use (&$calledWith): bool {
|
|
$calledWith[] = $instance->url;
|
|
|
|
return true;
|
|
});
|
|
|
|
$this->app->instance(PollFediverseAction::class, $action);
|
|
|
|
$this->artisan('fedi-discover:poll')->assertExitCode(0);
|
|
|
|
$this->assertEqualsCanonicalizing(
|
|
[$enabled1->url, $enabled2->url],
|
|
$calledWith,
|
|
);
|
|
}
|
|
|
|
public function test_one_instance_throwing_does_not_stop_remaining_instances_from_being_polled(): void
|
|
{
|
|
Instance::create([
|
|
'type' => InstanceType::Mastodon,
|
|
'url' => 'https://failing.example',
|
|
'enabled' => true,
|
|
'interval_seconds' => 600,
|
|
]);
|
|
|
|
$healthy = Instance::create([
|
|
'type' => InstanceType::Mastodon,
|
|
'url' => 'https://healthy.example',
|
|
'enabled' => true,
|
|
'interval_seconds' => 600,
|
|
]);
|
|
|
|
$calledWith = [];
|
|
|
|
$action = Mockery::mock(PollFediverseAction::class);
|
|
$action->shouldReceive('execute')
|
|
->twice()
|
|
->andReturnUsing(function (Instance $instance) use (&$calledWith): void {
|
|
$calledWith[] = $instance->url;
|
|
|
|
if ($instance->url === 'https://failing.example') {
|
|
throw new RuntimeException('Connection refused');
|
|
}
|
|
});
|
|
|
|
$this->app->instance(PollFediverseAction::class, $action);
|
|
|
|
$this->artisan('fedi-discover:poll')->assertExitCode(1);
|
|
|
|
$this->assertEqualsCanonicalizing(
|
|
['https://failing.example', $healthy->url],
|
|
$calledWith,
|
|
);
|
|
}
|
|
|
|
public function test_it_exits_one_when_at_least_one_instance_fails(): void
|
|
{
|
|
Instance::create([
|
|
'type' => InstanceType::Mastodon,
|
|
'url' => 'https://failing.example',
|
|
'enabled' => true,
|
|
'interval_seconds' => 600,
|
|
]);
|
|
|
|
Instance::create([
|
|
'type' => InstanceType::Mastodon,
|
|
'url' => 'https://healthy.example',
|
|
'enabled' => true,
|
|
'interval_seconds' => 600,
|
|
]);
|
|
|
|
$action = Mockery::mock(PollFediverseAction::class);
|
|
$action->shouldReceive('execute')
|
|
->twice()
|
|
->andReturnUsing(function (Instance $instance): void {
|
|
if ($instance->url === 'https://failing.example') {
|
|
throw new RuntimeException('Connection refused');
|
|
}
|
|
});
|
|
|
|
$this->app->instance(PollFediverseAction::class, $action);
|
|
|
|
$this->artisan('fedi-discover:poll')->assertExitCode(1);
|
|
}
|
|
}
|