You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

465 lines
14 KiB

11 months ago
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Visit;
use App\Models\Upload;
use App\Models\VisitLog;
use App\Models\GateLog;
use App\Models\Admin;
use App\Models\Department;
use App\Models\VisitArea;
use App\Models\VisitTime;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
class GateControllerTest extends TestCase
{
use RefreshDatabase, WithFaker;
protected $admin;
protected $department;
protected $visitArea;
protected $visitTime;
protected function setUp(): void
{
parent::setUp();
// 创建测试数据
$this->department = Department::factory()->create();
$this->admin = Admin::factory()->create(['department_id' => $this->department->id]);
$this->visitArea = VisitArea::factory()->create();
$this->visitTime = VisitTime::factory()->create();
}
/** @test */
public function it_can_get_visit_list()
{
// 创建测试拜访记录
$visit = Visit::factory()->create([
'date' => now()->format('Y-m-d'),
'audit_status' => Visit::AUDIT_STATUS_APPROVED,
'type' => Visit::TYPE_VISITOR,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->getJson('/api/gate/visits');
$response->assertStatus(200)
->assertJsonStructure([
'code',
'message',
'data' => [
'current_page',
'data' => [
'*' => [
'id',
'name',
'mobile',
'type',
'audit_status',
'date',
'visit_area',
'visit_time',
'accept_department',
'accept_admin',
]
],
'total'
]
]);
}
/** @test */
public function it_can_get_visit_list_with_filters()
{
// 创建测试拜访记录
$visit = Visit::factory()->create([
'date' => now()->format('Y-m-d'),
'audit_status' => Visit::AUDIT_STATUS_APPROVED,
'type' => Visit::TYPE_VISITOR,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->getJson('/api/gate/visits?' . http_build_query([
'date' => now()->format('Y-m-d'),
'status' => Visit::AUDIT_STATUS_APPROVED,
'type' => Visit::TYPE_VISITOR,
'keyword' => $visit->name,
'page' => 1,
'page_size' => 20
]));
$response->assertStatus(200);
}
/** @test */
public function it_can_get_visit_detail()
{
// 创建测试拜访记录
$visit = Visit::factory()->create([
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->getJson("/api/gate/visits/{$visit->id}");
$response->assertStatus(200)
->assertJsonStructure([
'code',
'message',
'data' => [
'id',
'name',
'mobile',
'type',
'audit_status',
'date',
'visit_area',
'visit_time',
'accept_department',
'accept_admin',
'accept_admin_sign',
'logs',
]
]);
}
/** @test */
public function it_returns_404_for_nonexistent_visit()
{
$response = $this->getJson('/api/gate/visits/999999');
$response->assertStatus(200)
->assertJson([
'code' => 404,
'message' => '拜访记录不存在'
]);
}
/** @test */
public function it_can_bind_id_card()
{
// 创建测试拜访记录
$visit = Visit::factory()->create([
'audit_status' => Visit::AUDIT_STATUS_APPROVED,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'bind_card',
'person_no' => 'P001',
'car_no' => 'C001',
]);
$response->assertStatus(200)
->assertJson([
'code' => 200,
'message' => 'success'
]);
// 验证数据已更新
$visit->refresh();
$this->assertEquals('P001', $visit->person_no);
$this->assertEquals('C001', $visit->car_no);
// 验证日志已创建
$this->assertDatabaseHas('visit_logs', [
'visit_id' => $visit->id,
'type' => VisitLog::TYPE_ENTER,
]);
}
/** @test */
public function it_can_enter_factory()
{
// 创建测试拜访记录
$visit = Visit::factory()->create([
'audit_status' => Visit::AUDIT_STATUS_APPROVED,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'enter',
'remark' => '进厂测试',
]);
$response->assertStatus(200)
->assertJson([
'code' => 200,
'message' => 'success'
]);
// 验证状态已更新
$visit->refresh();
$this->assertEquals(Visit::AUDIT_STATUS_ENTERED, $visit->audit_status);
// 验证日志已创建
$this->assertDatabaseHas('visit_logs', [
'visit_id' => $visit->id,
'type' => VisitLog::TYPE_ENTER,
]);
$this->assertDatabaseHas('gate_logs', [
'visit_id' => $visit->id,
'action' => 'enter',
]);
}
/** @test */
public function it_can_leave_factory()
{
// 创建测试拜访记录
$visit = Visit::factory()->create([
'audit_status' => Visit::AUDIT_STATUS_ENTERED,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'leave',
'remark' => '离厂测试',
]);
$response->assertStatus(200)
->assertJson([
'code' => 200,
'message' => 'success'
]);
// 验证状态已更新
$visit->refresh();
$this->assertEquals(Visit::AUDIT_STATUS_LEFT, $visit->audit_status);
// 验证日志已创建
$this->assertDatabaseHas('visit_logs', [
'visit_id' => $visit->id,
'type' => VisitLog::TYPE_LEAVE,
]);
$this->assertDatabaseHas('gate_logs', [
'visit_id' => $visit->id,
'action' => 'leave',
]);
}
/** @test */
public function it_can_upload_vehicle_images()
{
// 创建测试上传文件
$upload1 = Upload::factory()->create();
$upload2 = Upload::factory()->create();
// 创建物流车辆拜访记录
$visit = Visit::factory()->create([
'type' => Visit::TYPE_LOGISTICS_CAR,
'audit_status' => Visit::AUDIT_STATUS_APPROVED,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'upload_vehicle',
'vehicle_images' => [$upload1->id, $upload2->id],
]);
$response->assertStatus(200)
->assertJson([
'code' => 200,
'message' => 'success'
]);
// 验证数据已更新
$visit->refresh();
$this->assertEquals([$upload1->id, $upload2->id], $visit->vehicle_images);
// 验证日志已创建
$this->assertDatabaseHas('visit_logs', [
'visit_id' => $visit->id,
'type' => VisitLog::TYPE_ENTER,
]);
}
/** @test */
public function it_rejects_vehicle_upload_for_non_logistics_car()
{
// 创建非物流车辆拜访记录
$visit = Visit::factory()->create([
'type' => Visit::TYPE_VISITOR,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'upload_vehicle',
'vehicle_images' => [1, 2],
]);
$response->assertStatus(200)
->assertJson([
'code' => 400,
'message' => '只有物流车辆才能上传货车图片'
]);
}
/** @test */
public function it_rejects_enter_for_non_approved_visit()
{
// 创建未审核通过的拜访记录
$visit = Visit::factory()->create([
'audit_status' => Visit::AUDIT_STATUS_PENDING,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'enter',
]);
$response->assertStatus(200)
->assertJson([
'code' => 400,
'message' => '只有已审核通过的拜访才能进厂'
]);
}
/** @test */
public function it_rejects_leave_for_non_entered_visit()
{
// 创建未进厂的拜访记录
$visit = Visit::factory()->create([
'audit_status' => Visit::AUDIT_STATUS_APPROVED,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'leave',
]);
$response->assertStatus(200)
->assertJson([
'code' => 400,
'message' => '只有已进厂的访客才能离厂'
]);
}
/** @test */
public function it_rejects_invalid_vehicle_images()
{
// 创建物流车辆拜访记录
$visit = Visit::factory()->create([
'type' => Visit::TYPE_LOGISTICS_CAR,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'upload_vehicle',
'vehicle_images' => [999999, 888888], // 不存在的ID
]);
$response->assertStatus(200)
->assertJson([
'code' => 400,
'message' => '货车图片ID无效'
]);
}
/** @test */
public function it_rejects_empty_vehicle_images()
{
// 创建物流车辆拜访记录
$visit = Visit::factory()->create([
'type' => Visit::TYPE_LOGISTICS_CAR,
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'upload_vehicle',
'vehicle_images' => [],
]);
$response->assertStatus(200)
->assertJson([
'code' => 400,
'message' => '货车图片不能为空'
]);
}
/** @test */
public function it_rejects_invalid_action_type()
{
$visit = Visit::factory()->create([
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
$response = $this->postJson("/api/gate/visits/{$visit->id}/update", [
'action' => 'invalid_action',
]);
$response->assertStatus(200)
->assertJson([
'code' => 400,
'message' => '无效的操作类型'
]);
}
/** @test */
public function it_supports_multilingual_responses()
{
$visit = Visit::factory()->create([
'accept_department_id' => $this->department->id,
'accept_admin_id' => $this->admin->id,
'visit_area_id' => $this->visitArea->id,
'visit_time_id' => $this->visitTime->id,
]);
// 测试中文响应
$response = $this->withHeaders(['Accept-Language' => 'zh-CN'])
->getJson("/api/gate/visits/{$visit->id}");
$response->assertStatus(200);
// 测试英文响应
$response = $this->withHeaders(['Accept-Language' => 'en'])
->getJson("/api/gate/visits/{$visit->id}");
$response->assertStatus(200);
}
}