fix: check WordPress meta capabilities per field key
Fields from the meta/sample sources need edit_post_meta (update, checked in PostWriter::prepare) or add_post_meta (create, checked right after the insert; a refusal deletes the new draft again) for their key; a refusal is a fields.<key> validation error. 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:
@@ -39,6 +39,7 @@ final class ContentCreateAbilityTest extends TestCase
|
||||
$writer = Mockery::mock(PostWriter::class);
|
||||
$writer->allows('prepare')->andReturn(['fields' => ['role' => 'Leitung'], 'terms' => [], 'warnings' => $warnings]);
|
||||
$writer->allows('postData')->andReturn(['post_title' => 'Anna']);
|
||||
$writer->allows('deniedMeta')->andReturn([]);
|
||||
Functions\when('get_current_user_id')->justReturn(3);
|
||||
|
||||
return $writer;
|
||||
@@ -85,6 +86,7 @@ final class ContentCreateAbilityTest extends TestCase
|
||||
$writer = Mockery::mock(PostWriter::class);
|
||||
$writer->allows('prepare')->with('lit_person', $input, true)->andReturn($prepared);
|
||||
$writer->allows('postData')->andReturn(['post_title' => 'Anna']);
|
||||
$writer->expects('deniedMeta')->with(42, 'lit_person', ['role' => 'Leitung'], 'add_post_meta')->andReturn([]);
|
||||
$writer->expects('writeExtras')->with(42, 'lit_person', $prepared, $input);
|
||||
Functions\when('get_current_user_id')->justReturn(3);
|
||||
Functions\expect('wp_insert_post')->once()->with([
|
||||
@@ -126,6 +128,47 @@ final class ContentCreateAbilityTest extends TestCase
|
||||
self::assertSame('lit_write_failed', $failure->toError()->get_error_code());
|
||||
}
|
||||
|
||||
public function testMetaFieldsTheUserMayNotAddAreRefusedAndTheDraftIsRemoved(): void
|
||||
{
|
||||
$writer = Mockery::mock(PostWriter::class);
|
||||
$writer->allows('prepare')->andReturn(['fields' => ['city' => 'Trier'], 'terms' => [], 'warnings' => []]);
|
||||
$writer->allows('postData')->andReturn(['post_title' => 'Anna']);
|
||||
$writer->expects('deniedMeta')->with(42, 'lit_person', ['city' => 'Trier'], 'add_post_meta')
|
||||
->andReturn(['fields.city' => 'Keine Berechtigung, dieses Feld zu ändern.']);
|
||||
$writer->expects('writeExtras')->never();
|
||||
Functions\when('get_current_user_id')->justReturn(3);
|
||||
Functions\when('wp_insert_post')->justReturn(42);
|
||||
Functions\expect('wp_delete_post')->once()->with(42, true)->andReturn(new WP_Post(['ID' => 42]));
|
||||
$log = Mockery::mock(ChangeLog::class);
|
||||
$log->expects('record')->never();
|
||||
|
||||
$result = (new ContentCreateAbility($this->schema(), $writer, $log))->execute(self::INPUT);
|
||||
|
||||
self::assertSame('lit_validation_failed', $result->get_error_code());
|
||||
self::assertArrayHasKey('fields.city', $result->get_error_data()['fields']);
|
||||
}
|
||||
|
||||
public function testARefusedDraftThatCannotBeDeletedIsAPartialWrite(): void
|
||||
{
|
||||
$writer = Mockery::mock(PostWriter::class);
|
||||
$writer->allows('prepare')->andReturn(['fields' => ['city' => 'Trier'], 'terms' => [], 'warnings' => []]);
|
||||
$writer->allows('postData')->andReturn(['post_title' => 'Anna']);
|
||||
$writer->allows('deniedMeta')->andReturn(['fields.city' => 'Keine Berechtigung, dieses Feld zu ändern.']);
|
||||
Functions\when('get_current_user_id')->justReturn(3);
|
||||
Functions\when('wp_insert_post')->justReturn(42);
|
||||
Functions\when('wp_delete_post')->justReturn(false);
|
||||
$log = Mockery::mock(ChangeLog::class);
|
||||
$log->expects('recordPartial');
|
||||
|
||||
try {
|
||||
(new ContentCreateAbility($this->schema(), $writer, $log))->execute(self::INPUT);
|
||||
self::fail('WriteFailed expected');
|
||||
} catch (WriteFailed $e) {
|
||||
self::assertFalse($e->rolledBack);
|
||||
self::assertSame(42, $e->postId);
|
||||
}
|
||||
}
|
||||
|
||||
public function testADraftThatCannotBeDeletedIsAPartialWriteAndLogged(): void
|
||||
{
|
||||
$writer = $this->writer();
|
||||
|
||||
Reference in New Issue
Block a user