'Priced Product', 'description' => 'A product description', 'website_url' => 'https://example.com', 'category_id' => makeCategory()->id, ], $overrides); } test('submitter adds plans', function () { $user = userWithRole('user'); $this->actingAs($user)->post(route('products.store'), pricingPayload([ 'plans' => [ ['name' => 'Free', 'price' => '0', 'period' => 'monthly', 'description' => 'Basics'], ['name' => 'Team', 'price' => '9.99', 'period' => 'monthly'], ], ]))->assertRedirect()->assertSessionHasNoErrors(); $plans = Product::firstOrFail()->pricingPlans; expect($plans->pluck('name')->all())->toBe(['Free', 'Team']); expect($plans->pluck('position')->all())->toBe([0, 1]); expect((float) $plans[1]->price)->toBe(9.99); }); test('invalid plans fail validation and save nothing', function (array $plan, string $key) { $user = userWithRole('user'); $this->actingAs($user)->post(route('products.store'), pricingPayload([ 'plans' => [array_merge(['name' => 'Pro', 'price' => '5', 'period' => 'yearly'], $plan)], ]))->assertSessionHasErrors($key); expect(Product::count())->toBe(0); expect(PricingPlan::count())->toBe(0); })->with([ 'negative price' => [['price' => '-1'], 'plans.0.price'], 'non numeric price' => [['price' => 'abc'], 'plans.0.price'], 'bad period' => [['period' => 'weekly'], 'plans.0.period'], 'missing name' => [['name' => ''], 'plans.0.name'], ]); test('update replaces the plan list', function () { $user = userWithRole('user'); $product = Product::factory()->pending()->create(['user_id' => $user->id]); $product->pricingPlans()->create(['name' => 'Old', 'price' => 1, 'period' => 'monthly', 'position' => 0]); $product->pricingPlans()->create(['name' => 'Older', 'price' => 2, 'period' => 'yearly', 'position' => 1]); $this->actingAs($user)->put(route('products.update', $product), pricingPayload([ 'category_id' => $product->category_id, 'plans_present' => 1, 'plans' => [['name' => 'New', 'price' => '3', 'period' => 'one-time']], ]))->assertRedirect(); expect($product->pricingPlans()->pluck('name')->all())->toBe(['New']); }); test('show page prints price and period', function () { $product = Product::factory()->approved()->create(); $product->pricingPlans()->create(['name' => 'Free', 'price' => 0, 'period' => 'monthly', 'position' => 0]); $product->pricingPlans()->create(['name' => 'Team', 'price' => 9.99, 'period' => 'monthly', 'position' => 1]); $this->get(route('products.show', $product))->assertOk() ->assertSee('€9.99')->assertSee('monthly')->assertSee('€0'); }); test('no plans, no pricing section', function () { $product = Product::factory()->approved()->create(); $this->get(route('products.show', $product))->assertOk()->assertDontSee('data-pricing', false); });