summaryrefslogtreecommitdiffstats
path: root/tests/Stubs/Taskmanager.php
blob: a2f662a3948dd462558ed008ff7e061c985d7d07 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php

class Taskmanager
{
	// Mirror production status codes
	const NO_SUCH_TASK = 'NO_SUCH_TASK';
	const TASK_FINISHED = 'TASK_FINISHED';
	const TASK_ERROR = 'TASK_ERROR';
	const TASK_WAITING = 'TASK_WAITING';
	const NO_SUCH_INSTANCE = 'NO_SUCH_INSTANCE';
	const TASK_PROCESSING = 'TASK_PROCESSING';

	public static array $submissions = []; // list of ['id'=>, 'task'=>, 'data'=>]
	public static array $statusById = []; // id => ['id'=>, 'statusCode'=>..., 'data'=>[]]
	private static int $nextId = 1;

	public static function reset(): void
	{
		self::$submissions = [];
		self::$statusById = [];
		self::$nextId = 1;
	}

	/**
	 * Stubbed submit compatible with production signature.
	 * @return array{id: string, statusCode: string, data: array}|bool
	 */
	public static function submit(string $task, ?array $data = null, ?bool $async = false)
	{
		$id = (string)self::$nextId++;
		$record = ['id' => $id, 'task' => $task, 'data' => $data ?? []];
		self::$submissions[] = $record;
		// Default initial status: waiting
		self::$statusById[$id] = ['id' => $id, 'statusCode' => self::TASK_WAITING, 'data' => $record['data']];
		if ($async) return true;
		return self::$statusById[$id];
	}

	/**
	 * @param string|array $task
	 */
	public static function status($task)
	{
		if (is_array($task) && isset($task['id'])) {
			$task = $task['id'];
		}
		if (!is_string($task)) return false;
		return self::$statusById[$task] ?? ['id' => $task, 'statusCode' => self::NO_SUCH_TASK];
	}

	public static function isFailed($task): bool
	{
		if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id']))
			return true;
		// Consider failed if statusCode is none of waiting/processing/finished
		return !in_array($task['statusCode'], [self::TASK_WAITING, self::TASK_PROCESSING, self::TASK_FINISHED], true);
	}

	public static function isFinished($task): bool
	{
		if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id']))
			return false;
		return !in_array($task['statusCode'], [self::TASK_WAITING, self::TASK_PROCESSING], true);
	}

	public static function isRunning($task): bool
	{
		if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id']))
			return false;
		return in_array($task['statusCode'], [self::TASK_WAITING, self::TASK_PROCESSING], true);
	}

	public static function isTask($task): bool
	{
		if ($task === false) return false;
		if (is_string($task)) {
			$task = self::status($task);
		}
		return isset($task['statusCode'])
			&& $task['statusCode'] !== self::NO_SUCH_INSTANCE
			&& $task['statusCode'] !== self::NO_SUCH_TASK;
	}

	public static function addErrorMessage($task): void
	{
		if (!class_exists('Message')) return;
		if ($task === false) {
			Message::addError('main.taskmanager-error');
			return;
		}
		if (!isset($task['statusCode'])) {
			Message::addError('main.taskmanager-format');
			return;
		}
		if (isset($task['data']['error'])) {
			Message::addError('main.task-error', $task['statusCode'] . ' (' . $task['data']['error'] . ')');
			return;
		}
		Message::addError('main.task-error', $task['statusCode']);
	}

	/**
	 * Release a task: mark as NO_SUCH_TASK from now on
	 */
	public static function release($task): void
	{
		if (is_array($task) && isset($task['id'])) {
			$task = $task['id'];
		}
		if (!is_string($task)) return;
		self::$statusById[$task] = ['id' => $task, 'statusCode' => self::NO_SUCH_TASK];
	}
}