*/ private array $options = []; protected function setUp(): void { parent::setUp(); $this->options = []; Functions\when('get_option')->alias( fn (string $name, mixed $default = false): mixed => $this->options[$name] ?? $default ); Functions\when('update_option')->alias(function (string $name, mixed $value, mixed $autoload = null): bool { $this->options[$name] = $value; self::assertFalse($autoload, 'releases are read only by the gate – no autoload'); return true; }); } public function testAddsFindsAndWithdrawsPerVersionAndPluginVersion(): void { $store = new ReleaseStore('divi', 'divi_version'); $store->add('5.3.0', '0.6.0', 1, 'r1'); $store->add('5.3.0', '0.6.0', 2, 'r2'); self::assertCount(1, $store->entries(), 'one entry per version pair'); self::assertSame(2, $store->find('5.3.0', '0.6.0')['user_id'] ?? null); self::assertNull($store->find('5.3.0', '0.7.0'), 'another plugin version needs its own check'); self::assertTrue($store->withdraw('5.3.0', '0.6.0')); self::assertFalse($store->withdraw('5.3.0', '0.6.0')); self::assertSame([], $store->entries()); } public function testDiviKeepsOptionAndFormat(): void { $this->options['lit_mcp_divi_releases'] = [[ 'divi_version' => '5.2.2', 'plugin_version' => '0.6.0', 'user_id' => 3, 'released_at' => '2026-10-01T08:00:00+00:00', 'report_id' => 'r', ]]; $store = new ReleaseStore('divi', 'divi_version'); self::assertSame('r', $store->find('5.2.2', '0.6.0')['report_id'] ?? null); $store->add('5.3.0', '0.6.0', 1, 'r1'); $written = $this->options['lit_mcp_divi_releases']; self::assertSame(['lit_mcp_divi_releases'], array_keys($this->options)); self::assertSame( ['divi_version', 'plugin_version', 'user_id', 'released_at', 'report_id'], array_keys($written[1]) ); self::assertSame($this->options['lit_mcp_divi_releases'][0], [ 'divi_version' => '5.2.2', 'plugin_version' => '0.6.0', 'user_id' => 3, 'released_at' => '2026-10-01T08:00:00+00:00', 'report_id' => 'r', ]); } public function testAnotherProfileGetsItsOwnOptionAndTheVersionKey(): void { $store = new ReleaseStore('pods'); $store->add('3.3.9.2', '0.6.0', 1, 'r1'); self::assertSame(['lit_mcp_pods_releases'], array_keys($this->options)); self::assertSame('3.3.9.2', $this->options['lit_mcp_pods_releases'][0]['version']); self::assertSame('r1', $store->find('3.3.9.2', '0.6.0')['report_id'] ?? null); self::assertSame([], (new ReleaseStore('divi', 'divi_version'))->entries()); } public function testIgnoresBrokenRows(): void { $this->options['lit_mcp_divi_releases'] = ['x', ['divi_version' => '5.3.0'], [ 'divi_version' => '5.2.2', 'plugin_version' => '0.6.0', 'user_id' => 3, 'released_at' => 'd', 'report_id' => 'r', ]]; self::assertSame(['5.2.2'], array_column((new ReleaseStore('divi', 'divi_version'))->entries(), 'divi_version')); self::assertSame([], (new ReleaseStore('divi'))->entries(), 'rows hold divi_version, not version'); } }