shouldReceive('available')->andReturnTrue(); $repository->shouldReceive('state')->once()->andReturn([ 'status' => 'succeeded', 'last_attempted_at' => '2026-11-05 12:45:00', 'last_succeeded_at' => '2026-11-05 12:45:00', 'mirror_row_count' => 83, 'last_error_code' => null, ]); $repository->shouldReceive('dailySummary')->once()->andReturn([[ 'statistics_date' => '2026-11-04', 'submission_count' => 9, 'submitter_count' => 9, 'first_submitted_at' => '2026-11-04 20:16:55', 'last_submitted_at' => '2026-11-05 11:32:59', ]]); $repository->shouldNotReceive('submissionsForDate'); $penalty = Mockery::mock(DingWorklogPenaltyCalculator::class); $penalty->shouldReceive('summary')->once()->andReturn([ 'start_date' => '2026-11-04', 'end_date' => '2026-11-04', 'total_points' => '40', 'total_points_formatted' => '40', 'members' => [], ]); $data = (new DingWorklogStatisticsPageData($repository, $penalty))->page( Request::create('/?from=2026-10-22&to=2026-11-04') ); $this->assertFalse($data['worklogShowDetails']); $this->assertSame([], $data['worklogSubmissions']); $this->assertSame(9, $data['worklogDaily'][0]['submitter_count']); } finally { Carbon::setTestNow(); } } public function test_schedule_not_ready_is_reported_without_calculating_penalties(): void { Carbon::setTestNow(Carbon::parse('2026-11-10 13:00:00', 'Asia/Shanghai')); try { $repository = Mockery::mock(DingWorklogMirrorRepository::class); $repository->shouldReceive('available')->andReturnTrue(); $repository->shouldReceive('state')->once()->andReturn([ 'status' => 'succeeded', 'last_attempted_at' => '2026-11-10 12:45:00', 'last_succeeded_at' => '2026-11-10 12:45:00', 'mirror_row_count' => 83, 'last_error_code' => null, ]); $repository->shouldReceive('dailySummary')->once()->andReturn([]); $repository->shouldNotReceive('submissionsForDate'); $penalty = Mockery::mock(DingWorklogPenaltyCalculator::class); $penalty->shouldReceive('summary')->once()->andThrow( new \RuntimeException('dingtalk_attendance_schedule_not_ready') ); $data = (new DingWorklogStatisticsPageData($repository, $penalty))->page( Request::create('/?from=2026-11-04&to=2026-11-08') ); $this->assertSame( '钉钉排班镜像尚未完成首次同步,无法判断公司工作日,扣分暂不计算。', $data['worklogPenaltyError'], ); $this->assertSame([], $data['worklogPenalty']['members']); } finally { Carbon::setTestNow(); } } }