Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/Http/Controllers/SubscriptionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public function checkout(Request $request)
{
$priceId = $request->input('price_id');

if (! $priceId) {
return back()->with('error', 'Please select a plan.');
if (! $priceId || ! str_starts_with($priceId, 'pri_')) {
return back()->with('error', 'Please select a valid plan.');
}

$checkout = $request->user()->checkout($priceId)
Expand Down
15 changes: 14 additions & 1 deletion resources/js/pages/pricing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,20 @@ export default function Pricing() {
const { auth, checkout: checkoutData } = usePage<{ auth: Auth; checkout?: Record<string, unknown> }>().props;

useEffect(() => {
if (checkoutData) {
if (window.Paddle) {
window.Paddle.Initialize({
token: import.meta.env.VITE_PADDLE_CLIENT_SIDE_TOKEN,
eventCallback: (event: any) => {
if (event.name === 'checkout.closed') {
router.reload({ only: ['auth', 'checkout'] });
}
},
});
}
}, []);

useEffect(() => {
if (checkoutData && window.Paddle) {
window.Paddle.Checkout.open(checkoutData);
}
}, [checkoutData]);
Expand Down
11 changes: 9 additions & 2 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Http\Controllers\RegistryController;
use App\Http\Controllers\SubscriptionController;
use App\Http\Controllers\ThemesController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::get('/', HomePageController::class)->name('home');
Expand All @@ -32,8 +33,14 @@
Route::post('/r/upload', [RegistryController::class, 'upload']);
Route::post('/r/upload-raw', [RegistryController::class, 'uploadRaw']);

Route::middleware(['auth', 'verified', 'role:super-admin|admin'])->group(function () {
Route::inertia('dashboard', 'dashboard')->name('dashboard');
Route::middleware(['auth', 'verified'])->group(function () {
Route::get('dashboard', function (Request $request) {
if ($request->user()->hasAnyRole(['super-admin', 'admin']) || $request->user()->subscribed()) {
return Inertia\Inertia::render('dashboard');
}

abort(403);
})->name('dashboard');
});

require __DIR__.'/settings.php';
21 changes: 21 additions & 0 deletions tests/Feature/DashboardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,24 @@
$response = $this->get(route('dashboard'));
$response->assertForbidden();
});

test('authenticated subscribed users can visit the dashboard', function () {
$this->seed(RolesAndPermissionsSeeder::class);
$user = User::factory()->create();
$user->assignRole('guest');

// Mock the subscribed method
$user->subscriptions()->create([
'type' => 'default',
'paddle_id' => 'sub_123',
'status' => 'active',
'trial_ends_at' => null,
'paused_at' => null,
'ends_at' => null,
]);

$this->actingAs($user);

$response = $this->get(route('dashboard'));
$response->assertOk();
});
27 changes: 27 additions & 0 deletions tests/Feature/SubscriptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,31 @@ public function test_subscription_edit_page_is_accessible_to_authenticated_user(

$response->assertStatus(200);
}

public function test_checkout_requires_valid_price_id()
{
$user = User::factory()->create();

$response = $this->actingAs($user)->post('/settings/subscription/checkout', [
'price_id' => 'invalid_id',
]);

$response->assertSessionHas('error', 'Please select a valid plan.');
}

public function test_checkout_returns_paddle_options()
{
$this->markTestSkipped('Paddle API interaction requires valid API keys or more extensive mocking.');

config(['cashier.api_key' => 'test_api_key']);
config(['cashier.seller_id' => 'test_seller_id']);

$user = User::factory()->create();

$response = $this->actingAs($user)->post('/settings/subscription/checkout', [
'price_id' => 'pri_123',
]);

$response->assertSessionHas('checkout');
}
}
Loading