Final-review follow-ups: - MediaAttacher::resolveInlineMedia now deletes the media it hosted in this call when any item fails, so a mixed [good, bad] batch no longer orphans the good item's Media row + file while the request is correctly rejected with 422. Makes the create/update media resolution truly all-or-nothing. - PostMediaRules: keep source/source_meta on both contracts (the API previously passed them through with no item rules — don't silently drop them) so the media item shape is uniform; only id/path/url differ by contract. - Make MediaAttacher::fetchToWorkspace private (no external callers). - Test the partial-batch rollback (no Media, no post persisted).
36 lines
1.1 KiB
PHP
36 lines
1.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Support\PostMediaRules;
|
|
|
|
test('hosted media rules require id and path', function () {
|
|
$rules = PostMediaRules::rules(hosted: true);
|
|
|
|
expect($rules['media.*.id'])->toContain('required')
|
|
->and($rules['media.*.path'])->toContain('required')
|
|
->and($rules['media.*.url'])->not->toContain('url:http,https');
|
|
});
|
|
|
|
test('api media rules accept a bare external url with nullable id/path', function () {
|
|
$rules = PostMediaRules::rules(hosted: false);
|
|
|
|
expect($rules['media.*.id'])->toContain('nullable')
|
|
->and($rules['media.*.path'])->toContain('nullable')
|
|
->and($rules['media.*.url'])->toContain('url:http,https');
|
|
});
|
|
|
|
test('both variants keep the shared item keys so validated() preserves them', function () {
|
|
foreach ([true, false] as $hosted) {
|
|
expect(PostMediaRules::rules(hosted: $hosted))->toHaveKeys([
|
|
'media.*.id',
|
|
'media.*.path',
|
|
'media.*.url',
|
|
'media.*.type',
|
|
'media.*.mime_type',
|
|
'media.*.original_filename',
|
|
'media.*.size',
|
|
'media.*.meta',
|
|
]);
|
|
}
|
|
});
|