Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Blocks/DynamicContent/DynamicLoopBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function renderWithInner( array $attrs, array $innerBlocks )
return '<div class="ve-dynamic-loop-empty" role="note">No records to display.</div>';
}

$rendererClass = '\\ArtisanPackUI\\VisualEditorRendererBlade\\BlockRenderer';
$rendererClass = 'ArtisanPackUI\\VisualEditorRendererBlade\\BlockRenderer';

if ( ! class_exists( $rendererClass ) ) {
return '';
Expand Down
2 changes: 1 addition & 1 deletion src/Blocks/DynamicContent/SnippetBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public function render( array $attrs )
*/
protected function renderTree( array $blocks, string $ownerSlug ): string
{
$rendererClass = '\\ArtisanPackUI\\VisualEditorRendererBlade\\BlockRenderer';
$rendererClass = 'ArtisanPackUI\\VisualEditorRendererBlade\\BlockRenderer';

if ( ! class_exists( $rendererClass ) ) {
return '';
Expand Down
7 changes: 5 additions & 2 deletions src/Http/Controllers/EntitySearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,12 @@ public function index( Request $request ): JsonResponse
*/
protected function searchCmsFrameworkEntities( string $type, string $needle ): array
{
// No leading backslash: the container does not normalise FQCN
// keys, so `'\Foo\Bar'` would miss a binding registered under
// `Foo\Bar::class` and silently build a fresh resolver instead.
$resolverClass = 'template' === $type
? '\\ArtisanPackUI\\CMSFramework\\Modules\\SiteEditor\\Resolution\\TemplateResolver'
: '\\ArtisanPackUI\\CMSFramework\\Modules\\SiteEditor\\Resolution\\TemplatePartResolver';
? 'ArtisanPackUI\\CMSFramework\\Modules\\SiteEditor\\Resolution\\TemplateResolver'
: 'ArtisanPackUI\\CMSFramework\\Modules\\SiteEditor\\Resolution\\TemplatePartResolver';

if ( ! class_exists( $resolverClass ) ) {
return [];
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/MenuLocationsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ public function index(): JsonResponse
return response()->json( [ 'data' => [] ] );
}

$themeManagerClass = '\\ArtisanPackUI\\CMSFramework\\Modules\\Themes\\Managers\\ThemeManager';
$assignmentClass = '\\ArtisanPackUI\\CMSFramework\\Modules\\SiteEditor\\Models\\MenuLocationAssignment';
$themeManagerClass = 'ArtisanPackUI\\CMSFramework\\Modules\\Themes\\Managers\\ThemeManager';
$assignmentClass = 'ArtisanPackUI\\CMSFramework\\Modules\\SiteEditor\\Models\\MenuLocationAssignment';
$themeManager = app( $themeManagerClass );
$activeTheme = $themeManager->getActiveTheme();
$activeSlug = is_array( $activeTheme ) && ! empty( $activeTheme['slug'] ) ? (string) $activeTheme['slug'] : null;
Expand Down
2 changes: 1 addition & 1 deletion src/Visibility/VisibilityEvaluator.php
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ protected function fireEvaluatedHook(
*/
protected function resolveRoles( object $user ): array
{
$manager = '\\ArtisanPackUI\\CMSFramework\\Modules\\Users\\Managers\\RoleManager';
$manager = 'ArtisanPackUI\\CMSFramework\\Modules\\Users\\Managers\\RoleManager';

if ( class_exists( $manager ) ) {
try {
Expand Down
2 changes: 1 addition & 1 deletion src/VisualEditorServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ public function register(): void
*/
protected function registerQueryResolverBinding(): void
{
$cmsRuntime = '\\ArtisanPackUI\\CMSFramework\\Modules\\Blog\\Services\\QueryRuntime';
$cmsRuntime = 'ArtisanPackUI\\CMSFramework\\Modules\\Blog\\Services\\QueryRuntime';

if ( ! class_exists( $cmsRuntime ) ) {
return;
Expand Down
100 changes: 94 additions & 6 deletions tests/Feature/VisualEditor/EntitySearchControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,52 @@

declare( strict_types=1 );

use ArtisanPackUI\CMSFramework\Modules\SiteEditor\Resolution\ResolvedEntity;
use ArtisanPackUI\CMSFramework\Modules\SiteEditor\Resolution\TemplatePartResolver;
use ArtisanPackUI\CMSFramework\Modules\SiteEditor\Resolution\TemplateResolver;
use Tests\TestUser;

/*
* Template + template-part searches reach cms-framework's
* `TemplateResolver` / `TemplatePartResolver` (see
* `src/Http/Controllers/EntitySearchController.php`). The resolvers
* aren't bound in this Testbench environment, so the template /
* template-part branches return empty data — the consuming app's test
* suite covers the populated path.
* `src/Http/Controllers/EntitySearchController.php`). No theme is
* active in this Testbench environment, so the real resolvers return
* nothing and the template / template-part branches come back empty —
* the consuming app's test suite covers the populated path. The
* override tests below bind stand-in resolvers to prove the controller
* resolves them through the container.
*
* Resource-config sources (pages, posts, etc.) are still testable
* here because they go through Eloquent directly via the
* `artisanpack.visual-editor.resources` map.
*/

/**
* Builds the `ResolvedEntity` rows a stand-in resolver hands back.
* `area` is null for templates and the part's own area for parts,
* matching what cms-framework's resolvers emit.
*
* @param list<array{slug: string, title: string, area?: string}> $rows
* @return list<ResolvedEntity>
*/
function entitySearchStubEntities( array $rows ): array
{
return array_map( static fn ( array $row ): ResolvedEntity => new ResolvedEntity(
slug: $row['slug'],
theme: 'artisanpack-ui',
source: 'theme',
raw: '',
blocks: [],
title: $row['title'],
description: '',
status: 'publish',
hasThemeFile: true,
isCustom: false,
area: $row['area'] ?? null,
model: null,
), $rows );
}

function actingAsSearchUser(): TestUser
{
$user = TestUser::create( [
Expand Down Expand Up @@ -46,18 +77,75 @@ function actingAsSearchUser(): TestUser
->assertJsonPath( 'data', [] );
} );

it( 'returns an empty data array for template type when cms-framework is not installed', function () {
it( 'returns an empty data array for template type when no theme resolves', function () {
actingAsSearchUser();

$this->getJson( '/visual-editor/api/search?type=template' )
->assertOk()
->assertJsonPath( 'data', [] );
} );

it( 'returns an empty data array for template-part type when cms-framework is not installed', function () {
it( 'returns an empty data array for template-part type when no theme resolves', function () {
actingAsSearchUser();

$this->getJson( '/visual-editor/api/search?type=template-part' )
->assertOk()
->assertJsonPath( 'data', [] );
} );

/*
* #692 — the controller used to build the resolver FQCN with a leading
* backslash. Laravel's container doesn't normalise that, so a binding
* registered under `TemplateResolver::class` was skipped and a fresh
* resolver was constructed instead. These two tests fail against the
* old string and pass against the canonical key.
*/

it( 'resolves the template resolver through the container so hosts can override it', function () {
actingAsSearchUser();

app()->instance( TemplateResolver::class, new class extends TemplateResolver
{
public function __construct()
{
}

public function all(): array
{
return entitySearchStubEntities( [
[ 'slug' => 'single', 'title' => 'Single Post' ],
[ 'slug' => 'archive', 'title' => 'Archive' ],
] );
}
} );

$this->getJson( '/visual-editor/api/search?type=template' )
->assertOk()
->assertJsonPath( 'data.0', [ 'type' => 'template', 'id' => 'archive', 'title' => 'Archive', 'url' => null ] )
->assertJsonPath( 'data.1', [ 'type' => 'template', 'id' => 'single', 'title' => 'Single Post', 'url' => null ] );
} );

it( 'resolves the template-part resolver through the container so hosts can override it', function () {
actingAsSearchUser();

app()->instance( TemplatePartResolver::class, new class extends TemplatePartResolver
{
public function __construct()
{
}

public function all(): array
{
return entitySearchStubEntities( [
[ 'slug' => 'header', 'title' => 'Header', 'area' => 'header' ],
[ 'slug' => 'footer', 'title' => 'Footer', 'area' => 'footer' ],
] );
}
} );

$this->getJson( '/visual-editor/api/search?type=template-part&q=head' )
->assertOk()
->assertJsonPath( 'data', [
[ 'type' => 'template-part', 'id' => 'header', 'title' => 'Header', 'url' => null ],
] );
} );
Loading