trypost/tests/Feature/Ai/Templates/TemplateContractTest.php
Paulo Castellano 2c2ab69e68 Merge main + finalize AI brand-colors toggle
Resolves the AiPostWizard conflict and completes the feature:
- i18n parity: brand_colors_label + brand_colors_description in all 15 locales
  (was en/es/pt-BR only, which broke LocalizationParityTest).
- Reworked the two-button toggle into a Switch with an explanatory description
  (matches the settings Switch/card pattern).
- Only shown for templates that honor the flag: added appliesBrandVisuals() to
  the AiContentTemplate contract (ImageCard=true, tweet cards=false), exposed as
  applies_brand_visuals in the create-page DTO, and gated the toggle on it — so
  it no longer appears (as a no-op) for tweet-card styles.
- Tests: TemplateContractTest covers appliesBrandVisuals for all templates.
2026-07-18 15:12:26 -03:00

52 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
use App\Ai\Templates\ImageCardTemplate;
use App\Ai\Templates\TemplateContext;
use App\Ai\Templates\TweetCardImageTemplate;
use App\Ai\Templates\TweetCardTemplate;
use App\Enums\Ai\ContentStyle;
use App\Models\Workspace;
use Illuminate\JsonSchema\JsonSchemaTypeFactory;
test('image card template exposes its identity', function () {
$t = new ImageCardTemplate;
$workspace = Workspace::factory()->create();
$context = new TemplateContext($workspace, null, 'instagram_feed', 0, false);
expect($t->style())->toBe(ContentStyle::ImageCard)
->and($t->key())->toBe('image_card')
->and($t->needsAccount())->toBeFalse()
->and($t->appliesBrandVisuals())->toBeTrue()
->and($t->promptView($context))->toBe('prompts.post_content.generator')
->and($t->supportedFormats())->toBe([]);
});
test('tweet-card templates do not apply brand visuals', function () {
expect((new TweetCardTemplate)->appliesBrandVisuals())->toBeFalse()
->and((new TweetCardImageTemplate)->appliesBrandVisuals())->toBeFalse();
});
test('image card carousel context returns carousel schema shape', function () {
$t = new ImageCardTemplate;
$workspace = Workspace::factory()->create();
$context = new TemplateContext($workspace, null, 'instagram_carousel', 3, true);
$schema = new JsonSchemaTypeFactory;
$result = $t->schema($schema, $context);
expect($result)->toHaveKeys(['caption', 'slides'])
->and($t->promptView($context))->toBe('prompts.post_content.generator');
});
test('image card single context returns single schema shape', function () {
$t = new ImageCardTemplate;
$workspace = Workspace::factory()->create();
$context = new TemplateContext($workspace, null, 'instagram_feed', 1, false);
$schema = new JsonSchemaTypeFactory;
$result = $t->schema($schema, $context);
expect($result)->toHaveKeys(['content', 'image_title', 'image_body', 'image_keywords']);
});