Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
108 lines
3.7 KiB
PHP
108 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Release;
|
|
|
|
use Brain\Monkey\Functions;
|
|
use LIT\MCP\Integrations\Divi\Release\ManifestCheck;
|
|
use LIT\MCP\Integrations\Divi\Release\ReleaseResolver;
|
|
use LIT\MCP\Integrations\Divi\Release\ReleaseState;
|
|
use LIT\MCP\Integrations\Divi\Release\ReleaseStore;
|
|
use LIT\MCP\Plugin;
|
|
use LIT\MCP\Tests\Unit\TestCase;
|
|
use Mockery;
|
|
|
|
final class ReleaseResolverTest extends TestCase
|
|
{
|
|
/** @var array<string, mixed> */
|
|
private array $transients = [];
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->transients = [];
|
|
Functions\when('get_transient')->alias(fn (string $key): mixed => $this->transients[$key] ?? false);
|
|
Functions\when('set_transient')->alias(function (string $key, mixed $value): bool {
|
|
$this->transients[$key] = $value;
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param array<string, callable(): bool> $code
|
|
* @param array<string, callable(): bool> $mirrors
|
|
*/
|
|
private function resolver(
|
|
string $version,
|
|
array $code = [],
|
|
array $mirrors = [],
|
|
?array $entry = null
|
|
): ReleaseResolver {
|
|
$check = Mockery::mock(ManifestCheck::class);
|
|
$check->allows('codeChecks')->andReturn($code);
|
|
$check->allows('mirrorChecks')->andReturn($mirrors);
|
|
$store = Mockery::mock(ReleaseStore::class);
|
|
$store->allows('find')->with($version, Plugin::VERSION)->andReturn($entry);
|
|
|
|
return new ReleaseResolver(
|
|
$check,
|
|
$store,
|
|
static fn (): ?string => $version,
|
|
static fn (string $v): string => 'key-' . $v
|
|
);
|
|
}
|
|
|
|
public function testATestedVersionWithGreenChecksIsReleasedFromCode(): void
|
|
{
|
|
$status = $this->resolver('5.2.1')->resolve();
|
|
|
|
self::assertSame(ReleaseState::Released, $status->state);
|
|
self::assertSame('code', $status->source);
|
|
}
|
|
|
|
public function testAnUnknownVersionIsUntestedUnlessTheDatabaseReleasedIt(): void
|
|
{
|
|
self::assertSame(ReleaseState::Untested, $this->resolver('5.3.0')->resolve()->state);
|
|
|
|
$released = $this->resolver('5.3.0', entry: ['user_id' => 1, 'released_at' => 'd'])->resolve();
|
|
self::assertSame(ReleaseState::Released, $released->state);
|
|
self::assertSame('database', $released->source);
|
|
}
|
|
|
|
public function testAFailedCheckMakesEvenATestedVersionIncompatible(): void
|
|
{
|
|
$status = $this->resolver('5.2.1', ['Seiten: et_x()' => static fn (): bool => false])->resolve();
|
|
|
|
self::assertSame(ReleaseState::Incompatible, $status->state);
|
|
self::assertSame(['Seiten: et_x()'], $status->problems);
|
|
}
|
|
|
|
public function testMirrorResultsAreCachedByStateKey(): void
|
|
{
|
|
$calls = 0;
|
|
$mirrors = ['Theme Builder: Nachbau von y()' => static function () use (&$calls): bool {
|
|
++$calls;
|
|
|
|
return false;
|
|
}];
|
|
|
|
$first = $this->resolver('5.2.1', mirrors: $mirrors)->resolve();
|
|
$second = $this->resolver('5.2.1', mirrors: $mirrors)->resolve();
|
|
|
|
self::assertSame(1, $calls, 'the second resolve reads the transient');
|
|
self::assertSame(ReleaseState::Incompatible, $second->state);
|
|
self::assertSame($first->problems, $second->problems);
|
|
self::assertSame('key-5.2.1', $this->transients[ReleaseResolver::CACHE]['key']);
|
|
|
|
$this->resolver('5.2.2', mirrors: $mirrors)->resolve();
|
|
self::assertSame(2, $calls, 'another state key checks again');
|
|
}
|
|
|
|
public function testWithoutDiviTheVersionIsEmptyAndUntested(): void
|
|
{
|
|
self::assertSame(ReleaseState::Untested, $this->resolver('')->resolve()->state);
|
|
}
|
|
}
|