|
@@ -4,12 +4,16 @@ namespace Tests\Feature;
|
|
|
|
|
|
|
|
use App\Jobs\ExportMafJob;
|
|
use App\Jobs\ExportMafJob;
|
|
|
use App\Models\Order;
|
|
use App\Models\Order;
|
|
|
|
|
+use App\Models\Permission;
|
|
|
use App\Models\Product;
|
|
use App\Models\Product;
|
|
|
use App\Models\ProductSKU;
|
|
use App\Models\ProductSKU;
|
|
|
use App\Models\Role;
|
|
use App\Models\Role;
|
|
|
use App\Models\User;
|
|
use App\Models\User;
|
|
|
|
|
+use Database\Seeders\RbacSeeder;
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
|
+use Illuminate\Http\UploadedFile;
|
|
|
use Illuminate\Support\Facades\Bus;
|
|
use Illuminate\Support\Facades\Bus;
|
|
|
|
|
+use Illuminate\Support\Facades\Storage;
|
|
|
use Tests\TestCase;
|
|
use Tests\TestCase;
|
|
|
|
|
|
|
|
class ProductSKUControllerTest extends TestCase
|
|
class ProductSKUControllerTest extends TestCase
|
|
@@ -21,14 +25,26 @@ class ProductSKUControllerTest extends TestCase
|
|
|
private User $adminUser;
|
|
private User $adminUser;
|
|
|
private User $managerUser;
|
|
private User $managerUser;
|
|
|
private User $brigadierUser;
|
|
private User $brigadierUser;
|
|
|
|
|
+ private User $assistantHeadUser;
|
|
|
|
|
|
|
|
protected function setUp(): void
|
|
protected function setUp(): void
|
|
|
{
|
|
{
|
|
|
parent::setUp();
|
|
parent::setUp();
|
|
|
|
|
|
|
|
- $this->adminUser = User::factory()->create(['role' => Role::ADMIN]);
|
|
|
|
|
- $this->managerUser = User::factory()->create(['role' => Role::MANAGER]);
|
|
|
|
|
- $this->brigadierUser = User::factory()->create(['role' => Role::BRIGADIER]);
|
|
|
|
|
|
|
+ $this->seed(RbacSeeder::class);
|
|
|
|
|
+
|
|
|
|
|
+ $this->adminUser = $this->createUserWithRole(Role::ADMIN);
|
|
|
|
|
+ $this->managerUser = $this->createUserWithRole(Role::MANAGER);
|
|
|
|
|
+ $this->brigadierUser = $this->createUserWithRole(Role::BRIGADIER);
|
|
|
|
|
+ $this->assistantHeadUser = $this->createUserWithRole(Role::ASSISTANT_HEAD);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function createUserWithRole(string $roleSlug): User
|
|
|
|
|
+ {
|
|
|
|
|
+ return User::factory()->create([
|
|
|
|
|
+ 'role' => $roleSlug,
|
|
|
|
|
+ 'role_id' => Role::query()->where('slug', $roleSlug)->value('id'),
|
|
|
|
|
+ ]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ==================== Guest redirects ====================
|
|
// ==================== Guest redirects ====================
|
|
@@ -328,6 +344,169 @@ class ProductSKUControllerTest extends TestCase
|
|
|
]));
|
|
]));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public function test_admin_can_inline_update_product_sku_field(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $sku = ProductSKU::factory()->create(['rfid' => 'OLD-RFID']);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($this->adminUser)
|
|
|
|
|
+ ->postJson(route('product_sku.inline-update', $sku), [
|
|
|
|
|
+ 'field' => 'rfid',
|
|
|
|
|
+ 'value' => 'NEW-RFID',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertOk()
|
|
|
|
|
+ ->assertJson([
|
|
|
|
|
+ 'field' => 'rfid',
|
|
|
|
|
+ 'value' => 'NEW-RFID',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertDatabaseHas('products_sku', [
|
|
|
|
|
+ 'id' => $sku->id,
|
|
|
|
|
+ 'rfid' => 'NEW-RFID',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_assistant_head_can_inline_update_product_sku_date_field(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $sku = ProductSKU::factory()->create(['manufacture_date' => null]);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($this->assistantHeadUser)
|
|
|
|
|
+ ->postJson(route('product_sku.inline-update', $sku), [
|
|
|
|
|
+ 'field' => 'manufacture_date',
|
|
|
|
|
+ 'value' => '2026-05-19',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertOk()
|
|
|
|
|
+ ->assertJson([
|
|
|
|
|
+ 'field' => 'manufacture_date',
|
|
|
|
|
+ 'value' => '2026-05-19',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertDatabaseHas('products_sku', [
|
|
|
|
|
+ 'id' => $sku->id,
|
|
|
|
|
+ 'manufacture_date' => '2026-05-19',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_user_with_maf_field_update_permission_can_inline_update_product_sku_field(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $role = Role::query()->create([
|
|
|
|
|
+ 'slug' => 'maf_inline_editor',
|
|
|
|
|
+ 'name' => 'Редактор МАФ в таблице',
|
|
|
|
|
+ 'is_system' => false,
|
|
|
|
|
+ 'is_active' => true,
|
|
|
|
|
+ 'sort' => 100,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $permission = Permission::query()->where('slug', 'maf.fields.statement_number.update')->firstOrFail();
|
|
|
|
|
+ $role->permissions()->sync([
|
|
|
|
|
+ $permission->id => ['effect' => 'allow'],
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $user = User::factory()->create([
|
|
|
|
|
+ 'role' => $role->slug,
|
|
|
|
|
+ 'role_id' => $role->id,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $sku = ProductSKU::factory()->create(['statement_number' => 'OLD-STAT']);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($user)
|
|
|
|
|
+ ->postJson(route('product_sku.inline-update', $sku), [
|
|
|
|
|
+ 'field' => 'statement_number',
|
|
|
|
|
+ 'value' => 'NEW-STAT',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertOk()
|
|
|
|
|
+ ->assertJson([
|
|
|
|
|
+ 'field' => 'statement_number',
|
|
|
|
|
+ 'value' => 'NEW-STAT',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertDatabaseHas('products_sku', [
|
|
|
|
|
+ 'id' => $sku->id,
|
|
|
|
|
+ 'statement_number' => 'NEW-STAT',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_manager_cannot_inline_update_product_sku_field(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $sku = ProductSKU::factory()->create(['upd_number' => 'UPD-OLD']);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($this->managerUser)
|
|
|
|
|
+ ->postJson(route('product_sku.inline-update', $sku), [
|
|
|
|
|
+ 'field' => 'upd_number',
|
|
|
|
|
+ 'value' => 'UPD-NEW',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertForbidden();
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertDatabaseHas('products_sku', [
|
|
|
|
|
+ 'id' => $sku->id,
|
|
|
|
|
+ 'upd_number' => 'UPD-OLD',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_inline_update_rejects_unapproved_product_sku_field(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $sku = ProductSKU::factory()->create(['comment' => 'Old comment']);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($this->adminUser)
|
|
|
|
|
+ ->postJson(route('product_sku.inline-update', $sku), [
|
|
|
|
|
+ 'field' => 'comment',
|
|
|
|
|
+ 'value' => 'New comment',
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertUnprocessable();
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertDatabaseHas('products_sku', [
|
|
|
|
|
+ 'id' => $sku->id,
|
|
|
|
|
+ 'comment' => 'Old comment',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_user_with_passport_upload_permission_can_upload_product_sku_passport(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ Storage::fake('public');
|
|
|
|
|
+
|
|
|
|
|
+ $role = Role::query()->create([
|
|
|
|
|
+ 'slug' => 'maf_passport_loader',
|
|
|
|
|
+ 'name' => 'Загрузка паспортов МАФ',
|
|
|
|
|
+ 'is_system' => false,
|
|
|
|
|
+ 'is_active' => true,
|
|
|
|
|
+ 'sort' => 100,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $permission = Permission::query()->where('slug', 'maf.passports.upload')->firstOrFail();
|
|
|
|
|
+ $role->permissions()->sync([
|
|
|
|
|
+ $permission->id => ['effect' => 'allow'],
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $user = User::factory()->create([
|
|
|
|
|
+ 'role' => $role->slug,
|
|
|
|
|
+ 'role_id' => $role->id,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $sku = ProductSKU::factory()->create(['passport_id' => null]);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($user)
|
|
|
|
|
+ ->from(route('order.show', $sku->order))
|
|
|
|
|
+ ->post(route('product-sku.upload-passport', $sku), [
|
|
|
|
|
+ 'passport' => UploadedFile::fake()->create('passport.pdf', 10, 'application/pdf'),
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertRedirect(route('order.show', $sku->order));
|
|
|
|
|
+ $this->assertNotNull($sku->fresh()->passport_id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function test_user_without_passport_upload_permission_cannot_upload_product_sku_passport(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ Storage::fake('public');
|
|
|
|
|
+
|
|
|
|
|
+ $sku = ProductSKU::factory()->create(['passport_id' => null]);
|
|
|
|
|
+
|
|
|
|
|
+ $response = $this->actingAs($this->brigadierUser)
|
|
|
|
|
+ ->post(route('product-sku.upload-passport', $sku), [
|
|
|
|
|
+ 'passport' => UploadedFile::fake()->create('passport.pdf', 10, 'application/pdf'),
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $response->assertForbidden();
|
|
|
|
|
+ $this->assertNull($sku->fresh()->passport_id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// ==================== Export ====================
|
|
// ==================== Export ====================
|
|
|
|
|
|
|
|
public function test_admin_can_export_mafs(): void
|
|
public function test_admin_can_export_mafs(): void
|