trypost/tests/Unit/Support/PostMediaRulesTest.php
Paulo Castellano df891574f7 fix(api): roll back hosted media when an inline url batch partially fails
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).
2026-06-28 20:59:21 -03:00

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',
]);
}
});