diff --git a/app/Actions/Workspace/CreateWorkspace.php b/app/Actions/Workspace/CreateWorkspace.php index 4c42fe67..3c7c2df0 100644 --- a/app/Actions/Workspace/CreateWorkspace.php +++ b/app/Actions/Workspace/CreateWorkspace.php @@ -24,7 +24,7 @@ public static function execute(User $user, array $data): Workspace 'brand_color' => data_get($data, 'brand_color'), 'background_color' => data_get($data, 'background_color'), 'text_color' => data_get($data, 'text_color'), - 'content_language' => data_get($data, 'content_language'), + 'content_language' => data_get($data, 'content_language', app()->getLocale()), ], static fn ($value): bool => $value !== null); $workspace = DB::transaction(function () use ($user, $attributes): Workspace { diff --git a/app/Http/Controllers/App/OnboardingController.php b/app/Http/Controllers/App/OnboardingController.php index 80475a77..e78a502f 100644 --- a/app/Http/Controllers/App/OnboardingController.php +++ b/app/Http/Controllers/App/OnboardingController.php @@ -150,9 +150,15 @@ public function connect(Request $request): Response|RedirectResponse 'network' => $platform->network(), ])->values(); + $plan = Plan::where('slug', Slug::Workspace)->firstOrFail(); + return Inertia::render('onboarding/Connect', [ 'platforms' => $platforms, 'accounts' => SocialAccountResource::collection($accounts)->resolve(), + 'plan' => [ + 'name' => $plan->name, + 'interval' => 'monthly', + ], ]); } diff --git a/app/Services/GiphyService.php b/app/Services/GiphyService.php index e60ff667..f5e674d4 100644 --- a/app/Services/GiphyService.php +++ b/app/Services/GiphyService.php @@ -15,7 +15,7 @@ class GiphyService public function __construct() { - $this->apiKey = config('services.giphy.api_key', ''); + $this->apiKey = (string) config('services.giphy.api_key', ''); } /** diff --git a/app/Services/UnsplashService.php b/app/Services/UnsplashService.php index 5ac1ad9a..db16237e 100644 --- a/app/Services/UnsplashService.php +++ b/app/Services/UnsplashService.php @@ -15,7 +15,7 @@ class UnsplashService public function __construct() { - $this->accessKey = config('services.unsplash.access_key', ''); + $this->accessKey = (string) config('services.unsplash.access_key', ''); } /** diff --git a/resources/js/pages/onboarding/Connect.vue b/resources/js/pages/onboarding/Connect.vue index 4b9e914a..80ae728a 100644 --- a/resources/js/pages/onboarding/Connect.vue +++ b/resources/js/pages/onboarding/Connect.vue @@ -9,14 +9,18 @@ import NetworkConnectGrid, { type ConnectedAccount, } from '@/components/accounts/NetworkConnectGrid.vue'; import { Button } from '@/components/ui/button'; +import { useTracking } from '@/composables/useTracking'; const props = defineProps<{ platforms: AvailablePlatform[]; accounts: ConnectedAccount[]; + plan: { name: string; interval: string }; }>(); const form = useForm({}); +const { trackBeginCheckout } = useTracking(); + const hasConnected = computed((): boolean => props.accounts.length > 0); const submit = (): void => { @@ -24,6 +28,8 @@ const submit = (): void => { return; } + trackBeginCheckout({ name: props.plan.name, interval: props.plan.interval }); + form.post(checkout.url()); }; diff --git a/tests/Feature/Actions/Workspace/CreateWorkspaceTest.php b/tests/Feature/Actions/Workspace/CreateWorkspaceTest.php index a31bf419..7c57efd3 100644 --- a/tests/Feature/Actions/Workspace/CreateWorkspaceTest.php +++ b/tests/Feature/Actions/Workspace/CreateWorkspaceTest.php @@ -42,6 +42,28 @@ expect($member?->pivot->role)->toBe(Role::Admin->value); }); +test('CreateWorkspace inherits the app locale as content_language when none is given', function () { + app()->setLocale('pt-BR'); + + $account = Account::factory()->create(); + $user = User::factory()->create(['account_id' => $account->id]); + + $workspace = CreateWorkspace::execute($user, ['name' => 'Acme']); + + expect($workspace->content_language)->toBe('pt-BR'); +}); + +test('CreateWorkspace keeps an explicit content_language over the app locale', function () { + app()->setLocale('pt-BR'); + + $account = Account::factory()->create(); + $user = User::factory()->create(['account_id' => $account->id]); + + $workspace = CreateWorkspace::execute($user, ['name' => 'Acme', 'content_language' => 'es']); + + expect($workspace->content_language)->toBe('es'); +}); + test('CreateWorkspace ignores unknown extra keys like logo_url', function () { $account = Account::factory()->create(); $user = User::factory()->create(['account_id' => $account->id]); diff --git a/tests/Feature/Onboarding/OnboardingControllerTest.php b/tests/Feature/Onboarding/OnboardingControllerTest.php index 5f25e6aa..21c00f74 100644 --- a/tests/Feature/Onboarding/OnboardingControllerTest.php +++ b/tests/Feature/Onboarding/OnboardingControllerTest.php @@ -263,6 +263,22 @@ function subscribeOnboardingAccount(Account $account): void ); }); +test('connect passes the workspace plan so the client can fire begin_checkout', function () { + $this->user->update(['persona' => Persona::Agency->value, 'goals' => [Goal::SaveTime->value]]); + onboardingWorkspace($this->user); + + $plan = Plan::where('slug', Slug::Workspace)->firstOrFail(); + + $response = $this->actingAs($this->user->fresh())->get(route('app.onboarding.connect')); + + $response->assertOk(); + $response->assertInertia(fn ($page) => $page + ->component('onboarding/Connect') + ->where('plan.name', $plan->name) + ->where('plan.interval', 'monthly') + ); +}); + test('connect offers a single linkedin card and no standalone linkedin page card', function () { $this->user->update(['persona' => Persona::Agency->value, 'goals' => [Goal::SaveTime->value]]); onboardingWorkspace($this->user); diff --git a/tests/Unit/Services/MediaSearchKeyFallbackTest.php b/tests/Unit/Services/MediaSearchKeyFallbackTest.php new file mode 100644 index 00000000..6fa85c47 --- /dev/null +++ b/tests/Unit/Services/MediaSearchKeyFallbackTest.php @@ -0,0 +1,22 @@ + null]); + + $result = (new UnsplashService)->search('cats'); + + expect($result)->toBe(['results' => [], 'total' => 0, 'total_pages' => 0]); +}); + +test('giphy service tolerates a null api key without throwing', function () { + config(['services.giphy.api_key' => null]); + + $result = (new GiphyService)->search('cats'); + + expect($result)->toBe(['results' => [], 'total' => 0, 'total_pages' => 0]); +});