Merge pull request #280 from copenhagentruckwash/fix/self-serve-path-outcome-case-limit
Fix self-serve path outcome case limit
This commit is contained in:
@@ -48,8 +48,8 @@ class selfserve_studio_graph
|
||||
{
|
||||
private const DEFAULT_PATH_MAX_STATES = 2048;
|
||||
private const MAX_PATH_MAX_STATES = 2048;
|
||||
private const DEFAULT_PATH_SAMPLE_LIMIT = 200;
|
||||
private const MAX_PATH_SAMPLE_LIMIT = 200;
|
||||
private const DEFAULT_PATH_SAMPLE_LIMIT = 2048;
|
||||
private const MAX_PATH_SAMPLE_LIMIT = 2048;
|
||||
|
||||
/** @var array<string,array<int,string>> */
|
||||
private array $columnCache = [];
|
||||
|
||||
@@ -18441,10 +18441,10 @@ components:
|
||||
path_sample_limit:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 200
|
||||
default: 200
|
||||
maximum: 2048
|
||||
default: 2048
|
||||
nullable: true
|
||||
description: Optional cap for returned path rows. Omitted and larger values are capped at 200.
|
||||
description: Optional cap for returned path rows. Omitted returns every projected terminal path within the state cap; larger values are capped at 2048.
|
||||
|
||||
SelfserveStudioPathOutcomesResponse:
|
||||
type: object
|
||||
|
||||
@@ -26,6 +26,54 @@ function selfserve_virtual_hardware_without_constructor(): selfserve_virtual_har
|
||||
return $reflection->newInstanceWithoutConstructor();
|
||||
}
|
||||
|
||||
function selfserve_question_tree_simulator(int $questionCount): callable
|
||||
{
|
||||
return function (array $overrides) use ($questionCount): array {
|
||||
$answers = [];
|
||||
foreach ($overrides as $entry) {
|
||||
$answers[(int)($entry['question_id'] ?? 0)] = $entry['value'] ?? null;
|
||||
}
|
||||
|
||||
$questions = [];
|
||||
foreach (range(1, $questionCount) as $questionId) {
|
||||
$questions[] = [
|
||||
'id' => $questionId,
|
||||
'node_id' => 'question:' . $questionId,
|
||||
'label' => 'Question ' . $questionId,
|
||||
'visible' => true,
|
||||
'answer' => $answers[$questionId] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
$complete = count($answers) === $questionCount;
|
||||
$allowed = $complete && !in_array(false, $answers, true);
|
||||
|
||||
return [
|
||||
'allowed' => $allowed,
|
||||
'questions' => [],
|
||||
'tasks' => $allowed ? [
|
||||
['id' => 41, 'task' => 'Start machine', 'services' => ['MACHINE'], 'buttons' => ['start']],
|
||||
] : [],
|
||||
'allowed_services' => $allowed ? ['MACHINE'] : [],
|
||||
'debug' => [
|
||||
'questions' => $questions,
|
||||
'tasks' => [
|
||||
[
|
||||
'id' => 41,
|
||||
'node_id' => 'task:41',
|
||||
'label' => 'Start machine',
|
||||
'active' => $allowed,
|
||||
'services' => ['MACHINE'],
|
||||
'buttons' => ['start'],
|
||||
'order_priority' => 1,
|
||||
],
|
||||
],
|
||||
'signal_timeline' => [],
|
||||
],
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
it('serializes questions, conditions, tasks, scopes, and gateways into one graph', function (): void {
|
||||
$service = selfserve_studio_graph_without_constructor();
|
||||
|
||||
@@ -1321,52 +1369,20 @@ it('truncates path outcome projection when the state cap is reached', function (
|
||||
->and($projection['warnings'][0])->toContain('truncated at 2 explored state');
|
||||
});
|
||||
|
||||
it('applies default caps for wide question trees and reports progress', function (): void {
|
||||
it('returns more than 200 projected path cases by default', function (): void {
|
||||
$service = selfserve_studio_graph_without_constructor();
|
||||
$simulate = function (array $overrides): array {
|
||||
$answers = [];
|
||||
foreach ($overrides as $entry) {
|
||||
$answers[(int)($entry['question_id'] ?? 0)] = $entry['value'] ?? null;
|
||||
}
|
||||
$projection = $service->projectPathOutcomesFromSimulator(selfserve_question_tree_simulator(8));
|
||||
|
||||
$questions = [];
|
||||
foreach (range(1, 12) as $questionId) {
|
||||
$questions[] = [
|
||||
'id' => $questionId,
|
||||
'node_id' => 'question:' . $questionId,
|
||||
'label' => 'Question ' . $questionId,
|
||||
'visible' => true,
|
||||
'answer' => $answers[$questionId] ?? null,
|
||||
];
|
||||
}
|
||||
expect($projection['truncated'])->toBeFalse()
|
||||
->and($projection['summary']['state_count'])->toBe(511)
|
||||
->and($projection['summary']['terminal_path_count'])->toBe(256)
|
||||
->and($projection['summary']['path_sample_count'])->toBe(256)
|
||||
->and($projection['paths'])->toHaveCount(256);
|
||||
});
|
||||
|
||||
$complete = count($answers) === 12;
|
||||
$allowed = $complete && !in_array(false, $answers, true);
|
||||
|
||||
return [
|
||||
'allowed' => $allowed,
|
||||
'questions' => [],
|
||||
'tasks' => $allowed ? [
|
||||
['id' => 41, 'task' => 'Start machine', 'services' => ['MACHINE'], 'buttons' => ['start']],
|
||||
] : [],
|
||||
'allowed_services' => $allowed ? ['MACHINE'] : [],
|
||||
'debug' => [
|
||||
'questions' => $questions,
|
||||
'tasks' => [
|
||||
[
|
||||
'id' => 41,
|
||||
'node_id' => 'task:41',
|
||||
'label' => 'Start machine',
|
||||
'active' => $allowed,
|
||||
'services' => ['MACHINE'],
|
||||
'buttons' => ['start'],
|
||||
'order_priority' => 1,
|
||||
],
|
||||
],
|
||||
'signal_timeline' => [],
|
||||
],
|
||||
];
|
||||
};
|
||||
it('applies the default state cap for wide question trees and reports progress', function (): void {
|
||||
$service = selfserve_studio_graph_without_constructor();
|
||||
$simulate = selfserve_question_tree_simulator(12);
|
||||
|
||||
$progressEvents = [];
|
||||
$projection = $service->projectPathOutcomesFromSimulator($simulate, [
|
||||
@@ -1385,10 +1401,10 @@ it('applies default caps for wide question trees and reports progress', function
|
||||
->and($projection['summary']['question_count'])->toBe(12)
|
||||
->and($projection['summary']['terminal_path_count'])->toBe(1023)
|
||||
->and($projection['summary']['outcome_count'])->toBe(2)
|
||||
->and($projection['summary']['path_sample_count'])->toBe(200)
|
||||
->and($projection['summary']['path_sample_count'])->toBe(1023)
|
||||
->and($projection['progress']['complete'])->toBeFalse()
|
||||
->and($projection['progress']['percent'])->toBe(99)
|
||||
->and($projection['paths'])->toHaveCount(200)
|
||||
->and($projection['paths'])->toHaveCount(1023)
|
||||
->and($projection['paths'][0]['answers'])->toHaveCount(12)
|
||||
->and($projection['paths'][0]['result'])->toBe('Allowed')
|
||||
->and($projection['warnings'][0])->toContain('truncated at 2048 explored state')
|
||||
|
||||
Reference in New Issue
Block a user