agent/php/tests/Feature/Mod/Admin/SearchProviderRegistryTest.php
Snider f96bd67bd6 feat(agent/admin+hub): RFC foundation — admin scaffold + Hub global components
Foundation slice for Mantis #843 php/Mod/Admin + php/Website/Hub RFC:

* php/Mod/Admin/Boot.php — search registry, menu registry, form component
  layer, HasRateLimiting concern, reusable form/view primitives under
  Mod/Admin/Forms
* php/Website/Hub/Boot.php — host-aware Hub route naming for secondary
  domains
* WorkspaceSwitcher and GlobalSearch global Hub Livewire components
* Foundation routed slice in Hub/Routes/admin.php: dashboard shell,
  workspace listing, site settings (with WordPress/webhook connector),
  account usage, platform user list+detail
* Foundation tests under php/tests/Feature/Mod/Admin/

53 PHP files. php -l clean. Pest unrunnable in sandbox (no vendor/).

Foundation slice only — composer.json kept off-limits so namespace stays
under Core\Mod\Agentic\... rather than standalone Core\Admin package.
Deferred: Profile, Settings, ServiceManager, ServicesAdmin, Honeypot,
Entitlement\{Dashboard,FeatureManager,PackageManager}, PromptManager,
WaitlistManager, Console, Databases, Deployments, Content,
ContentManager, ContentEditor, ActivityLog, Analytics, AIServices,
BoostPurchase. Lane was under-instructed by supervisor with stop-at
framing — follow-up tickets needed for remainder.

Co-authored-by: Codex <noreply@openai.com>
Closes tasks.lthn.sh/view.php?id=843
2026-04-25 21:09:22 +01:00

67 lines
2.1 KiB
PHP

<?php
// SPDX-License-Identifier: EUPL-1.2
declare(strict_types=1);
namespace Core\Mod\Agentic\Tests\Feature\Mod\Admin;
use Core\Mod\Agentic\Mod\Admin\Search\Contracts\SearchProvider;
use Core\Mod\Agentic\Mod\Admin\Search\SearchProviderRegistry;
use Core\Mod\Agentic\Mod\Admin\Search\SearchResult;
class SearchProviderRegistryTest extends AdminTestCase
{
public function test_SearchProviderRegistry_register_Good(): void
{
$registry = new SearchProviderRegistry;
$registry->register($this->makeProvider());
$this->assertCount(1, $registry->providers());
}
public function test_SearchProviderRegistry_search_Good_groups_results(): void
{
$registry = new SearchProviderRegistry;
$registry->register($this->makeProvider());
$results = $registry->search('dash', $this->hadesUser);
$this->assertArrayHasKey('pages', $results);
$this->assertSame('Pages', $results['pages']['label']);
$this->assertCount(2, $results['pages']['results']);
}
public function test_SearchProviderRegistry_fuzzyMatch_Ugly_handles_abbreviations(): void
{
$registry = new SearchProviderRegistry;
$this->assertTrue($registry->fuzzyMatch('gs', 'Global Search'));
$this->assertTrue($registry->fuzzyMatch('dbd', 'dashboard'));
$this->assertFalse($registry->fuzzyMatch('zzz', 'dashboard'));
}
protected function makeProvider(): SearchProvider
{
return new class implements SearchProvider
{
public function search(string $query): array
{
return [
new SearchResult('1', 'admin_page', 'Dashboard', 'Hub landing page', '/hub', 'house'),
new SearchResult('2', 'admin_page', 'Usage', 'Usage page', '/hub/account/usage', 'chart-pie'),
];
}
public function name(): string
{
return 'Pages';
}
public function icon(): string
{
return 'rectangle-stack';
}
};
}
}