fix: TB dry runs hide uneditable live templates, off-switch despite draft (rulings Q20, Q21)

- ThemeBuilderAccess::editableLiveTemplates() shared by tb-list and the tb-assign/tb-activate dry runs;
  uneditable live templates only as a count (hidden_overlaps, hidden_live)
- tb-activate enabled:false works while the Theme Builder has a draft, with a warning
- possible_overlaps skips identical conditions; reattach records the previous enabled state;
  exclude_from must be a list; tb-activate live from the read-back

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-27 20:55:53 +02:00
co-authored by Claude Opus 5.5
parent 64fc439cb2
commit a31d4340f9
11 changed files with 355 additions and 37 deletions
@@ -241,4 +241,31 @@ final class ThemeBuilderAccessTest extends TestCase
'rev_mismatch'
);
}
/** Ruling Q21: one split of the live list by canEditTemplate(). */
public function testEditableLiveTemplatesSplitsByTheRightToEdit(): void
{
LibraryFixtures::given([]);
Functions\when('current_user_can')->alias(
static fn (string $cap, mixed ...$args): bool => ! ($cap === 'edit_post' && ($args[0] ?? 0) === 1070)
);
$mine = ThemeBuilderFixtures::template(1066);
$other = ThemeBuilderFixtures::template(1070);
$split = ThemeBuilderFixtures::access([], true, ThemeBuilderFixtures::store([$mine, $other]))->editableLiveTemplates();
self::assertSame([$mine], $split['templates']);
self::assertSame([$other], $split['hidden']);
}
/** Ruling Q20: the off-switch works while the Theme Builder has unsaved changes; nothing else does. */
public function testTheOffSwitchIgnoresTheThemeBuilderDraft(): void
{
LibraryFixtures::given([ThemeBuilderFixtures::templatePost(1066)]);
$template = ThemeBuilderFixtures::template(1066, ['enabled' => true]);
$access = ThemeBuilderFixtures::access([], true, ThemeBuilderFixtures::store([$template], 999));
$input = ['template_id' => 1066, 'template_rev' => $template->rev()];
self::assertSame($template, $access->changeableTemplate($input, true));
self::assertToolError($access->changeableTemplate($input), 'unsupported');
}
}