From b633f97ce13eb1f2c8aec3212fd286a10625887d Mon Sep 17 00:00:00 2001 From: Julien Nahum Date: Tue, 4 Mar 2025 13:36:02 +0800 Subject: [PATCH] Refactor FormSubmissionDataFactory to use TestHelpers trait - Move FormSubmissionDataFactory methods into TestHelpers trait - Update import statements across multiple test files - Remove standalone FormSubmissionDataFactory class - Simplify form submission data generation in tests - Add documentation for new generateFormSubmissionData method --- .../Zapier/IntegrationController.php | 6 +-- .../Forms}/FormSubmissionDataFactory.php | 37 ++++++++----------- api/tests/Feature/Forms/AnswerFormTest.php | 21 +++++------ .../Forms/CreateDynamicSelectOptionTest.php | 6 +-- api/tests/Feature/Forms/CustomSmtpTest.php | 3 +- .../Feature/Forms/EmailNotificationTest.php | 9 ++--- api/tests/Feature/Forms/FormLogicTest.php | 9 ++--- api/tests/Feature/Forms/FormPasswordTest.php | 3 +- .../Forms/FormSubmissionExportTest.php | 3 +- api/tests/Feature/Forms/FormUpdateTest.php | 6 +-- api/tests/Feature/Forms/MatrixInputTest.php | 12 +++--- .../UpdateWorkspaceSelectOptionJobTest.php | 5 +-- .../Submissions/EditSubmissionTest.php | 6 +-- api/tests/Feature/Zapier/IntegrationsTest.php | 3 +- api/tests/TestHelpers.php | 35 +++++++++++++++++- 15 files changed, 91 insertions(+), 73 deletions(-) rename api/{tests/Helpers => app/Service/Forms}/FormSubmissionDataFactory.php (73%) diff --git a/api/app/Http/Controllers/Integrations/Zapier/IntegrationController.php b/api/app/Http/Controllers/Integrations/Zapier/IntegrationController.php index 4a8b97b0..fc4f52a1 100644 --- a/api/app/Http/Controllers/Integrations/Zapier/IntegrationController.php +++ b/api/app/Http/Controllers/Integrations/Zapier/IntegrationController.php @@ -7,7 +7,8 @@ use App\Http\Requests\Zapier\CreateIntegrationRequest; use App\Http\Requests\Zapier\DeleteIntegrationRequest; use App\Integrations\Handlers\ZapierIntegration; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; -use Tests\Helpers\FormSubmissionDataFactory; +use App\Service\Forms\FormSubmissionDataFactory; +use Illuminate\Support\Facades\Cache; class IntegrationController { @@ -58,9 +59,8 @@ class IntegrationController $submissionData = (new FormSubmissionDataFactory($form))->asFormSubmissionData()->createSubmissionData(); } $cacheKey = "zapier-poll-submissions-{$form->id}"; - return (array) \Cache::remember($cacheKey, 60 * 5, function () use ($form, $submissionData, $lastSubmission) { + return (array) Cache::remember($cacheKey, 60 * 5, function () use ($form, $submissionData, $lastSubmission) { return [ZapierIntegration::formatWebhookData($form, $submissionData ?? $lastSubmission->data)]; }); - } } diff --git a/api/tests/Helpers/FormSubmissionDataFactory.php b/api/app/Service/Forms/FormSubmissionDataFactory.php similarity index 73% rename from api/tests/Helpers/FormSubmissionDataFactory.php rename to api/app/Service/Forms/FormSubmissionDataFactory.php index ed30123c..c445c0bb 100644 --- a/api/tests/Helpers/FormSubmissionDataFactory.php +++ b/api/app/Service/Forms/FormSubmissionDataFactory.php @@ -1,6 +1,6 @@ form->properties)->each(function ($property) use (&$data) { - if ($property['type'] === 'phone_number') { - $data[$property['id']] = '+33749119783'; - } - }); return $data; } private function generateSelectValue($property) { - $values = []; - if (isset($property['select']['options']) && count($property['select']['options']) > 0) { - $values = collect($property['select']['options'])->map(function ($option) { - return $option['name']; - })->toArray(); + if (empty($property['options'])) { + return null; } - return ($values) ? $this->faker->randomElement($values) : null; + $option = $this->faker->randomElement($property['options']); + return $option['id']; } private function generateMultiSelectValues($property) { - $values = []; - if (isset($property['multi_select']['options']) && count($property['multi_select']['options']) > 0) { - $values = collect($property['multi_select']['options'])->map(function ($option) { - return $option['name']; - })->toArray(); + if (empty($property['options'])) { + return []; } - return ($values) ? $this->faker->randomElements( - $values, - $this->faker->numberBetween(1, count($values)) - ) : null; + $numOptions = count($property['options']); + $numToSelect = $this->faker->numberBetween(1, min(3, $numOptions)); + + $selectedOptions = $this->faker->randomElements( + array_column($property['options'], 'id'), + $numToSelect + ); + + return $selectedOptions; } } diff --git a/api/tests/Feature/Forms/AnswerFormTest.php b/api/tests/Feature/Forms/AnswerFormTest.php index 064ca601..362193d3 100644 --- a/api/tests/Feature/Forms/AnswerFormTest.php +++ b/api/tests/Feature/Forms/AnswerFormTest.php @@ -1,7 +1,6 @@ actingAsUser(); @@ -17,7 +16,7 @@ it('can submit form if close date is in future', function () { $form = $this->createForm($user, $workspace, [ 'closes_at' => \Carbon\Carbon::now()->addDays(1)->toDateTimeString(), ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful() @@ -33,7 +32,7 @@ it('can not submit closed form', function () { $form = $this->createForm($user, $workspace, [ 'closes_at' => \Carbon\Carbon::now()->subDays(1)->toDateTimeString(), ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(403); @@ -45,7 +44,7 @@ it('can submit form till max submissions count is not reached at limit', functio $form = $this->createForm($user, $workspace, [ 'max_submissions_count' => 3, ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); // Can submit form for ($i = 1; $i <= 3; $i++) { @@ -79,7 +78,7 @@ it('can not submit draft form', function () { $form = $this->createForm($user, $workspace, [ 'visibility' => 'draft', ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(403); @@ -91,7 +90,7 @@ it('can not submit visibility closed form', function () { $form = $this->createForm($user, $workspace, [ 'visibility' => 'closed', ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(403); @@ -113,7 +112,7 @@ it('can not submit form with past dates', function () { })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(422) @@ -138,7 +137,7 @@ it('can not submit form with future dates', function () { })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(422) @@ -183,7 +182,7 @@ it('can submit form with passed custom validation condition', function () { })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $response = $this->postJson(route('forms.answer', $form->slug), $formData); $response->assertSuccessful() @@ -229,7 +228,7 @@ it('can not submit form with failed custom validation condition', function () { $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(422) @@ -343,7 +342,7 @@ it('executes custom validation before required field validation', function () { })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(422) diff --git a/api/tests/Feature/Forms/CreateDynamicSelectOptionTest.php b/api/tests/Feature/Forms/CreateDynamicSelectOptionTest.php index fc0ebac2..18c5b09b 100644 --- a/api/tests/Feature/Forms/CreateDynamicSelectOptionTest.php +++ b/api/tests/Feature/Forms/CreateDynamicSelectOptionTest.php @@ -1,6 +1,6 @@ actingAsUser(); @@ -11,14 +11,14 @@ it('can submit form with dyanamic select option', function () { $form->properties = collect($form->properties)->map(function ($property) use (&$selectionsPreData) { if (in_array($property['type'], ['select', 'multi_select'])) { $property['allow_creation'] = true; - $selectionsPreData[$property['id']] = ($property['type'] == 'select') ? 'New single select - '.time() : ['New multi select - '.time()]; + $selectionsPreData[$property['id']] = ($property['type'] == 'select') ? 'New single select - ' . time() : ['New multi select - ' . time()]; } return $property; })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $selectionsPreData); + $formData = $this->generateFormSubmissionData($form, $selectionsPreData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful() ->assertJson([ diff --git a/api/tests/Feature/Forms/CustomSmtpTest.php b/api/tests/Feature/Forms/CustomSmtpTest.php index 467791f4..9218e3c7 100644 --- a/api/tests/Feature/Forms/CustomSmtpTest.php +++ b/api/tests/Feature/Forms/CustomSmtpTest.php @@ -1,7 +1,6 @@ 'reply@example.com', ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); Notification::fake(); diff --git a/api/tests/Feature/Forms/EmailNotificationTest.php b/api/tests/Feature/Forms/EmailNotificationTest.php index 1ef97c93..8e5c613c 100644 --- a/api/tests/Feature/Forms/EmailNotificationTest.php +++ b/api/tests/Feature/Forms/EmailNotificationTest.php @@ -1,7 +1,6 @@ 'reply@example.com', ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $event = new \App\Events\Forms\FormSubmitted($form, $formData); $mailable = new FormEmailNotification($event, $integrationData, 'mail'); @@ -119,7 +118,7 @@ it('uses custom sender email in self-hosted mode', function () { 'reply_to' => 'reply@example.com', ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $event = new \App\Events\Forms\FormSubmitted($form, $formData); $mailable = new FormEmailNotification($event, $integrationData, 'mail'); @@ -152,7 +151,7 @@ it('does not use custom sender email in non-self-hosted mode', function () { 'reply_to' => 'reply@example.com', ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $event = new \App\Events\Forms\FormSubmitted($form, $formData); $mailable = new FormEmailNotification($event, $integrationData, 'mail'); @@ -243,7 +242,7 @@ it('uses exact email address without timestamp in self-hosted mode', function () 'include_submission_data' => true, ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $event = new \App\Events\Forms\FormSubmitted($form, $formData); $mailable = new FormEmailNotification($event, $integrationData, 'mail'); diff --git a/api/tests/Feature/Forms/FormLogicTest.php b/api/tests/Feature/Forms/FormLogicTest.php index c3a18b6b..e87560b7 100644 --- a/api/tests/Feature/Forms/FormLogicTest.php +++ b/api/tests/Feature/Forms/FormLogicTest.php @@ -1,7 +1,6 @@ actingAsUser(); @@ -390,7 +389,7 @@ it('can submit form with passed regex validation condition', function () { })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $response = $this->postJson(route('forms.answer', $form->slug), $formData); $response->assertSuccessful() @@ -439,7 +438,7 @@ it('can not submit form with failed regex validation condition', function () { })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(422) @@ -487,7 +486,7 @@ it('can submit form with does not match regex validation condition', function () })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $response = $this->postJson(route('forms.answer', $form->slug), $formData); $response->assertSuccessful() @@ -536,7 +535,7 @@ it('handles invalid regex patterns gracefully', function () { })->toArray(); $form->update(); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(422) diff --git a/api/tests/Feature/Forms/FormPasswordTest.php b/api/tests/Feature/Forms/FormPasswordTest.php index 8b931746..4dfebc10 100644 --- a/api/tests/Feature/Forms/FormPasswordTest.php +++ b/api/tests/Feature/Forms/FormPasswordTest.php @@ -1,7 +1,6 @@ password = '12345'; @@ -10,7 +9,7 @@ beforeEach(function () { $this->form = $this->createForm($user, $workspace, [ 'password' => $this->password, ]); - $this->formData = FormSubmissionDataFactory::generateSubmissionData($this->form); + $this->formData = $this->generateFormSubmissionData($this->form); }); it('can allow form owner to access and submit form without password', function () { diff --git a/api/tests/Feature/Forms/FormSubmissionExportTest.php b/api/tests/Feature/Forms/FormSubmissionExportTest.php index c2f1241a..c31d98ad 100644 --- a/api/tests/Feature/Forms/FormSubmissionExportTest.php +++ b/api/tests/Feature/Forms/FormSubmissionExportTest.php @@ -2,7 +2,6 @@ use App\Models\User; use Laravel\Sanctum\Sanctum; -use Tests\Helpers\FormSubmissionDataFactory; it('can export form submissions with selected columns', function () { $user = $this->actingAsProUser(); @@ -31,7 +30,7 @@ it('can export form submissions with selected columns', function () { ]; foreach ($submissions as $submission) { - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submission); + $formData = $this->generateFormSubmissionData($form, $submission); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful(); } diff --git a/api/tests/Feature/Forms/FormUpdateTest.php b/api/tests/Feature/Forms/FormUpdateTest.php index 928a6eef..e4efb476 100644 --- a/api/tests/Feature/Forms/FormUpdateTest.php +++ b/api/tests/Feature/Forms/FormUpdateTest.php @@ -1,6 +1,6 @@ actingAsProUser(); @@ -23,7 +23,7 @@ it('can update form with existing record', function () { expect($submissionId)->toBeString(); if ($submissionId) { - $formData = FormSubmissionDataFactory::generateSubmissionData($form, ['submission_id' => $submissionId, $nameProperty['id'] => 'Testing Updated']); + $formData = $this->generateFormSubmissionData($form, ['submission_id' => $submissionId, $nameProperty['id'] => 'Testing Updated']); $response = $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful() ->assertJson([ @@ -36,6 +36,6 @@ it('can update form with existing record', function () { $response = $this->getJson(route('forms.fetchSubmission', [$form->slug, $submissionId])) ->assertSuccessful(); - expect($response->json('data.'.$nameProperty['id']))->toBe('Testing Updated'); + expect($response->json('data.' . $nameProperty['id']))->toBe('Testing Updated'); } }); diff --git a/api/tests/Feature/Forms/MatrixInputTest.php b/api/tests/Feature/Forms/MatrixInputTest.php index 6215bb8b..035277ab 100644 --- a/api/tests/Feature/Forms/MatrixInputTest.php +++ b/api/tests/Feature/Forms/MatrixInputTest.php @@ -1,6 +1,6 @@ actingAsUser(); @@ -27,7 +27,7 @@ it('can submit form with valid matrix input', function () { ] ]; - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful() @@ -62,7 +62,7 @@ it('cannot submit form with invalid matrix input', function () { ] ]; - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(422) @@ -97,7 +97,7 @@ it('can submit form with optional matrix input left empty', function () { 'matrix_field' => [] ]; - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful() @@ -128,7 +128,7 @@ it('cannot submit form with required matrix input left empty', function () { 'matrix_field' => [] ]; - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertStatus(422) @@ -167,7 +167,7 @@ it('can validate matrix input with precognition', function () { ] ]; - $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData); + $formData = $this->generateFormSubmissionData($form, $submissionData); $response = $this->withPrecognition()->withHeaders([ 'Precognition-Validate-Only' => 'matrix_field' diff --git a/api/tests/Feature/Forms/UpdateWorkspaceSelectOptionJobTest.php b/api/tests/Feature/Forms/UpdateWorkspaceSelectOptionJobTest.php index 5b8db1f8..872fb148 100644 --- a/api/tests/Feature/Forms/UpdateWorkspaceSelectOptionJobTest.php +++ b/api/tests/Feature/Forms/UpdateWorkspaceSelectOptionJobTest.php @@ -1,13 +1,12 @@ actingAsUser(); $workspace = $this->createUserWorkspace($user); $form = $this->createForm($user, $workspace); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful() @@ -16,7 +15,7 @@ it('can validate Update Workspace Select Option Job', function () { 'message' => 'Form submission saved.', ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful() ->assertJson([ diff --git a/api/tests/Feature/Submissions/EditSubmissionTest.php b/api/tests/Feature/Submissions/EditSubmissionTest.php index 250846ac..2f00b7c4 100644 --- a/api/tests/Feature/Submissions/EditSubmissionTest.php +++ b/api/tests/Feature/Submissions/EditSubmissionTest.php @@ -1,6 +1,6 @@ actingAsUser(); @@ -9,7 +9,7 @@ it('can update form submission', function () { $form = $this->createForm($user, $workspace, [ 'closes_at' => \Carbon\Carbon::now()->addDays(1)->toDateTimeString(), ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, ['text' => 'John']); + $formData = $this->generateFormSubmissionData($form, ['text' => 'John']); $textFieldId = array_keys($formData)[0]; $updatedFormData = $formData; $updatedFormTextValue = 'Updated text'; @@ -41,7 +41,7 @@ it('cannot update form submission as non admin', function () { $form = $this->createForm($user, $workspace, [ 'closes_at' => \Carbon\Carbon::now()->addDays(1)->toDateTimeString(), ]); - $formData = FormSubmissionDataFactory::generateSubmissionData($form, ['text' => 'John']); + $formData = $this->generateFormSubmissionData($form, ['text' => 'John']); $textFieldId = array_keys($formData)[0]; $updatedFormData = $formData; $updatedFormTextValue = 'Updated text'; diff --git a/api/tests/Feature/Zapier/IntegrationsTest.php b/api/tests/Feature/Zapier/IntegrationsTest.php index 08b238cf..4e2b6b02 100644 --- a/api/tests/Feature/Zapier/IntegrationsTest.php +++ b/api/tests/Feature/Zapier/IntegrationsTest.php @@ -3,7 +3,6 @@ use App\Models\Integration\FormIntegration; use App\Models\User; use Laravel\Sanctum\Sanctum; -use Tests\Helpers\FormSubmissionDataFactory; use function Pest\Laravel\assertDatabaseCount; use function Pest\Laravel\delete; @@ -157,7 +156,7 @@ test('poll for the latest submission', function () { ]); // Create a submission for the form - $formData = FormSubmissionDataFactory::generateSubmissionData($form); + $formData = $this->generateFormSubmissionData($form); $this->postJson(route('forms.answer', $form->slug), $formData) ->assertSuccessful() diff --git a/api/tests/TestHelpers.php b/api/tests/TestHelpers.php index 91afd990..ccc7448c 100644 --- a/api/tests/TestHelpers.php +++ b/api/tests/TestHelpers.php @@ -5,6 +5,7 @@ namespace Tests; use App\Models\Forms\Form; use App\Models\User; use App\Models\Workspace; +use App\Service\Forms\FormSubmissionDataFactory; use Database\Factories\FormFactory; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Str; @@ -35,9 +36,12 @@ trait TestHelpers } /** - * Generates a Form instance (not saved) + * Creates a form model instance without saving it to the database * - * @return array + * @param User $user The user who owns the form + * @param Workspace $workspace The workspace the form belongs to + * @param array $data Additional data for the form + * @return Form The form model instance */ public function makeForm(User $user, Workspace $workspace, array $data = []) { @@ -151,6 +155,14 @@ trait TestHelpers ->make($data); } + /** + * Creates a form with the given data + * + * @param User $user The user who owns the form + * @param Workspace $workspace The workspace the form belongs to + * @param array $data Additional data for the form + * @return Form The created form + */ public function createForm(User $user, Workspace $workspace, array $data = []) { $form = $this->makeForm($user, $workspace, $data); @@ -257,4 +269,23 @@ trait TestHelpers return (object) $response->json('form_integration.data'); } + + /** + * Generates fake form submission data for testing + * + * @param Form $form The form to generate data for + * @param array $data Additional data to merge with the generated data + * @param bool $asFormSubmissionData If true, formats data as stored in FormSubmission + * @return array The generated submission data + */ + public function generateFormSubmissionData(Form $form, array $data = [], bool $asFormSubmissionData = false) + { + $factory = new FormSubmissionDataFactory($form); + + if ($asFormSubmissionData) { + $factory->asFormSubmissionData(); + } + + return $factory->createSubmissionData($data); + } }