diff --git a/assets/js/mailchimp.js b/assets/js/mailchimp.js index a27900ea..753c8ab9 100644 --- a/assets/js/mailchimp.js +++ b/assets/js/mailchimp.js @@ -93,4 +93,19 @@ }); }); } + + // Phone validation custom error message. + if ($('.mailchimp-sf-phone').length > 0) { + $('.mailchimp-sf-phone').each(function () { + $(this) + .on('input', function () { + this.setCustomValidity(''); + }) + .on('invalid', function () { + if (!this.validity.valid) { + this.setCustomValidity(window.mailchimpSF.phone_validation_error); + } + }); + }); + } })(window.jQuery); diff --git a/includes/blocks/mailchimp-form-field/edit.js b/includes/blocks/mailchimp-form-field/edit.js index b1dcd9d4..ed44f745 100644 --- a/includes/blocks/mailchimp-form-field/edit.js +++ b/includes/blocks/mailchimp-form-field/edit.js @@ -232,37 +232,20 @@ export const MailchimpFormField = (props) => { ); case 'phone': - if (field?.options?.phone_format === 'US') { - return ( - <> - - - - - ); - } - return ; + // eslint-disable-next-line no-case-declarations + const isUSPhone = field?.options?.phone_format === 'US'; + // eslint-disable-next-line no-case-declarations + const placeholder = isUSPhone ? '(###) ### - ####' : ''; + return ( + + ); case 'email': case 'url': diff --git a/includes/class-mailchimp-form-submission.php b/includes/class-mailchimp-form-submission.php index f111c8b6..b0a8de07 100644 --- a/includes/class-mailchimp-form-submission.php +++ b/includes/class-mailchimp-form-submission.php @@ -178,6 +178,64 @@ public function handle_form_submission() { return $message; } + /** + * Validate phone + * + * @param string $opt_val Option value. + * @param array $data Data. + * @return string|WP_Error Option value or error. + */ + public function validate_phone( $opt_val, $data ) { + if ( empty( $opt_val ) ) { + return ''; + } + + // Backwards compatibility for old phone format. + if ( is_array( $opt_val ) ) { + $opt_val = implode( '-', $opt_val ); + } + + $opt_val = trim( $opt_val ); + + // Validate phone number. + if ( preg_match( '/^\+?[\d\s\-\(\)\.]*$/', $opt_val ) ) { + return $opt_val; + } else { + /* translators: %s: field name */ + $message = sprintf( esc_html__( 'Please enter a valid %s.', 'mailchimp' ), esc_html( $data['name'] ) ); + return new WP_Error( 'mc_phone_validation', $message ); + } + } + + /** + * Validate address + * + * @param array $opt_val Option value + * @param array $data Data + * @return mixed + */ + public function validate_address( $opt_val, $data ) { + if ( true === (bool) $data['required'] ) { + if ( empty( $opt_val['addr1'] ) || empty( $opt_val['city'] ) ) { + /* translators: %s: field name */ + $message = sprintf( esc_html__( '%s: Please enter a complete address.', 'mailchimp' ), esc_html( $data['name'] ) ); + $error = new WP_Error( 'invalid_address_merge', $message ); + return $error; + } + } elseif ( empty( $opt_val['addr1'] ) || empty( $opt_val['city'] ) ) { + return false; + } + + $merge = new stdClass(); + $merge->addr1 = $opt_val['addr1']; + $merge->addr2 = $opt_val['addr2']; + $merge->city = $opt_val['city']; + $merge->state = $opt_val['state']; + $merge->zip = $opt_val['zip']; + $merge->country = $opt_val['country']; + return $merge; + } + /** * Prepare the merge fields body for the API request. * @@ -193,7 +251,7 @@ public function prepare_merge_fields_body( $merge_fields, $skip_merge_validation $opt = 'mc_mv_' . $tag; // Skip if the field is not required and not submitted. - if ( ( 'Y' !== $merge_field['required'] && ! isset( $_POST[ $opt ] ) ) || $skip_merge_validation ) { + if ( ( true !== (bool) $merge_field['required'] && ! isset( $_POST[ $opt ] ) ) || $skip_merge_validation ) { continue; } @@ -201,21 +259,12 @@ public function prepare_merge_fields_body( $merge_fields, $skip_merge_validation switch ( $merge_field['type'] ) { /** - * US Phone validation - * - * - Merge field is phone - * - Phone format is set in Mailchimp account - * - Phone format is US in Mailchimp account + * US/International Phone validation */ case 'phone': - if ( - isset( $merge_field['options']['phone_format'] ) - && 'US' === $merge_field['options']['phone_format'] - ) { - $opt_val = mailchimp_sf_merge_validate_phone( $opt_val, $merge_field ); - if ( is_wp_error( $opt_val ) ) { - return $opt_val; - } + $opt_val = $this->validate_phone( $opt_val, $merge_field ); + if ( is_wp_error( $opt_val ) ) { + return $opt_val; } break; @@ -227,7 +276,7 @@ public function prepare_merge_fields_body( $merge_fields, $skip_merge_validation */ case 'address': if ( is_array( $opt_val ) ) { - $validate = mailchimp_sf_merge_validate_address( $opt_val, $merge_field ); + $validate = $this->validate_address( $opt_val, $merge_field ); if ( is_wp_error( $validate ) ) { return $validate; } @@ -260,9 +309,9 @@ public function prepare_merge_fields_body( $merge_fields, $skip_merge_validation /** * Required fields * - * If the field is required and empty, return an error + * If the field is required and empty, +return an error */ - if ( 'Y' === $merge_field['required'] && trim( $opt_val ) === '' ) { + if ( true === (bool) $merge_field['required'] && empty( $opt_val ) ) { /* translators: %s: field name */ $message = sprintf( esc_html__( 'You must fill in %s.', 'mailchimp' ), esc_html( $merge_field['name'] ) ); $error = new WP_Error( 'missing_required_field', $message ); @@ -512,6 +561,16 @@ protected function validate_form_submission() { return new WP_Error( 'spam', $spam_message ); } + // Early return if the email is not set + if ( empty( $_POST['mc_mv_EMAIL'] ) ) { + return new WP_Error( 'email_required', esc_html__( 'Please enter your email address.', 'mailchimp' ) ); + } + + // Check if the email is valid + if ( ! is_email( sanitize_email( wp_unslash( $_POST['mc_mv_EMAIL'] ) ) ) ) { + return new WP_Error( 'invalid_email', esc_html__( 'Please enter a valid email address.', 'mailchimp' ) ); + } + /** * Filter to allow for custom validation of the form submission. * diff --git a/includes/mailchimp-deprecated-functions.php b/includes/mailchimp-deprecated-functions.php index 00ac791c..f3885cde 100644 --- a/includes/mailchimp-deprecated-functions.php +++ b/includes/mailchimp-deprecated-functions.php @@ -113,3 +113,39 @@ function mailchimp_sf_merge_remove_empty( $merge ) { $form_submission = new Mailchimp_Form_Submission(); return $form_submission->remove_empty_merge_fields( $merge ); } + + +/** + * Validate phone + * + * @deprecated x.x.x + * + * @param array $opt_val Option value. + * @param array $data Data. + * @return string|WP_Error Option value or error. + */ +function mailchimp_sf_merge_validate_phone( $opt_val, $data ): string|WP_Error { + _deprecated_function( __FUNCTION__, 'x.x.x', 'Mailchimp_Form_Submission::validate_phone()' ); + + if ( is_array( $opt_val ) ) { + $opt_val = implode( '-', $opt_val ); + } + $form_submission = new Mailchimp_Form_Submission(); + return $form_submission->validate_phone( $opt_val, $data ); +} + +/** + * Validate address + * + * @deprecated x.x.x + * + * @param array $opt_val Option value. + * @param array $data Data. + * @return mixed + */ +function mailchimp_sf_merge_validate_address( $opt_val, $data ) { + _deprecated_function( __FUNCTION__, 'x.x.x', 'Mailchimp_Form_Submission::validate_address()' ); + + $form_submission = new Mailchimp_Form_Submission(); + return $form_submission->validate_address( $opt_val, $data ); +} diff --git a/mailchimp.php b/mailchimp.php index 08ff6a06..1082e59b 100644 --- a/mailchimp.php +++ b/mailchimp.php @@ -164,7 +164,8 @@ function mailchimp_sf_load_resources() { 'mailchimp_sf_main_js', 'mailchimpSF', array( - 'ajax_url' => trailingslashit( home_url() ), + 'ajax_url' => trailingslashit( home_url() ), + 'phone_validation_error' => esc_html__( 'Please enter a valid phone number.', 'mailchimp' ), ) ); @@ -510,7 +511,7 @@ function mailchimp_sf_save_general_form_settings() { if ( is_array( $mv ) ) { foreach ( $mv as $mv_var ) { $opt = 'mc_mv_' . $mv_var['tag']; - if ( isset( $_POST[ $opt ] ) || 'Y' === $mv_var['required'] ) { + if ( isset( $_POST[ $opt ] ) || true === (bool) $mv_var['required'] ) { update_option( $opt, 'on' ); } else { update_option( $opt, 'off' ); @@ -787,65 +788,6 @@ function mailchimp_sf_check_status( $endpoint ) { return $subscriber['status']; } -/** - * Validate phone - * - * @param array $opt_val Option value - * @param array $data Data - * @return void - */ -function mailchimp_sf_merge_validate_phone( $opt_val, $data ) { - // This filters out all 'falsey' elements - $opt_val = array_filter( $opt_val ); - // If they weren't all empty - if ( ! $opt_val ) { - return; - } - - $opt_val = implode( '-', $opt_val ); - if ( strlen( $opt_val ) < 12 ) { - $opt_val = ''; - } - - if ( ! preg_match( '/[0-9]{0,3}-[0-9]{0,3}-[0-9]{0,4}/A', $opt_val ) ) { - /* translators: %s: field name */ - $message = sprintf( esc_html__( '%s must consist of only numbers', 'mailchimp' ), esc_html( $data['name'] ) ); - $error = new WP_Error( 'mc_phone_validation', $message ); - return $error; - } - - return $opt_val; -} - -/** - * Validate address - * - * @param array $opt_val Option value - * @param array $data Data - * @return mixed - */ -function mailchimp_sf_merge_validate_address( $opt_val, $data ) { - if ( 'Y' === $data['required'] ) { - if ( empty( $opt_val['addr1'] ) || empty( $opt_val['city'] ) ) { - /* translators: %s: field name */ - $message = sprintf( esc_html__( 'You must fill in %s.', 'mailchimp' ), esc_html( $data['name'] ) ); - $error = new WP_Error( 'invalid_address_merge', $message ); - return $error; - } - } elseif ( empty( $opt_val['addr1'] ) || empty( $opt_val['city'] ) ) { - return false; - } - - $merge = new stdClass(); - $merge->addr1 = $opt_val['addr1']; - $merge->addr2 = $opt_val['addr2']; - $merge->city = $opt_val['city']; - $merge->state = $opt_val['state']; - $merge->zip = $opt_val['zip']; - $merge->country = $opt_val['country']; - return $merge; -} - /** * Verify key * diff --git a/mailchimp_widget.php b/mailchimp_widget.php index 6950af20..6e9a36ff 100644 --- a/mailchimp_widget.php +++ b/mailchimp_widget.php @@ -452,17 +452,9 @@ function mailchimp_form_field( $data, $num_fields, $should_display = null, $labe '; break; case 'phone': - if ( isset( $data['options']['phone_format'] ) && 'US' === $data['options']['phone_format'] ) { - $html .= ' - - - - '; - } else { - $html .= ' - - '; - } + $is_us_phone = isset( $data['options']['phone_format'] ) && 'US' === $data['options']['phone_format']; + $html .= ' + '; break; case 'email': case 'url': diff --git a/tests/cypress/e2e/block.test.js b/tests/cypress/e2e/block.test.js index 37932e29..33e987f6 100644 --- a/tests/cypress/e2e/block.test.js +++ b/tests/cypress/e2e/block.test.js @@ -35,7 +35,7 @@ describe('Block Tests', () => { cy.get('#mc_signup_submit').should('exist'); cy.get('#mc_signup_submit').click(); cy.get('.mc_error_msg').should('exist'); - cy.get('.mc_error_msg').contains('Email Address: This value should not be blank.'); + cy.get('.mc_error_msg').contains('Please enter your email address.'); } }); }); @@ -55,6 +55,7 @@ describe('Block Tests', () => { .type(subHeader); cy.getBlockEditor().find('button[aria-label="Enter button text."]').clear().type(button); cy.get('button.editor-post-publish-button').click(); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -74,6 +75,7 @@ describe('Block Tests', () => { .find('button[aria-label="Move down"]') .click(); cy.get('button.editor-post-publish-button').click(); + cy.wait(1000); // Verify order of fields cy.visit(`/?p=${postId}`); @@ -90,6 +92,7 @@ describe('Block Tests', () => { .find('button[aria-label="Move up"]') .click(); cy.get('button.editor-post-publish-button').click(); + cy.wait(1000); // Verify order of fields cy.visit(`/?p=${postId}`); @@ -107,7 +110,7 @@ describe('Block Tests', () => { cy.get('.block-editor-block-toolbar__slot').find('button[aria-label="Visibility"]').click(); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -123,7 +126,7 @@ describe('Block Tests', () => { .find('button[aria-label="Visibility"].is-pressed') .click(); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -141,7 +144,7 @@ describe('Block Tests', () => { .find('button[aria-label="Visibility"].is-pressed') .click(); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -156,7 +159,7 @@ describe('Block Tests', () => { cy.get('.block-editor-block-toolbar__slot').find('button[aria-label="Visibility"]').click(); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -171,7 +174,7 @@ describe('Block Tests', () => { cy.getBlockEditor().find('label[for="EMAIL"] label').clear().type(emailLabel); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -186,7 +189,7 @@ describe('Block Tests', () => { cy.openDocumentSettingsPanel('Form Settings', 'Block'); cy.get('.mailchimp-unsubscribe-link input.components-form-toggle__input').first().check(); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -198,7 +201,7 @@ describe('Block Tests', () => { cy.openDocumentSettingsPanel('Form Settings', 'Block'); cy.get('.mailchimp-unsubscribe-link input.components-form-toggle__input').first().uncheck(); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -216,7 +219,7 @@ describe('Block Tests', () => { cy.getBlockEditor().find('label[for="MMERGE9"]').should('not.exist'); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -232,7 +235,7 @@ describe('Block Tests', () => { cy.wait(2000); cy.getBlockEditor().find('label[for="MMERGE9"]').should('exist'); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); }); it('[Backward Compatibility] Admin can see settings for the existing old block', () => { @@ -257,7 +260,7 @@ describe('Block Tests', () => { .clear() .type(header); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${oldBlockPostId}`); @@ -274,7 +277,7 @@ describe('Block Tests', () => { .first() .check(); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); // Verify cy.visit(`/?p=${postId}`); @@ -293,7 +296,7 @@ describe('Block Tests', () => { cy.openDocumentSettingsPanel('Form Settings', 'Block'); cy.get('.mailchimp-double-opt-in input.components-form-toggle__input').first().check(); cy.get('button.editor-post-publish-button').click(); - cy.wait(500); + cy.wait(1000); }); it('Form data should persist if validation fails', () => { @@ -307,7 +310,7 @@ describe('Block Tests', () => { cy.get('#mc_signup_submit').should('exist'); cy.get('#mc_signup_submit').click(); cy.get('.mc_error_msg').should('exist'); - cy.get('.mc_error_msg').contains('Email Address: This value should not be blank.'); + cy.get('.mc_error_msg').contains('Please enter your email address.'); cy.get('#mc_mv_FNAME').should('have.value', firstName); cy.get('#mc_mv_LNAME').should('have.value', lastName); }); @@ -332,7 +335,7 @@ describe('Block Tests', () => { cy.get('#mc_signup_submit').should('exist'); cy.get('#mc_signup_submit').click(); cy.get('.mc_error_msg').should('exist'); - cy.get('.mc_error_msg').contains('Email Address: This value should not be blank.'); + cy.get('.mc_error_msg').contains('Please enter your email address.'); }); // TODO: Add tests for the Double Opt-in and Update existing subscribers settings. diff --git a/tests/cypress/e2e/settings/settings.test.js b/tests/cypress/e2e/settings/settings.test.js index ec841fc6..930d6e51 100644 --- a/tests/cypress/e2e/settings/settings.test.js +++ b/tests/cypress/e2e/settings/settings.test.js @@ -177,7 +177,7 @@ describe('Admin can update plugin settings', () => { cy.get('#mc_signup_submit').should('exist'); cy.get('#mc_signup_submit').click(); cy.get('.mc_error_msg').should('exist'); - cy.get('.mc_error_msg').contains('Email Address: This value should not be blank.'); + cy.get('.mc_error_msg').contains('Please enter your email address.'); cy.get('#mc_mv_FNAME').should('have.value', firstName); cy.get('#mc_mv_LNAME').should('have.value', lastName); }); @@ -235,7 +235,7 @@ describe('Admin can update plugin settings', () => { cy.get('#mc_signup_submit').should('exist'); cy.get('#mc_signup_submit').click(); cy.get('.mc_error_msg').should('exist'); - cy.get('.mc_error_msg').contains('Email Address: This value should not be blank.'); + cy.get('.mc_error_msg').contains('Please enter your email address.'); }); }); diff --git a/tests/cypress/e2e/submission/js-submission.test.js b/tests/cypress/e2e/submission/js-submission.test.js index 5a43d455..f82f99a3 100644 --- a/tests/cypress/e2e/submission/js-submission.test.js +++ b/tests/cypress/e2e/submission/js-submission.test.js @@ -47,7 +47,7 @@ describe('JavaScript submission', () => { }); it('Disables the submit button before attempting submission', () => { - submitEmail('invalidemail@--'); // Submit blank email + submitEmail('invalidemail@test.com'); // Submit blank email // Step 4: Assert that the submit button is disabled after submitting the form cy.get('#mc_signup_submit').should('be.disabled'); @@ -81,13 +81,7 @@ describe('JavaScript submission', () => { cy.deleteContactFromList(email); }); - // TODO: This is a bug and is currently broken - it.skip('Persist form data on Mailchimp API validation failure', () => { - // Write test... - }); - - // TODO: BUG: Single opt-in is currently broken, but a fix is scheduled for 1.7.0 - it.skip('Success submission with JS support adds email to Mailchimp account as contact', () => { + it('Success submission with JS support adds email to Mailchimp account as contact', () => { const email = generateRandomEmail('javascript-submission-verify-submission'); submitEmail(email); diff --git a/tests/cypress/e2e/submission/subscribe.test.js b/tests/cypress/e2e/submission/subscribe.test.js index 910b8af5..c5d3076d 100644 --- a/tests/cypress/e2e/submission/subscribe.test.js +++ b/tests/cypress/e2e/submission/subscribe.test.js @@ -22,7 +22,7 @@ describe('Subscribe actions', () => { // Step 4: Test error handling cy.get('#mc_signup_submit').click(); cy.get('.mc_error_msg').should('exist'); - cy.get('.mc_error_msg').contains('Email Address: This value should not be blank.'); + cy.get('.mc_error_msg').contains('Please enter your email address.'); // Step 5: Test that the form can be submitted const email = generateRandomEmail('shortcode-signup-test'); diff --git a/tests/cypress/e2e/validation/email.test.js b/tests/cypress/e2e/validation/email.test.js index 175da63c..e1cf1e8f 100644 --- a/tests/cypress/e2e/validation/email.test.js +++ b/tests/cypress/e2e/validation/email.test.js @@ -42,7 +42,7 @@ describe('General merge field validation', () => { // Email assertions cy.get('#mc_mv_EMAIL').clear(); // No email cy.submitFormAndVerifyError(); - cy.get('.mc_error_msg').contains('Email Address: This value should not be blank.'); + cy.get('.mc_error_msg').contains('Please enter your email address.'); cy.get('#mc_mv_EMAIL').clear().type('user@'); // Missing domain cy.submitFormAndVerifyError(); @@ -72,10 +72,9 @@ describe('General merge field validation', () => { cy.submitFormAndVerifyError(); cy.get('.mc_error_msg').contains(invalidEmailErrorRegex); - // TODO: Mailchimp accepts this. Is this a bug? - // cy.get('#mc_mv_EMAIL').clear().type('user@example-.com'); // Domain ending with dash - // cy.submitFormAndVerifyError(); - // cy.get('.mc_error_msg').contains(invalidEmailErrorRegex); + cy.get('#mc_mv_EMAIL').clear().type('user@example-.com'); // Domain ending with dash + cy.submitFormAndVerifyError(); + cy.get('.mc_error_msg').contains(invalidEmailErrorRegex); cy.get('#mc_mv_EMAIL').clear().type('"user@example.com'); // Unclosed quoted string cy.submitFormAndVerifyError(); diff --git a/tests/cypress/e2e/validation/us-phone.test.js b/tests/cypress/e2e/validation/us-phone.test.js index a523a7fc..36cf3b80 100644 --- a/tests/cypress/e2e/validation/us-phone.test.js +++ b/tests/cypress/e2e/validation/us-phone.test.js @@ -2,32 +2,13 @@ import { generateRandomEmail } from '../../support/functions/utility'; /** - * Test Suite for Multi-Input Phone Number Validation - * Handles both JavaScript-enabled and disabled scenarios for length and format validation. + * Test for Phone Number Validation */ -// TODO: BUG: Skipping for now because when a US phone number is selected in the Mailchimp account, but -// not present on the webform there will always be a fatal error. There is a fix pending for 1.7.0. -// TODO: Skipping for now because the Mailchimp API does not allow changing the format for a phone merge -// field to the US style -describe.skip('US Multi-Input Phone Number Validation', () => { +describe('Phone Number Validation', () => { let blockPostPostURL; - const validPhones = [ - { area: '123', detail1: '456', detail2: '7890' }, - { area: '987', detail1: '654', detail2: '3210' }, - ]; - const invalidPhones = [ - { area: '123', detail1: '456', detail2: '78a0' }, - { area: '123', detail1: '45!', detail2: '7890' }, - ]; - const tooShortPhones = [ - { area: '12', detail1: '456', detail2: '789' }, - { area: '', detail1: '45', detail2: '7890' }, - ]; - const tooLongPhones = [ - { area: '1234', detail1: '567', detail2: '890' }, - { area: '123', detail1: '4567', detail2: '8901' }, - ]; + const validPhones = ['1234567890', '+1 (234) 567-890']; + const invalidPhones = ['12345678a0', '12345!7890']; before(() => { cy.login(); @@ -37,31 +18,29 @@ describe.skip('US Multi-Input Phone Number Validation', () => { ({ blockPostPostURL } = urls); }); - // cy.getListId('10up').then((listId) => { - // cy.updateMergeFieldByTag(listId, 'PHONE', { - // required: true, - // options: { phone_format: 'US' }, - // }).then(() => { - // cy.selectList('10up'); - // }); - // }); + cy.getListId('10up').then((listId) => { + cy.updateMergeFieldByTag(listId, 'PHONE', { + required: true, + options: { phone_format: 'US' }, + }).then(() => { + cy.selectList('10up'); + }); + }); }); after(() => { - // cy.getListId('10up').then((listId) => { - // cy.updateMergeFieldByTag(listId, 'PHONE', { - // required: false, - // options: { phone_format: 'none' }, - // }).then(() => { - // cy.selectList('10up'); - // }); - // }); + cy.getListId('10up').then((listId) => { + cy.updateMergeFieldByTag(listId, 'PHONE', { + required: false, + options: { phone_format: 'none' }, + }).then(() => { + cy.selectList('10up'); + }); + }); }); function fillPhoneInputs(phone) { - cy.get('#mc_mv_PHONE-area').clear().type(phone.area); - cy.get('#mc_mv_PHONE-detail1').clear().type(phone.detail1); - cy.get('#mc_mv_PHONE-detail2').clear().type(phone.detail2); + cy.get('#mc_mv_PHONE').clear().type(phone); } it('Valid phone numbers', () => { @@ -85,28 +64,10 @@ describe.skip('US Multi-Input Phone Number Validation', () => { const email = generateRandomEmail('invalidphone'); cy.get('#mc_mv_EMAIL').type(email); fillPhoneInputs(phone); - cy.submitFormAndVerifyError(); - cy.get('.mc_error_msg').contains('must consist of only numbers'); - }); - }); - - it('Phone length validation', () => { - cy.visit(blockPostPostURL); - - tooShortPhones.forEach((phone) => { - const email = generateRandomEmail('shortphone'); - cy.get('#mc_mv_EMAIL').type(email); - fillPhoneInputs(phone); - cy.submitFormAndVerifyError(); - cy.get('.mc_error_msg').contains('Phone number is too short'); - }); - - tooLongPhones.forEach((phone) => { - const email = generateRandomEmail('longphone'); - cy.get('#mc_mv_EMAIL').type(email); - fillPhoneInputs(phone); - cy.submitFormAndVerifyError(); - cy.get('.mc_error_msg').contains('Phone number is too long'); + cy.get('#mc_signup_submit').click(); + cy.get('#mc_mv_PHONE:invalid') + .invoke('prop', 'validationMessage') + .should('equal', 'Please enter a valid phone number.'); }); }); }); diff --git a/tests/cypress/e2e/validation/validate-required-fields.test.js b/tests/cypress/e2e/validation/validate-required-fields.test.js index 9bbff306..f9e79c14 100644 --- a/tests/cypress/e2e/validation/validate-required-fields.test.js +++ b/tests/cypress/e2e/validation/validate-required-fields.test.js @@ -7,21 +7,29 @@ describe('Validate required fields', () => { // (almost) the same in the WP admin as on the FE const requiredFields = [ - { selector: '#mc_mv_FNAME', errorMessage: 'First Name:', input: 'Test' }, - { selector: '#mc_mv_LNAME', errorMessage: 'Last Name:', input: 'User' }, + { selector: '#mc_mv_FNAME', errorMessage: 'You must fill in First Name', input: 'Test' }, + { selector: '#mc_mv_LNAME', errorMessage: 'You must fill in Last Name', input: 'User' }, { selector: '#mc_mv_ADDRESS-addr1', errorMessage: 'Address:', input: '123 Fake St.' }, // Address has sub fields on the FE form { selector: '#mc_mv_ADDRESS-city', errorMessage: 'Address:', input: 'Nashville' }, // Address has sub fields on the FE form { selector: '#mc_mv_ADDRESS-state', errorMessage: 'Address:', input: 'TN' }, // Address has sub fields on the FE form { selector: '#mc_mv_ADDRESS-zip', errorMessage: 'Address:', input: '12345' }, // Address has sub fields on the FE form - { selector: '#mc_mv_BIRTHDAY', errorMessage: 'Birthday:', input: '01/10' }, - { selector: '#mc_mv_COMPANY', errorMessage: 'Company:', input: '10up' }, - { selector: '#mc_mv_PHONE', errorMessage: 'Phone Number:', input: '555-555-5555' }, - { selector: '#mc_mv_MMERGE8', errorMessage: 'Date:', input: '01/01/2030' }, - { selector: '#mc_mv_MMERGE9', errorMessage: 'Zip Code:', input: '12345' }, - { selector: '#mc_mv_MMERGE10', errorMessage: 'Website:', input: 'https://10up.com' }, + { selector: '#mc_mv_BIRTHDAY', errorMessage: 'You must fill in Birthday', input: '01/10' }, + { selector: '#mc_mv_COMPANY', errorMessage: 'You must fill in Company', input: '10up' }, + { + selector: '#mc_mv_PHONE', + errorMessage: 'You must fill in Phone Number.', + input: '555-555-5555', + }, + { selector: '#mc_mv_MMERGE8', errorMessage: 'You must fill in Date.', input: '01/01/2030' }, + { selector: '#mc_mv_MMERGE9', errorMessage: 'You must fill in Zip Code.', input: '12345' }, + { + selector: '#mc_mv_MMERGE10', + errorMessage: 'You must fill in Website.', + input: 'https://10up.com', + }, { selector: '#mc_mv_MMERGE11', - errorMessage: 'Image:', + errorMessage: 'You must fill in Image.', input: 'https://10up.com/wp-content/themes/10up-sept2016/assets/img/icon-strategy.png', }, ]; @@ -86,20 +94,11 @@ describe('Validate required fields', () => { cy.toggleMergeFields('uncheck'); }); - // TODO: Validation errors clear the entire form. We should fix this. - // We could also significantly reduce the time this test takes by fixing this bug. function fillOutAllFields() { cy.get('#mc_mv_EMAIL').clear().type(email); // Email is always required requiredFields.forEach((field) => { - if (field.selector === '#mc_mv_PHONE') { - const phone = field.input.split('-'); - cy.get('#mc_mv_PHONE-area').clear().type(phone[0]); - cy.get('#mc_mv_PHONE-detail1').clear().type(phone[1]); - cy.get('#mc_mv_PHONE-detail2').clear().type(phone[2]); - } else { - cy.get(field.selector).clear().type(field.input); - } + cy.get(field.selector).clear().type(field.input); cy.get('body').click(0, 0); // Click outside the field to clear the datepicker modal }); @@ -114,7 +113,6 @@ describe('Validate required fields', () => { }); } - // TODO: Test just takes too long to run it('ensures that a required field can not be empty', () => { cy.visit(blockPostPostURL); @@ -126,14 +124,7 @@ describe('Validate required fields', () => { // Test validation for each required field requiredFields.forEach((field) => { - // Submit the form without input to trigger validation - if (field.selector === '#mc_mv_PHONE') { - cy.get('#mc_mv_PHONE-area').clear(); - cy.get('#mc_mv_PHONE-detail1').clear(); - cy.get('#mc_mv_PHONE-detail2').clear(); - } else { - cy.get(field.selector).clear(); // Ensure field is empty - } + cy.get(field.selector).clear(); // Ensure field is empty cy.get('body').click(0, 0); // Click outside the field to clear the datepicker modal cy.get('#mc_signup_submit').click(); @@ -142,14 +133,7 @@ describe('Validate required fields', () => { cy.get('.mc_error_msg').should('include.text', field.errorMessage); // Fill in the field - if (field.selector === '#mc_mv_PHONE') { - const phone = field.input.split('-'); - cy.get('#mc_mv_PHONE-area').clear().type(phone[0]); - cy.get('#mc_mv_PHONE-detail1').clear().type(phone[1]); - cy.get('#mc_mv_PHONE-detail2').clear().type(phone[2]); - } else { - cy.get(field.selector).type(field.input); - } + cy.get(field.selector).type(field.input); cy.get('body').click(0, 0); // Click outside the field to clear the datepicker modal }); });