Repo rebuild
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Platform;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Modules\Company\Models\Company;
|
||||
use Modules\Platform\app\Models\LicenseKey;
|
||||
use Modules\Platform\app\Models\Payment;
|
||||
use Modules\Platform\app\Models\PlatformPrice;
|
||||
use Modules\Warehouse\app\Models\Warehouse;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* Covers PlatformDashboardController, CompanyController, LicenseKeyController, PaymentController and StripeWebhookController.
|
||||
*/
|
||||
class PlatformAdministrationTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
* Ensure guests are redirected away from platform administration.
|
||||
*/
|
||||
public function test_guest_is_redirected_from_platform_dashboard(): void
|
||||
{
|
||||
$this->get(route('platform.dashboard'))->assertRedirect(route('login'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure non-platform users cannot access admin administration.
|
||||
*/
|
||||
public function test_regular_user_is_forbidden_from_platform_dashboard(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user)->get(route('platform.dashboard'))->assertForbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure dashboard renders the single platform header and pricing cards.
|
||||
*/
|
||||
public function test_platform_dashboard_renders_counts_without_pricing_cards_and_recent_companies(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
PlatformPrice::query()->delete();
|
||||
$company = Company::create(['name' => 'Customer One', 'slug' => 'customer-one']);
|
||||
LicenseKey::issueFor($company, 'Customer licence', 'enterprise', 25);
|
||||
Warehouse::create(['company_id' => $company->id, 'code' => 'MAIN', 'name' => 'Main Warehouse']);
|
||||
Payment::create(['company_id' => $company->id, 'amount' => 12500, 'currency' => 'gbp', 'status' => 'paid']);
|
||||
PlatformPrice::create($this->pricePayload(['code' => 'basic', 'name' => 'Basic']));
|
||||
PlatformPrice::create($this->pricePayload(['code' => 'advanced', 'name' => 'Advanced', 'sort_order' => 20]));
|
||||
PlatformPrice::create($this->pricePayload(['code' => 'pro', 'name' => 'Pro', 'sort_order' => 30]));
|
||||
|
||||
$this->actingAs($admin)
|
||||
->get(route('platform.dashboard'))
|
||||
->assertOk()
|
||||
->assertSee('Platform Dashboard', false)
|
||||
->assertDontSee('Pricing plans', false)
|
||||
->assertSee('Customer One', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure companies can be created by platform admins.
|
||||
*/
|
||||
public function test_platform_admin_can_create_company(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
|
||||
$this->actingAs($admin)->withSession(['_token' => 'test-token'])->post(route('platform.companies.store'), $this->csrfPayload([
|
||||
'name' => 'Abbott Logistics Limited',
|
||||
'billing_email' => 'billing@abbott.example',
|
||||
'status' => 'active',
|
||||
]))->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('companies', [
|
||||
'name' => 'Abbott Logistics Limited',
|
||||
'slug' => 'abbott-logistics-limited',
|
||||
'billing_email' => 'billing@abbott.example',
|
||||
'status' => 'active',
|
||||
'timezone' => 'Europe/London',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure invalid company submissions are rejected.
|
||||
*/
|
||||
public function test_company_create_validates_input(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->from(route('platform.companies.index'))
|
||||
->withSession(['_token' => 'test-token'])
|
||||
->post(route('platform.companies.store'), $this->csrfPayload([
|
||||
'name' => '',
|
||||
'billing_email' => 'not-an-email',
|
||||
'status' => 'unknown',
|
||||
]))
|
||||
->assertRedirect(route('platform.companies.index'))
|
||||
->assertSessionHasErrors(['name', 'billing_email', 'status']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure licences are issued hashed and shown once in session.
|
||||
*/
|
||||
public function test_platform_admin_can_issue_license_key(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
$company = Company::create(['name' => 'Tenant A', 'slug' => 'tenant-a']);
|
||||
|
||||
$response = $this->actingAs($admin)->withSession(['_token' => 'test-token'])->post(route('platform.licenses.store'), $this->csrfPayload([
|
||||
'company_id' => $company->id,
|
||||
'label' => 'Production licence',
|
||||
'plan' => 'enterprise',
|
||||
'max_users' => 500,
|
||||
]));
|
||||
|
||||
$response->assertRedirect()->assertSessionHas('plain_license_key');
|
||||
|
||||
$plainKey = session('plain_license_key');
|
||||
$license = LicenseKey::firstOrFail();
|
||||
|
||||
$this->assertStringStartsWith('WMS-', $plainKey);
|
||||
$this->assertSame(hash('sha256', $plainKey), $license->key_hash);
|
||||
$this->assertSame('enterprise', $license->plan);
|
||||
$this->assertSame(500, $license->max_users);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure licence input is validated.
|
||||
*/
|
||||
public function test_license_create_validates_input(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->from(route('platform.licenses.index'))
|
||||
->withSession(['_token' => 'test-token'])
|
||||
->post(route('platform.licenses.store'), $this->csrfPayload([
|
||||
'company_id' => 999,
|
||||
'label' => '',
|
||||
'plan' => 'ultimate',
|
||||
'max_users' => 0,
|
||||
]))
|
||||
->assertRedirect(route('platform.licenses.index'))
|
||||
->assertSessionHasErrors(['company_id', 'label', 'plan', 'max_users']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure manual payments are recorded with paid_at for paid statuses.
|
||||
*/
|
||||
public function test_platform_admin_can_create_manual_payment(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
$company = Company::create(['name' => 'Tenant Payment', 'slug' => 'tenant-payment']);
|
||||
|
||||
$this->actingAs($admin)->withSession(['_token' => 'test-token'])->post(route('platform.payments.store'), $this->csrfPayload([
|
||||
'company_id' => $company->id,
|
||||
'amount' => 12345,
|
||||
'currency' => 'gbp',
|
||||
'status' => 'paid',
|
||||
'description' => 'Manual bank transfer',
|
||||
]))->assertRedirect();
|
||||
|
||||
$payment = Payment::firstOrFail();
|
||||
|
||||
$this->assertSame($company->id, $payment->company_id);
|
||||
$this->assertSame(12345, $payment->amount);
|
||||
$this->assertSame('manual_admin', $payment->metadata['source']);
|
||||
$this->assertNotNull($payment->paid_at);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure unpaid statuses do not set paid_at.
|
||||
*/
|
||||
public function test_pending_payment_does_not_set_paid_at(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
$company = Company::create(['name' => 'Tenant Pending', 'slug' => 'tenant-pending']);
|
||||
|
||||
$this->actingAs($admin)->withSession(['_token' => 'test-token'])->post(route('platform.payments.store'), $this->csrfPayload([
|
||||
'company_id' => $company->id,
|
||||
'amount' => 5000,
|
||||
'currency' => 'gbp',
|
||||
'status' => 'pending',
|
||||
'description' => 'Awaiting payment',
|
||||
]))->assertRedirect();
|
||||
|
||||
$this->assertNull(Payment::firstOrFail()->paid_at);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the Stripe webhook creates or updates paid records.
|
||||
*/
|
||||
public function test_stripe_webhook_records_successful_payment_intent(): void
|
||||
{
|
||||
$company = Company::create([
|
||||
'name' => 'Stripe Tenant',
|
||||
'slug' => 'stripe-tenant',
|
||||
'stripe_customer_id' => 'cus_test_123',
|
||||
]);
|
||||
|
||||
$payload = [
|
||||
'type' => 'payment_intent.succeeded',
|
||||
'data' => [
|
||||
'object' => [
|
||||
'id' => 'pi_123',
|
||||
'customer' => 'cus_test_123',
|
||||
'amount_received' => 7800,
|
||||
'currency' => 'gbp',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->withSession(['_token' => 'test-token'])->withHeader('X-CSRF-TOKEN', 'test-token')->postJson(route('stripe.webhook'), $payload)
|
||||
->assertOk()
|
||||
->assertJson(['received' => true]);
|
||||
|
||||
$this->assertDatabaseHas('payments', [
|
||||
'company_id' => $company->id,
|
||||
'stripe_payment_intent_id' => 'pi_123',
|
||||
'amount' => 7800,
|
||||
'currency' => 'gbp',
|
||||
'status' => 'paid',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure unrelated Stripe events are acknowledged but do not create payments.
|
||||
*/
|
||||
public function test_stripe_webhook_ignores_unhandled_events(): void
|
||||
{
|
||||
$this->withSession(['_token' => 'test-token'])->withHeader('X-CSRF-TOKEN', 'test-token')->postJson(route('stripe.webhook'), ['type' => 'customer.created'])
|
||||
->assertOk()
|
||||
->assertJson(['received' => true]);
|
||||
|
||||
$this->assertDatabaseCount('payments', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $overrides
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function pricePayload(array $overrides = []): array
|
||||
{
|
||||
return [
|
||||
'code' => 'basic',
|
||||
'name' => 'Basic',
|
||||
'strapline' => 'Starter WMS platform access.',
|
||||
'description' => 'Core warehouse management tools.',
|
||||
'monthly_amount' => 4900,
|
||||
'annual_amount' => 49000,
|
||||
'currency' => 'gbp',
|
||||
'badge_label' => 'Starter',
|
||||
'features' => ['2 warehouses', '10 users', 'Standard support'],
|
||||
'sort_order' => 10,
|
||||
'is_featured' => false,
|
||||
'is_active' => true,
|
||||
...$overrides,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload with a valid test CSRF token.
|
||||
*
|
||||
* @param array<string, mixed> $payload
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function csrfPayload(array $payload = []): array
|
||||
{
|
||||
return ['_token' => 'test-token'] + $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seed the test session with the matching CSRF token.
|
||||
*/
|
||||
private function withCsrfSession(): self
|
||||
{
|
||||
$this->withSession(['_token' => 'test-token']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Platform;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Modules\Platform\app\Models\PlatformPrice;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Tests\TestCase;
|
||||
|
||||
class PlatformPriceCrudTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
* Ensure the customer-facing Platform pricing page only shows active prices in display order.
|
||||
*/
|
||||
public function test_platform_pricing_page_displays_active_prices_in_card_grid(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
PlatformPrice::query()->delete();
|
||||
|
||||
PlatformPrice::create($this->pricePayload(['code' => 'pro', 'name' => 'Pro', 'sort_order' => 30]));
|
||||
PlatformPrice::create($this->pricePayload(['code' => 'basic', 'name' => 'Basic', 'sort_order' => 10]));
|
||||
PlatformPrice::create($this->pricePayload(['code' => 'legacy', 'name' => 'Legacy', 'is_active' => false, 'sort_order' => 1]));
|
||||
|
||||
$response = $this->actingAs($user)->get(route('platform.pricing.index'));
|
||||
|
||||
$response->assertOk()
|
||||
->assertSee('Pricing', false)
|
||||
->assertSee('Basic', false)
|
||||
->assertSee('Pro', false)
|
||||
->assertDontSee('Legacy', false)
|
||||
->assertSeeInOrder(['Basic', 'Pro']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the admin pricing index remains an Administration CRUD area.
|
||||
*/
|
||||
public function test_platform_admin_can_view_price_crud_index(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
PlatformPrice::query()->delete();
|
||||
PlatformPrice::create($this->pricePayload(['code' => 'advanced', 'name' => 'Advanced']));
|
||||
|
||||
$this->actingAs($admin)
|
||||
->get(route('platform.prices.index'))
|
||||
->assertOk()
|
||||
->assertSee('Pricing Administration', false)
|
||||
->assertSee('Advanced', false)
|
||||
->assertSee('Add price', false)
|
||||
->assertSee(route('platform.prices.create'), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure only MPBA platform admins can reach price administration.
|
||||
*/
|
||||
public function test_non_platform_admin_cannot_access_price_crud(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('platform.prices.index'))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure create renders with default form values.
|
||||
*/
|
||||
public function test_platform_admin_can_open_create_price_form(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->get(route('platform.prices.create'))
|
||||
->assertOk()
|
||||
->assertSee('Create Price', false)
|
||||
->assertSee('Currency', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure store normalises amounts, code, booleans, currency and feature rows.
|
||||
*/
|
||||
public function test_platform_admin_can_create_price(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
|
||||
$response = $this->actingAs($admin)->withSession(['_token' => 'test-token'])->post(route('platform.prices.store'), $this->csrfPayload([
|
||||
'code' => '',
|
||||
'name' => 'Ultimate Plan',
|
||||
'strapline' => 'Full control',
|
||||
'description' => 'Unlimited warehouses and users.',
|
||||
'monthly_amount' => '199.99',
|
||||
'annual_amount' => '1999.00',
|
||||
'currency' => 'GBP',
|
||||
'badge_label' => 'Best Value',
|
||||
'features' => "Unlimited warehouses\nUnlimited users\nPriority support\n",
|
||||
'sort_order' => 40,
|
||||
'is_featured' => '1',
|
||||
'is_active' => '1',
|
||||
]));
|
||||
|
||||
$response->assertRedirect(route('platform.prices.index'));
|
||||
|
||||
$this->assertDatabaseHas('platform_prices', [
|
||||
'code' => 'ultimate-plan',
|
||||
'name' => 'Ultimate Plan',
|
||||
'monthly_amount' => 19999,
|
||||
'annual_amount' => 199900,
|
||||
'currency' => 'gbp',
|
||||
'is_featured' => true,
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
$this->assertSame(
|
||||
['Unlimited warehouses', 'Unlimited users', 'Priority support'],
|
||||
PlatformPrice::where('code', 'ultimate-plan')->firstOrFail()->featureRows(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure validation protects required fields and amount limits.
|
||||
*/
|
||||
public function test_create_price_validates_required_fields(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->from(route('platform.prices.create'))
|
||||
->withSession(['_token' => 'test-token'])
|
||||
->post(route('platform.prices.store'), $this->csrfPayload([
|
||||
'name' => '',
|
||||
'monthly_amount' => '-1',
|
||||
'currency' => 'GB',
|
||||
'sort_order' => -5,
|
||||
]))
|
||||
->assertRedirect(route('platform.prices.create'))
|
||||
->assertSessionHasErrors(['name', 'monthly_amount', 'currency', 'sort_order']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure edit renders the current price.
|
||||
*/
|
||||
public function test_platform_admin_can_open_edit_price_form(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
PlatformPrice::query()->delete();
|
||||
$price = PlatformPrice::create($this->pricePayload(['code' => 'basic-edit', 'name' => 'Basic']));
|
||||
|
||||
$this->actingAs($admin)
|
||||
->get(route('platform.prices.edit', $price))
|
||||
->assertOk()
|
||||
->assertSee('Edit Basic', false)
|
||||
->assertSee('Basic', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure update preserves unique-code validation for the current record.
|
||||
*/
|
||||
public function test_platform_admin_can_update_price(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
PlatformPrice::query()->delete();
|
||||
$price = PlatformPrice::create($this->pricePayload(['code' => 'basic', 'name' => 'Basic']));
|
||||
|
||||
$this->actingAs($admin)->withSession(['_token' => 'test-token'])->put(route('platform.prices.update', $price), $this->csrfPayload([
|
||||
'code' => 'basic',
|
||||
'name' => 'Basic Updated',
|
||||
'strapline' => 'Entry level stock control',
|
||||
'description' => 'Updated description.',
|
||||
'monthly_amount' => '29.00',
|
||||
'annual_amount' => '',
|
||||
'currency' => 'GBP',
|
||||
'badge_label' => '',
|
||||
'features' => "2 warehouses\n10 users",
|
||||
'sort_order' => 5,
|
||||
'is_active' => '1',
|
||||
]))->assertRedirect(route('platform.prices.index'));
|
||||
|
||||
$this->assertDatabaseHas('platform_prices', [
|
||||
'id' => $price->id,
|
||||
'code' => 'basic',
|
||||
'name' => 'Basic Updated',
|
||||
'monthly_amount' => 2900,
|
||||
'annual_amount' => null,
|
||||
'sort_order' => 5,
|
||||
'is_featured' => false,
|
||||
'is_active' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure duplicate codes are rejected on update.
|
||||
*/
|
||||
public function test_price_code_must_remain_unique(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
PlatformPrice::query()->delete();
|
||||
PlatformPrice::create($this->pricePayload(['code' => 'basic', 'name' => 'Basic']));
|
||||
$price = PlatformPrice::create($this->pricePayload(['code' => 'advanced', 'name' => 'Advanced']));
|
||||
|
||||
$this->actingAs($admin)
|
||||
->from(route('platform.prices.edit', $price))
|
||||
->withSession(['_token' => 'test-token'])
|
||||
->put(route('platform.prices.update', $price), $this->csrfPayload([
|
||||
...$this->requestPayload(),
|
||||
'code' => 'basic',
|
||||
'name' => 'Advanced',
|
||||
]))
|
||||
->assertRedirect(route('platform.prices.edit', $price))
|
||||
->assertSessionHasErrors(['code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure destroy removes the price.
|
||||
*/
|
||||
public function test_platform_admin_can_delete_price(): void
|
||||
{
|
||||
$admin = User::factory()->mpbaPlatformAdmin()->create();
|
||||
PlatformPrice::query()->delete();
|
||||
$price = PlatformPrice::create($this->pricePayload(['code' => 'legacy', 'name' => 'Legacy']));
|
||||
|
||||
$this->actingAs($admin)
|
||||
->withSession(['_token' => 'test-token'])
|
||||
->delete(route('platform.prices.destroy', $price), ['_token' => 'test-token'])
|
||||
->assertRedirect(route('platform.prices.index'));
|
||||
|
||||
$this->assertDatabaseMissing('platform_prices', ['id' => $price->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure currencies render with correct symbols.
|
||||
*/
|
||||
#[DataProvider('currencySymbolProvider')]
|
||||
public function test_price_currency_symbol_and_formatting(string $currency, string $expected): void
|
||||
{
|
||||
$price = new PlatformPrice(['currency' => $currency]);
|
||||
|
||||
$this->assertSame($expected, $price->currencySymbol());
|
||||
$this->assertStringStartsWith($expected, $price->formatAmount(12345));
|
||||
$this->assertSame('—', $price->formatAmount(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{0: string, 1: string}>
|
||||
*/
|
||||
public static function currencySymbolProvider(): array
|
||||
{
|
||||
return [
|
||||
['gbp', '£'],
|
||||
['eur', '€'],
|
||||
['usd', '$'],
|
||||
['aud', 'AUD '],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $overrides
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function pricePayload(array $overrides = []): array
|
||||
{
|
||||
return [
|
||||
'code' => 'basic',
|
||||
'name' => 'Basic',
|
||||
'strapline' => 'Starter WMS platform access.',
|
||||
'description' => 'Core warehouse management tools.',
|
||||
'monthly_amount' => 4900,
|
||||
'annual_amount' => 49000,
|
||||
'currency' => 'gbp',
|
||||
'badge_label' => 'Starter',
|
||||
'features' => ['2 warehouses', '10 users', 'Standard support'],
|
||||
'sort_order' => 10,
|
||||
'is_featured' => false,
|
||||
'is_active' => true,
|
||||
...$overrides,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function requestPayload(): array
|
||||
{
|
||||
return [
|
||||
'code' => 'advanced',
|
||||
'name' => 'Advanced',
|
||||
'strapline' => 'Expanded controls.',
|
||||
'description' => 'Larger warehouse estate support.',
|
||||
'monthly_amount' => '99.00',
|
||||
'annual_amount' => '999.00',
|
||||
'currency' => 'GBP',
|
||||
'badge_label' => 'Popular',
|
||||
'features' => "5 warehouses\n100 users",
|
||||
'sort_order' => 20,
|
||||
'is_featured' => '1',
|
||||
'is_active' => '1',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload with a valid test CSRF token.
|
||||
*
|
||||
* @param array<string, mixed> $payload
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function csrfPayload(array $payload = []): array
|
||||
{
|
||||
return ['_token' => 'test-token'] + $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seed the test session with the matching CSRF token.
|
||||
*/
|
||||
private function withCsrfSession(): self
|
||||
{
|
||||
$this->withSession(['_token' => 'test-token']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user