62 lines
3.0 KiB
PHP
62 lines
3.0 KiB
PHP
<?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";
|