From 2c88d1dbdf27193c139e7465cc558d3cfd955806 Mon Sep 17 00:00:00 2001 From: Lari Taskula Date: Tue, 4 Apr 2017 14:00:31 +0000 Subject: [PATCH] Bug 14620: Contact information validations This patch adds a phone number validation by regex and centralizes different validation methods into Koha::Validation class. Introduces a new system preference, ValidatePhoneNumber, that takes a regular expression and uses it to validate phone numbers both client and server side. Unit tests to test: 1. prove t/db_dependent/Koha/Validation.t To test: 1. Apply the patches and run updatedatabase.pl to install the new system preference 2. Set system preference ValidatePhoneNumber to any regex you like (there is an example in the description of the preference) 3. Navigate to edit user contact informations in Staff client and OPAC. 4. Insert invalid email (e.g. "invalid") and invalid phone number ("+123invalid") and send the form. 5. Confirm that form will not be submitted and errors will be given. 6. Disable JavaScript and test that these errors will also be provided by the server. Sponsored-by: Koha-Suomi Oy --- Koha/Validation.pm | 80 +++++++++++++++++++ ..._14620-Contact-information-validation.perl | 7 ++ installer/data/mysql/sysprefs.sql | 1 + .../en/modules/admin/preferences/patrons.pref | 9 +++ .../prog/en/modules/members/memberentrygen.tt | 24 ++++++ koha-tmpl/intranet-tmpl/prog/js/members.js | 25 ++++++ .../bootstrap/en/modules/opac-memberentry.tt | 37 +++++++++ .../bootstrap/en/modules/opac-messaging.tt | 44 ++++++++++ members/memberentry.pl | 32 ++++---- opac/opac-memberentry.pl | 21 ++++- opac/opac-messaging.pl | 13 ++- t/db_dependent/Koha/Validation.t | 76 ++++++++++++++++++ 12 files changed, 349 insertions(+), 20 deletions(-) create mode 100644 Koha/Validation.pm create mode 100644 installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl create mode 100644 t/db_dependent/Koha/Validation.t diff --git a/Koha/Validation.pm b/Koha/Validation.pm new file mode 100644 index 0000000000..94006d88bd --- /dev/null +++ b/Koha/Validation.pm @@ -0,0 +1,80 @@ +package Koha::Validation; + +# Copyright 2017 Koha-Suomi Oy +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use C4::Context; +use Email::Valid; + +=head1 NAME + +Koha::Validation - validates inputs + +=head1 SYNOPSIS + + use Koha::Validation + +=head1 DESCRIPTION + +This module lets you validate given inputs. + +=head2 METHODS + +=head3 email + +Koha::Validation::email("email@address.com"); + +Validates given email. + +returns: 1 if the given email is valid (or empty), 0 otherwise. + +=cut + +sub email { + my $address = shift; + + return 1 unless $address; + return 0 if $address =~ /(^(\s))|((\s)$)/; + + return (not defined Email::Valid->address($address)) ? 0:1; +} + +=head3 phone + +Koha::Validation::validate_phonenumber(123456789); + +Validates given phone number. + +returns: 1 if the given phone number is valid (or empty), 0 otherwise. + +=cut + +sub phone { + my $phonenumber = shift; + + return 1 unless $phonenumber; + return 0 if $phonenumber =~ /(^(\s))|((\s)$)/; + + my $regex = C4::Context->preference("ValidatePhoneNumber"); + $regex = qr/$regex/; + + return ($phonenumber !~ /$regex/) ? 0:1; +} + +1; diff --git a/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl b/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl new file mode 100644 index 0000000000..d816b0ca80 --- /dev/null +++ b/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl @@ -0,0 +1,7 @@ +$DBversion = 'XXX'; # will be replaced by the RM +if( CheckVersion( $DBversion ) ) { + $dbh->do("INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('ValidatePhoneNumber','','','Regex for validation of patron phone numbers.','Textarea')"); + + SetVersion( $DBversion ); + print "Upgrade to $DBversion done (Bug 14620 - description)\n"; +} diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index f1ace4b088..79b3f241e1 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -663,6 +663,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('UseQueryParser','0',NULL,'If enabled, try to use QueryParser for queries.','YesNo'), ('UseTransportCostMatrix','0','','Use Transport Cost Matrix when filling holds','YesNo'), ('UseWYSIWYGinSystemPreferences','0','','Show WYSIWYG editor when editing certain HTML system preferences.','YesNo'), +('ValidatePhoneNumber','','','Regex for validation of patron phone numbers.','Textarea'), ('viewISBD','1','','Allow display of ISBD view of bibiographic records','YesNo'), ('viewLabeledMARC','0','','Allow display of labeled MARC view of bibiographic records','YesNo'), ('viewMARC','1','','Allow display of MARC view of bibiographic records','YesNo'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref index 14f1ef910c..da14441786 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref @@ -257,3 +257,12 @@ Patrons: - days and remove anonymized patron accounts after - pref: PatronRemovalDelay - "days.
IMPORTANT: No action is performed when these delays are empty (no text). But a zero value ('0') is interpreted as no delay (do it now)! The actions are performed by the cleanup database cron job." + - + - Use the following regex / + - pref: ValidatePhoneNumber + type: textarea + class: code + - / to validate patrons' phone numbers. + - Example ^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$ + - (Source of example RegExLib.com) + - Leave blank to accept any phone number. diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt index 19c4b5f3c6..6f5287ae50 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt @@ -127,6 +127,18 @@ [% END %] [% IF ERROR_bad_email_alternative %]
  • The alternative email is invalid.
  • + [% END %] + [% IF ERROR_bad_phone %] +
  • The primary phone is invalid.
  • + [% END %] + [% IF ERROR_bad_phone_secondary %] +
  • The secondary phone is invalid.
  • + [% END %] + [% IF ERROR_bad_phone_alternative %] +
  • The alternative phone is invalid.
  • + [% END %] + [% IF ERROR_bad_smsnumber %] +
  • The SMS number is invalid.
  • [% END %] @@ -1317,6 +1329,18 @@ }); }); + var MSG_INCORRECT_PHONE = _("Please enter a valid phone number."); + $.validator.addMethod('phone', function(value) { + value = value.trim(); + if (!value.trim()) { + return 1; + } + else { + return (value.match(/[% ValidatePhoneNumber %]/)); + } + }, + MSG_INCORRECT_PHONE); + var MSG_SEPARATOR = _("Separator must be / in field %s"); var MSG_INCORRECT_DAY = _("Invalid day entered in field %s"); var MSG_INCORRECT_MONTH = _("Invalid month entered in field %s"); diff --git a/koha-tmpl/intranet-tmpl/prog/js/members.js b/koha-tmpl/intranet-tmpl/prog/js/members.js index 3579dbeed5..b7a2e98548 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/members.js +++ b/koha-tmpl/intranet-tmpl/prog/js/members.js @@ -343,6 +343,18 @@ $(document).ready(function(){ password2: { password_match: true }, + phone: { + phone: true + }, + phonepro: { + phone: true + }, + B_phone: { + phone: true + }, + mobile: { + phone: true + }, SMSnumber: { phone: true, } @@ -353,10 +365,23 @@ $(document).ready(function(){ return false; else form.beenSubmitted = true; + $("#email, #emailpro, #B_email").each(function(){ + $(this).val($.trim($(this).val())); + }); + $("#phone, #phonepro, #B_phone, #SMSnumber").each(function(){ + $(this).val($.trim($(this).val())); + }); form.submit(); } }); + $("#email, #emailpro, #B_email").each(function(){ + $(this).val($.trim($(this).val())); + }); + $("#phone, #phonepro, #B_phone, #SMSnumber").each(function(){ + $(this).val($.trim($(this).val())); + }); + var mrform = $("#manual_restriction_form"); var mrlink = $("#add_manual_restriction"); mrform.hide(); diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt index 8761cc88ae..b2ea980710 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt @@ -80,6 +80,10 @@ [% IF field == "email" %]
  • Contact information: primary email address
  • [% END %] [% IF field == "emailpro" %]
  • Contact information: secondary email address
  • [% END %] [% IF field == "B_email" %]
  • Alternate address information: email address
  • [% END %] + [% IF field == "phone" %]
  • Contact information: primary phone
  • [% END %] + [% IF field == "phonepro" %]
  • Contact information: secondary phone
  • [% END %] + [% IF field == "mobile" %]
  • Contact information: other phone
  • [% END %] + [% IF field == "B_phone" %]
  • Alternate address information: phone
  • [% END %] [% IF field == "password_match" %]
  • Passwords do not match! password
  • [% END %] [% IF field == "password_too_short" %]
  • Password must be at least [% minPasswordLength | html %] characters long.
  • @@ -999,6 +1003,17 @@ $('label.required').removeClass('required'); [% END %] + var MSG_INCORRECT_PHONE = _("Please enter a valid phone number."); + $.validator.addMethod('phone', function(value) { + if (!value.trim()) { + return 1; + } + else { + return (value.match(/[% ValidatePhoneNumber %]/)); + } + }, + MSG_INCORRECT_PHONE); + $("#memberentry-form").validate({ rules: { borrower_email: { @@ -1010,6 +1025,18 @@ borrower_B_email: { email: true }, + borrower_mobile: { + phone: true + }, + borrower_phone: { + phone: true + }, + borrower_phonepro: { + phone: true + }, + borrower_B_phone: { + phone: true + }, borrower_password: { [% IF mandatory.defined('password') %] required: true, @@ -1033,6 +1060,12 @@ } else { form.beenSubmitted = true; + $("#borrower_email, #borrower_emailpro, #borrower_B_email").each(function(){ + $(this).val($.trim($(this).val())); + }); + $("#borrower_phone, #borrower_phonepro, #borrower_B_phone").each(function(){ + $(this).val($.trim($(this).val())); + }); form.submit(); } }, @@ -1047,6 +1080,10 @@ } }); + $("#borrower_email, #borrower_emailpro, #borrower_B_email, #borrower_phone, #borrower_phonepro, #borrower_B_phone").on("change", function(){ + $(this).val($.trim($(this).val())); + }); + [% IF patron.guarantor_relationships && !Koha.Preference('OPACPrivacy') %] [% IF Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt index d33c7b7b88..50d8799de3 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt @@ -28,6 +28,9 @@ [% IF ( settings_updated ) %]

    Settings updated

    [% END %] + [% IF ( invalid_smsnumber ) %] +

    Invalid SMS number

    + [% END %]
    @@ -182,6 +185,46 @@ } }); $("#info_digests").tooltip(); + + var MSG_INCORRECT_PHONE = _("Please enter a valid phone number."); + $.validator.addMethod('phone', function(value) { + if (!value.trim()) { + return 1; + } + else { + return (value.match(/[% ValidatePhoneNumber %]/)); + } + }, + MSG_INCORRECT_PHONE); + + $("form[name='opacmessaging']").validate({ + rules: { + SMSnumber: { + phone: true + } + }, + submitHandler: function(form) { + $("body, form input[type='submit'], form button[type='submit'], form a").addClass('waiting'); + if (form.beenSubmitted) { + return false; + } + else { + form.beenSubmitted = true; + $("#SMSnumber").each(function(){ + $(this).val($.trim($(this).val())); + }); + form.submit(); + } + }, + errorPlacement: function(error, element) { + error.insertAfter(element.closest("li")).wrap('
  • '); + error.addClass('alert-error'); + error.width("auto"); + } + }); + $("#SMSnumber").on("change", function(){ + $(this).val($.trim($(this).val())); + }); }); function normalizeSMS(value){ @@ -207,4 +250,5 @@ sms_input.addEventListener('paste', function(event) { //]]> + [% END %] diff --git a/members/memberentry.pl b/members/memberentry.pl index fa5cbe427e..01dd026ebe 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -47,8 +47,8 @@ use Koha::Patron::Categories; use Koha::Patron::HouseboundRole; use Koha::Patron::HouseboundRoles; use Koha::Token; -use Email::Valid; use Koha::SMS::Providers; +use Koha::Validation; use vars qw($debug); @@ -371,19 +371,13 @@ if ($op eq 'save' || $op eq 'insert'){ } # Validate emails - my $emailprimary = $input->param('email'); - my $emailsecondary = $input->param('emailpro'); - my $emailalt = $input->param('B_email'); - - if ($emailprimary) { - push (@errors, "ERROR_bad_email") if (!Email::Valid->address($emailprimary)); - } - if ($emailsecondary) { - push (@errors, "ERROR_bad_email_secondary") if (!Email::Valid->address($emailsecondary)); - } - if ($emailalt) { - push (@errors, "ERROR_bad_email_alternative") if (!Email::Valid->address($emailalt)); - } + push (@errors, "ERROR_bad_email") if ($input->param('email') && !Koha::Validation::email($input->param('email'))); + push (@errors, "ERROR_bad_email_secondary") if ($input->param('emailpro') && !Koha::Validation::email($input->param('emailpro'))); + push (@errors, "ERROR_bad_email_alternative") if ($input->param('B_email') && !Koha::Validation::email($input->param('B_email'))); + # Validate phone numbers + push (@errors, "ERROR_bad_phone") if ($input->param('phone') && !Koha::Validation::phone($input->param('phone'))); + push (@errors, "ERROR_bad_phone_secondary") if ($input->param('phonepro') && !Koha::Validation::phone($input->param('phonepro'))); + push (@errors, "ERROR_bad_phone_alternative") if ($input->param('B_phone') && !Koha::Validation::phone($input->param('B_phone'))); if (C4::Context->preference('ExtendedPatronAttributes')) { $extended_patron_attributes = parse_extended_patron_attributes($input); @@ -411,7 +405,11 @@ if ( ($op eq 'modify' || $op eq 'insert' || $op eq 'save'|| $op eq 'duplicate') # BZ 14683: Do not mixup mobile [read: other phone] with smsalertnumber my $sms = $input->param('SMSnumber'); if ( defined $sms ) { - $newdata{smsalertnumber} = $sms; + if (Koha::Validation::phone($sms)){ + $newdata{smsalertnumber} = $sms; + } else { + push (@errors, "ERROR_bad_smsnumber"); + } } ### Error checks should happen before this line. @@ -746,6 +744,10 @@ if (C4::Context->preference('ExtendedPatronAttributes')) { patron_attributes_form($template, $borrowernumber, $op); } +$template->param( + ValidatePhoneNumber => C4::Context->preference('ValidatePhoneNumber') || '.*', +); + if (C4::Context->preference('EnhancedMessagingPreferences')) { if ($op eq 'add') { C4::Form::MessagingPreferences::set_form_values({ categorycode => $categorycode }, $template); diff --git a/opac/opac-memberentry.pl b/opac/opac-memberentry.pl index 62cdd0d205..1dc71146a3 100755 --- a/opac/opac-memberentry.pl +++ b/opac/opac-memberentry.pl @@ -34,7 +34,6 @@ use Koha::Patron::Consent; use Koha::Patron::Modification; use Koha::Patron::Modifications; use C4::Scrubber; -use Email::Valid; use Koha::DateUtils; use Koha::Libraries; use Koha::Patron::Attribute::Types; @@ -44,6 +43,7 @@ use Koha::Patron::Modification; use Koha::Patron::Modifications; use Koha::Patrons; use Koha::Token; +use Koha::Validation; my $cgi = new CGI; my $dbh = C4::Context->dbh; @@ -93,6 +93,7 @@ $template->param( mandatory => $mandatory, libraries => \@libraries, OPACPatronDetails => C4::Context->preference('OPACPatronDetails'), + ValidatePhoneNumber => C4::Context->preference('ValidatePhoneNumber') || '.*', ); my $attributes = ParsePatronAttributes($borrowernumber,$cgi); @@ -408,7 +409,7 @@ sub CheckForInvalidFields { my $borrower = shift; my @invalidFields; if ($borrower->{'email'}) { - unless ( Email::Valid->address($borrower->{'email'}) ) { + unless ( Koha::Validation::email($borrower->{'email'}) ) { push(@invalidFields, "email"); } elsif ( C4::Context->preference("PatronSelfRegistrationEmailMustBeUnique") ) { my $patrons_with_same_email = Koha::Patrons->search( # FIXME Should be search_limited? @@ -428,10 +429,22 @@ sub CheckForInvalidFields { } } if ($borrower->{'emailpro'}) { - push(@invalidFields, "emailpro") if (!Email::Valid->address($borrower->{'emailpro'})); + push(@invalidFields, "emailpro") if (!Koha::Validation::email($borrower->{'emailpro'})); } if ($borrower->{'B_email'}) { - push(@invalidFields, "B_email") if (!Email::Valid->address($borrower->{'B_email'})); + push(@invalidFields, "B_email") if (!Koha::Validation::email($borrower->{'B_email'})); + } + if ($borrower->{'mobile'}) { + push(@invalidFields, "mobile") if (!Koha::Validation::phone($borrower->{'mobile'})); + } + if ($borrower->{'phone'}) { + push(@invalidFields, "phone") if (!Koha::Validation::phone($borrower->{'phone'})); + } + if ($borrower->{'phonepro'}) { + push(@invalidFields, "phonepro") if (!Koha::Validation::phone($borrower->{'phonepro'})); + } + if ($borrower->{'B_phone'}) { + push(@invalidFields, "B_phone") if (!Koha::Validation::phone($borrower->{'B_phone'})); } if ( defined $borrower->{'password'} and $borrower->{'password'} ne $borrower->{'password2'} ) diff --git a/opac/opac-messaging.pl b/opac/opac-messaging.pl index 8a6996ae18..0b37751750 100755 --- a/opac/opac-messaging.pl +++ b/opac/opac-messaging.pl @@ -31,6 +31,7 @@ use C4::Members::Messaging; use C4::Form::MessagingPreferences; use Koha::Patrons; use Koha::SMS::Providers; +use Koha::Validation; my $query = CGI->new(); @@ -54,10 +55,20 @@ my $patron = Koha::Patrons->find( $borrowernumber ); # FIXME and if borrowernumb my $messaging_options = C4::Members::Messaging::GetMessagingOptions(); +my $validate_phone = C4::Context->preference('ValidatePhoneNumber'); + +$template->param( + ValidatePhoneNumber => $validate_phone || '.*', +); + if ( defined $query->param('modify') && $query->param('modify') eq 'yes' ) { my $sms = $query->param('SMSnumber'); my $sms_provider_id = $query->param('sms_provider_id'); - if ( defined $sms && ( $patron->smsalertnumber // '' ) ne $sms + + my $valid_sms = Koha::Validation::phone($sms); + $template->param( invalid_smsnumber => 1 ) unless $valid_sms; + + if ( defined $sms && $valid_sms && ( $patron->smsalertnumber // '' ) ne $sms or ( $patron->sms_provider_id // '' ) ne $sms_provider_id ) { $patron->set({ smsalertnumber => $sms, diff --git a/t/db_dependent/Koha/Validation.t b/t/db_dependent/Koha/Validation.t new file mode 100644 index 0000000000..481ea8583d --- /dev/null +++ b/t/db_dependent/Koha/Validation.t @@ -0,0 +1,76 @@ +#!/usr/bin/perl +# +# Copyright 2017 Koha-Suomi Oy +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Test::More tests => 3; + +use t::lib::Mocks; + +BEGIN { + use_ok('Koha::Validation'); +} + +subtest 'email() tests' => sub { + plan tests => 2; + + is(Koha::Validation::email('test'), 0, "'test' is invalid e-mail address'"); + is(Koha::Validation::email('test@example.com'), 1, '\'test@example.com\' is ' + .'valid e-mail address'); +}; + +subtest 'phone() tests' => sub { + plan tests => 3; + + t::lib::Mocks::mock_preference('ValidatePhoneNumber', ''); + + is(Koha::Validation::phone('test'), 1, 'Phone number validation is switched ' + .'off, so \'test\' is a valid phone number'); + + # An example: Finnish Phone number validation regex + subtest 'Finnish phone number validation regex' => sub { + t::lib::Mocks::mock_preference('ValidatePhoneNumber', + '^((90[0-9]{3})?0|\+358\s?)(?!(100|20(0|2(0|[2-3])|9[8-9])|300|600|70' + .'0|708|75(00[0-3]|(1|2)\d{2}|30[0-2]|32[0-2]|75[0-2]|98[0-2])))(4|50|' + .'10[1-9]|20(1|2(1|[4-9])|[3-9])|29|30[1-9]|71|73|75(00[3-9]|30[3-9]|3' + .'2[3-9]|53[3-9]|83[3-9])|2|3|5|6|8|9|1[3-9])\s?(\d\s?){4,19}\d$' + ); + + is(Koha::Validation::phone('1234'), 0, '1234 is invalid phone number.'); + is(Koha::Validation::phone('+358501234567'), 1, '+358501234567 is valid ' + .'phone number.'); + is(Koha::Validation::phone('+1-202-555-0198'), 0, '+1-202-555-0198 is ' + .'invalid phone number.'); + }; + + subtest 'International phone number validation regex' => sub { + t::lib::Mocks::mock_preference('ValidatePhoneNumber', + '^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]' + .'{1,12}){1,2}$' + ); + + is(Koha::Validation::phone('nope'), 0, 'nope is invalid phone number.'); + is(Koha::Validation::phone('1234'), 1, '1234 is valid phone number.'); + is(Koha::Validation::phone('+358501234567'), 1, '+358501234567 is valid ' + .'phone number.'); + is(Koha::Validation::phone('+1-202-555-0198'), 1, '+1-202-555-0198 is ' + .'valid phone number.'); + }; + +}; -- 2.17.1