diff --git a/tests/Feature/Livewire/PurchaseModalTest.php b/tests/Feature/Livewire/PurchaseModalTest.php
index b34e1d12..f1da549e 100644
--- a/tests/Feature/Livewire/PurchaseModalTest.php
+++ b/tests/Feature/Livewire/PurchaseModalTest.php
@@ -3,22 +3,18 @@
namespace Tests\Feature\Livewire;
use App\Livewire\PurchaseModal;
-use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class PurchaseModalTest extends TestCase
{
- use RefreshDatabase;
-
#[Test]
- public function purchase_modal_can_be_opened_with_plan()
+ public function purchase_modal_can_set_a_plan()
{
Livewire::test(PurchaseModal::class)
- ->call('openModal', 'mini')
- ->assertSet('selectedPlan', 'mini')
- ->assertSet('showModal', true);
+ ->call('setPlan', 'mini')
+ ->assertSet('selectedPlan', 'mini');
}
#[Test]
@@ -38,9 +34,8 @@ public function purchase_modal_can_be_closed()
public function purchase_modal_validates_email()
{
Livewire::test(PurchaseModal::class)
- ->call('openModal', 'mini')
->set('email', 'invalid-email')
- ->call('emitEmail')
+ ->call('submit')
->assertHasErrors(['email' => 'email']);
}
@@ -48,20 +43,19 @@ public function purchase_modal_validates_email()
public function purchase_modal_requires_email()
{
Livewire::test(PurchaseModal::class)
- ->call('openModal', 'mini')
->set('email', '')
- ->call('emitEmail')
+ ->call('submit')
->assertHasErrors(['email' => 'required']);
}
#[Test]
- public function purchase_modal_emits_event_with_valid_email()
+ public function test_submit_action()
{
Livewire::test(PurchaseModal::class)
- ->call('openModal', 'mini')
+ ->call('setPlan', 'mini')
->set('email', 'valid@example.com')
- ->call('emitEmail')
- ->assertDispatched('email-submitted', [
+ ->call('submit')
+ ->assertDispatched('purchase-request-submitted', [
'email' => 'valid@example.com',
'plan' => 'mini',
]);
@@ -71,25 +65,9 @@ public function purchase_modal_emits_event_with_valid_email()
public function purchase_modal_closes_after_emitting_event()
{
Livewire::test(PurchaseModal::class)
- ->call('openModal', 'mini')
+ ->call('setPlan', 'mini')
->set('email', 'valid@example.com')
- ->call('emitEmail')
+ ->call('submit')
->assertSet('showModal', false);
}
-
- #[Test]
- public function purchase_modal_can_be_opened_via_alpine_event()
- {
- $component = Livewire::test(PurchaseModal::class);
-
- // Simulate the Alpine.js event
- $component->dispatch('open-purchase-modal', ['plan' => 'pro'])
- ->assertDispatched('open-purchase-modal');
-
- // Since we can't directly test Alpine.js event handling in PHPUnit,
- // we'll verify that the openModal method works as expected
- $component->call('openModal', 'pro')
- ->assertSet('selectedPlan', 'pro')
- ->assertSet('showModal', true);
- }
}
diff --git a/tests/Feature/MobilePricingTest.php b/tests/Feature/MobilePricingTest.php
index 89bed179..5deba73e 100644
--- a/tests/Feature/MobilePricingTest.php
+++ b/tests/Feature/MobilePricingTest.php
@@ -6,10 +6,6 @@
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Auth;
-use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\Hash;
-use Illuminate\Support\Str;
-use Laravel\Cashier\Cashier;
use Livewire\Livewire;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
@@ -18,211 +14,50 @@ class MobilePricingTest extends TestCase
{
use RefreshDatabase;
- protected string $testPriceId;
-
- protected function setUp(): void
- {
- parent::setUp();
-
- // Make sure we're using Stripe test keys
- $this->assertStringStartsWith('sk_test_', config('cashier.secret'));
-
- // Create a test price in Stripe for our tests
- $product = Cashier::stripe()->products->create([
- 'name' => 'Test Product',
- 'description' => 'Created for testing',
- ]);
-
- $price = Cashier::stripe()->prices->create([
- 'product' => $product->id,
- 'unit_amount' => 5000, // $50.00
- 'currency' => 'usd',
- 'recurring' => [
- 'interval' => 'year',
- ],
- ]);
-
- $this->testPriceId = $price->id;
-
- // Configure our test price ID in the app
- Config::set('subscriptions.plans.mini.stripe_price_id', $this->testPriceId);
- }
-
- protected function tearDown(): void
- {
- // Clean up Stripe resources
- if (isset($this->testPriceId)) {
- $price = Cashier::stripe()->prices->retrieve($this->testPriceId);
- Cashier::stripe()->products->delete($price->product, []);
- // Prices cannot be deleted in Stripe, but the product can be
- }
-
- parent::tearDown();
- }
-
#[Test]
- public function authenticated_users_can_directly_create_checkout_session()
+ public function authenticated_users_will_directly_create_checkout_session()
{
- // Create and authenticate a user
$user = User::factory()->create();
Auth::login($user);
- // Test the component with real Stripe integration
$component = Livewire::test(MobilePricing::class);
-
- // Call the method and assert the redirect
- $response = $component->call('createCheckoutSession', 'mini', $user);
-
- // The response should be a redirect to Stripe checkout
- $response->assertRedirect();
- $redirectUrl = $response->effects['redirect'];
-
- // Verify it's a Stripe checkout URL
- $this->assertStringContainsString('checkout.stripe.com', $redirectUrl);
-
- // Verify the user has a Stripe customer ID
- $user->refresh();
- $this->assertNotNull($user->stripe_id);
-
- // Verify the customer exists in Stripe
- $customer = Cashier::stripe()->customers->retrieve($user->stripe_id);
- $this->assertEquals($user->email, $customer->email);
+ $component->assertSeeHtml([
+ 'wire:click="createCheckoutSession(\'mini\')"',
+ 'wire:click="createCheckoutSession(\'pro\')"',
+ 'wire:click="createCheckoutSession(\'max\')"',
+ ]);
+ $component->assertDontSeeHtml([
+ '@click="$dispatch(\'open-purchase-modal\', { plan: \'mini\' })"',
+ '@click="$dispatch(\'open-purchase-modal\', { plan: \'pro\' })"',
+ '@click="$dispatch(\'open-purchase-modal\', { plan: \'max\' })"',
+ ]);
}
#[Test]
public function guest_users_see_purchase_modal_component()
{
- // Make sure no user is authenticated
Auth::logout();
- $response = $this->get(route('early-adopter'));
-
- // Assert that the page contains the purchase modal component
- $response->assertSeeLivewire('purchase-modal');
- }
-
- #[Test]
- public function it_can_find_or_create_user_by_email()
- {
- $email = 'test-find-create-'.Str::random(10).'@example.com';
-
- // Test with a new email
- $component = Livewire::test(MobilePricing::class);
- $method = new \ReflectionMethod(MobilePricing::class, 'findOrCreateUser');
- $method->setAccessible(true);
-
- $user = $method->invoke($component->instance(), $email);
-
- $this->assertInstanceOf(User::class, $user);
- $this->assertEquals($email, $user->email);
- $this->assertDatabaseHas('users', ['email' => $email]);
-
- // Test with an existing email
- $existingEmail = 'existing-'.Str::random(10).'@example.com';
- $existingUser = User::factory()->create(['email' => $existingEmail]);
- $foundUser = $method->invoke($component->instance(), $existingEmail);
-
- $this->assertEquals($existingUser->id, $foundUser->id);
- }
-
- #[Test]
- public function it_handles_email_submission_and_creates_checkout_session()
- {
- $email = 'test-email-submission-'.Str::random(10).'@example.com';
-
- // Test the component with real Stripe integration
- $component = Livewire::test(MobilePricing::class);
-
- // Call the method with test data
- $response = $component->call('handleEmailSubmitted', [
- 'email' => $email,
- 'plan' => 'mini',
- ]);
-
- // The response should be a redirect to Stripe checkout
- $response->assertRedirect();
- $redirectUrl = $response->effects['redirect'];
-
- // Verify it's a Stripe checkout URL
- $this->assertStringContainsString('checkout.stripe.com', $redirectUrl);
-
- // Verify a user was created with the email
- $this->assertDatabaseHas('users', ['email' => $email]);
-
- // Verify the user has a Stripe customer ID
- $user = User::where('email', $email)->first();
- $this->assertNotNull($user->stripe_id);
-
- // Verify the customer exists in Stripe
- $customer = Cashier::stripe()->customers->retrieve($user->stripe_id);
- $this->assertEquals($email, $customer->email);
- }
-
- #[Test]
- public function success_url_contains_checkout_session_id_placeholder()
- {
- $component = Livewire::test(MobilePricing::class);
- $method = new \ReflectionMethod(MobilePricing::class, 'successUrl');
- $method->setAccessible(true);
-
- $url = $method->invoke($component->instance());
-
- $this->assertStringContainsString('{CHECKOUT_SESSION_ID}', $url);
- }
-
- #[Test]
- public function it_creates_stripe_customer_for_new_users()
- {
- $email = 'new-stripe-customer-'.Str::random(10).'@example.com';
-
- // Create a new user
- $user = User::create([
- 'email' => $email,
- 'password' => Hash::make(Str::random(72)),
- ]);
-
- // Test the component with real Stripe integration
- $component = Livewire::test(MobilePricing::class);
-
- // Call the method and assert the redirect
- $response = $component->call('createCheckoutSession', 'mini', $user);
-
- // Refresh the user to get the updated stripe_id
- $user->refresh();
-
- // Verify the user has a Stripe customer ID
- $this->assertNotNull($user->stripe_id);
-
- // Verify the customer exists in Stripe
- $customer = Cashier::stripe()->customers->retrieve($user->stripe_id);
- $this->assertEquals($email, $customer->email);
+ Livewire::test(MobilePricing::class)
+ ->assertSeeLivewire('purchase-modal')
+ ->assertSeeHtml([
+ '@click="$dispatch(\'open-purchase-modal\', { plan: \'mini\' })"',
+ '@click="$dispatch(\'open-purchase-modal\', { plan: \'pro\' })"',
+ '@click="$dispatch(\'open-purchase-modal\', { plan: \'max\' })"',
+ ])
+ ->assertDontSeeHtml([
+ 'wire:click="createCheckoutSession(\'mini\')"',
+ 'wire:click="createCheckoutSession(\'pro\')"',
+ 'wire:click="createCheckoutSession(\'max\')"',
+ ]);
}
#[Test]
- public function it_uses_existing_stripe_customer_for_existing_users()
+ public function authenticated_users_do_not_see_purchase_modal_component()
{
- $email = 'existing-stripe-customer-'.Str::random(10).'@example.com';
-
- // Create a new user
- $user = User::create([
- 'email' => $email,
- 'password' => Hash::make(Str::random(72)),
- ]);
-
- // Create a Stripe customer for this user
- $user->createAsStripeCustomer();
- $originalStripeId = $user->stripe_id;
-
- // Test the component with real Stripe integration
- $component = Livewire::test(MobilePricing::class);
-
- // Call the method and assert the redirect
- $response = $component->call('createCheckoutSession', 'mini', $user);
-
- // Refresh the user to get the updated stripe_id
- $user->refresh();
+ Auth::login(User::factory()->create());
- // Verify the user still has the same Stripe customer ID
- $this->assertEquals($originalStripeId, $user->stripe_id);
+ Livewire::test(MobilePricing::class)
+ ->assertDontSeeLivewire('purchase-modal');
}
}
diff --git a/tests/Feature/MobileRouteTest.php b/tests/Feature/MobileRouteTest.php
index 95c85437..1c0b9bb4 100644
--- a/tests/Feature/MobileRouteTest.php
+++ b/tests/Feature/MobileRouteTest.php
@@ -2,27 +2,26 @@
namespace Tests\Feature;
-use Illuminate\Support\Facades\Config;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class MobileRouteTest extends TestCase
{
#[Test]
- public function mobile_route_includes_stripe_payment_links()
+ public function mobile_route_does_not_include_stripe_payment_links()
{
- $mockLinks = [
- 'mini' => ['stripe_payment_link' => 'https://buy.stripe.com/mini-payment'],
- 'pro' => ['stripe_payment_link' => 'https://buy.stripe.com/pro-payment'],
- 'max' => ['stripe_payment_link' => 'https://buy.stripe.com/max-payment'],
- ];
-
- Config::set('subscriptions.plans', $mockLinks);
-
- $response = $this->withoutVite()->get(route('early-adopter'))->getContent();
+ $this
+ ->withoutVite()
+ ->get(route('early-adopter'))
+ ->assertDontSee('buy.stripe.com');
+ }
- $this->assertStringContainsString($mockLinks['mini']['stripe_payment_link'], $response);
- $this->assertStringContainsString($mockLinks['pro']['stripe_payment_link'], $response);
- $this->assertStringContainsString($mockLinks['max']['stripe_payment_link'], $response);
+ #[Test]
+ public function mobile_route_includes_mobile_pricing_livewire_component()
+ {
+ $this
+ ->withoutVite()
+ ->get(route('early-adopter'))
+ ->assertSeeLivewire('mobile-pricing');
}
}
From 7da4544379ef8fc1dd0a7677ea66fca012650ac2 Mon Sep 17 00:00:00 2001
From: Steven Fox <62109327+steven-fox@users.noreply.github.com>
Date: Sat, 17 May 2025 13:12:13 -0400
Subject: [PATCH 4/4] remove comment
---
resources/views/early-adopter.blade.php | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/resources/views/early-adopter.blade.php b/resources/views/early-adopter.blade.php
index 541273bc..c208f3fa 100644
--- a/resources/views/early-adopter.blade.php
+++ b/resources/views/early-adopter.blade.php
@@ -676,11 +676,14 @@ class="mx-auto flex w-full max-w-2xl flex-col items-center gap-4 pt-10"
-
+
- Yes! Once we've hit sustainability and can afford to continue
- investing in this project indirectly, then a version of it will
- be fully open source and made available for free.
+ Yes! Once we've hit sustainability and can afford to
+ continue investing in this project indirectly, then a
+ version of it will be fully open source and made available
+ for free.
@@ -694,9 +697,7 @@ class="mx-auto flex w-full max-w-2xl flex-col items-center gap-4 pt-10"
-
- It's READY! Sign up and build apps for Android today!
-
+ It's READY! Sign up and build apps for Android today!
@@ -744,14 +745,15 @@ class="mx-auto flex w-full max-w-2xl flex-col items-center gap-4 pt-10"
- If you purchased after May 6, 2025, you should get an invoice with your receipt via email.
+ If you purchased after May 6, 2025, you should get an
+ invoice with your receipt via email.
For purchases made before this, you simply need to
follow the instructions here
@@ -843,5 +845,4 @@ class="dark:text-white"
-