From 24d9653f6ed64a27fc84398c8fe52aa66ecd575f Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Wed, 17 Jun 2026 17:56:52 -0300 Subject: [PATCH] fix(ai-templates): real needsAccount + content_type test coverage; drop unwired humanizableFields; cleanup --- app/Ai/Templates/AiContentTemplate.php | 8 -------- app/Ai/Templates/CarouselTemplate.php | 8 -------- app/Ai/Templates/ImageCardTemplate.php | 9 --------- app/Ai/Templates/TweetCardTemplate.php | 6 ------ app/Services/Image/TemplateImageGenerator.php | 2 -- tests/Feature/Ai/PostAiCreateTest.php | 17 ++++++++++++++++- tests/Feature/Ai/StreamPostCreationTest.php | 6 +++++- 7 files changed, 21 insertions(+), 35 deletions(-) diff --git a/app/Ai/Templates/AiContentTemplate.php b/app/Ai/Templates/AiContentTemplate.php index 8ec3d62a..2600d48f 100644 --- a/app/Ai/Templates/AiContentTemplate.php +++ b/app/Ai/Templates/AiContentTemplate.php @@ -43,14 +43,6 @@ public function promptView(): string; */ public function schema(JsonSchema $schema, TemplateContext $context): array; - /** - * Text fields (by structured-output key) the humanizer should rewrite. - * Empty = skip humanization. - * - * @return array - */ - public function humanizableFields(): array; - /** * Build the post from the (humanized) structured output. * diff --git a/app/Ai/Templates/CarouselTemplate.php b/app/Ai/Templates/CarouselTemplate.php index 9bdf3fcf..e28b8d27 100644 --- a/app/Ai/Templates/CarouselTemplate.php +++ b/app/Ai/Templates/CarouselTemplate.php @@ -4,15 +4,12 @@ namespace App\Ai\Templates; -use App\Ai\Templates\Concerns\ResolvesContentType; use App\Enums\PostPlatform\ContentType; use App\Services\Image\PostImagePipeline; use Illuminate\Contracts\JsonSchema\JsonSchema; class CarouselTemplate implements AiContentTemplate { - use ResolvesContentType; - public function key(): string { return 'carousel'; @@ -76,11 +73,6 @@ public function schema(JsonSchema $schema, TemplateContext $context): array ]; } - public function humanizableFields(): array - { - return ['caption' => 'caption']; - } - /** * @param array $structured */ diff --git a/app/Ai/Templates/ImageCardTemplate.php b/app/Ai/Templates/ImageCardTemplate.php index 4213a739..15ffa976 100644 --- a/app/Ai/Templates/ImageCardTemplate.php +++ b/app/Ai/Templates/ImageCardTemplate.php @@ -62,15 +62,6 @@ public function schema(JsonSchema $schema, TemplateContext $context): array ]; } - public function humanizableFields(): array - { - return [ - 'content' => 'content', - 'image_title' => 'image_title', - 'image_body' => 'image_body', - ]; - } - /** * @param array $structured */ diff --git a/app/Ai/Templates/TweetCardTemplate.php b/app/Ai/Templates/TweetCardTemplate.php index bcd08568..dd7fcd79 100644 --- a/app/Ai/Templates/TweetCardTemplate.php +++ b/app/Ai/Templates/TweetCardTemplate.php @@ -63,12 +63,6 @@ public function schema(JsonSchema $schema, TemplateContext $context): array ]; } - /** @return array */ - public function humanizableFields(): array - { - return ['tweet_text' => 'tweet_text']; - } - /** * @param array $structured */ diff --git a/app/Services/Image/TemplateImageGenerator.php b/app/Services/Image/TemplateImageGenerator.php index be13923b..dbd76322 100644 --- a/app/Services/Image/TemplateImageGenerator.php +++ b/app/Services/Image/TemplateImageGenerator.php @@ -590,8 +590,6 @@ public function renderTweetCard(Workspace $workspace, SocialAccount $socialAccou $bodyLineHeight = 1.55; $paragraphGap = (int) round($bodySize * $bodyLineHeight * 0.6); - $textMaxWidth = $cardW - 2 * $cardPadding - $avatarSize - 24; - $paragraphs = array_filter(array_map('trim', explode("\n\n", $tweetText)), fn ($p) => $p !== ''); $allBodyLines = []; foreach ($paragraphs as $i => $para) { diff --git a/tests/Feature/Ai/PostAiCreateTest.php b/tests/Feature/Ai/PostAiCreateTest.php index 90919810..8f588452 100644 --- a/tests/Feature/Ai/PostAiCreateTest.php +++ b/tests/Feature/Ai/PostAiCreateTest.php @@ -215,7 +215,7 @@ ->assertJsonValidationErrors(['template']); }); -it('requires social_account_id when the template needsAccount', function () { +it('allows image_card without a social account', function () { Bus::fake(); $this->actingAs($this->user) @@ -226,3 +226,18 @@ ]) ->assertAccepted(); }); + +it('requires social_account_id when the template needsAccount', function () { + Bus::fake(); + + $this->actingAs($this->user) + ->postJson(route('app.posts.ai.create'), [ + 'format' => 'x_post', + 'prompt' => 'a punchy take on productivity', + 'template' => 'tweet_card', + ]) + ->assertUnprocessable() + ->assertJsonValidationErrors(['social_account_id']); + + Bus::assertNotDispatched(StreamPostCreation::class); +}); diff --git a/tests/Feature/Ai/StreamPostCreationTest.php b/tests/Feature/Ai/StreamPostCreationTest.php index 8cd73f2e..fa16a161 100644 --- a/tests/Feature/Ai/StreamPostCreationTest.php +++ b/tests/Feature/Ai/StreamPostCreationTest.php @@ -102,7 +102,7 @@ function runStreamPostCreation(string $format, SocialAccount $account, int $imag userId: $this->user->id, creationId: (string) Str::uuid(), workspaceId: $this->workspace->id, - format: 'x_twitter', + format: 'x_post', socialAccountId: $this->account->id, imageCount: 1, prompt: 'A punchy take on productivity', @@ -113,6 +113,10 @@ function runStreamPostCreation(string $format, SocialAccount $account, int $imag expect($post->content)->toBe('Hello world\n\nSecond para.') ->and($post->media)->toHaveCount(1); + + $platform = PostPlatform::where('social_account_id', $this->account->id)->firstOrFail(); + + expect($platform->content_type)->toBe(ContentType::XPost); }); test('the humanizer is given the same platform context as the generator so the rewrite honours the character cap', function () {