feat: content-query and content-get tools
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Integrations\WordPress\Content;
|
||||
|
||||
use Brain\Monkey\Functions;
|
||||
use LIT\MCP\Abilities\Cursor;
|
||||
use LIT\MCP\Integrations\WordPress\Content\ContentQueryAbility;
|
||||
use LIT\MCP\Integrations\WordPress\Content\PostPresenter;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use LIT\MCP\Tests\Unit\TestCase;
|
||||
use Mockery;
|
||||
use WP_Post;
|
||||
|
||||
final class ContentQueryAbilityTest extends TestCase
|
||||
{
|
||||
private function ability(): ContentQueryAbility
|
||||
{
|
||||
$presenter = Mockery::mock(PostPresenter::class);
|
||||
$presenter->allows('summary')->andReturnUsing(static fn (WP_Post $post): array => ['id' => $post->ID]);
|
||||
|
||||
return new ContentQueryAbility(Mockery::mock(ContentSchema::class), $presenter);
|
||||
}
|
||||
|
||||
public function testBuildsTheQueryAndPaginates(): void
|
||||
{
|
||||
Functions\when('current_user_can')->justReturn(true);
|
||||
Functions\expect('get_posts')->once()->with(Mockery::on(static function (array $args): bool {
|
||||
return $args['post_type'] === 'lit_person'
|
||||
&& $args['post_status'] === ['draft']
|
||||
&& $args['s'] === 'Anna'
|
||||
&& $args['posts_per_page'] === 3
|
||||
&& $args['offset'] === 4
|
||||
&& $args['orderby'] === 'title'
|
||||
&& $args['order'] === 'ASC'
|
||||
&& $args['tax_query'] === [
|
||||
'relation' => 'OR',
|
||||
['taxonomy' => 'category', 'field' => 'term_id', 'terms' => [4]],
|
||||
['taxonomy' => 'category', 'field' => 'slug', 'terms' => ['news']],
|
||||
]
|
||||
&& $args['meta_query'] === [['key' => 'level', 'compare' => '=', 'value' => 'senior']]
|
||||
&& $args['date_query'] === [['after' => '2026-01-01', 'inclusive' => true]];
|
||||
}))->andReturn([new WP_Post(['ID' => 1]), new WP_Post(['ID' => 2]), new WP_Post(['ID' => 3])]);
|
||||
|
||||
$result = $this->ability()->execute([
|
||||
'post_type' => 'lit_person',
|
||||
'status' => ['draft'],
|
||||
'search' => 'Anna',
|
||||
'taxonomy' => ['taxonomy' => 'category', 'terms' => [4, 'news']],
|
||||
'field' => ['key' => 'level', 'value' => 'senior'],
|
||||
'date_after' => '2026-01-01',
|
||||
'orderby' => 'title',
|
||||
'order' => 'asc',
|
||||
'limit' => 2,
|
||||
'cursor' => Cursor::encode(4),
|
||||
]);
|
||||
|
||||
self::assertSame([['id' => 1], ['id' => 2]], $result['items']);
|
||||
self::assertSame(6, Cursor::decode($result['next_cursor']));
|
||||
}
|
||||
|
||||
public function testExistsFilterHasNoValueAndLastPageHasNoCursor(): void
|
||||
{
|
||||
Functions\when('current_user_can')->justReturn(true);
|
||||
Functions\expect('get_posts')->once()->with(Mockery::on(
|
||||
static fn (array $args): bool => $args['meta_query'] === [['key' => 'role', 'compare' => 'EXISTS']]
|
||||
&& $args['post_status'] === ['publish', 'draft', 'pending', 'private', 'future']
|
||||
))->andReturn([new WP_Post(['ID' => 1])]);
|
||||
|
||||
$result = $this->ability()->execute(['post_type' => 'page', 'field' => ['key' => 'role', 'compare' => 'EXISTS']]);
|
||||
|
||||
self::assertNull($result['next_cursor']);
|
||||
}
|
||||
|
||||
public function testPostsTheUserCannotEditAreDropped(): void
|
||||
{
|
||||
Functions\when('current_user_can')->alias(static fn (string $cap, int $id = 0): bool => $id !== 2);
|
||||
Functions\when('get_posts')->justReturn([new WP_Post(['ID' => 1]), new WP_Post(['ID' => 2])]);
|
||||
|
||||
$result = $this->ability()->execute(['post_type' => 'page']);
|
||||
|
||||
self::assertSame([['id' => 1]], $result['items']);
|
||||
}
|
||||
|
||||
public function testInvalidCursorIsRejected(): void
|
||||
{
|
||||
$result = $this->ability()->execute(['post_type' => 'page', 'cursor' => '???']);
|
||||
|
||||
self::assertSame('lit_validation_failed', $result->get_error_code());
|
||||
}
|
||||
|
||||
public function testPermissionNeedsAManagedTypeAndEditRights(): void
|
||||
{
|
||||
$schema = Mockery::mock(ContentSchema::class);
|
||||
$schema->allows('isManaged')->andReturn(false);
|
||||
$ability = new ContentQueryAbility($schema, Mockery::mock(PostPresenter::class));
|
||||
|
||||
self::assertSame('lit_not_found', $ability->permission(['post_type' => 'secret'])->get_error_code());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user