actingAsUser(); $workspace = $this->createUserWorkspace($user); $form = $this->createForm($user, $workspace, [ 'properties' => [ [ 'id' => 'title', 'name' => 'Name', 'type' => 'title', 'hidden' => false, 'required' => true, 'logic' => [ 'conditions' => [ 'operatorIdentifier' => 'and', 'children' => [ [ 'identifier' => 'email', 'value' => [ 'operator' => 'is_empty', 'property_meta' => [ 'id' => '93ea3198-353f-440b-8dc9-2ac9a7bee124', 'type' => 'email', ], 'value' => true, ], ], ], ], 'actions' => ['make-it-optional'], ], ], ], ]); $this->getJson(route('forms.show', $form->slug)) ->assertSuccessful() ->assertJson(function (AssertableJson $json) use ($form) { return $json->where('id', $form->id) ->where('properties', function ($values) { return count($values[0]['logic']) > 0; }) ->etc(); }); // Should submit form $forData = ['93ea3198-353f-440b-8dc9-2ac9a7bee124' => '']; $this->postJson(route('forms.answer', $form->slug), $forData) ->assertSuccessful() ->assertJson([ 'type' => 'success', 'message' => 'Form submission saved.', ]); }); it('create form with multi select logic', function () { $user = $this->actingAsUser(); $workspace = $this->createUserWorkspace($user); $form = $this->createForm($user, $workspace, [ 'properties' => [ [ 'id' => 'title', 'name' => 'Name', 'type' => 'title', 'hidden' => false, 'required' => false, 'logic' => [ 'conditions' => [ 'operatorIdentifier' => 'and', 'children' => [ [ 'identifier' => 'multi_select', 'value' => [ 'operator' => 'contains', 'property_meta' => [ 'id' => '93ea3198-353f-440b-8dc9-2ac9a7bee124', 'type' => 'multi_select', ], 'value' => 'One', ], ], ], ], 'actions' => ['require-answer'], ], ], ], ]); $this->getJson(route('forms.show', $form->slug)) ->assertSuccessful() ->assertJson(function (AssertableJson $json) use ($form) { return $json->where('id', $form->id) ->where('properties', function ($values) { return count($values[0]['logic']) > 0; }) ->etc(); }); // Should submit form $forData = ['93ea3198-353f-440b-8dc9-2ac9a7bee124' => ['One']]; $this->postJson(route('forms.answer', $form->slug), $forData) ->assertStatus(422) ->assertJson([ 'message' => 'The Name field is required.', 'errors' => [ 'title' => [ 'The Name field is required.', ], ], ]); }); 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.'] ] ]); });