|
@@ -0,0 +1,156 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+namespace Tests\Feature;
|
|
|
|
|
+
|
|
|
|
|
+use App\Models\Permission;
|
|
|
|
|
+use App\Models\PricingCode;
|
|
|
|
|
+use App\Models\Role;
|
|
|
|
|
+use App\Models\User;
|
|
|
|
|
+use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
|
+use Tests\TestCase;
|
|
|
|
|
+
|
|
|
|
|
+class ManagerMenuTest extends TestCase
|
|
|
|
|
+{
|
|
|
|
|
+ use RefreshDatabase;
|
|
|
|
|
+
|
|
|
|
|
+ protected $seed = true;
|
|
|
|
|
+
|
|
|
|
|
+ public function test_admin_sees_existing_sections_in_new_menu_groups(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $user = $this->createSystemRoleUser(Role::ADMIN);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($user)->get(route('common-catalog.index'));
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertOk()
|
|
|
|
|
+ ->assertSeeText('ДКР')
|
|
|
|
|
+ ->assertSee(route('order.index'), false)
|
|
|
|
|
+ ->assertSee(route('product_sku.index'), false)
|
|
|
|
|
+ ->assertSee(route('catalog.index'), false)
|
|
|
|
|
+ ->assertSee(route('reports.index'), false)
|
|
|
|
|
+ ->assertSee(route('responsible.index'), false)
|
|
|
|
|
+ ->assertSee(route('maf_order.index'), false)
|
|
|
|
|
+ ->assertSeeText('Графики')
|
|
|
|
|
+ ->assertSee(route('schedule.index'), false)
|
|
|
|
|
+ ->assertSeeText('Запчасти')
|
|
|
|
|
+ ->assertSee(route('spare_parts.index'), false)
|
|
|
|
|
+ ->assertSee(route('spare_part_orders.index'), false)
|
|
|
|
|
+ ->assertSee(route('spare_part_inventory.index'), false)
|
|
|
|
|
+ ->assertSee(route('pricing_codes.index'), false)
|
|
|
|
|
+ ->assertSeeText('Администратор')
|
|
|
|
|
+ ->assertSee(route('contractors.index'), false)
|
|
|
|
|
+ ->assertSee(route('contract.index'), false)
|
|
|
|
|
+ ->assertSee(route('user.index'), false)
|
|
|
|
|
+ ->assertSee(route('admin.roles.index'), false)
|
|
|
|
|
+ ->assertSee(route('admin.settings.index'), false)
|
|
|
|
|
+ ->assertSee(route('admin.district.index'), false)
|
|
|
|
|
+ ->assertSee(route('admin.area.index'), false)
|
|
|
|
|
+ ->assertSee(route('admin.notifications.log'), false)
|
|
|
|
|
+ ->assertSee(route('import.index'), false)
|
|
|
|
|
+ ->assertSee(route('year-data.index'), false)
|
|
|
|
|
+ ->assertSee(route('clear-data.index'), false)
|
|
|
|
|
+ ->assertDontSeeText('Администрирование');
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertSame(1, substr_count($response->getContent(), '>Подрядчики</a>'));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_contractor_viewer_sees_contractors_only_inside_admin_group(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $user = $this->createUserWithPermissions('contractor_viewer', ['contractors.view']);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($user)->get(route('common-catalog.index'));
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertOk()
|
|
|
|
|
+ ->assertSeeText('Администратор')
|
|
|
|
|
+ ->assertSee(route('contractors.index'), false);
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertSame(1, substr_count($response->getContent(), '>Подрядчики</a>'));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_spare_parts_viewer_can_read_pricing_codes_without_edit_controls(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $user = $this->createUserWithPermissions('spare_parts_reader', ['spare_parts.view']);
|
|
|
|
|
+ $pricingCode = PricingCode::query()->create([
|
|
|
|
|
+ 'type' => PricingCode::TYPE_PRICING_CODE,
|
|
|
|
|
+ 'code' => 'TEST-01',
|
|
|
|
|
+ 'description' => 'Тестовая расшифровка',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($user)->get(route('pricing_codes.index'));
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertOk()
|
|
|
|
|
+ ->assertSeeText('Справочник расшифровок')
|
|
|
|
|
+ ->assertSeeText('TEST-01')
|
|
|
|
|
+ ->assertSeeText('Тестовая расшифровка')
|
|
|
|
|
+ ->assertSee(route('spare_parts.index'), false)
|
|
|
|
|
+ ->assertSee(route('spare_parts.help'), false)
|
|
|
|
|
+ ->assertDontSee(route('spare_part_orders.index'), false)
|
|
|
|
|
+ ->assertDontSee(route('spare_part_inventory.index'), false)
|
|
|
|
|
+ ->assertDontSee('data-bs-target="#addCodeModal"', false)
|
|
|
|
|
+ ->assertDontSee('action="'.route('pricing_codes.update', $pricingCode).'"', false)
|
|
|
|
|
+ ->assertDontSee('action="'.route('pricing_codes.destroy', $pricingCode).'"', false)
|
|
|
|
|
+ ->assertDontSee('data-confirm-message=', false);
|
|
|
|
|
+
|
|
|
|
|
+ $this->actingAs($user)
|
|
|
|
|
+ ->post(route('pricing_codes.store'), [
|
|
|
|
|
+ 'type' => PricingCode::TYPE_PRICING_CODE,
|
|
|
|
|
+ 'code' => 'TEST-02',
|
|
|
|
|
+ ])
|
|
|
|
|
+ ->assertForbidden();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_spare_parts_subsections_set_their_own_active_menu_item(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $user = $this->createSystemRoleUser(Role::ADMIN);
|
|
|
|
|
+
|
|
|
|
|
+ $this->actingAs($user)
|
|
|
|
|
+ ->get(route('spare_part_orders.index'))
|
|
|
|
|
+ ->assertOk()
|
|
|
|
|
+ ->assertViewHas('active', 'spare_part_orders')
|
|
|
|
|
+ ->assertSeeText('Заказы запчастей');
|
|
|
|
|
+
|
|
|
|
|
+ $this->actingAs($user)
|
|
|
|
|
+ ->get(route('spare_part_inventory.index'))
|
|
|
|
|
+ ->assertOk()
|
|
|
|
|
+ ->assertViewHas('active', 'spare_part_inventory');
|
|
|
|
|
+
|
|
|
|
|
+ $this->actingAs($user)
|
|
|
|
|
+ ->get(route('pricing_codes.index'))
|
|
|
|
|
+ ->assertOk()
|
|
|
|
|
+ ->assertViewHas('active', 'pricing_codes');
|
|
|
|
|
+
|
|
|
|
|
+ $this->actingAs($user)
|
|
|
|
|
+ ->get(route('spare_parts.help'))
|
|
|
|
|
+ ->assertOk()
|
|
|
|
|
+ ->assertViewHas('active', 'spare_parts_help');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function createSystemRoleUser(string $slug): User
|
|
|
|
|
+ {
|
|
|
|
|
+ $role = Role::query()->where('slug', $slug)->firstOrFail();
|
|
|
|
|
+
|
|
|
|
|
+ return User::factory()->create([
|
|
|
|
|
+ 'role' => $role->slug,
|
|
|
|
|
+ 'role_id' => $role->id,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function createUserWithPermissions(string $slug, array $permissionSlugs): User
|
|
|
|
|
+ {
|
|
|
|
|
+ $role = Role::query()->create([
|
|
|
|
|
+ 'slug' => $slug,
|
|
|
|
|
+ 'name' => $slug,
|
|
|
|
|
+ 'is_system' => false,
|
|
|
|
|
+ 'is_active' => true,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $permissions = Permission::query()
|
|
|
|
|
+ ->whereIn('slug', $permissionSlugs)
|
|
|
|
|
+ ->pluck('id')
|
|
|
|
|
+ ->mapWithKeys(fn (int $id): array => [$id => ['effect' => 'allow']]);
|
|
|
|
|
+ $role->permissions()->sync($permissions);
|
|
|
|
|
+
|
|
|
|
|
+ return User::factory()->create([
|
|
|
|
|
+ 'role' => $role->slug,
|
|
|
|
|
+ 'role_id' => $role->id,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|