CaiWuXiTong/tests/Unit/EcommerceFinance/DingWorklogStatisticsPageDataTest.php
renshen d6fe74ad1e fix: 日志统计固定使用中国时区 (#1105)
合并 PR #1105:日志统计统一使用 Asia/Shanghai,修复页面扣分日期滞后。
2026-11-11 18:56:53 +08:00

140 lines
5.6 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Mockery;
use Modules\EcommerceFinance\Repositories\DingWorklogMirrorRepository;
use Modules\EcommerceFinance\Services\DingWorklogPenaltyCalculator;
use Modules\EcommerceFinance\View\DingWorklogStatisticsPageData;
use Tests\TestCase;
class DingWorklogStatisticsPageDataTest extends TestCase
{
public function test_submission_details_are_hidden_until_requested(): void
{
Carbon::setTestNow(Carbon::parse('2026-11-05 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-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_page_uses_worklog_timezone_instead_of_company_timezone(): void
{
config([
'dingtalk.worklog.timezone' => 'Asia/Shanghai',
'app.timezone' => 'Europe/London',
'app.platform_timezone' => 'Asia/Shanghai',
]);
Carbon::setTestNow(Carbon::parse('2026-11-11 18:51: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-11 18:51:03',
'last_succeeded_at' => '2026-11-11 18:51:03',
'mirror_row_count' => 131,
'last_error_code' => null,
]);
$repository->shouldReceive('dailySummary')
->once()
->with('2026-10-28', '2026-11-10')
->andReturn([]);
$penalty = Mockery::mock(DingWorklogPenaltyCalculator::class);
$penalty->shouldReceive('summary')->once()->andReturn([
'start_date' => '2026-11-04',
'end_date' => '2026-11-10',
'total_points' => '20',
'total_points_formatted' => '20',
'members' => [],
]);
$data = (new DingWorklogStatisticsPageData($repository, $penalty))->page(
Request::create('/?from=2026-10-28&to=2026-11-10')
);
$this->assertSame('2026-11-10', $data['worklogCurrent']['statistics_date']);
$this->assertSame('2026-11-11 12:00:00', $data['worklogCutoffAt']);
$this->assertSame('20', $data['worklogPenalty']['total_points']);
} 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();
}
}
}