diff --git a/app/Actions/Automation/Node/RunGenerateNode.php b/app/Actions/Automation/Node/RunGenerateNode.php index c44652562..41e7da30d 100644 --- a/app/Actions/Automation/Node/RunGenerateNode.php +++ b/app/Actions/Automation/Node/RunGenerateNode.php @@ -12,6 +12,7 @@ use App\DataTransferObjects\Automation\NodeRunResult; use App\Enums\Ai\ContentStyle; use App\Enums\Ai\GeneratorFormat; +use App\Enums\Post\CreatedVia; use App\Enums\PostPlatform\ContentType; use App\Models\AutomationRun; use App\Models\SocialAccount; @@ -145,6 +146,7 @@ public function __invoke(AutomationRun $run, array $config): NodeRunResult 'content' => $generated->content, 'media' => $generated->media, 'platforms' => $platforms, + 'created_via' => CreatedVia::Automation, ]); $run->update(['generated_post_id' => $post->id]); diff --git a/app/Actions/Post/CreatePost.php b/app/Actions/Post/CreatePost.php index 215838b6e..26535cecf 100644 --- a/app/Actions/Post/CreatePost.php +++ b/app/Actions/Post/CreatePost.php @@ -4,8 +4,8 @@ namespace App\Actions\Post; +use App\Enums\Post\CreatedVia; use App\Enums\Post\Status as PostStatus; -use App\Events\PostCreated; use App\Models\Post; use App\Models\User; use App\Models\Workspace; @@ -26,11 +26,15 @@ class CreatePost * `label_ids[]` are attached after creation so the same set of UUIDs * works for REST, MCP, and web callers. * + * `created_via` records which entry point created the post (web, mcp, + * api, or automation). Analytical only — null when omitted. + * * @param array{ * content?: ?string, * media?: array, * date?: ?string, * scheduled_at?: ?string, + * created_via?: ?CreatedVia, * platforms?: array}>, * label_ids?: array * } $data @@ -45,6 +49,7 @@ public static function execute(Workspace $workspace, User $user, array $data): P 'content' => data_get($data, 'content', ''), 'media' => data_get($data, 'media', []), 'status' => PostStatus::Draft, + 'created_via' => data_get($data, 'created_via'), 'scheduled_at' => $scheduledAt, ]); @@ -85,8 +90,6 @@ public static function execute(Workspace $workspace, User $user, array $data): P return $post; }); - PostCreated::dispatch($post); - return $post; } diff --git a/app/Actions/Post/DuplicatePost.php b/app/Actions/Post/DuplicatePost.php index 3fdd67ecc..1e40854e2 100644 --- a/app/Actions/Post/DuplicatePost.php +++ b/app/Actions/Post/DuplicatePost.php @@ -4,6 +4,7 @@ namespace App\Actions\Post; +use App\Enums\Post\CreatedVia; use App\Enums\Post\Status as PostStatus; use App\Enums\PostPlatform\Status as PostPlatformStatus; use App\Models\Post; @@ -25,6 +26,7 @@ public static function execute(Post $original, User $user): Post 'content' => $original->content, 'media' => $original->media, 'status' => PostStatus::Draft, + 'created_via' => CreatedVia::Web, 'scheduled_at' => null, 'published_at' => null, ]); diff --git a/app/Enums/Post/CreatedVia.php b/app/Enums/Post/CreatedVia.php new file mode 100644 index 000000000..bd7143328 --- /dev/null +++ b/app/Enums/Post/CreatedVia.php @@ -0,0 +1,13 @@ +owner, $data); $post->load(['postPlatforms.socialAccount']); diff --git a/app/Http/Controllers/App/PostController.php b/app/Http/Controllers/App/PostController.php index 3b6e6ef7c..7ef6f6332 100644 --- a/app/Http/Controllers/App/PostController.php +++ b/app/Http/Controllers/App/PostController.php @@ -12,6 +12,7 @@ use App\Ai\Templates\AiContentTemplate; use App\Ai\Templates\AiTemplateRegistry; use App\Enums\Post\Action as PostAction; +use App\Enums\Post\CreatedVia; use App\Enums\Post\Status as PostStatus; use App\Enums\SocialAccount\Platform; use App\Http\Requests\App\Post\StorePostRequest; @@ -189,6 +190,7 @@ public function store(StorePostRequest $request): RedirectResponse|\Symfony\Comp $post = CreatePost::execute($workspace, $request->user(), [ 'date' => $request->input('date'), 'media' => $request->input('media', []), + 'created_via' => CreatedVia::Web, ]); return Inertia::location(route('app.posts.edit', $post)); diff --git a/app/Http/Controllers/App/PostTemplateController.php b/app/Http/Controllers/App/PostTemplateController.php index c7889097b..18ce4cdc8 100644 --- a/app/Http/Controllers/App/PostTemplateController.php +++ b/app/Http/Controllers/App/PostTemplateController.php @@ -6,6 +6,7 @@ use App\Actions\Post\CreatePost; use App\Enums\Media\Type as MediaType; +use App\Enums\Post\CreatedVia; use App\Http\Requests\App\PostTemplate\ApplyPostTemplateRequest; use App\Http\Requests\App\PostTemplate\IndexPostTemplateRequest; use App\Http\Resources\App\PostTemplateResource; @@ -89,6 +90,7 @@ public function apply(ApplyPostTemplateRequest $request, string $slug, TemplateI 'content' => $content, 'media' => $media, 'date' => $request->input('date'), + 'created_via' => CreatedVia::Web, ]); return response()->json([ diff --git a/app/Jobs/Ai/StreamPostCreation.php b/app/Jobs/Ai/StreamPostCreation.php index f8c9eb144..ad8b8f264 100644 --- a/app/Jobs/Ai/StreamPostCreation.php +++ b/app/Jobs/Ai/StreamPostCreation.php @@ -14,6 +14,7 @@ use App\Enums\Ai\GeneratorFormat; use App\Enums\Notification\Channel as NotificationChannel; use App\Enums\Notification\Type as NotificationType; +use App\Enums\Post\CreatedVia; use App\Enums\PostPlatform\ContentType; use App\Events\Ai\PostCreationReady; use App\Jobs\SendNotification; @@ -195,6 +196,7 @@ private function createPostFromGenerated(Workspace $workspace, GeneratedPost $ge 'content' => $generated->content, 'media' => $generated->media, 'date' => $this->date, + 'created_via' => CreatedVia::Web, ]); if ($generated->contentType && $socialAccount) { diff --git a/app/Jobs/PostHog/TrackPost.php b/app/Jobs/PostHog/TrackPost.php new file mode 100644 index 000000000..bd31ff04d --- /dev/null +++ b/app/Jobs/PostHog/TrackPost.php @@ -0,0 +1,67 @@ +onQueue('posthog'); + } + + public function handle(PostHogService $postHog): void + { + if (! PostHogService::isEnabled()) { + return; + } + + $post = Post::query() + ->with(['workspace.account.plan']) + ->find($this->postId); + + if (! $post) { + return; + } + + $account = $post->workspace?->account; + + if (! $account) { + return; + } + + $distinctId = (string) ($post->user_id ?? $account->owner_id); + + if ($distinctId === '') { + return; + } + + $postHog->capture( + $distinctId, + PostEvent::Created->value, + [ + 'post_id' => (string) $post->id, + 'workspace_id' => (string) $post->workspace_id, + 'created_via' => $post->created_via?->value, + 'status' => $post->status->value, + ], + $account, + ); + } +} diff --git a/app/Listeners/PostHog/TrackPostCreated.php b/app/Listeners/PostHog/TrackPostCreated.php new file mode 100644 index 000000000..eab05d0e7 --- /dev/null +++ b/app/Listeners/PostHog/TrackPostCreated.php @@ -0,0 +1,21 @@ +post->id); + } +} diff --git a/app/Mcp/Tools/Post/CreatePostTool.php b/app/Mcp/Tools/Post/CreatePostTool.php index 80851f06a..50c1ce08d 100644 --- a/app/Mcp/Tools/Post/CreatePostTool.php +++ b/app/Mcp/Tools/Post/CreatePostTool.php @@ -5,6 +5,7 @@ namespace App\Mcp\Tools\Post; use App\Actions\Post\CreatePost; +use App\Enums\Post\CreatedVia; use App\Enums\PostPlatform\ContentType; use App\Http\Resources\Api\PostResource; use App\Rules\ContentTypeMatchesPlatform; @@ -41,6 +42,8 @@ public function handle(Request $request): ResponseFactory ...PostPlatformMetaRules::rules(), ]); + $validated['created_via'] = CreatedVia::Mcp; + $post = CreatePost::execute($workspace, $request->user(), $validated); $post->load(['postPlatforms.socialAccount', 'labels']); diff --git a/app/Models/Post.php b/app/Models/Post.php index 1fa414560..8d587d7f1 100644 --- a/app/Models/Post.php +++ b/app/Models/Post.php @@ -6,6 +6,7 @@ use App\DataTransferObjects\MediaItem; use App\Enums\Media\Type; +use App\Enums\Post\CreatedVia; use App\Enums\Post\Status as PostStatus; use App\Enums\SocialAccount\Platform; use App\Observers\PostObserver; @@ -34,6 +35,7 @@ class Post extends Model 'content', 'media', 'status', + 'created_via', 'scheduled_at', 'published_at', ]; @@ -42,6 +44,7 @@ protected function casts(): array { return [ 'status' => PostStatus::class, + 'created_via' => CreatedVia::class, 'media' => 'array', 'scheduled_at' => 'datetime', 'published_at' => 'datetime', diff --git a/app/Observers/PostObserver.php b/app/Observers/PostObserver.php index 33456b275..1486cfc04 100644 --- a/app/Observers/PostObserver.php +++ b/app/Observers/PostObserver.php @@ -6,11 +6,18 @@ use App\Enums\Automation\Trigger\Type as TriggerType; use App\Enums\Post\Status as PostStatus; +use App\Events\PostCreated; use App\Jobs\Automation\DispatchPostTriggerAutomationsJob; use App\Models\Post; +use Illuminate\Support\Facades\DB; class PostObserver { + public function created(Post $post): void + { + DB::afterCommit(fn () => PostCreated::dispatch($post)); + } + public function saved(Post $post): void { if (! $post->wasChanged('status')) { diff --git a/database/migrations/2026_07_24_141454_add_created_via_to_posts_table.php b/database/migrations/2026_07_24_141454_add_created_via_to_posts_table.php new file mode 100644 index 000000000..3e44bf5e6 --- /dev/null +++ b/database/migrations/2026_07_24_141454_add_created_via_to_posts_table.php @@ -0,0 +1,30 @@ +string('created_via')->nullable()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('posts', function (Blueprint $table) { + $table->dropColumn('created_via'); + }); + } +}; diff --git a/tests/Feature/Actions/Post/CreatePostTest.php b/tests/Feature/Actions/Post/CreatePostTest.php index 4a1252e0b..3a50dceee 100644 --- a/tests/Feature/Actions/Post/CreatePostTest.php +++ b/tests/Feature/Actions/Post/CreatePostTest.php @@ -3,12 +3,13 @@ declare(strict_types=1); use App\Actions\Post\CreatePost; +use App\Enums\Post\CreatedVia; use App\Events\PostCreated; use App\Models\User; use App\Models\Workspace; use Illuminate\Support\Facades\Event; -test('execute dispatches PostCreated with the persisted post', function () { +test('execute relies on the observer to dispatch PostCreated', function () { Event::fake([PostCreated::class]); $user = User::factory()->create(); @@ -16,6 +17,7 @@ $post = CreatePost::execute($workspace, $user, [ 'content' => 'Hello world', + 'created_via' => CreatedVia::Web, ]); Event::assertDispatched( @@ -24,3 +26,31 @@ && $event->post->workspace_id === $workspace->id, ); }); + +test('execute persists created_via for each entry point', function (CreatedVia $createdVia) { + $user = User::factory()->create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + + $post = CreatePost::execute($workspace, $user, [ + 'content' => 'Hello world', + 'created_via' => $createdVia, + ]); + + expect($post->fresh()->created_via)->toBe($createdVia); +})->with([ + 'web' => CreatedVia::Web, + 'mcp' => CreatedVia::Mcp, + 'api' => CreatedVia::Api, + 'automation' => CreatedVia::Automation, +]); + +test('execute leaves created_via null when omitted', function () { + $user = User::factory()->create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + + $post = CreatePost::execute($workspace, $user, [ + 'content' => 'Hello world', + ]); + + expect($post->fresh()->created_via)->toBeNull(); +}); diff --git a/tests/Feature/Actions/Post/DuplicatePostTest.php b/tests/Feature/Actions/Post/DuplicatePostTest.php new file mode 100644 index 000000000..13e43daf4 --- /dev/null +++ b/tests/Feature/Actions/Post/DuplicatePostTest.php @@ -0,0 +1,51 @@ +create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + $original = Post::factory()->create([ + 'workspace_id' => $workspace->id, + 'user_id' => $user->id, + 'content' => 'Original content', + 'created_via' => CreatedVia::Api, + 'status' => PostStatus::Published, + ]); + + $copy = DuplicatePost::execute($original, $user); + + expect($copy->id)->not->toBe($original->id) + ->and($copy->content)->toBe('Original content') + ->and($copy->status)->toBe(PostStatus::Draft) + ->and($copy->created_via)->toBe(CreatedVia::Web) + ->and($copy->scheduled_at)->toBeNull() + ->and($copy->published_at)->toBeNull(); +}); + +test('execute relies on the observer to dispatch PostCreated for the duplicate', function () { + $user = User::factory()->create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + $original = Post::factory()->create([ + 'workspace_id' => $workspace->id, + 'user_id' => $user->id, + ]); + + Event::fake([PostCreated::class]); + + $copy = DuplicatePost::execute($original, $user); + + Event::assertDispatched( + PostCreated::class, + fn (PostCreated $event) => $event->post->id === $copy->id, + ); +}); diff --git a/tests/Feature/Ai/StreamPostCreationTest.php b/tests/Feature/Ai/StreamPostCreationTest.php index 513da29bd..457d1f642 100644 --- a/tests/Feature/Ai/StreamPostCreationTest.php +++ b/tests/Feature/Ai/StreamPostCreationTest.php @@ -4,6 +4,7 @@ use App\Ai\Agents\PostContentGenerator; use App\Ai\Agents\PostContentHumanizer; +use App\Enums\Post\CreatedVia; use App\Enums\PostPlatform\ContentType; use App\Enums\UserWorkspace\Role; use App\Jobs\Ai\StreamPostCreation; @@ -111,7 +112,8 @@ function runStreamPostCreation(string $format, SocialAccount $account, int $imag $post = $this->user->currentWorkspace->posts()->latest()->first(); expect($post->content)->toBe('Hello world\n\nSecond para.') - ->and($post->media)->toHaveCount(1); + ->and($post->media)->toHaveCount(1) + ->and($post->created_via)->toBe(CreatedVia::Web); $platform = PostPlatform::where('social_account_id', $this->account->id)->firstOrFail(); diff --git a/tests/Feature/Api/PostApiTest.php b/tests/Feature/Api/PostApiTest.php index 5163af934..567607a60 100644 --- a/tests/Feature/Api/PostApiTest.php +++ b/tests/Feature/Api/PostApiTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use App\Enums\Post\CreatedVia; use App\Enums\Post\Status as PostStatus; use App\Enums\PostPlatform\ContentType; use App\Enums\SocialAccount\Platform; @@ -72,7 +73,26 @@ ->assertCreated() ->assertJsonPath('status', PostStatus::Draft->value); - expect(Post::where('workspace_id', $this->workspace->id)->count())->toBe(1); + $post = Post::where('workspace_id', $this->workspace->id)->first(); + expect($post)->not->toBeNull(); + expect($post->created_via)->toBe(CreatedVia::Api); +}); + +it('ignores a client-supplied created_via and always records api', function () { + $this->withHeaders(['Authorization' => 'Bearer '.$this->plainToken]) + ->postJson(route('api.posts.store'), [ + 'created_via' => 'web', + 'platforms' => [ + [ + 'social_account_id' => $this->socialAccount->id, + 'content_type' => 'linkedin_post', + ], + ], + ]) + ->assertCreated(); + + $post = Post::where('workspace_id', $this->workspace->id)->first(); + expect($post->created_via)->toBe(CreatedVia::Api); }); it('creates a post with content, media, and labels', function () { diff --git a/tests/Feature/Automation/Node/GenerateNodeTest.php b/tests/Feature/Automation/Node/GenerateNodeTest.php index f8fa56739..368a99de1 100644 --- a/tests/Feature/Automation/Node/GenerateNodeTest.php +++ b/tests/Feature/Automation/Node/GenerateNodeTest.php @@ -7,6 +7,7 @@ use App\Ai\Agents\PostContentHumanizer; use App\Enums\Ai\ContentStyle; use App\Enums\Ai\GeneratorFormat; +use App\Enums\Post\CreatedVia; use App\Enums\Post\Status as PostStatus; use App\Enums\PostPlatform\ContentType; use App\Models\Automation; @@ -47,6 +48,7 @@ $post = Post::find($run->generated_post_id); expect($post)->not->toBeNull(); expect($post->status)->toBe(PostStatus::Draft); + expect($post->created_via)->toBe(CreatedVia::Automation); }); it('applies brand voice by default', function () { diff --git a/tests/Feature/Jobs/PostHog/TrackPostTest.php b/tests/Feature/Jobs/PostHog/TrackPostTest.php new file mode 100644 index 000000000..350042a8e --- /dev/null +++ b/tests/Feature/Jobs/PostHog/TrackPostTest.php @@ -0,0 +1,96 @@ + true, 'services.posthog.api_key' => 'phc_test_key']); + + $this->account = Account::factory()->create(); + $this->user = User::factory()->create(['account_id' => $this->account->id]); + $this->account->update(['owner_id' => $this->user->id]); + $this->workspace = Workspace::factory()->create([ + 'account_id' => $this->account->id, + 'user_id' => $this->user->id, + ]); +}); + +test('job is queued on the posthog queue', function () { + $job = new TrackPost((string) Str::uuid()); + + expect($job->queue)->toBe('posthog'); +}); + +test('handle captures post.created with created_via and account group', function () { + Queue::fake(); + + $post = Post::factory()->create([ + 'workspace_id' => $this->workspace->id, + 'user_id' => $this->user->id, + 'created_via' => CreatedVia::Api, + ]); + + (new TrackPost((string) $post->id))->handle(app(PostHogService::class)); + + Queue::assertPushed(SendEvent::class, function ($job) use ($post) { + return $job->method === 'capture' + && $job->payload['event'] === PostEvent::Created->value + && $job->payload['distinctId'] === (string) $this->user->id + && $job->payload['properties']['post_id'] === (string) $post->id + && $job->payload['properties']['workspace_id'] === (string) $this->workspace->id + && $job->payload['properties']['created_via'] === CreatedVia::Api->value + && $job->payload['properties']['$groups']['account'] === (string) $this->account->id; + }); +}); + +test('handle falls back to account owner when post has no user', function () { + Queue::fake(); + + $post = Post::factory()->create([ + 'workspace_id' => $this->workspace->id, + 'user_id' => null, + 'created_via' => CreatedVia::Mcp, + ]); + + (new TrackPost((string) $post->id))->handle(app(PostHogService::class)); + + Queue::assertPushed( + SendEvent::class, + fn ($job) => $job->payload['distinctId'] === (string) $this->user->id + && $job->payload['properties']['created_via'] === CreatedVia::Mcp->value, + ); +}); + +test('handle returns silently when post does not exist', function () { + Queue::fake(); + + (new TrackPost((string) Str::uuid()))->handle(app(PostHogService::class)); + + Queue::assertNothingPushed(); +}); + +test('handle does not push when PostHog is disabled', function () { + config(['services.posthog.api_key' => null]); + Queue::fake(); + + $post = Post::factory()->create([ + 'workspace_id' => $this->workspace->id, + 'user_id' => $this->user->id, + 'created_via' => CreatedVia::Web, + ]); + + (new TrackPost((string) $post->id))->handle(app(PostHogService::class)); + + Queue::assertNotPushed(SendEvent::class); +}); diff --git a/tests/Feature/Listeners/PostHog/TrackPostCreatedTest.php b/tests/Feature/Listeners/PostHog/TrackPostCreatedTest.php new file mode 100644 index 000000000..311d39c11 --- /dev/null +++ b/tests/Feature/Listeners/PostHog/TrackPostCreatedTest.php @@ -0,0 +1,71 @@ + true, 'services.posthog.api_key' => 'phc_test_key']); + + $this->account = Account::factory()->create(); + $this->user = User::factory()->create(['account_id' => $this->account->id]); + $this->account->update(['owner_id' => $this->user->id]); + $this->workspace = Workspace::factory()->create([ + 'account_id' => $this->account->id, + 'user_id' => $this->user->id, + ]); +}); + +test('listener dispatches TrackPost with the post id', function () { + $post = Post::factory()->create([ + 'workspace_id' => $this->workspace->id, + 'user_id' => $this->user->id, + 'created_via' => CreatedVia::Web, + ]); + + Bus::fake(); + + (new TrackPostCreated)->handle(new PostCreated($post)); + + Bus::assertDispatched( + TrackPost::class, + fn ($job) => $job->postId === (string) $post->id, + ); +}); + +test('listener is wired to the PostCreated event via auto-discovery', function () { + $post = Post::factory()->create([ + 'workspace_id' => $this->workspace->id, + 'user_id' => $this->user->id, + 'created_via' => CreatedVia::Automation, + ]); + + Bus::fake(); + + PostCreated::dispatch($post); + + Bus::assertDispatched(TrackPost::class); +}); + +test('listener does not dispatch when PostHog is disabled', function () { + config(['services.posthog.enabled' => false]); + + $post = Post::factory()->create([ + 'workspace_id' => $this->workspace->id, + 'user_id' => $this->user->id, + ]); + + Bus::fake(); + + (new TrackPostCreated)->handle(new PostCreated($post)); + + Bus::assertNotDispatched(TrackPost::class); +}); diff --git a/tests/Feature/Mcp/PostToolTest.php b/tests/Feature/Mcp/PostToolTest.php index dfd631b49..ba60f0101 100644 --- a/tests/Feature/Mcp/PostToolTest.php +++ b/tests/Feature/Mcp/PostToolTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use App\Enums\Post\CreatedVia; use App\Enums\SocialAccount\Platform; use App\Enums\UserWorkspace\Role; use App\Mcp\Servers\TryPostServer; @@ -109,7 +110,9 @@ ->etc(); }); - expect(Post::where('workspace_id', $this->workspace->id)->count())->toBe(1); + $post = Post::where('workspace_id', $this->workspace->id)->first(); + expect($post)->not->toBeNull(); + expect($post->created_via)->toBe(CreatedVia::Mcp); }); test('create post with platforms enables only those', function () { diff --git a/tests/Feature/Observers/PostObserverTest.php b/tests/Feature/Observers/PostObserverTest.php new file mode 100644 index 000000000..ebda452b2 --- /dev/null +++ b/tests/Feature/Observers/PostObserverTest.php @@ -0,0 +1,40 @@ +create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + + $post = Post::factory()->create([ + 'workspace_id' => $workspace->id, + 'user_id' => $user->id, + ]); + + Event::assertDispatched( + PostCreated::class, + fn (PostCreated $event) => $event->post->id === $post->id, + ); +}); + +test('creating a post quietly does not dispatch PostCreated', function () { + Event::fake([PostCreated::class]); + + $user = User::factory()->create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + + Post::factory()->createQuietly([ + 'workspace_id' => $workspace->id, + 'user_id' => $user->id, + ]); + + Event::assertNotDispatched(PostCreated::class); +}); diff --git a/tests/Feature/PostControllerTest.php b/tests/Feature/PostControllerTest.php index a7da0b149..2ea4c55b5 100644 --- a/tests/Feature/PostControllerTest.php +++ b/tests/Feature/PostControllerTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use App\Enums\Post\CreatedVia; use App\Enums\Post\Status as PostStatus; use App\Enums\PostPlatform\ContentType; use App\Enums\PostPlatform\Status; @@ -257,6 +258,7 @@ $post = Post::where('workspace_id', $this->workspace->id)->first(); expect($post)->not->toBeNull(); expect($post->status)->toBe(PostStatus::Draft); + expect($post->created_via)->toBe(CreatedVia::Web); expect($post->postPlatforms)->toHaveCount(1); }); diff --git a/tests/Feature/PostTemplateControllerTest.php b/tests/Feature/PostTemplateControllerTest.php index be4b34bd7..7e20d520c 100644 --- a/tests/Feature/PostTemplateControllerTest.php +++ b/tests/Feature/PostTemplateControllerTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use App\Enums\Post\CreatedVia; use App\Enums\UserWorkspace\Role; use App\Models\Account; use App\Models\SocialAccount; @@ -72,6 +73,9 @@ expect($response->json('post_id'))->toBeString(); expect($response->json('redirect_url'))->toContain('edit'); + + $post = $this->workspace->posts()->find($response->json('post_id')); + expect($post->created_via)->toBe(CreatedVia::Web); }); test('apply interpolates brand_name in content', function () {