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); } }