This commit is contained in:
Your Name
2026-09-09 15:47:48 +08:00
parent bd5d5c5f08
commit cb10e75ead
98 changed files with 7031 additions and 804 deletions
+61
View File
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
// 使用真实命令与定时调度器,内存替代业务逻辑、Console facade、任务模型。
final class ImCommandLogicFixture
{
public static array $result = ['diagnoses' => 1, 'inserted' => 2, 'errors' => []];
public static function syncImChatArchiveBatch($days, $limit, $id): array { return self::$result; }
}
final class ImCommandConsoleFixture
{
public static bool $fail = true;
public static function call($name, $params = []): void
{
if (self::$fail) throw new RuntimeException('云端暂不可用');
}
}
final class ImCommandTaskFixture
{
public static array $writes = [];
public static function where($key, $value): self { return new self(); }
public function update(array $data): void { self::$writes[] = $data; }
}
final class ImCommandLogFixture { public static function error($message): void {} }
class_alias(ImCommandLogicFixture::class, 'app\adminapi\logic\tcm\DiagnosisLogic');
class_alias(ImCommandConsoleFixture::class, 'think\facade\Console');
class_alias(ImCommandTaskFixture::class, 'app\common\model\Crontab');
class_alias(ImCommandLogFixture::class, 'think\facade\Log');
require dirname(__DIR__) . '/vendor/autoload.php';
function imCommandExpect(bool $condition, string $message): void
{
if (!$condition) throw new RuntimeException($message);
}
$task = ['id' => 3, 'params' => '--since-days=0 --limit=200', 'command' => 'sync_im_chat_archive', 'max_time' => 0];
\app\common\command\Crontab::start($task);
imCommandExpect(ImCommandTaskFixture::$writes[0]['error'] === '云端暂不可用', 'sync failure remains visible in scheduler');
imCommandExpect(ImCommandTaskFixture::$writes[0]['status'] === \app\common\enum\CrontabEnum::START, 'IM sync retries next scheduled round');
ImCommandTaskFixture::$writes = [];
\app\common\command\Crontab::start(array_merge($task, ['command' => 'unrelated_command']));
imCommandExpect(ImCommandTaskFixture::$writes[0]['status'] === \app\common\enum\CrontabEnum::ERROR, 'other command failure behavior is unchanged');
ImCommandTaskFixture::$writes = [];
ImCommandConsoleFixture::$fail = false;
\app\common\command\Crontab::start($task);
imCommandExpect(ImCommandTaskFixture::$writes[0]['error'] === '', 'successful round clears previous error');
$command = new \app\common\command\SyncImChatArchive();
$input = new \think\console\Input([]);
$output = new \think\console\Output('buffer');
ImCommandLogicFixture::$result['errors'] = ['doctor fixture unavailable'];
try {
$command->run($input, $output);
throw new RuntimeException('command silently succeeded');
} catch (RuntimeException $e) {
imCommandExpect(str_contains($e->getMessage(), 'IM 聊天归档未完全同步'), 'command propagates failure even though Console::call discards return codes');
}
ImCommandLogicFixture::$result['errors'] = [];
imCommandExpect($command->run(new \think\console\Input([]), new \think\console\Output('buffer')) === 0, 'successful command returns zero');
echo "IM archive command and scheduler propagation: OK (no database/network)\n";