You've already forked wp-prometheus
377 lines
12 KiB
PHP
377 lines
12 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace Magdev\WpPrometheus\Tests\Unit\Admin;
|
||
|
|
|
||
|
|
use Magdev\WpPrometheus\Admin\DashboardProvider;
|
||
|
|
use Magdev\WpPrometheus\Tests\Helpers\GlobalFunctionState;
|
||
|
|
use Magdev\WpPrometheus\Tests\Unit\TestCase;
|
||
|
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||
|
|
use PHPUnit\Framework\Attributes\Test;
|
||
|
|
|
||
|
|
#[CoversClass(DashboardProvider::class)]
|
||
|
|
class DashboardProviderTest extends TestCase
|
||
|
|
{
|
||
|
|
private DashboardProvider $provider;
|
||
|
|
|
||
|
|
protected function setUp(): void
|
||
|
|
{
|
||
|
|
parent::setUp();
|
||
|
|
$this->provider = new DashboardProvider();
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── register_dashboard() - Validation ────────────────────────────
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_with_inline_json_succeeds(): void
|
||
|
|
{
|
||
|
|
$result = $this->provider->register_dashboard('my-dashboard', [
|
||
|
|
'title' => 'My Dashboard',
|
||
|
|
'json' => '{"panels":[]}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertTrue($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_rejects_empty_slug(): void
|
||
|
|
{
|
||
|
|
$result = $this->provider->register_dashboard('', [
|
||
|
|
'title' => 'Test',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_rejects_invalid_slug_characters(): void
|
||
|
|
{
|
||
|
|
// sanitize_key removes all non [a-z0-9_-] characters
|
||
|
|
// A slug like '!@#' becomes '' after sanitize_key
|
||
|
|
$result = $this->provider->register_dashboard('!@#', [
|
||
|
|
'title' => 'Test',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_rejects_duplicate_builtin_slug(): void
|
||
|
|
{
|
||
|
|
$result = $this->provider->register_dashboard('wordpress-overview', [
|
||
|
|
'title' => 'Override Built-in',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_rejects_duplicate_registered_slug(): void
|
||
|
|
{
|
||
|
|
$this->provider->register_dashboard('my-dashboard', [
|
||
|
|
'title' => 'First',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$result = $this->provider->register_dashboard('my-dashboard', [
|
||
|
|
'title' => 'Second',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_requires_title(): void
|
||
|
|
{
|
||
|
|
$result = $this->provider->register_dashboard('no-title', [
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_requires_file_or_json(): void
|
||
|
|
{
|
||
|
|
$result = $this->provider->register_dashboard('no-content', [
|
||
|
|
'title' => 'No Content',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_rejects_both_file_and_json(): void
|
||
|
|
{
|
||
|
|
$fileExists = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'file_exists');
|
||
|
|
$fileExists->expects($this->any())->willReturn(true);
|
||
|
|
|
||
|
|
$isReadable = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'is_readable');
|
||
|
|
$isReadable->expects($this->any())->willReturn(true);
|
||
|
|
|
||
|
|
$realpath = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'realpath');
|
||
|
|
$realpath->expects($this->any())->willReturnArgument(0);
|
||
|
|
|
||
|
|
$result = $this->provider->register_dashboard('both', [
|
||
|
|
'title' => 'Both',
|
||
|
|
'file' => '/tmp/wordpress/wp-content/plugins/test/dashboard.json',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_file_requires_absolute_path(): void
|
||
|
|
{
|
||
|
|
$result = $this->provider->register_dashboard('relative', [
|
||
|
|
'title' => 'Relative Path',
|
||
|
|
'file' => 'relative/path/dashboard.json',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_file_must_exist(): void
|
||
|
|
{
|
||
|
|
$fileExists = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'file_exists');
|
||
|
|
$fileExists->expects($this->any())->willReturn(false);
|
||
|
|
|
||
|
|
$result = $this->provider->register_dashboard('missing-file', [
|
||
|
|
'title' => 'Missing File',
|
||
|
|
'file' => '/tmp/wordpress/wp-content/plugins/test/nonexistent.json',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_file_rejects_path_traversal(): void
|
||
|
|
{
|
||
|
|
$fileExists = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'file_exists');
|
||
|
|
$fileExists->expects($this->any())->willReturn(true);
|
||
|
|
|
||
|
|
$isReadable = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'is_readable');
|
||
|
|
$isReadable->expects($this->any())->willReturn(true);
|
||
|
|
|
||
|
|
$realpath = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'realpath');
|
||
|
|
$realpath->expects($this->any())->willReturnArgument(0);
|
||
|
|
|
||
|
|
$result = $this->provider->register_dashboard('evil', [
|
||
|
|
'title' => 'Evil Dashboard',
|
||
|
|
'file' => '/etc/passwd',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_file_accepts_path_under_wp_content(): void
|
||
|
|
{
|
||
|
|
$fileExists = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'file_exists');
|
||
|
|
$fileExists->expects($this->any())->willReturn(true);
|
||
|
|
|
||
|
|
$isReadable = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'is_readable');
|
||
|
|
$isReadable->expects($this->any())->willReturn(true);
|
||
|
|
|
||
|
|
$realpath = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'realpath');
|
||
|
|
$realpath->expects($this->any())->willReturnArgument(0);
|
||
|
|
|
||
|
|
$result = $this->provider->register_dashboard('valid-file', [
|
||
|
|
'title' => 'Valid File Dashboard',
|
||
|
|
'file' => '/tmp/wordpress/wp-content/plugins/my-plugin/dashboard.json',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertTrue($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_rejects_invalid_inline_json(): void
|
||
|
|
{
|
||
|
|
$result = $this->provider->register_dashboard('bad-json', [
|
||
|
|
'title' => 'Bad JSON',
|
||
|
|
'json' => '{invalid json',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function register_sets_source_to_third_party(): void
|
||
|
|
{
|
||
|
|
$this->provider->register_dashboard('ext-dashboard', [
|
||
|
|
'title' => 'Extension',
|
||
|
|
'json' => '{}',
|
||
|
|
'plugin' => 'My Plugin',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertTrue($this->provider->is_third_party('ext-dashboard'));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── get_available() ──────────────────────────────────────────────
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_available_includes_builtin_dashboards(): void
|
||
|
|
{
|
||
|
|
$fileExists = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'file_exists');
|
||
|
|
$fileExists->expects($this->any())->willReturn(true);
|
||
|
|
|
||
|
|
$available = $this->provider->get_available();
|
||
|
|
|
||
|
|
$this->assertArrayHasKey('wordpress-overview', $available);
|
||
|
|
$this->assertArrayHasKey('wordpress-runtime', $available);
|
||
|
|
$this->assertArrayHasKey('wordpress-woocommerce', $available);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_available_includes_registered_dashboards(): void
|
||
|
|
{
|
||
|
|
$fileExists = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'file_exists');
|
||
|
|
$fileExists->expects($this->any())->willReturn(true);
|
||
|
|
|
||
|
|
$this->provider->register_dashboard('custom-dash', [
|
||
|
|
'title' => 'Custom',
|
||
|
|
'json' => '{"panels":[]}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$available = $this->provider->get_available();
|
||
|
|
$this->assertArrayHasKey('custom-dash', $available);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_available_excludes_builtin_with_missing_file(): void
|
||
|
|
{
|
||
|
|
$fileExists = $this->getFunctionMock('Magdev\\WpPrometheus\\Admin', 'file_exists');
|
||
|
|
$fileExists->expects($this->any())->willReturn(false);
|
||
|
|
|
||
|
|
$available = $this->provider->get_available();
|
||
|
|
|
||
|
|
// Built-in dashboards should be excluded (files don't exist).
|
||
|
|
$this->assertArrayNotHasKey('wordpress-overview', $available);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── is_third_party() ─────────────────────────────────────────────
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function builtin_dashboard_is_not_third_party(): void
|
||
|
|
{
|
||
|
|
$this->assertFalse($this->provider->is_third_party('wordpress-overview'));
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function registered_dashboard_is_third_party(): void
|
||
|
|
{
|
||
|
|
$this->provider->register_dashboard('ext-dash', [
|
||
|
|
'title' => 'Extension Dashboard',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertTrue($this->provider->is_third_party('ext-dash'));
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function unknown_slug_is_not_third_party(): void
|
||
|
|
{
|
||
|
|
$this->assertFalse($this->provider->is_third_party('nonexistent'));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── get_plugin_name() ────────────────────────────────────────────
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_plugin_name_returns_name_for_registered(): void
|
||
|
|
{
|
||
|
|
$this->provider->register_dashboard('ext-dash', [
|
||
|
|
'title' => 'Extension',
|
||
|
|
'json' => '{}',
|
||
|
|
'plugin' => 'My Awesome Plugin',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertSame('My Awesome Plugin', $this->provider->get_plugin_name('ext-dash'));
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_plugin_name_returns_null_for_builtin(): void
|
||
|
|
{
|
||
|
|
$this->assertNull($this->provider->get_plugin_name('wordpress-overview'));
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_plugin_name_returns_null_when_empty(): void
|
||
|
|
{
|
||
|
|
$this->provider->register_dashboard('no-plugin', [
|
||
|
|
'title' => 'No Plugin',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertNull($this->provider->get_plugin_name('no-plugin'));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── get_filename() ───────────────────────────────────────────────
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_filename_returns_file_for_builtin(): void
|
||
|
|
{
|
||
|
|
$filename = $this->provider->get_filename('wordpress-overview');
|
||
|
|
$this->assertSame('wordpress-overview.json', $filename);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_filename_returns_slug_json_for_inline(): void
|
||
|
|
{
|
||
|
|
$this->provider->register_dashboard('my-dash', [
|
||
|
|
'title' => 'My Dashboard',
|
||
|
|
'json' => '{}',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->assertSame('my-dash.json', $this->provider->get_filename('my-dash'));
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_filename_returns_null_for_unknown(): void
|
||
|
|
{
|
||
|
|
$this->assertNull($this->provider->get_filename('nonexistent'));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── get_metadata() ───────────────────────────────────────────────
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_metadata_returns_builtin_data(): void
|
||
|
|
{
|
||
|
|
$metadata = $this->provider->get_metadata('wordpress-overview');
|
||
|
|
|
||
|
|
$this->assertIsArray($metadata);
|
||
|
|
$this->assertSame('WordPress Overview', $metadata['title']);
|
||
|
|
$this->assertSame('builtin', $metadata['source']);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_metadata_returns_registered_data(): void
|
||
|
|
{
|
||
|
|
$this->provider->register_dashboard('ext-dash', [
|
||
|
|
'title' => 'Extension',
|
||
|
|
'description' => 'A test dashboard',
|
||
|
|
'json' => '{}',
|
||
|
|
'plugin' => 'TestPlugin',
|
||
|
|
]);
|
||
|
|
|
||
|
|
$metadata = $this->provider->get_metadata('ext-dash');
|
||
|
|
|
||
|
|
$this->assertIsArray($metadata);
|
||
|
|
$this->assertSame('Extension', $metadata['title']);
|
||
|
|
$this->assertSame('third-party', $metadata['source']);
|
||
|
|
$this->assertSame('TestPlugin', $metadata['plugin']);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[Test]
|
||
|
|
public function get_metadata_returns_null_for_unknown(): void
|
||
|
|
{
|
||
|
|
$this->assertNull($this->provider->get_metadata('nonexistent'));
|
||
|
|
}
|
||
|
|
}
|