[ESC-389]form-requires-to-answer
This commit is contained in:
parent
a41563a183
commit
e2c6af69e6
|
|
@ -66,12 +66,20 @@ class AnswerFormRequest extends FormRequest
|
||||||
foreach ($selectionFields as $field) {
|
foreach ($selectionFields as $field) {
|
||||||
if (isset($data[$field['id']]) && is_array($data[$field['id']])) {
|
if (isset($data[$field['id']]) && is_array($data[$field['id']])) {
|
||||||
$data[$field['id']] = array_map(function ($val) use ($field) {
|
$data[$field['id']] = array_map(function ($val) use ($field) {
|
||||||
|
// Find the option by exact ID match first
|
||||||
$tmpop = collect($field[$field['type']]['options'])->first(function ($op) use ($val) {
|
$tmpop = collect($field[$field['type']]['options'])->first(function ($op) use ($val) {
|
||||||
return $op['id'] ?? $op['value'] === $val;
|
return $op['id'] === $val || $op['name'] === $val;
|
||||||
});
|
});
|
||||||
|
|
||||||
return isset($tmpop['name']) ? $tmpop['name'] : '';
|
// Return the original value if no match found
|
||||||
|
return isset($tmpop['name']) ? $tmpop['name'] : $val;
|
||||||
}, $data[$field['id']]);
|
}, $data[$field['id']]);
|
||||||
|
} elseif (isset($data[$field['id']])) {
|
||||||
|
// Handle single select values
|
||||||
|
$tmpop = collect($field[$field['type']]['options'])->first(function ($op) use ($field, $data) {
|
||||||
|
return $op['id'] === $data[$field['id']] || $op['name'] === $data[$field['id']];
|
||||||
|
});
|
||||||
|
$data[$field['id']] = isset($tmpop['name']) ? $tmpop['name'] : $data[$field['id']];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (FormLogicPropertyResolver::isRequired($property, $data)) {
|
if (FormLogicPropertyResolver::isRequired($property, $data)) {
|
||||||
|
|
|
||||||
|
|
@ -113,3 +113,238 @@ it('create form with multi select logic', function () {
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('preserves multi-select values during validation with logic conditions', function () {
|
||||||
|
$user = $this->actingAsUser();
|
||||||
|
$workspace = $this->createUserWorkspace($user);
|
||||||
|
|
||||||
|
// Create a form with a multi-select field and a text field that has logic based on the multi-select
|
||||||
|
$form = $this->createForm($user, $workspace, [
|
||||||
|
'properties' => [
|
||||||
|
[
|
||||||
|
'id' => 'multi_select_field',
|
||||||
|
'name' => 'Multi Select Field',
|
||||||
|
'type' => 'multi_select',
|
||||||
|
'hidden' => false,
|
||||||
|
'required' => true,
|
||||||
|
'multi_select' => [
|
||||||
|
'options' => [
|
||||||
|
['id' => 'option1', 'name' => 'Option 1'],
|
||||||
|
['id' => 'option2', 'name' => 'Option 2'],
|
||||||
|
['id' => 'option3', 'name' => 'Option 3']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => 'text_field',
|
||||||
|
'name' => 'Text Field',
|
||||||
|
'type' => 'text',
|
||||||
|
'hidden' => false,
|
||||||
|
'required' => false,
|
||||||
|
'logic' => [
|
||||||
|
'conditions' => [
|
||||||
|
'operatorIdentifier' => 'and',
|
||||||
|
'children' => [
|
||||||
|
[
|
||||||
|
'identifier' => 'multi_select',
|
||||||
|
'value' => [
|
||||||
|
'operator' => 'contains',
|
||||||
|
'property_meta' => [
|
||||||
|
'id' => 'multi_select_field',
|
||||||
|
'type' => 'multi_select'
|
||||||
|
],
|
||||||
|
'value' => 'Option 1'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'actions' => ['require-answer']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Submit form data with multi-select values
|
||||||
|
$formData = [
|
||||||
|
'multi_select_field' => ['Option 1', 'Option 2']
|
||||||
|
];
|
||||||
|
|
||||||
|
ray($formData)->blue('Original form data');
|
||||||
|
|
||||||
|
$response = $this->postJson(route('forms.answer', $form->slug), $formData);
|
||||||
|
|
||||||
|
// The validation should fail because text_field is required when Option 1 is selected
|
||||||
|
$response->assertStatus(422)
|
||||||
|
->assertJson([
|
||||||
|
'message' => 'The Text Field field is required.',
|
||||||
|
'errors' => [
|
||||||
|
'text_field' => ['The Text Field field is required.']
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Check that the multi-select values were preserved in the validation data
|
||||||
|
ray($response->json())->purple('Response data');
|
||||||
|
expect($response->json('errors.multi_select_field'))->toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly handles multi-select values with complex form logic', function () {
|
||||||
|
$user = $this->actingAsUser();
|
||||||
|
$workspace = $this->createUserWorkspace($user);
|
||||||
|
|
||||||
|
// Create form with the specific fields from your example
|
||||||
|
$form = $this->createForm($user, $workspace, [
|
||||||
|
'properties' => [
|
||||||
|
[
|
||||||
|
'id' => '93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b',
|
||||||
|
'name' => 'Which event would you like to join?',
|
||||||
|
'type' => 'multi_select',
|
||||||
|
'hidden' => false,
|
||||||
|
'required' => true,
|
||||||
|
'multi_select' => [
|
||||||
|
'options' => [
|
||||||
|
['id' => 'Ashkelon Run (March 21)', 'name' => 'Ashkelon Run (March 21)'],
|
||||||
|
['id' => 'Jerusalem Marathon (April 4)', 'name' => 'Jerusalem Marathon (April 4)'],
|
||||||
|
['id' => 'Neither', 'name' => 'Neither']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => '0ca51469-6bda-40f4-831c-084f066643d7',
|
||||||
|
'name' => 'Jerusalem Marathon - Run Options',
|
||||||
|
'type' => 'select',
|
||||||
|
'hidden' => true,
|
||||||
|
'required' => false,
|
||||||
|
'select' => [
|
||||||
|
'options' => [
|
||||||
|
['id' => '10km (Most popular)', 'name' => '10km (Most popular)']
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'logic' => [
|
||||||
|
'conditions' => [
|
||||||
|
'operatorIdentifier' => 'and',
|
||||||
|
'children' => [
|
||||||
|
[
|
||||||
|
'identifier' => '93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b',
|
||||||
|
'value' => [
|
||||||
|
'operator' => 'contains',
|
||||||
|
'property_meta' => [
|
||||||
|
'id' => '93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b',
|
||||||
|
'type' => 'multi_select'
|
||||||
|
],
|
||||||
|
'value' => 'Jerusalem Marathon (April 4)'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'actions' => ['require-answer', 'show-block']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Submit form data matching your payload
|
||||||
|
$formData = [
|
||||||
|
'93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b' => ['Jerusalem Marathon (April 4)'],
|
||||||
|
'0ca51469-6bda-40f4-831c-084f066643d7' => '10km (Most popular)'
|
||||||
|
];
|
||||||
|
|
||||||
|
ray($formData)->blue('Original form data');
|
||||||
|
|
||||||
|
$response = $this->postJson(route('forms.answer', $form->slug), $formData);
|
||||||
|
|
||||||
|
ray($response->json())->purple('Response data');
|
||||||
|
|
||||||
|
// Should be successful since all required fields are filled
|
||||||
|
$response->assertSuccessful()
|
||||||
|
->assertJson([
|
||||||
|
'type' => 'success',
|
||||||
|
'message' => 'Form submission saved.'
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Now let's verify the saved submission data
|
||||||
|
$submission = $form->submissions()->first();
|
||||||
|
expect($submission->data['93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b'])->toBe(['Jerusalem Marathon (April 4)']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves multi-select values when building validation rules', function () {
|
||||||
|
$user = $this->actingAsUser();
|
||||||
|
$workspace = $this->createUserWorkspace($user);
|
||||||
|
|
||||||
|
// Create form with the exact fields from your real form
|
||||||
|
$form = $this->createForm($user, $workspace, [
|
||||||
|
'properties' => [
|
||||||
|
[
|
||||||
|
'id' => '93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b',
|
||||||
|
'name' => 'Which event would you like to join?',
|
||||||
|
'type' => 'multi_select',
|
||||||
|
'required' => true,
|
||||||
|
'multi_select' => [
|
||||||
|
'options' => [
|
||||||
|
['id' => 'Jerusalem Marathon (April 4)', 'name' => 'Jerusalem Marathon (April 4)'],
|
||||||
|
['id' => 'Ashkelon Run (March 21)', 'name' => 'Ashkelon Run (March 21)']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => '72565901-c345-427a-b988-0ce3de9ad9f4',
|
||||||
|
'name' => 'Additional Days',
|
||||||
|
'type' => 'multi_select',
|
||||||
|
'required' => false,
|
||||||
|
'multi_select' => [
|
||||||
|
'options' => [
|
||||||
|
['id' => 'Thursday', 'name' => 'Thursday'],
|
||||||
|
['id' => 'Sunday', 'name' => 'Sunday']
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'logic' => [
|
||||||
|
'conditions' => [
|
||||||
|
'operatorIdentifier' => 'and',
|
||||||
|
'children' => [
|
||||||
|
[
|
||||||
|
'identifier' => '93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b',
|
||||||
|
'value' => [
|
||||||
|
'operator' => 'contains',
|
||||||
|
'property_meta' => [
|
||||||
|
'id' => '93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b',
|
||||||
|
'type' => 'multi_select'
|
||||||
|
],
|
||||||
|
'value' => 'Ashkelon Run (March 21)'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'actions' => ['require-answer']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Submit form data with Jerusalem Marathon
|
||||||
|
$formData = [
|
||||||
|
'93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b' => ['Jerusalem Marathon (April 4)']
|
||||||
|
];
|
||||||
|
|
||||||
|
ray($formData)->blue('Original form data');
|
||||||
|
|
||||||
|
$response = $this->postJson(route('forms.answer', $form->slug), $formData);
|
||||||
|
|
||||||
|
ray($response->json())->purple('Response data');
|
||||||
|
|
||||||
|
// Should be successful since Jerusalem Marathon doesn't require Additional Days
|
||||||
|
$response->assertSuccessful();
|
||||||
|
|
||||||
|
// Now try with Ashkelon Run which requires Additional Days
|
||||||
|
$formData = [
|
||||||
|
'93c8ebe9-b1ba-42ce-841c-bf3b9be1ca4b' => ['Ashkelon Run (March 21)']
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->postJson(route('forms.answer', $form->slug), $formData);
|
||||||
|
|
||||||
|
// Should fail because Additional Days is required when Ashkelon Run is selected
|
||||||
|
$response->assertStatus(422)
|
||||||
|
->assertJson([
|
||||||
|
'errors' => [
|
||||||
|
'72565901-c345-427a-b988-0ce3de9ad9f4' => ['The Additional Days field is required.']
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue