diff --git a/website/tests/Feature/Marketing/DedicatedServersTest.php b/website/tests/Feature/Marketing/DedicatedServersTest.php new file mode 100644 index 0000000..258fa0a --- /dev/null +++ b/website/tests/Feature/Marketing/DedicatedServersTest.php @@ -0,0 +1,167 @@ +seed(RoleAndPermissionSeeder::class); + $this->seed(PlanSeeder::class); + $this->seed(ConfigOptionSeeder::class); +}); + +test('dedicated-servers landing page returns all 14th-gen + legacy plans', function (): void { + $response = $this->get('/dedicated-servers'); + $response->assertOk(); + + $page = $response->viewData('page'); + expect($page['component'])->toBe('Marketing/DedicatedServers'); + + $plans = collect($page['props']['plans']); + expect($plans)->toHaveCount(16); + + // 8 14th-gen build-to-order + $buildToOrder = $plans->where('features.generation', '14th-gen'); + expect($buildToOrder)->toHaveCount(8); + + // 8 legacy 12th/13th-gen in-stock + $legacy = $plans->whereIn('features.generation', ['12th-gen', '13th-gen']); + expect($legacy)->toHaveCount(8); +}); + +test('all 8 14th-gen chassis have setup_fee in the expected tier band', function (): void { + $expected = [ + 'r440-4lff' => 349, + 'r540-8lff' => 549, + 'r640-8sff' => 349, + 'r740-16sff' => 549, + 'r740xd-24sff' => 549, + 'r740xd-12lff' => 549, + 'r640-10nvme' => 799, + 'r740xd-24nvme' => 799, + ]; + + foreach ($expected as $slug => $fee) { + $plan = Plan::where('slug', $slug)->first(); + expect($plan)->not->toBeNull("Plan $slug missing"); + expect((float) $plan->setup_fee)->toBe((float) $fee); + expect($plan->status)->toBe('active'); + } +}); + +test('legacy 12th/13th-gen plans are active with zero setup fee', function (): void { + $legacySlugs = [ + 'dell-r330-lff', 'dell-r420-lff', 'dell-r620-sff-10-bay', + 'dell-r620-sff-8-bay', 'dell-r520-lff', 'dell-r430-lff', + 'dell-r630-sff', 'dell-r730-lff', + ]; + + foreach ($legacySlugs as $slug) { + $plan = Plan::where('slug', $slug)->first(); + expect($plan)->not->toBeNull(); + expect($plan->status)->toBe('active'); + expect((float) $plan->setup_fee)->toBe(0.0); + } +}); + +test('per-chassis detail page renders for every 14th-gen slug', function (): void { + $slugs = [ + 'r440-4lff', 'r540-8lff', 'r640-8sff', 'r740-16sff', + 'r740xd-24sff', 'r740xd-12lff', 'r640-10nvme', 'r740xd-24nvme', + ]; + + foreach ($slugs as $slug) { + $response = $this->get("/dedicated-servers/{$slug}"); + $response->assertOk(); + $page = $response->viewData('page'); + expect($page['component'])->toBe('Marketing/DedicatedServerDetail'); + expect($page['props']['plan']['slug'])->toBe($slug); + } +}); + +test('detail page returns 404 for invalid slug', function (): void { + $this->get('/dedicated-servers/does-not-exist')->assertNotFound(); +}); + +test('detail page exposes chassis-specific config groups', function (): void { + $response = $this->get('/dedicated-servers/r740xd-24nvme'); + $response->assertOk(); + + $configGroups = collect($response->viewData('page')['props']['configGroups']); + $names = $configGroups->pluck('name'); + + // R740xd variants get the R740xd CPU group, not the standard CPU group + expect($names)->toContain('Dedicated 14th Gen — CPU Upgrade (R740xd)'); + expect($names)->not->toContain('Dedicated 14th Gen — CPU Upgrade'); + + // Universal groups (RAM, OS, Bandwidth, IPv4) attach to all 8 chassis + expect($names)->toContain('Dedicated 14th Gen — RAM Upgrade'); + expect($names)->toContain('Dedicated 14th Gen — Operating System'); + expect($names)->toContain('Dedicated 14th Gen — Bandwidth'); + expect($names)->toContain('Dedicated 14th Gen — IPv4 Block'); +}); + +test('non-R740xd chassis get the standard CPU group', function (): void { + $response = $this->get('/dedicated-servers/r440-4lff'); + $response->assertOk(); + + $names = collect($response->viewData('page')['props']['configGroups'])->pluck('name'); + + expect($names)->toContain('Dedicated 14th Gen — CPU Upgrade'); + expect($names)->not->toContain('Dedicated 14th Gen — CPU Upgrade (R740xd)'); +}); + +test('seeder creates the 6 dedicated 14th-gen config groups', function (): void { + $names = PlanConfigGroup::query() + ->where('name', 'like', 'Dedicated 14th Gen%') + ->pluck('name') + ->all(); + + expect(count($names))->toBe(6); + expect($names)->toContain('Dedicated 14th Gen — CPU Upgrade'); + expect($names)->toContain('Dedicated 14th Gen — CPU Upgrade (R740xd)'); + expect($names)->toContain('Dedicated 14th Gen — RAM Upgrade'); + expect($names)->toContain('Dedicated 14th Gen — Operating System'); + expect($names)->toContain('Dedicated 14th Gen — Bandwidth'); + expect($names)->toContain('Dedicated 14th Gen — IPv4 Block'); +}); + +test('RAM upgrade group standardizes on DDR4-2400 across all tiers', function (): void { + $group = PlanConfigGroup::where('name', 'Dedicated 14th Gen — RAM Upgrade')->first(); + $values = $group->options->first()->values; + + expect($values)->toHaveCount(7); + foreach ($values as $value) { + expect($value->label)->toContain('DDR4-2400'); + } +}); + +test('checkout setupFee prop is exposed on dedicated plan checkout', function (): void { + $user = \App\Models\User::factory()->create(); + $user->assignRole('customer'); + + $r440 = Plan::where('slug', 'r440-4lff')->first(); + $accountUrl = 'http://'.config('app.domains.account'); + + $response = $this->actingAs($user)->get("{$accountUrl}/checkout/{$r440->id}"); + $response->assertOk(); + + expect($response->viewData('page')['props']['setupFee'])->toBe(349.0); +}); + +test('checkout setupFee on a VPS plan is zero', function (): void { + $user = \App\Models\User::factory()->create(); + $user->assignRole('customer'); + + $vps = Plan::where('slug', 'vps-1')->first(); + $accountUrl = 'http://'.config('app.domains.account'); + + $response = $this->actingAs($user)->get("{$accountUrl}/checkout/{$vps->id}"); + $response->assertOk(); + + expect($response->viewData('page')['props']['setupFee'])->toBe(0.0); +});