trucks (with optional last_known_coordinates POINT 4326), collection_teams, team_members. Admin CRUD for both. TeamConflictDetector flags double-assignment of driver/scanner/truck/helper across active teams; override_conflicts: true bypasses for emergencies. Promotes routes.default_team_id to a real FK now that collection_teams exists. 144 feature tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
115 lines
3.6 KiB
PHP
115 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Api\V1\Team;
|
|
|
|
use App\Models\CollectionTeam;
|
|
use App\Models\Truck;
|
|
use App\Models\User;
|
|
use Database\Seeders\RoleSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Laravel\Sanctum\Sanctum;
|
|
use Tests\TestCase;
|
|
|
|
class TeamCrudTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private User $admin;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->seed(RoleSeeder::class);
|
|
$this->admin = User::factory()->create([
|
|
'role' => User::ROLE_ADMIN,
|
|
'status' => User::STATUS_ACTIVE,
|
|
]);
|
|
}
|
|
|
|
public function test_admin_can_create_truck_and_team(): void
|
|
{
|
|
Sanctum::actingAs($this->admin);
|
|
|
|
$truck = $this->postJson('/api/v1/admin/trucks', [
|
|
'plate_number' => 'NCR-1234',
|
|
'model' => 'Isuzu Forward',
|
|
'capacity_kg' => 5000,
|
|
]);
|
|
$truck->assertCreated();
|
|
$truckId = Truck::first()->id;
|
|
|
|
$driver = User::factory()->create(['role' => User::ROLE_DRIVER, 'status' => User::STATUS_ACTIVE]);
|
|
$scanner = User::factory()->create(['role' => User::ROLE_SCANNER, 'status' => User::STATUS_ACTIVE]);
|
|
|
|
$response = $this->postJson('/api/v1/admin/teams', [
|
|
'name' => 'QC Team A',
|
|
'driver_id' => $driver->id,
|
|
'scanner_id' => $scanner->id,
|
|
'truck_id' => $truckId,
|
|
]);
|
|
|
|
$response->assertCreated()
|
|
->assertJsonPath('data.name', 'QC Team A');
|
|
}
|
|
|
|
public function test_double_assigned_driver_rejected(): void
|
|
{
|
|
Sanctum::actingAs($this->admin);
|
|
$driver = User::factory()->create(['role' => User::ROLE_DRIVER]);
|
|
|
|
$this->postJson('/api/v1/admin/teams', [
|
|
'name' => 'Team 1', 'driver_id' => $driver->id,
|
|
])->assertCreated();
|
|
|
|
$response = $this->postJson('/api/v1/admin/teams', [
|
|
'name' => 'Team 2', 'driver_id' => $driver->id,
|
|
]);
|
|
|
|
$response->assertStatus(422);
|
|
$this->assertNotEmpty($response->json('errors.conflicts'));
|
|
}
|
|
|
|
public function test_override_conflicts_lets_admin_force_assign(): void
|
|
{
|
|
Sanctum::actingAs($this->admin);
|
|
$driver = User::factory()->create(['role' => User::ROLE_DRIVER]);
|
|
|
|
$this->postJson('/api/v1/admin/teams', [
|
|
'name' => 'Team 1', 'driver_id' => $driver->id,
|
|
])->assertCreated();
|
|
|
|
$this->postJson('/api/v1/admin/teams', [
|
|
'name' => 'Team 2', 'driver_id' => $driver->id, 'override_conflicts' => true,
|
|
])->assertCreated();
|
|
}
|
|
|
|
public function test_admin_can_update_team_helpers(): void
|
|
{
|
|
Sanctum::actingAs($this->admin);
|
|
$helper1 = User::factory()->create(['role' => User::ROLE_HELPER]);
|
|
$helper2 = User::factory()->create(['role' => User::ROLE_HELPER]);
|
|
|
|
$created = $this->postJson('/api/v1/admin/teams', [
|
|
'name' => 'Team', 'helper_ids' => [$helper1->id],
|
|
]);
|
|
$uuid = $created->json('data.id');
|
|
|
|
$response = $this->patchJson("/api/v1/admin/teams/{$uuid}", [
|
|
'name' => 'Team',
|
|
'helper_ids' => [$helper1->id, $helper2->id],
|
|
]);
|
|
|
|
$response->assertOk();
|
|
$team = CollectionTeam::where('uuid', $uuid)->first();
|
|
$this->assertSame(2, $team->helpers()->count());
|
|
}
|
|
|
|
public function test_resident_blocked(): void
|
|
{
|
|
$resident = User::factory()->create(['role' => User::ROLE_RESIDENT, 'status' => User::STATUS_ACTIVE]);
|
|
Sanctum::actingAs($resident);
|
|
|
|
$this->getJson('/api/v1/admin/teams')->assertStatus(403);
|
|
}
|
|
}
|