From 484fa204b393e201cc430109b069f99e7c7b4282 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Fri, 31 Jul 2026 10:36:46 -0300 Subject: [PATCH] feat(tenant): add BootstrapTenantController and corresponding tests for tenant bootstrapping functionality --- .../AdminApp/BootstrapTenantController.php | 34 +++++++ app/Domains/Tenant/routes/adminapp.php | 2 + .../AdminAppBootstrapTenantControllerTest.php | 93 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 app/Domains/Tenant/Controllers/AdminApp/BootstrapTenantController.php create mode 100644 tests/Feature/Tenant/AdminAppBootstrapTenantControllerTest.php diff --git a/app/Domains/Tenant/Controllers/AdminApp/BootstrapTenantController.php b/app/Domains/Tenant/Controllers/AdminApp/BootstrapTenantController.php new file mode 100644 index 0000000..cbaffaf --- /dev/null +++ b/app/Domains/Tenant/Controllers/AdminApp/BootstrapTenantController.php @@ -0,0 +1,34 @@ +user(); + $tenant = $user->tenant()->firstOrFail(); + + return TenantResource::make( + $this->tenantInformationService->load($tenant, [ + 'menues' => fn ($query) => $query + ->where('code', 'like', 'admin.%') + ->whereHas( + 'roles', + fn ($query) => $query->where('codigo', $user->rol_codigo) + ), + ]) + ); + } +} diff --git a/app/Domains/Tenant/routes/adminapp.php b/app/Domains/Tenant/routes/adminapp.php index 0dcc615..f5ef025 100644 --- a/app/Domains/Tenant/routes/adminapp.php +++ b/app/Domains/Tenant/routes/adminapp.php @@ -1,11 +1,13 @@ middleware(['auth:sanctum', 'adminapp.tenant']) ->group(function (): void { + Route::get('bootstrap', BootstrapTenantController::class); Route::get('website-extras', [WebsiteExtraController::class, 'show']); Route::get('website-extras/{websiteExtraCode}', [WebsiteExtraController::class, 'showExtra']); Route::put('website-extras/{websiteExtraCode}', [WebsiteExtraController::class, 'update']); diff --git a/tests/Feature/Tenant/AdminAppBootstrapTenantControllerTest.php b/tests/Feature/Tenant/AdminAppBootstrapTenantControllerTest.php new file mode 100644 index 0000000..bd000ef --- /dev/null +++ b/tests/Feature/Tenant/AdminAppBootstrapTenantControllerTest.php @@ -0,0 +1,93 @@ +getJson('/api/v1/adminapp/tenant/bootstrap') + ->assertUnauthorized(); + } + + public function test_a_customer_cannot_bootstrap_adminapp(): void + { + $userRole = $this->createRole(RoleCode::User); + $customer = User::factory()->create([ + 'rol_codigo' => $userRole->codigo, + 'tenant_codigo' => null, + ]); + + Sanctum::actingAs($customer); + + $this->getJson('/api/v1/adminapp/tenant/bootstrap') + ->assertForbidden(); + } + + public function test_it_returns_the_authenticated_users_tenant_and_admin_menus(): void + { + $adminAppRole = $this->createRole(RoleCode::AdminApp); + $tenant = $this->createTenant('acme'); + $otherTenant = $this->createTenant('other'); + + $catalog = $this->createMenu('admin.catalog', 'Catálogo', '/admin/catalog'); + $staff = $this->createMenu('admin.staff', 'Staff', '/admin/staff'); + $storefront = $this->createMenu('index', 'Inicio', '/'); + + $adminAppRole->menus()->sync([$catalog->code, $storefront->code]); + $tenant->menues()->sync([$catalog->code, $staff->code, $storefront->code]); + $otherTenant->menues()->sync([$staff->code]); + + Sanctum::actingAs(User::factory()->create([ + 'rol_codigo' => $adminAppRole->codigo, + 'tenant_codigo' => $tenant->codigo, + ])); + + $this->getJson('/api/v1/adminapp/tenant/bootstrap') + ->assertOk() + ->assertJsonPath('data.codigo', 'acme') + ->assertJsonCount(1, 'data.menues') + ->assertJsonPath('data.menues.0.code', 'admin.catalog') + ->assertJsonPath('data.menues.0.label', 'Catálogo') + ->assertJsonPath('data.menues.0.route', '/admin/catalog') + ->assertJsonMissing(['code' => 'admin.staff']) + ->assertJsonMissing(['code' => 'index']); + } + + private function createRole(RoleCode $role): Role + { + return Role::query()->create([ + 'codigo' => $role->value, + 'nombre' => $role->value, + ]); + } + + private function createTenant(string $code): Tenant + { + return Tenant::query()->create([ + 'codigo' => $code, + 'nombre' => ucfirst($code), + 'dominio' => "{$code}.test", + ]); + } + + private function createMenu(string $code, string $label, string $route): Menu + { + return Menu::query()->create([ + 'code' => $code, + 'label' => $label, + 'route' => $route, + ]); + } +}