2 - Add InstanceConfig value object and InstanceType enum
This commit is contained in:
parent
7a2db5a14d
commit
bdd2b0f2e5
4 changed files with 199 additions and 3 deletions
65
packages/Lvl0/FediDiscover/src/Config/InstanceConfig.php
Normal file
65
packages/Lvl0/FediDiscover/src/Config/InstanceConfig.php
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Lvl0\FediDiscover\Config;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
final readonly class InstanceConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $extras
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public InstanceType $type,
|
||||||
|
public string $url,
|
||||||
|
public bool $enabled,
|
||||||
|
public int $intervalSeconds,
|
||||||
|
public array $extras
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $array): self
|
||||||
|
{
|
||||||
|
foreach (['type', 'url', 'enabled', 'interval_seconds'] as $key) {
|
||||||
|
if (! array_key_exists($key, $array)) {
|
||||||
|
throw new InvalidArgumentException("Missing required key: {$key}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($array['interval_seconds'] <= 0) {
|
||||||
|
throw new InvalidArgumentException('Interval seconds needs to be larger than zero');
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = InstanceType::tryFrom($array['type']);
|
||||||
|
if ($type === null) {
|
||||||
|
throw new InvalidArgumentException('Invalid type: ' . $array['type']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_var($array['url'], FILTER_VALIDATE_URL) === false) {
|
||||||
|
throw new InvalidArgumentException('Invalid URL: ' . $array['url']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new self(
|
||||||
|
type: $type,
|
||||||
|
url: $array['url'],
|
||||||
|
enabled: $array['enabled'],
|
||||||
|
intervalSeconds: $array['interval_seconds'],
|
||||||
|
extras: $array['extras'] ?? []
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => $this->type->value,
|
||||||
|
'url' => $this->url,
|
||||||
|
'enabled' => $this->enabled,
|
||||||
|
'interval_seconds' => $this->intervalSeconds,
|
||||||
|
'extras' => $this->extras,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
10
packages/Lvl0/FediDiscover/src/Config/InstanceType.php
Normal file
10
packages/Lvl0/FediDiscover/src/Config/InstanceType.php
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Lvl0\FediDiscover\Config;
|
||||||
|
|
||||||
|
enum InstanceType: string
|
||||||
|
{
|
||||||
|
case Mastodon = 'mastodon';
|
||||||
|
}
|
||||||
|
|
@ -10,16 +10,16 @@ class FediDiscoverServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
public function register(): void
|
public function register(): void
|
||||||
{
|
{
|
||||||
$this->mergeConfigFrom(__DIR__.'/../config/fedi-discover.php', 'fedi-discover');
|
$this->mergeConfigFrom(__DIR__ . '/../config/fedi-discover.php', 'fedi-discover');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
$this->loadMigrationsFrom(__DIR__.'/../database/migrations');
|
$this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
|
||||||
|
|
||||||
if ($this->app->runningInConsole()) {
|
if ($this->app->runningInConsole()) {
|
||||||
$this->publishes([
|
$this->publishes([
|
||||||
__DIR__.'/../config/fedi-discover.php' => config_path('fedi-discover.php'),
|
__DIR__ . '/../config/fedi-discover.php' => config_path('fedi-discover.php'),
|
||||||
], 'fedi-discover-config');
|
], 'fedi-discover-config');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
121
packages/Lvl0/FediDiscover/tests/Unit/InstanceConfigTest.php
Normal file
121
packages/Lvl0/FediDiscover/tests/Unit/InstanceConfigTest.php
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Lvl0\FediDiscover\Tests\Unit;
|
||||||
|
|
||||||
|
use Lvl0\FediDiscover\Config\InstanceConfig;
|
||||||
|
use Lvl0\FediDiscover\Config\InstanceType;
|
||||||
|
use PHPUnit\Framework\Attributes\DataProvider;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class InstanceConfigTest extends TestCase
|
||||||
|
{
|
||||||
|
public function test_from_array_returns_instance_config_with_correct_field_values(): void
|
||||||
|
{
|
||||||
|
$config = InstanceConfig::fromArray([
|
||||||
|
'type' => 'mastodon',
|
||||||
|
'url' => 'https://mastodon.social',
|
||||||
|
'enabled' => true,
|
||||||
|
'interval_seconds' => 600,
|
||||||
|
'extras' => ['token' => 'abc123'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertSame(InstanceType::Mastodon, $config->type);
|
||||||
|
$this->assertSame('https://mastodon.social', $config->url);
|
||||||
|
$this->assertTrue($config->enabled);
|
||||||
|
$this->assertSame(600, $config->intervalSeconds);
|
||||||
|
$this->assertSame(['token' => 'abc123'], $config->extras);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_from_array_rejects_non_positive_interval_seconds(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
|
||||||
|
InstanceConfig::fromArray([
|
||||||
|
'type' => 'mastodon',
|
||||||
|
'url' => 'https://mastodon.social',
|
||||||
|
'enabled' => true,
|
||||||
|
'interval_seconds' => 0,
|
||||||
|
'extras' => [],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_extras_defaults_to_empty_array_when_omitted(): void
|
||||||
|
{
|
||||||
|
$config = InstanceConfig::fromArray([
|
||||||
|
'type' => 'mastodon',
|
||||||
|
'url' => 'https://mastodon.social',
|
||||||
|
'enabled' => true,
|
||||||
|
'interval_seconds' => 600,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertSame([], $config->extras);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[DataProvider('requiredKeyProvider')]
|
||||||
|
public function test_from_array_throws_when_required_key_is_missing(string $missingKey): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'type' => 'mastodon',
|
||||||
|
'url' => 'https://mastodon.social',
|
||||||
|
'enabled' => true,
|
||||||
|
'interval_seconds' => 600,
|
||||||
|
];
|
||||||
|
|
||||||
|
unset($input[$missingKey]);
|
||||||
|
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessageMatches('/' . preg_quote($missingKey, '/') . '/');
|
||||||
|
|
||||||
|
InstanceConfig::fromArray($input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function requiredKeyProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type missing' => ['type'],
|
||||||
|
'url missing' => ['url'],
|
||||||
|
'enabled missing' => ['enabled'],
|
||||||
|
'interval_seconds missing' => ['interval_seconds'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_from_array_throws_invalid_argument_exception_for_unknown_type_string(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessageMatches('/pleroma/');
|
||||||
|
|
||||||
|
InstanceConfig::fromArray([
|
||||||
|
'type' => 'pleroma',
|
||||||
|
'url' => 'https://pleroma.example.com',
|
||||||
|
'enabled' => true,
|
||||||
|
'interval_seconds' => 600,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_from_array_rejects_malformed_url(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
|
||||||
|
InstanceConfig::fromArray([
|
||||||
|
'type' => 'mastodon',
|
||||||
|
'url' => 'not a url',
|
||||||
|
'enabled' => true,
|
||||||
|
'interval_seconds' => 600,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_to_array_produces_array_that_round_trips_through_from_array(): void
|
||||||
|
{
|
||||||
|
$original = [
|
||||||
|
'type' => 'mastodon',
|
||||||
|
'url' => 'https://mastodon.social',
|
||||||
|
'enabled' => true,
|
||||||
|
'interval_seconds' => 600,
|
||||||
|
'extras' => ['token' => 'abc123'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->assertSame($original, InstanceConfig::fromArray($original)->toArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue