states(); $states[NonJingxiRefundMirrorRepository::SUPPLEMENT_DATASET]['status'] = 'failed'; $states[NonJingxiRefundMirrorRepository::SUPPLEMENT_DATASET]['last_error_code'] = 'PDOException'; $status = $this->service($states)->current(Carbon::parse('2026-11-04 08:30:00')); $this->assertSame('failed', $status['state']); $this->assertSame('退款待确认同步异常', $status['title']); $this->assertSame('淘系退款清单', $status['issues'][0]['label']); $this->assertSame('PDOException', $status['issues'][0]['error_code']); } public function test_running_before_deadline_is_informational_not_an_exception(): void { $states = $this->states(); $states[NonJingxiRefundMirrorRepository::ITEM_DATASET]['status'] = 'running'; $status = $this->service($states)->current(Carbon::parse('2026-11-04 09:30:00')); $this->assertSame('syncing', $status['state']); $this->assertSame([], $status['issues']); } public function test_previous_day_success_becomes_a_morning_deadline_warning(): void { $states = $this->states(); foreach ($states as &$state) { $state['last_attempted_at'] = '2026-11-03 06:10:00'; $state['last_succeeded_at'] = '2026-11-03 06:10:00'; } unset($state); $status = $this->service($states)->current(Carbon::parse('2026-11-04 10:05:00')); $this->assertSame('warning', $status['state']); $this->assertSame('退款待确认同步未完成', $status['title']); $this->assertCount(5, $status['issues']); } public function test_success_after_ten_still_reports_a_deadline_warning(): void { $states = $this->states(); foreach ($states as &$state) { $state['last_attempted_at'] = '2026-11-04 10:20:00'; $state['last_succeeded_at'] = '2026-11-04 10:20:00'; } unset($state); $status = $this->service($states)->current(Carbon::parse('2026-11-04 10:30:00')); $this->assertSame('warning', $status['state']); $this->assertCount(5, $status['issues']); } public function test_healthy_message_describes_realtime_status_refresh(): void { $states = $this->states(); foreach ($states as &$state) { $state['last_attempted_at'] = '2026-11-04 10:29:00'; $state['last_succeeded_at'] = '2026-11-04 10:29:00'; } unset($state); $status = $this->service($states)->current(Carbon::parse('2026-11-04 10:30:00')); $this->assertSame('healthy', $status['state']); $this->assertSame('基础退款镜像每日 06:00 同步,当前退款状态每分钟刷新。', $status['message']); } /** @param array> $states */ private function service(array $states): RefundPendingSyncStatus { $repository = Mockery::mock(NonJingxiRefundMirrorRepository::class); $repository->shouldReceive('pendingConfirmationDailySyncStates')->once()->andReturn($states); return new RefundPendingSyncStatus($repository); } /** @return array> */ private function states(): array { $state = [ 'status' => 'succeeded', 'initial_completed_at' => '2026-10-01 02:00:00', 'last_attempted_at' => '2026-11-04 06:10:00', 'last_succeeded_at' => '2026-11-04 06:10:00', 'last_error_code' => null, ]; return [ NonJingxiRefundMirrorRepository::INFO_DATASET => $state, NonJingxiRefundMirrorRepository::ITEM_DATASET => $state, NonJingxiRefundMirrorRepository::SUPPLEMENT_DATASET => $state, NonJingxiRefundMirrorRepository::SUPPLEMENT_ITEM_DATASET => $state, NonJingxiRefundMirrorRepository::STATUS_DATASET => $state, ]; } }