From 2df2e6bee9e5a582d16c6ed49cd114c1151e13a0 Mon Sep 17 00:00:00 2001 From: Vincent Gao Date: Wed, 12 Apr 2023 20:06:39 +1000 Subject: [PATCH] Adds a kernel and Functional test 1. Adds a kernel test 2. Remove outdated verification steps from tide_webform.module --- .../src/Resource/AddWebform.php | 108 ++------- .../src/TideWebformJsonapiHelper.php | 96 ++++++++ ...rm.webform.tide_webform_content_rating.yml | 186 ++++++++++++++ .../config/optional/webform.settings.yml | 228 ++++++++++++++++++ .../tide_webform_jsonapi_test.info.yml | 12 + .../TideWebformJsonapiResourceTest.php | 132 ++++++++++ .../tests/src/Kernel/Utility/UtilityTest.php | 162 +++++++++++++ .../tide_webform_jsonapi.services.yml | 3 + tide_webform.module | 8 - 9 files changed, 835 insertions(+), 100 deletions(-) create mode 100644 modules/tide_webform_jsonapi/src/TideWebformJsonapiHelper.php create mode 100644 modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/config/install/webform.webform.tide_webform_content_rating.yml create mode 100644 modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/config/optional/webform.settings.yml create mode 100644 modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/tide_webform_jsonapi_test.info.yml create mode 100644 modules/tide_webform_jsonapi/tests/src/Functional/TideWebformJsonapiResourceTest.php create mode 100644 modules/tide_webform_jsonapi/tests/src/Kernel/Utility/UtilityTest.php create mode 100644 modules/tide_webform_jsonapi/tide_webform_jsonapi.services.yml diff --git a/modules/tide_webform_jsonapi/src/Resource/AddWebform.php b/modules/tide_webform_jsonapi/src/Resource/AddWebform.php index 652b4b3..eb78b4c 100644 --- a/modules/tide_webform_jsonapi/src/Resource/AddWebform.php +++ b/modules/tide_webform_jsonapi/src/Resource/AddWebform.php @@ -11,6 +11,7 @@ use Drupal\jsonapi\JsonApiResource\ResourceObjectData; use Drupal\jsonapi\ResourceResponse; use Drupal\jsonapi_resources\Resource\EntityQueryResourceBase; +use Drupal\tide_webform_jsonapi\TideWebformJsonapiHelper; use Drupal\webform\Entity\Webform; use Drupal\webform\WebformSubmissionForm; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -27,6 +28,13 @@ */ final class AddWebform extends EntityQueryResourceBase implements ContainerInjectionInterface { + /** + * The ResourceTypeRepository. + * + * @var \Drupal\jsonapi\ResourceType\ResourceTypeRepository + */ + protected $tideWebformJsonapiHelper; + /** * The ResourceTypeRepository. * @@ -44,7 +52,8 @@ final class AddWebform extends EntityQueryResourceBase implements ContainerInjec /** * {@inheritdoc} */ - public function __construct(ResourceTypeRepository $resource_type_repository, EntityResource $resource) { + public function __construct(TideWebformJsonapiHelper $tide_webform_jsonapi_helper, ResourceTypeRepository $resource_type_repository, EntityResource $resource) { + $this->tideWebformJsonapiHelper = $tide_webform_jsonapi_helper; $this->resourceTypeRepository = $resource_type_repository; $this->resource = $resource; } @@ -54,6 +63,7 @@ public function __construct(ResourceTypeRepository $resource_type_repository, En */ public static function create(ContainerInterface $container) { return new static( + $container->get('tide_webform_jsonapi.helper'), $container->get('jsonapi.resource_type.repository'), $container->get('jsonapi.entity_resource') ); @@ -78,7 +88,7 @@ public static function create(ContainerInterface $container) { * Thrown if the entity could not be saved. */ public function process(Request $request, Webform $webform): ResourceResponse { - // Purely business logic part to get the webform_submission entity. + // Purely business logic to get the webform_submission entity. $resource_type = $this->resourceTypeRepository->get( 'webform_submission', $webform->id() @@ -100,13 +110,13 @@ public function process(Request $request, Webform $webform): ResourceResponse { $entity->save(); // Massage, organise and verify the data. $original_elements = $webform->getElementsDecodedAndFlattened(); - $supported_validations = $this->getSupportedValidateElements(); - $results = $this->webformValidateSettingsExtractor($supported_validations, $original_elements); + $supported_validations = $this->tideWebformJsonapiHelper->getSupportedValidateElements(); + $results = $this->tideWebformJsonapiHelper->webformValidateSettingsExtractor($supported_validations, $original_elements); $new_array = []; foreach ($results as $key => $r) { - $new_array[$key] = $this->attachValidateSettingsToPayload($r); + $new_array[$key] = $this->tideWebformJsonapiHelper->attachValidateSettingsToPayload($r); } - $errors = $this->validatePayload($entity->getData(), $new_array); + $errors = $this->tideWebformJsonapiHelper->validatePayload($entity->getData(), $new_array); // Let webform core checks words and characters. $internal_errors = WebformSubmissionForm::validateWebformSubmission($entity); // Prepare error messages. @@ -140,90 +150,4 @@ public function getRouteResourceTypes(Route $route, string $route_name): array { return $this->getResourceTypesByEntityTypeId('webform_submission'); } - /** - * Extracts validate settings from the webform settings. - */ - public function webformValidateSettingsExtractor(array $supported_validation, array $original_elements): array { - $res = []; - // Iterate through webform values. - foreach ($original_elements as $w_key => $items) { - // Iterate through supported validation keys and their values. - foreach ($supported_validation as $key => $value) { - // If the current value is an array, check for a match with the key. - if (is_array($value)) { - if (array_key_exists($key, $items)) { - $res[$w_key][$key] = $items[$key]; - } - } - else { - // If the value exists in the items and is not an array, - // store it in the result. - if (array_key_exists($value, $items)) { - $res[$w_key][$value] = $items[$value]; - } - } - } - } - return $res; - } - - /** - * Supported validators. - */ - private function getSupportedValidateElements() { - return [ - '#required', - '#required_error', - '#pattern', - '#pattern_error', - ]; - } - - /** - * Attached supported validator to Payload. - */ - private function attachValidateSettingsToPayload(array $payload) { - $output = []; - $mapping = [ - '#required' => 'required', - '#required_error' => 'required', - '#pattern' => 'pattern', - '#pattern_error' => 'pattern', - ]; - foreach ($payload as $key => $value) { - if (isset($mapping[$key])) { - $output[$mapping[$key]][] = $value; - } - } - return $output; - } - - /** - * Verifies the payload. - */ - private function validatePayload(array $payload, array $massaged_validates_array) { - $results = []; - foreach ($payload as $id => $value) { - if (array_key_exists($id, $massaged_validates_array)) { - if (!empty($this->generateErrorString($value, $massaged_validates_array[$id]))) { - $results[$id] = $this->generateErrorString($value, $massaged_validates_array[$id]); - } - } - } - return $results; - } - - /** - * Generates error messages. - */ - private function generateErrorString($value, array $arr) { - $res = []; - foreach ($arr as $k => $v) { - if (call_user_func('tide_webform_jsonapi_' . $k . '_validate', $value, $v) !== TRUE) { - $res[] = call_user_func('tide_webform_jsonapi_' . $k . '_validate', $value, $v); - } - } - return $res; - } - } diff --git a/modules/tide_webform_jsonapi/src/TideWebformJsonapiHelper.php b/modules/tide_webform_jsonapi/src/TideWebformJsonapiHelper.php new file mode 100644 index 0000000..bcd6ec2 --- /dev/null +++ b/modules/tide_webform_jsonapi/src/TideWebformJsonapiHelper.php @@ -0,0 +1,96 @@ + $items) { + // Iterate through supported validation keys and their values. + foreach ($supported_validation as $key => $value) { + // If the current value is an array, check for a match with the key. + if (is_array($value)) { + if (array_key_exists($key, $items)) { + $res[$w_key][$key] = $items[$key]; + } + } + else { + // If the value exists in the items and is not an array, + // store it in the result. + if (array_key_exists($value, $items)) { + $res[$w_key][$value] = $items[$value]; + } + } + } + } + return $res; + } + + /** + * Supported validators. + */ + public function getSupportedValidateElements() { + return [ + '#required', + '#required_error', + '#pattern', + '#pattern_error', + ]; + } + + /** + * Attached supported validator to Payload. + */ + public function attachValidateSettingsToPayload(array $payload) { + $output = []; + $mapping = [ + '#required' => 'required', + '#required_error' => 'required', + '#pattern' => 'pattern', + '#pattern_error' => 'pattern', + ]; + foreach ($payload as $key => $value) { + if (isset($mapping[$key])) { + $output[$mapping[$key]][] = $value; + } + } + return $output; + } + + /** + * Verifies the payload. + */ + public function validatePayload(array $payload, array $massaged_validates_array) { + $results = []; + foreach ($payload as $id => $value) { + if (array_key_exists($id, $massaged_validates_array)) { + if (!empty($this->generateErrorString($value, $massaged_validates_array[$id]))) { + $results[$id] = $this->generateErrorString($value, $massaged_validates_array[$id]); + } + } + } + return $results; + } + + /** + * Generates error messages. + */ + public function generateErrorString($value, array $arr) { + $res = []; + foreach ($arr as $k => $v) { + if (call_user_func('tide_webform_jsonapi_' . $k . '_validate', $value, $v) !== TRUE) { + $res[] = call_user_func('tide_webform_jsonapi_' . $k . '_validate', $value, $v); + } + } + return $res; + } + +} diff --git a/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/config/install/webform.webform.tide_webform_content_rating.yml b/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/config/install/webform.webform.tide_webform_content_rating.yml new file mode 100644 index 0000000..851102a --- /dev/null +++ b/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/config/install/webform.webform.tide_webform_content_rating.yml @@ -0,0 +1,186 @@ +langcode: en +status: open +dependencies: { } +weight: 0 +open: null +close: null +uid: null +template: false +archive: false +id: tide_webform_content_rating +title: 'Content Rating' +description: ''Was this page helpful' rating/survey on content pages.' +category: '' +elements: | + url: + '#type': hidden + '#title': URL + was_this_page_helpful: + '#type': radios + '#title': 'Was this page helpful?' + '#options': yes_no + '#required': true + comments: + '#type': textarea + '#title': 'Any comments? (optional)' + '#rows': 2 + '#counter_type': word + '#counter_minimum': 1 + '#counter_maximum': 2 + '#states': + visible: + ':input[name="was_this_page_helpful"]': + checked: true + '#format_items': comma + reset: + '#type': processed_text + '#wrapper_attributes': + class: + - webform-content-rating-cancel + '#states': + visible: + ':input[name="was_this_page_helpful"]': + checked: true + '#text': '

Cancel

' + '#format': admin_text + testextfield: + '#type': textfield + '#title': testextfield + '#required': true + '#required_error': helloworld + testemail: + '#type': email + '#title': testemail + '#pattern': '/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/' + actions: + '#type': webform_actions + '#title': 'Submit button(s)' + '#states': + visible: + ':input[name="was_this_page_helpful"]': + checked: true +css: '' +javascript: '' +settings: + ajax: false + ajax_scroll_top: form + page: true + page_submit_path: '' + page_confirm_path: '' + form_submit_once: false + form_open_message: '' + form_close_message: '' + form_exception_message: '' + form_previous_submissions: false + form_confidential: false + form_confidential_message: '' + form_convert_anonymous: false + form_prepopulate: false + form_prepopulate_source_entity: false + form_prepopulate_source_entity_required: false + form_prepopulate_source_entity_type: '' + form_unsaved: false + form_disable_back: false + form_submit_back: false + form_disable_autocomplete: false + form_novalidate: false + form_required: false + form_autofocus: false + form_details_toggle: false + form_reset: false + submission_label: '' + submission_exception_message: '' + submission_locked_message: '' + submission_log: false + submission_user_columns: { } + autofill: false + autofill_message: '' + autofill_excluded_elements: { } + wizard_progress_bar: true + wizard_progress_pages: false + wizard_progress_percentage: false + wizard_start_label: '' + wizard_confirmation: true + wizard_confirmation_label: '' + wizard_track: '' + preview: 0 + preview_label: '' + preview_title: '' + preview_message: '' + preview_attributes: { } + preview_excluded_elements: { } + preview_exclude_empty: true + draft: none + draft_multiple: false + draft_auto_save: false + draft_saved_message: '' + draft_loaded_message: '' + confirmation_type: message + confirmation_url: '' + confirmation_title: '' + confirmation_message: 'Thank you, your feedback is valuable to us.' + confirmation_attributes: { } + confirmation_back: true + confirmation_back_label: '' + confirmation_back_attributes: { } + limit_total: null + limit_total_interval: null + limit_total_message: '' + limit_user: null + limit_user_interval: null + limit_user_message: '' + entity_limit_total: null + entity_limit_total_interval: null + entity_limit_user: null + entity_limit_user_interval: null + purge: none + purge_days: null + results_disabled: false + results_disabled_ignore: false + token_update: false +access: + create: + roles: + - anonymous + - authenticated + users: { } + permissions: { } + view_any: + roles: { } + users: { } + permissions: { } + update_any: + roles: { } + users: { } + permissions: { } + delete_any: + roles: { } + users: { } + permissions: { } + purge_any: + roles: { } + users: { } + permissions: { } + view_own: + roles: { } + users: { } + permissions: { } + update_own: + roles: { } + users: { } + permissions: { } + delete_own: + roles: { } + users: { } + permissions: { } + administer: + roles: { } + users: { } + permissions: { } + configuration: + roles: + - anonymous + users: { } + permissions: { } +handlers: { } +variants: { } diff --git a/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/config/optional/webform.settings.yml b/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/config/optional/webform.settings.yml new file mode 100644 index 0000000..f4b5aef --- /dev/null +++ b/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/config/optional/webform.settings.yml @@ -0,0 +1,228 @@ +settings: + default_status: open + default_page_base_path: form + default_form_open_message: 'This form has not yet been opened to submissions.' + default_form_close_message: 'Sorry...This form is closed to new submissions.' + default_form_exception_message: 'Unable to display this webform. Please contact the site administrator.' + default_submit_button_label: Submit + default_reset_button_label: Reset + default_form_submit_once: false + default_form_confidential_message: 'This form is confidential. You must Log out to submit it.' + default_form_login_message: 'Please login to access this form.' + default_form_disable_back: false + default_form_submit_back: false + default_form_unsaved: false + default_form_novalidate: false + default_form_disable_inline_errors: false + default_form_required: false + default_form_required_label: 'Indicates required field' + default_form_details_toggle: true + form_classes: "container-inline clearfix\nform--inline clearfix\nmessages messages--error\nmessages messages--warning\nmessages messages--status\n" + button_classes: '' + default_wizard_prev_button_label: '< Previous Page' + default_wizard_next_button_label: 'Next Page >' + default_wizard_start_label: Start + default_wizard_confirmation_label: Complete + default_preview_next_button_label: Preview + default_preview_prev_button_label: '< Previous' + default_preview_label: Preview + default_preview_title: '[webform:title]: Preview' + default_preview_message: 'Please review your submission. Your submission is not complete until you press the "Submit" button!' + default_draft_button_label: 'Save Draft' + default_draft_saved_message: 'Submission saved. You may return to this form later and it will restore the current values.' + default_draft_loaded_message: 'A partially-completed form was found. Please complete the remaining portions.' + default_confirmation_message: 'New submission added to [webform:title].' + default_confirmation_back_label: 'Back to form' + default_submission_label: '[webform_submission:submitted-to]: Submission #[webform_submission:serial]' + default_submission_access_denied_message: 'Please login to access this submission.' + default_submission_exception_message: 'Unable to process this submission. Please contact the site administrator.' + default_submission_locked_message: 'This submission has been locked.' + default_submission_log: false + webform_submission_bulk_form: true + webform_submission_bulk_form_actions: + - webform_submission_make_sticky_action + - webform_submission_make_unsticky_action + - webform_submission_make_lock_action + - webform_submission_make_unlock_action + - webform_submission_delete_action + - webform_submission_make_process_action + - webform_submission_make_unprocess_action + default_autofill_message: 'This submission has been autofilled with your previous submission.' + preview_classes: "messages messages--error\nmessages messages--warning\nmessages messages--status\n" + confirmation_classes: "messages messages--error\nmessages messages--warning\nmessages messages--status\n" + confirmation_back_classes: "button\n" + default_limit_total_message: 'No more submissions are permitted.' + default_limit_user_message: 'No more submissions are permitted.' + dialog: false + dialog_options: + narrow: + title: Narrow + width: 600 + normal: + title: Normal + width: 800 + wide: + title: Wide + width: 1000 +assets: + css: '' + javascript: '' +handler: + excluded_handlers: { } +export: + exporter: delimited + multiple_delimiter: ; + header_format: label + header_prefix: true + header_prefix_label_delimiter: ': ' + header_prefix_key_delimiter: __ + composite_element_item_format: label + options_single_format: compact + options_multiple_format: compact + options_item_format: label + entity_reference_items: + - id + - title + - url + likert_answers_format: label + signature_format: status + delimiter: ',' + excel: false + excluded_exporters: { } +batch: + default_batch_export_size: 500 + default_batch_update_size: 500 + default_batch_delete_size: 500 + default_batch_email_size: 500 +purge: + cron_size: 100 +element: + empty_message: '{Empty}' + allowed_tags: admin + wrapper_classes: "container-inline clearfix\nform--inline clearfix\nmessages messages--error\nmessages messages--warning\nmessages messages--status\n" + classes: "container-inline clearfix\nform--inline clearfix\nmessages messages--error\nmessages messages--warning\nmessages messages--status\n" + horizontal_rule_classes: "webform-horizontal-rule--solid\nwebform-horizontal-rule--dashed\nwebform-horizontal-rule--dotted\nwebform-horizontal-rule--gradient\nwebform-horizontal-rule--thin\nwebform-horizontal-rule--medium\nwebform-horizontal-rule--thick\nwebform-horizontal-rule--flaired\nwebform-horizontal-rule--glyph\n" + default_description_display: '' + default_more_title: More + default_section_title_tag: h2 + default_empty_option: true + default_empty_option_required: '' + default_empty_option_optional: '' + default_icheck: '' + default_google_maps_api_key: '' + excluded_elements: + password: password + password_confirm: password_confirm + checkboxes: checkboxes + color: color + container: container + datelist: datelist + datetime: datetime + details: details + entity_autocomplete: entity_autocomplete + fieldset: fieldset + item: item + language_select: language_select + managed_file: managed_file + range: range + search: search + tableselect: tableselect + text_format: text_format + value: value + view: view + webform_address: webform_address + webform_audio_file: webform_audio_file + webform_autocomplete: webform_autocomplete + webform_checkboxes_other: webform_checkboxes_other + webform_codemirror: webform_codemirror + webform_computed_token: webform_computed_token + webform_computed_twig: webform_computed_twig + webform_contact: webform_contact + webform_custom_composite: webform_custom_composite + webform_document_file: webform_document_file + webform_element: webform_element + webform_email_confirm: webform_email_confirm + webform_email_multiple: webform_email_multiple + webform_entity_checkboxes: webform_entity_checkboxes + webform_entity_radios: webform_entity_radios + webform_entity_select: webform_entity_select + webform_flexbox: webform_flexbox + webform_image_file: webform_image_file + webform_likert: webform_likert + webform_link: webform_link + webform_location_places: webform_location_places + webform_mapping: webform_mapping + webform_message: webform_message + webform_more: webform_more + webform_name: webform_name + webform_radios_other: webform_radios_other + webform_rating: webform_rating + webform_same: webform_same + webform_scale: webform_scale + webform_section: webform_section + webform_select_other: webform_select_other + webform_signature: webform_signature + webform_table: webform_table + webform_table_row: webform_table_row + webform_table_sort: webform_table_sort + webform_tableselect_sort: webform_tableselect_sort + webform_telephone: webform_telephone + webform_term_checkboxes: webform_term_checkboxes + webform_terms_of_service: webform_terms_of_service + webform_time: webform_time + webform_variant: webform_variant + webform_video_file: webform_video_file + webform_wizard_page: webform_wizard_page +html_editor: + disabled: false + format: '' + tidy: true +file: + file_public: false + file_private_redirect: true + file_private_redirect_message: 'Please login to access the uploaded file.' + default_max_filesize: '' + default_managed_file_extensions: 'gif jpg png bmp eps tif pict psd txt rtf html odf pdf doc docx ppt pptx xls xlsx xml avi mov mp3 ogg wav bz2 dmg gz jar rar sit svg tar zip' + default_audio_file_extensions: 'mp3 ogg wav' + default_document_file_extensions: 'txt rtf pdf doc docx odt ppt pptx odp xls xlsx ods' + default_image_file_extensions: 'gif jpg png svg' + default_video_file_extensions: 'avi mov mp4 ogg wav webm' + make_unused_managed_files_temporary: true + delete_temporary_managed_files: true +format: { } +mail: + default_to_mail: '[site:mail]' + default_from_mail: '[site:mail]' + default_from_name: '[site:name]' + default_reply_to: '' + default_return_path: '' + default_sender_mail: '' + default_sender_name: '' + default_subject: 'Webform submission from: [webform_submission:source-entity]' + default_body_text: "Submitted on [webform_submission:created]\nSubmitted by: [webform_submission:user]\n\nSubmitted values are:\n[webform_submission:values]\n" + default_body_html: "

Submitted on [webform_submission:created]

\n

Submitted by: [webform_submission:user]

\n

Submitted values are:

\n[webform_submission:values]\n" + roles: { } +test: + types: "checkbox:\n - true\ncolor:\n - '#ffffcc'\n - '#ffffcc'\n - '#ccffff'\nemail:\n - 'example@example.com'\n - 'test@test.com'\n - 'random@random.com'\nlanguage_select:\n - en\nmachine_name:\n - 'loremipsum'\n - 'oratione'\n - 'dixisset'\ntel:\n - '123-456-7890'\n - '098-765-4321'\ntextarea:\n - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Negat esse eam, inquit, propter se expetendam. Primum Theophrasti, Strato, physicum se voluit; Id mihi magnum videtur. Itaque mihi non satis videmini considerare quod iter sit naturae quaeque progressio. Quare hoc videndum est, possitne nobis hoc ratio philosophorum dare. Est enim tanti philosophi tamque nobilis audacter sua decreta defendere.'\n - 'Huius, Lyco, oratione locuples, rebus ipsis ielunior. Duo Reges: constructio interrete. Sed haec in pueris; Sed utrum hortandus es nobis, Luci, inquit, an etiam tua sponte propensus es? Sapiens autem semper beatus est et est aliquando in dolore; Immo videri fortasse. Paulum, cum regem Persem captum adduceret, eodem flumine invectio? Et ille ridens: Video, inquit, quid agas;'\n - 'Quae cum dixisset, finem ille. Quamquam non negatis nos intellegere quid sit voluptas, sed quid ille dicat. Progredientibus autem aetatibus sensim tardeve potius quasi nosmet ipsos cognoscimus. Gloriosa ostentatio in constituendo summo bono. Qui-vere falsone, quaerere mittimus-dicitur oculis se privasse; Duarum enim vitarum nobis erunt instituta capienda. Comprehensum, quod cognitum non habet? Qui enim existimabit posse se miserum esse beatus non erit. Causa autem fuit huc veniendi ut quosdam hinc libros promerem. Nunc omni virtuti vitium contrario nomine opponitur.'\ntext_format:\n - value: '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Negat esse eam, inquit, propter se expetendam. Primum Theophrasti, Strato, physicum se voluit; Id mihi magnum videtur. Itaque mihi non satis videmini considerare quod iter sit naturae quaeque progressio. Quare hoc videndum est, possitne nobis hoc ratio philosophorum dare. Est enim tanti philosophi tamque nobilis audacter sua decreta defendere.

'\n - value: '

Huius, Lyco, oratione locuples, rebus ipsis ielunior. Duo Reges: constructio interrete. Sed haec in pueris; Sed utrum hortandus es nobis, Luci, inquit, an etiam tua sponte propensus es? Sapiens autem semper beatus est et est aliquando in dolore; Immo videri fortasse. Paulum, cum regem Persem captum adduceret, eodem flumine invectio? Et ille ridens: Video, inquit, quid agas;

'\n - value: '

Quae cum dixisset, finem ille. Quamquam non negatis nos intellegere quid sit voluptas, sed quid ille dicat. Progredientibus autem aetatibus sensim tardeve potius quasi nosmet ipsos cognoscimus. Gloriosa ostentatio in constituendo summo bono. Qui-vere falsone, quaerere mittimus-dicitur oculis se privasse; Duarum enim vitarum nobis erunt instituta capienda. Comprehensum, quod cognitum non habet? Qui enim existimabit posse se miserum esse beatus non erit. Causa autem fuit huc veniendi ut quosdam hinc libros promerem. Nunc omni virtuti vitium contrario nomine opponitur.

'\nurl:\n - 'http://example.com'\n - 'http://test.com'\nwebform_email_confirm:\n - 'example@example.com'\n - 'test@test.com'\n - 'random@random.com'\nwebform_email_multiple:\n - 'example@example.com, test@test.com, random@random.com'\nwebform_location:\n - value: 'The White House, 1600 Pennsylvania Ave NW, Washington, DC 20500, USA'\n - value: 'London SW1A 1AA, United Kingdom'\n - value: 'Moscow, Russia, 10307'\nwebform_time:\n - '09:00'\n - '17:00'\n" + names: "first_name:\n - 'John'\n - 'Paul'\n - 'Ringo'\n - 'George'\nlast_name:\n - 'Lennon'\n - 'McCartney'\n - 'Starr'\n - 'Harrison'\naddress:\n - '10 Main Street'\n - '11 Brook Alley Road. APT 1'\nzip:\n - '11111'\n - '12345'\n - '12345-6789'\npostal_code:\n - '11111'\n - '12345'\n - '12345-6789'\nphone:\n - '123-456-7890'\n - '098-765-4321'\nfax:\n - '123-456-7890'\n - '098-765-4321'\ncity:\n - 'Springfield'\n - 'Pleasantville'\n - 'Hill Valley'\nurl:\n - 'http://example.com'\n - 'http://test.com'\ndefault:\n - 'Loremipsum'\n - 'Oratione'\n - 'Dixisset'\n" +ui: + video_display: dialog + details_save: true + dialog_disabled: false + offcanvas_disabled: false + contribute_disabled: false + promotions_disabled: false + description_help: true +libraries: + excluded_libraries: + - jquery.chosen + - jquery.icheck +requirements: + cdn: true + bootstrap: true + spam: true +contribute: + account_type: user + account_id: null +langcode: en +third_party_settings: { } diff --git a/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/tide_webform_jsonapi_test.info.yml b/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/tide_webform_jsonapi_test.info.yml new file mode 100644 index 0000000..b36e3d0 --- /dev/null +++ b/modules/tide_webform_jsonapi/tests/modules/tide_webform_jsonapi_test/tide_webform_jsonapi_test.info.yml @@ -0,0 +1,12 @@ +name: 'JSON:API Tide_webform test module' +type: module +package: Testing +dependencies: + - drupal:jsonapi + - jsonapi_resources:jsonapi_resources +core_version_requirement: ^9 || ^10 +config_devel: + install: + - webform.webform.tide_webform_content_rating + optional: + - webform.settings \ No newline at end of file diff --git a/modules/tide_webform_jsonapi/tests/src/Functional/TideWebformJsonapiResourceTest.php b/modules/tide_webform_jsonapi/tests/src/Functional/TideWebformJsonapiResourceTest.php new file mode 100644 index 0000000..7ad4cd0 --- /dev/null +++ b/modules/tide_webform_jsonapi/tests/src/Functional/TideWebformJsonapiResourceTest.php @@ -0,0 +1,132 @@ +getPermissions() as $permission) { + $user_role->revokePermission($permission); + } + $user_role->save(); + assert([] === $user_role->getPermissions(), 'The anonymous user role has no permissions at all.'); + + // Ensure the authenticated user role has no permissions at all. + $user_role = Role::load(RoleInterface::AUTHENTICATED_ID); + foreach ($user_role->getPermissions() as $permission) { + $user_role->revokePermission($permission); + } + $user_role->save(); + assert([] === $user_role->getPermissions(), 'The authenticated user role has no permissions at all.'); + $this->account = $this->createUser(); + $this->container->get('current_user')->setAccount($this->account); + } + + /** + * Tests the custom Add Webform resource. + */ + public function testAddWebformResource() { + $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE); + $this->grantPermissionsToTestedRole([ + 'access content', + ]); + $url = Url::fromRoute('tide_webform_jsonapi.add_webform', + ['webform' => 'tide_webform_content_rating']); + $request_options = []; + $request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json'; + $request_options[RequestOptions::HEADERS]['Content-Type'] = 'application/vnd.api+json'; + $request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions()); + $normalization = [ + 'data' => [ + 'type' => 'webform_submission--tide_webform_content_rating', + 'attributes' => [ + 'remote_addr' => '1.2.3.4', + 'data' => "url: '/home'\nwas_this_page_helpful: 'Yes'\ncomments: 'TEST\n Content Rating comment1'\ntestemail: 'w'\ntestextfield: ''\ntestemail: ''", + ], + ], + ]; + $request_options[RequestOptions::BODY] = Json::encode($normalization); + $response = $this->request('POST', $url, $request_options); + $this->assertSame(422, $response->getStatusCode(), $response->getBody()); + } + + /** + * Grants permissions to the authenticated role. + * + * @param string[] $permissions + * Permissions to grant. + */ + protected function grantPermissionsToTestedRole(array $permissions) { + $this->grantPermissions(Role::load(RoleInterface::AUTHENTICATED_ID), $permissions); + } + + /** + * Returns Guzzle request options for authentication. + * + * @return array + * Guzzle request options to use for authentication. + * + * @see \GuzzleHttp\ClientInterface::request() + */ + protected function getAuthenticationRequestOptions() { + return [ + 'headers' => [ + 'Authorization' => 'Basic ' . base64_encode($this->account->name->value . ':' . $this->account->passRaw), + ], + ]; + } + +} diff --git a/modules/tide_webform_jsonapi/tests/src/Kernel/Utility/UtilityTest.php b/modules/tide_webform_jsonapi/tests/src/Kernel/Utility/UtilityTest.php new file mode 100644 index 0000000..7d63543 --- /dev/null +++ b/modules/tide_webform_jsonapi/tests/src/Kernel/Utility/UtilityTest.php @@ -0,0 +1,162 @@ +tideWebformJsonapiHelper = \Drupal::service('tide_webform_jsonapi.helper'); + } + + /** + * Tests if the functions could convert and validate payloads. + * + * @covers ::webformValidateSettingsExtractor + * @covers ::getSupportedValidateElements + * @covers ::attachValidateSettingsToPayload + * @covers ::validatePayload + * @covers ::generateErrorString + * + * @dataProvider webformDataProvider + */ + public function testWebformValidation($payload, $webform_settings, $expected) { + $supported_validations = $this->tideWebformJsonapiHelper->getSupportedValidateElements(); + $results = $this->tideWebformJsonapiHelper->webformValidateSettingsExtractor($supported_validations, $webform_settings); + $new_array = []; + foreach ($results as $key => $r) { + $new_array[$key] = $this->tideWebformJsonapiHelper->attachValidateSettingsToPayload($r); + } + $errors = $this->tideWebformJsonapiHelper->validatePayload($payload, $new_array); + $this->assertEquals($expected, $errors); + } + + /** + * Data Provider. + */ + public function webformDataProvider() { + return [ + [ + [ + "comments" => "TEST Content Rating comment1", + "test_email" => "", + "url" => "/home", + "was_this_page_helpful" => "Yes", + "test_extfield" => "", + ], + [ + 'url' => [ + "#type" => "hidden", + "#title" => "URL", + ], + 'was_this_page_helpful' => [ + "#type" => "radios", + "#title" => "Was this page helpful?", + "#options" => "yes_no", + "#required" => TRUE, + ], + 'test_email' => [ + "#type" => "email", + "#title" => "testemail", + "#required" => TRUE, + '#required_error' => 'The field is mandatory 1.', + "#pattern" => "/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/", + "#pattern_error" => "The value does not match the criteria 1.", + ], + 'test_extfield' => [ + "#type" => "textfield", + "#title" => "testextfield", + "#required" => TRUE, + "#required_error" => "The field is mandatory.", + "#pattern" => "/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/", + "#pattern_error" => "The value does not match the criteria 2.", + "#counter_type" => "character", + "#counter_minimum" => 1, + "#counter_maximum" => 5, + "#counter_maximum_message" => "sdfgsdfg", + ], + ], + [ + "test_email" => [ + "The field is mandatory 1.", + "The value does not match the criteria 1.", + ], + "test_extfield" => [ + "The field is mandatory.", + "The value does not match the criteria 2.", + ], + ], + ], + [ + [ + "comments" => "TEST Content Rating comment1", + "test_email" => "", + "url" => "/home", + "was_this_page_helpful" => "Yes", + "test_extfield" => "", + ], + [ + 'url' => [ + "#type" => "hidden", + "#title" => "URL", + ], + 'was_this_page_helpful' => [ + "#type" => "radios", + "#title" => "Was this page helpful?", + "#options" => "yes_no", + "#required" => TRUE, + "#required_error" => 'The field is mandatory 1.', + ], + 'test_email' => [ + "#type" => "email", + "#title" => "testemail", + "#required" => TRUE, + "#pattern" => "/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/", + ], + 'test_extfield' => [ + "#type" => "textfield", + "#title" => "testextfield", + "#required" => TRUE, + "#required_error" => "The field is mandatory.", + "#pattern" => "/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/", + "#counter_type" => "character", + "#counter_minimum" => 1, + "#counter_maximum" => 5, + "#counter_maximum_message" => "sdfgsdfg", + ], + ], + [ + "test_email" => [ + "The field is mandatory.", + "The value does not match the criteria.", + ], + "test_extfield" => [ + "The field is mandatory.", + "The value does not match the criteria.", + ], + ], + ], + ]; + } + +} diff --git a/modules/tide_webform_jsonapi/tide_webform_jsonapi.services.yml b/modules/tide_webform_jsonapi/tide_webform_jsonapi.services.yml new file mode 100644 index 0000000..b112293 --- /dev/null +++ b/modules/tide_webform_jsonapi/tide_webform_jsonapi.services.yml @@ -0,0 +1,3 @@ +services: + tide_webform_jsonapi.helper: + class: Drupal\tide_webform_jsonapi\TideWebformJsonapiHelper diff --git a/tide_webform.module b/tide_webform.module index e1560f1..75af969 100644 --- a/tide_webform.module +++ b/tide_webform.module @@ -289,14 +289,6 @@ function tide_webform_webform_submission_presave(WebformSubmission $webform_subm } } } - $errors = WebformSubmissionForm::validateWebformSubmission($webform_submission); - if ($errors) { - foreach ($elements as $key => $element) { - if (isset($errors[$key]) && !empty($errors[$key])) { - throw new Exception($errors[$key]); - } - } - } } /**