Files
shopit-back/tests/Feature/Catalog/OnTicketFeaturedGroupControllerTest.php

263 lines
9.5 KiB
PHP

<?php
namespace Tests\Feature\Catalog;
use App\Domains\Auth\Models\User;
use App\Domains\Authorization\Enums\RoleCode;
use App\Domains\Catalog\Enums\FeaturedGroupSource;
use App\Domains\Catalog\Enums\GroupLayout;
use App\Domains\Catalog\Enums\ProductLayout;
use App\Domains\Catalog\Models\Category;
use App\Domains\Catalog\Models\FeaturedGroup;
use App\Domains\Tenant\Models\Tenant;
use App\Domains\Tenant\Models\WebsiteType;
use Database\Seeders\AuthorizationSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class OnTicketFeaturedGroupControllerTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->seed(AuthorizationSeeder::class);
WebsiteType::query()->create([
'codigo' => 'onticket',
'nombre' => 'OnTicket',
]);
WebsiteType::query()->create([
'codigo' => 'shopit',
'nombre' => 'Shopit',
]);
}
public function test_authentication_is_required(): void
{
$this->getJson('/api/v1/adminapp/tenant/featured-groups')->assertUnauthorized();
$this->postJson('/api/v1/adminapp/tenant/featured-groups', $this->payload())
->assertUnauthorized();
$this->putJson('/api/v1/adminapp/tenant/featured-groups/1', $this->payload())
->assertUnauthorized();
}
public function test_index_returns_only_category_groups_for_the_onticket_tenant(): void
{
$tenant = $this->createTenant('acme');
$otherTenant = $this->createTenant('other');
$first = $this->createCategoryGroup($tenant, 'Food', order: 2);
$second = $this->createCategoryGroup($tenant, 'Tickets', order: 1);
$this->createCategoryGroup($otherTenant, 'Other tenant');
FeaturedGroup::query()->create([
'tenant_code' => $tenant->codigo,
'source_type' => FeaturedGroupSource::All,
'product_layout' => ProductLayout::Row,
'group_layout' => GroupLayout::Paginated,
'group_name' => 'All products',
'group_order' => 0,
]);
Sanctum::actingAs($this->createAdminAppUser($tenant));
$this->getJson('/api/v1/adminapp/tenant/featured-groups')
->assertOk()
->assertJsonCount(2, 'data')
->assertJsonPath('data.0.id', $second->id)
->assertJsonPath('data.0.category_name', 'Tickets')
->assertJsonPath('data.1.id', $first->id)
->assertJsonMissing(['category_name' => 'Other tenant'])
->assertJsonMissing(['group_name' => 'All products']);
}
public function test_store_creates_a_category_and_a_featured_horizontal_group(): void
{
$tenant = $this->createTenant('acme');
Sanctum::actingAs($this->createAdminAppUser($tenant));
$response = $this->postJson('/api/v1/adminapp/tenant/featured-groups', [
'category_name' => 'Food',
'is_featured' => true,
])
->assertCreated()
->assertJsonPath('data.category_name', 'Food')
->assertJsonPath('data.group_name', 'Food')
->assertJsonPath('data.is_featured', true)
->assertJsonPath('data.type', 'category')
->assertJsonPath('data.product_layout', 'row')
->assertJsonPath('data.group_layout', 'paginated');
$categoryId = $response->json('data.category_id');
$this->assertDatabaseHas('categorias', [
'id' => $categoryId,
'tenant_code' => $tenant->codigo,
'nombre' => 'Food',
]);
$this->assertDatabaseHas('featured_groups', [
'tenant_code' => $tenant->codigo,
'source_type' => 'category',
'category_id' => $categoryId,
'product_layout' => 'row',
'group_layout' => 'paginated',
'group_name' => 'Food',
]);
}
public function test_store_uses_column_with_cart_when_the_category_is_not_featured(): void
{
$tenant = $this->createTenant('acme');
Sanctum::actingAs($this->createAdminAppUser($tenant));
$this->postJson('/api/v1/adminapp/tenant/featured-groups', [
'category_name' => 'Parking',
'is_featured' => false,
])
->assertCreated()
->assertJsonPath('data.is_featured', false)
->assertJsonPath('data.product_layout', 'column_with_cart')
->assertJsonPath('data.group_layout', 'paginated');
}
public function test_update_changes_the_category_and_group_together(): void
{
$tenant = $this->createTenant('acme');
$group = $this->createCategoryGroup($tenant, 'Old name', ProductLayout::ColumnWithCart);
Sanctum::actingAs($this->createAdminAppUser($tenant));
$this->putJson("/api/v1/adminapp/tenant/featured-groups/{$group->id}", [
'category_name' => 'New name',
'is_featured' => true,
])
->assertOk()
->assertJsonPath('data.category_name', 'New name')
->assertJsonPath('data.group_name', 'New name')
->assertJsonPath('data.is_featured', true)
->assertJsonPath('data.product_layout', 'row')
->assertJsonPath('data.group_layout', 'paginated');
$this->assertDatabaseHas('categorias', [
'id' => $group->category_id,
'nombre' => 'New name',
]);
$this->assertDatabaseHas('featured_groups', [
'id' => $group->id,
'group_name' => 'New name',
'product_layout' => 'row',
'group_layout' => 'paginated',
]);
}
public function test_update_rejects_groups_from_another_tenant_or_source(): void
{
$tenant = $this->createTenant('acme');
$otherTenant = $this->createTenant('other');
$otherGroup = $this->createCategoryGroup($otherTenant, 'Other');
$allGroup = FeaturedGroup::query()->create([
'tenant_code' => $tenant->codigo,
'source_type' => FeaturedGroupSource::All,
'product_layout' => ProductLayout::Row,
'group_layout' => GroupLayout::Paginated,
'group_name' => 'All products',
'group_order' => 0,
]);
Sanctum::actingAs($this->createAdminAppUser($tenant));
$this->putJson(
"/api/v1/adminapp/tenant/featured-groups/{$otherGroup->id}",
$this->payload(),
)->assertNotFound();
$this->putJson(
"/api/v1/adminapp/tenant/featured-groups/{$allGroup->id}",
$this->payload(),
)->assertNotFound();
}
public function test_name_and_featured_flag_are_required(): void
{
$tenant = $this->createTenant('acme');
Sanctum::actingAs($this->createAdminAppUser($tenant));
$this->postJson('/api/v1/adminapp/tenant/featured-groups', [
'category_name' => '',
'is_featured' => 'yes',
])
->assertUnprocessable()
->assertJsonValidationErrors(['category_name', 'is_featured']);
$this->assertDatabaseCount('categorias', 0);
$this->assertDatabaseCount('featured_groups', 0);
}
public function test_the_controller_is_not_available_for_non_onticket_tenants(): void
{
$tenant = $this->createTenant('store', 'shopit');
Sanctum::actingAs($this->createAdminAppUser($tenant));
$this->getJson('/api/v1/adminapp/tenant/featured-groups')->assertNotFound();
$this->postJson('/api/v1/adminapp/tenant/featured-groups', $this->payload())
->assertNotFound();
}
public function test_a_customer_cannot_manage_onticket_featured_groups(): void
{
Sanctum::actingAs(User::factory()->create([
'rol_codigo' => RoleCode::User->value,
'tenant_codigo' => null,
]));
$this->getJson('/api/v1/adminapp/tenant/featured-groups')->assertForbidden();
$this->postJson('/api/v1/adminapp/tenant/featured-groups', $this->payload())
->assertForbidden();
}
/** @return array{category_name: string, is_featured: bool} */
private function payload(): array
{
return [
'category_name' => 'Food',
'is_featured' => true,
];
}
private function createTenant(string $code, string $websiteType = 'onticket'): Tenant
{
return Tenant::query()->create([
'codigo' => $code,
'nombre' => ucfirst($code),
'dominio' => "{$code}.test",
'website_type_code' => $websiteType,
]);
}
private function createAdminAppUser(Tenant $tenant): User
{
return User::factory()->create([
'rol_codigo' => RoleCode::AdminApp->value,
'tenant_codigo' => $tenant->codigo,
]);
}
private function createCategoryGroup(
Tenant $tenant,
string $name,
ProductLayout $productLayout = ProductLayout::Row,
int $order = 0,
): FeaturedGroup {
$category = Category::query()->create([
'tenant_code' => $tenant->codigo,
'nombre' => $name,
]);
return FeaturedGroup::query()->create([
'tenant_code' => $tenant->codigo,
'source_type' => FeaturedGroupSource::Category,
'category_id' => $category->id,
'product_layout' => $productLayout,
'group_layout' => GroupLayout::Paginated,
'group_name' => $name,
'group_order' => $order,
]);
}
}