6 Commits
Author SHA1 Message Date
janniclas.loosenandClaude Opus 5.5 72eeaa46ad test: FakeChangeLog and SchemaFixture instead of repeated mocks (T2)
- tests/Support/FakeChangeLog extends ChangeLog: records record()/recordPartial()
  calls, increasing ids, optional failure; new FakeChangeLog(id) / partialsOnly() /
  any(id) / forbidden() mirror what the replaced mocks allowed. assertRecorded() /
  assertPartials() check count and the named arguments. Calls a fake does not allow
  throw and are also verified in TestCase::tearDown (one assertion per test that
  uses a fake), so swallowed change-log calls still fail like a never() expectation.
- All ChangeLog mocks of ability/integration tests replaced (the admin tests that
  stub query/purge/clear keep their mocks); expectException tests that checked the
  partial log now catch and assert.
- SchemaFixture::managed(?divi) replaces the 21 isManaged-only ContentSchema mocks;
  DiviFixtures::schema() uses it.
Tests 1397 -> 1404 (FakeChangeLogTest); no test has fewer assertions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 17:53:54 +02:00
janniclas.loosenandClaude Opus 5.5 931ddeb137 feat: batch media metadata updates and delete with usage check
lit/media-update validates the whole batch first (edit_post, lengths, optional
modified lock) and restores already written items when a write fails midway.
lit/media-delete requires confirm, refuses used media without force and
reports refused deletes as write_failed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 02:49:41 +02:00
janniclas.loosenandClaude Opus 5.5 2e29a6cd4d feat: media upload by URL and base64 with whitelist and size limit
MediaImporter streams URL imports via wp_safe_remote_get with limit_response_size,
checks Content-Length, intersects the MIME whitelist with get_allowed_mime_types and
validates real content; base64 is size-checked before decoding. Server-side failures
are write_failed; a failed alt text deletes the new attachment again (or partial_write).
MediaUploads is the shared permission/result helper of both upload abilities.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 02:37:43 +02:00
janniclas.loosenandClaude Opus 5.5 f027da1785 feat: media preview as image content and download as embedded resource
lit/media-preview downscales an image attachment via wp_get_image_editor
and returns it as ImageContent; lit/media-download returns a file (full
or a named size) as an embedded resource, rejecting files above the
upload limit. Both are direct tools (ruling Q6: embedded resources, like
ImageContent, only become content blocks for tools called directly).
Adds MediaFiles::isWithinUploads() so neither tool ever reads a file
outside wp_upload_dir()'s basedir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 02:29:12 +02:00
janniclas.loosenandClaude Opus 5.5 5099c9fc89 feat: media-search with missing_alt and unused filters
Ruling Q8 caps the unused scan at 20 candidates per call (not the
brief's 500/50), and each result (search and unused alike) is
filtered to attachments the current user may edit; overview.md lists
media-search as a direct tool (ruling Q2).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 02:12:18 +02:00
janniclas.loosenandClaude Opus 5.5 a2a2da1ae7 feat: media usage finder and media-get tool
Usage search distinguishes certain (ID referenced) and possible (file URL
only) usages, hides titles the user cannot read, and keeps queries bounded.
MediaGuard checks per-attachment capabilities and refuses trashed media
unless the caller opts in.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 01:54:55 +02:00