112 lines
5.2 KiB
PHP
112 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Business;
|
|
use App\Models\BusinessDomain;
|
|
use App\Models\CustomerProfile;
|
|
use App\Models\User;
|
|
use App\Services\Businesses\BusinessProvisioningService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class TenantAndAuthTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_manager_is_restricted_to_platform_super_admins(): void
|
|
{
|
|
$this->get('/manager')->assertRedirect(route('manager.login'));
|
|
|
|
$member = User::factory()->create(['isSuperAdmin' => false]);
|
|
$this->actingAs($member)->get('/manager')->assertForbidden();
|
|
|
|
$admin = User::factory()->create(['isSuperAdmin' => true]);
|
|
$this->actingAs($admin)->get('/manager')->assertOk()->assertSee('Businesses');
|
|
}
|
|
|
|
public function test_manager_provisions_an_isolated_business_and_owner_invitation(): void
|
|
{
|
|
$admin = User::factory()->create(['isSuperAdmin' => true]);
|
|
|
|
$response = $this->actingAs($admin)->post('/manager/businesses', [
|
|
'name' => 'New Chair Studio',
|
|
'shortName' => 'New Chair',
|
|
'slug' => 'new-chair-studio',
|
|
'domain' => 'new-chair.test',
|
|
'email' => 'hello@new-chair.test',
|
|
'timezone' => 'Europe/London',
|
|
'currency' => 'GBP',
|
|
'ownerName' => 'Owner Person',
|
|
'ownerEmail' => 'owner@new-chair.test',
|
|
]);
|
|
|
|
$business = Business::where('slug', 'new-chair-studio')->firstOrFail();
|
|
$response->assertRedirect(route('manager.businesses.show', $business));
|
|
$this->assertDatabaseHas('BusinessSettings', ['businessId' => $business->id]);
|
|
$this->assertDatabaseHas('BookingRule', ['businessId' => $business->id]);
|
|
$this->assertSame(7, $business->hours()->count());
|
|
$this->assertDatabaseHas('Role', ['businessId' => $business->id, 'name' => 'Owner']);
|
|
$this->assertDatabaseHas('StaffInvitation', ['businessId' => $business->id, 'email' => 'owner@new-chair.test']);
|
|
$this->assertDatabaseMissing('User', ['email' => 'owner@new-chair.test', 'isSuperAdmin' => 1]);
|
|
}
|
|
|
|
public function test_owner_invitation_is_one_time_and_redirects_to_the_business_domain(): void
|
|
{
|
|
$result = $this->app->make(BusinessProvisioningService::class)->provision([
|
|
'name' => 'Invite Shop', 'slug' => 'invite-shop', 'domain' => 'invite.test',
|
|
], ['name' => 'Invited Owner', 'email' => 'invited-owner@example.test']);
|
|
|
|
$this->get('http://invite.test/invite/'.$result->ownerInvitation->token)
|
|
->assertOk()
|
|
->assertSee('Finish your owner setup');
|
|
|
|
$this->post('http://invite.test/invite/'.$result->ownerInvitation->token, [
|
|
'password' => 'password123',
|
|
'password_confirmation' => 'password123',
|
|
])->assertRedirect('http://invite.test/owner');
|
|
|
|
$this->assertNotNull($result->ownerInvitation->fresh()->acceptedAt);
|
|
$this->assertAuthenticatedAs(User::where('email', 'invited-owner@example.test')->firstOrFail());
|
|
$this->get('http://invite.test/invite/'.$result->ownerInvitation->token)->assertStatus(410);
|
|
}
|
|
|
|
public function test_the_host_selects_only_its_business(): void
|
|
{
|
|
$provisioner = $this->app->make(BusinessProvisioningService::class);
|
|
$first = $provisioner->provision([
|
|
'name' => 'First Barbershop', 'slug' => 'first-barbershop', 'domain' => 'first.test',
|
|
], ['name' => 'First Owner', 'email' => 'first-owner@example.test']);
|
|
$second = $provisioner->provision([
|
|
'name' => 'Second Barbershop', 'slug' => 'second-barbershop', 'domain' => 'second.test',
|
|
], ['name' => 'Second Owner', 'email' => 'second-owner@example.test']);
|
|
|
|
$this->get('http://first.test/')->assertOk()->assertSee('First Barbershop')->assertDontSee('Second Barbershop');
|
|
$this->get('http://second.test/')->assertOk()->assertSee('Second Barbershop')->assertDontSee('First Barbershop');
|
|
$this->assertNotSame($first->business->id, $second->business->id);
|
|
}
|
|
|
|
public function test_registration_creates_a_customer_profile_in_the_current_tenant(): void
|
|
{
|
|
$business = $this->app->make(BusinessProvisioningService::class)->provision([
|
|
'name' => 'Customer Shop', 'slug' => 'customer-shop', 'domain' => 'customer.test',
|
|
], ['name' => 'Shop Owner', 'email' => 'shop-owner@example.test'])->business;
|
|
|
|
$response = $this->post('http://customer.test/register', [
|
|
'firstName' => 'Taylor',
|
|
'lastName' => 'Member',
|
|
'email' => 'taylor@example.test',
|
|
'phone' => '020 7000 0000',
|
|
'password' => 'password123',
|
|
'password_confirmation' => 'password123',
|
|
]);
|
|
|
|
$response->assertRedirect(route('customer.dashboard'));
|
|
$this->assertAuthenticated();
|
|
$this->assertDatabaseHas('CustomerProfile', ['email' => 'taylor@example.test', 'isGuest' => 0, 'businessId' => $business->id]);
|
|
$this->get('http://customer.test/account')->assertOk()->assertSee('Good to see you, Taylor');
|
|
$this->get('http://customer.test/owner')->assertForbidden();
|
|
$this->assertSame(1, CustomerProfile::where('email', 'taylor@example.test')->count());
|
|
}
|
|
}
|