CaiWuXiTong/tests/Feature/Console/ImportDingAttendanceSchedulesTest.php
renshen c47af23709 fix: 日志漏写按公司排班判断工作日 (#1030)
合并 PR #1030:日志漏写扣分改用钉钉公司排班判断工作日。
2026-11-10 10:57:47 +08:00

107 lines
4.4 KiB
PHP

<?php
namespace Tests\Feature\Console;
use App\Services\Auth\FinanceRoster;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Mockery;
use Tests\TestCase;
class ImportDingAttendanceSchedulesTest extends TestCase
{
public function test_command_imports_work_and_rest_schedule_records(): void
{
config([
'database.connections.business_mirror' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
],
'upstream_mirrors.connection' => 'business_mirror',
'app.timezone' => 'Asia/Shanghai',
]);
DB::purge('business_mirror');
Schema::connection('business_mirror')->create('business_mirror_table_states', function (Blueprint $table): void {
$table->string('dataset_key', 191)->primary();
$table->string('source_key', 64);
$table->string('source_object', 191);
$table->string('target_table', 64);
$table->string('status', 24)->default('pending');
$table->string('run_mode', 24)->nullable();
$table->json('cursor')->nullable();
$table->json('high_watermark')->nullable();
$table->dateTime('window_started_at')->nullable();
$table->dateTime('window_ends_at')->nullable();
$table->dateTime('initial_completed_at')->nullable();
$table->dateTime('last_attempted_at')->nullable();
$table->dateTime('last_succeeded_at')->nullable();
$table->unsignedBigInteger('last_upserted_rows')->default(0);
$table->unsignedBigInteger('mirror_row_count')->default(0);
$table->string('last_error_code', 120)->nullable();
$table->timestamps();
});
(require base_path('database/migrations/2026_11_10_120000_create_ding_attendance_schedule_records.php'))->up();
$roster = Mockery::mock(FinanceRoster::class);
$roster->shouldReceive('cachedFinanceMembers')->once()->andReturn([
['userid' => '1004216768778351', 'name' => '人参'],
]);
$this->app->instance(FinanceRoster::class, $roster);
$path = tempnam(sys_get_temp_dir(), 'ding-schedule-');
file_put_contents($path, json_encode([
'success' => true,
'result' => [
[
'id' => 'schedule-work',
'userId' => '1004216768778351',
'workDate' => 1793980800000,
'groupId' => 967215034,
'classId' => 123,
'isRest' => 'N',
'checkStatus' => 'Init',
'timeChanged' => false,
],
[
'id' => 'schedule-rest',
'userId' => '1004216768778351',
'workDate' => 1794067200000,
'groupId' => 967215034,
'isRest' => 'Y',
'checkStatus' => 'Init',
'timeChanged' => false,
],
],
], JSON_UNESCAPED_UNICODE));
try {
$this->artisan('business-mirror:import-ding-attendance-schedules', [
'--file' => $path,
'--from' => '2026-11-07',
'--to' => '2026-11-08',
])->expectsOutputToContain('1 人、2 天、2 条排班')->assertSuccessful();
$rows = DB::connection('business_mirror')
->table('ding_attendance_schedule_records')
->orderBy('work_date')
->get(['user_id', 'user_name', 'work_date', 'is_rest'])
->map(static fn (object $row): array => (array) $row)
->all();
$this->assertSame([
['user_id' => '1004216768778351', 'user_name' => '人参', 'work_date' => '2026-11-07', 'is_rest' => 'N'],
['user_id' => '1004216768778351', 'user_name' => '人参', 'work_date' => '2026-11-08', 'is_rest' => 'Y'],
], $rows);
$this->assertSame(
'succeeded',
DB::connection('business_mirror')->table('business_mirror_table_states')
->where('dataset_key', 'dingtalk.attendance.finance_schedules')
->value('status'),
);
} finally {
@unlink($path);
}
}
}