From 8e3b3061d381489a7add2e75b08132eef5906906 Mon Sep 17 00:00:00 2001 From: ahumulescu <65591728+ahumulescu@users.noreply.github.com> Date: Wed, 6 Jan 2021 17:14:01 +0200 Subject: [PATCH] [REALEX] Improvements, validations and formatted phone number (#348) [REALEX] Improvements, validations and formatted phone number Co-authored-by: Tomasz Jozwik Co-authored-by: Adina Petrovici --- .../integrations/realex_offsite.rb | 389 +++++++++++++++++- .../realex_offsite_helper_test.rb | 173 +++++++- 2 files changed, 539 insertions(+), 23 deletions(-) diff --git a/lib/offsite_payments/integrations/realex_offsite.rb b/lib/offsite_payments/integrations/realex_offsite.rb index 73bf0a03d..5574a94a4 100644 --- a/lib/offsite_payments/integrations/realex_offsite.rb +++ b/lib/offsite_payments/integrations/realex_offsite.rb @@ -141,6 +141,256 @@ module Common 'WY' => 'Wyoming' } + COUNTRY_PHONE_NUMBERS = { + 'AD' => { :code => '376', :length => [6, 7, 8, 9] }, + 'AE' => { :code => '971', :length => [7, 8, 9] }, + 'AF' => { :code => '93', :length => [8, 9] }, + 'AG' => { :code => '1', :length => [10] }, + 'AI' => { :code => '1', :length => [10] }, + 'AL' => { :code => '355', :length => [7, 8, 9] }, + 'AM' => { :code => '374', :length => [8] }, + 'AO' => { :code => '244', :length => [9] }, + 'AQ' => { :code => '672', :length => [] }, + 'AR' => { :code => '54', :length => [8, 9] }, + 'AS' => { :code => '1', :length => [10] }, + 'AT' => { :code => '43', :length => [7, 8, 9, 10, 11, 12, 13] }, + 'AU' => { :code => '61', :length => [9] }, + 'AW' => { :code => '297', :length => [7] }, + 'AX' => { :code => '358', :length => [] }, + 'AZ' => { :code => '994', :length => [8, 9] }, + 'BA' => { :code => '387', :length => [8] }, + 'BB' => { :code => '1', :length => [10] }, + 'BD' => { :code => '880', :length => [10] }, + 'BE' => { :code => '32', :length => [8, 9] }, + 'BF' => { :code => '226', :length => [8] }, + 'BG' => { :code => '359', :length => [8, 9, 10] }, + 'BH' => { :code => '973', :length => [8] }, + 'BI' => { :code => '257', :length => [8] }, + 'BJ' => { :code => '229', :length => [8] }, + 'BL' => { :code => '590', :length => [] }, + 'BM' => { :code => '1', :length => [10] }, + 'BN' => { :code => '673', :length => [7] }, + 'BO' => { :code => '591', :length => [8] }, + 'BQ' => { :code => '599', :length => [7] }, + 'BR' => { :code => '55', :length => [10, 11] }, + 'BS' => { :code => '1', :length => [10] }, + 'BT' => { :code => '975', :length => [7, 8] }, + 'BV' => { :code => '47', :length => [] }, + 'BW' => { :code => '267', :length => [7] }, + 'BY' => { :code => '375', :length => [9] }, + 'BZ' => { :code => '501', :length => [7] }, + 'CA' => { :code => '1', :length => [10] }, + 'CC' => { :code => '61', :length => [9] }, + 'CD' => { :code => '243', :length => [8] }, + 'CF' => { :code => '236', :length => [8] }, + 'CG' => { :code => '242', :length => [7] }, + 'CH' => { :code => '41', :length => [9, 10] }, + 'CI' => { :code => '225', :length => [8] }, + 'CK' => { :code => '682', :length => [5] }, + 'CL' => { :code => '56', :length => [8, 9] }, + 'CM' => { :code => '237', :length => [8] }, + 'CN' => { :code => '86', :length => [7, 8, 9, 10, 11] }, + 'CO' => { :code => '57', :length => [9, 10] }, + 'CR' => { :code => '506', :length => [8] }, + 'CU' => { :code => '53', :length => [8] }, + 'CV' => { :code => '238', :length => [7] }, + 'CW' => { :code => '599', :length => [7] }, + 'CX' => { :code => '61', :length => [] }, + 'CY' => { :code => '357', :length => [8] }, + 'CZ' => { :code => '420', :length => [9] }, + 'DE' => { :code => '49', :length => [6, 7, 8, 9, 10, 11] }, + 'DJ' => { :code => '253', :length => [6] }, + 'DK' => { :code => '45', :length => [8] }, + 'DM' => { :code => '1', :length => [10] }, + 'DO' => { :code => '1', :length => [10] }, + 'DZ' => { :code => '213', :length => [8] }, + 'EC' => { :code => '593', :length => [8, 9] }, + 'EE' => { :code => '372', :length => [7, 8] }, + 'EG' => { :code => '20', :length => [9] }, + 'EH' => { :code => '212', :length => [] }, + 'ER' => { :code => '291', :length => [7] }, + 'ES' => { :code => '34', :length => [9] }, + 'ET' => { :code => '251', :length => [9] }, + 'FI' => { :code => '358', :length => [9] }, + 'FJ' => { :code => '679', :length => [7] }, + 'FK' => { :code => '500', :length => [5] }, + 'FM' => { :code => '691', :length => [7] }, + 'FO' => { :code => '298', :length => [6] }, + 'FR' => { :code => '33', :length => [9, 10] }, + 'GA' => { :code => '241', :length => [6, 7, 8] }, + 'GB' => { :code => '44', :length => [10, 11] }, + 'GD' => { :code => '1', :length => [10] }, + 'GE' => { :code => '995', :length => [9] }, + 'GF' => { :code => '594', :length => [10] }, + 'GG' => { :code => '44', :length => [] }, + 'GH' => { :code => '233', :length => [5, 6, 7, 8] }, + 'GI' => { :code => '350', :length => [8] }, + 'GL' => { :code => '299', :length => [6] }, + 'GM' => { :code => '220', :length => [7] }, + 'GN' => { :code => '224', :length => [8] }, + 'GP' => { :code => '590', :length => [10] }, + 'GQ' => { :code => '240', :length => [6] }, + 'GR' => { :code => '30', :length => [10] }, + 'GS' => { :code => '500', :length => [] }, + 'GT' => { :code => '502', :length => [8] }, + 'GU' => { :code => '1', :length => [10] }, + 'GW' => { :code => '245', :length => [7] }, + 'GY' => { :code => '592', :length => [6, 7] }, + 'HK' => { :code => '852', :length => [8] }, + 'HN' => { :code => '504', :length => [7, 8] }, + 'HR' => { :code => '385', :length => [8] }, + 'HT' => { :code => '509', :length => [8] }, + 'HU' => { :code => '36', :length => [8, 9] }, + 'ID' => { :code => '62', :length => [8, 9, 10, 11] }, + 'IE' => { :code => '353', :length => [9] }, + 'IL' => { :code => '972', :length => [7, 8, 9] }, + 'IM' => { :code => '44', :length => [] }, + 'IN' => { :code => '91', :length => [10] }, + 'IO' => { :code => '246', :length => [] }, + 'IQ' => { :code => '964', :length => [8, 9, 10] }, + 'IR' => { :code => '98', :length => [10] }, + 'IS' => { :code => '354', :length => [7, 8, 9] }, + 'IT' => { :code => '39', :length => [9, 11] }, + 'JE' => { :code => '44', :length => [] }, + 'JM' => { :code => '1', :length => [10] }, + 'JO' => { :code => '962', :length => [8, 9] }, + 'JP' => { :code => '81', :length => [9, 10] }, + 'KE' => { :code => '254', :length => [9] }, + 'KG' => { :code => '996', :length => [9] }, + 'KH' => { :code => '855', :length => [8] }, + 'KI' => { :code => '686', :length => [5] }, + 'KM' => { :code => '269', :length => [7] }, + 'KN' => { :code => '1', :length => [10] }, + 'KP' => { :code => '850', :length => [8, 9] }, + 'KR' => { :code => '82', :length => [8, 9] }, + 'KW' => { :code => '965', :length => [7] }, + 'KY' => { :code => '1', :length => [10] }, + 'KZ' => { :code => '7', :length => [10] }, + 'LA' => { :code => '856', :length => [8] }, + 'LB' => { :code => '961', :length => [8] }, + 'LC' => { :code => '1', :length => [10] }, + 'LI' => { :code => '423', :length => [7] }, + 'LK' => { :code => '94', :length => [10] }, + 'LR' => { :code => '231', :length => [6, 7, 8] }, + 'LS' => { :code => '266', :length => [8] }, + 'LT' => { :code => '370', :length => [8] }, + 'LU' => { :code => '352', :length => [9] }, + 'LV' => { :code => '371', :length => [8] }, + 'LY' => { :code => '218', :length => [8, 9] }, + 'MA' => { :code => '212', :length => [8] }, + 'MC' => { :code => '377', :length => [8, 9] }, + 'MD' => { :code => '373', :length => [8] }, + 'ME' => { :code => '382', :length => [8] }, + 'MF' => { :code => '590', :length => [] }, + 'MG' => { :code => '261', :length => [9] }, + 'MH' => { :code => '692', :length => [7] }, + 'MK' => { :code => '389', :length => [7, 8] }, + 'ML' => { :code => '223', :length => [8] }, + 'MM' => { :code => '95', :length => [7, 8] }, + 'MN' => { :code => '976', :length => [7, 8, 9, 10] }, + 'MO' => { :code => '853', :length => [8] }, + 'MP' => { :code => '1', :length => [10] }, + 'MQ' => { :code => '596', :length => [10] }, + 'MR' => { :code => '222', :length => [7] }, + 'MS' => { :code => '1', :length => [10] }, + 'MT' => { :code => '356', :length => [8] }, + 'MU' => { :code => '230', :length => [7] }, + 'MV' => { :code => '960', :length => [7] }, + 'MW' => { :code => '265', :length => [8] }, + 'MX' => { :code => '52', :length => [8, 9, 10] }, + 'MY' => { :code => '60', :length => [9, 10] }, + 'MZ' => { :code => '258', :length => [8, 9] }, + 'NA' => { :code => '264', :length => [6, 7] }, + 'NC' => { :code => '687', :length => [6] }, + 'NE' => { :code => '227', :length => [8] }, + 'NF' => { :code => '672', :length => [6] }, + 'NG' => { :code => '234', :length => [7, 8] }, + 'NI' => { :code => '505', :length => [8] }, + 'NL' => { :code => '31', :length => [9] }, + 'NO' => { :code => '47', :length => [8] }, + 'NP' => { :code => '977', :length => [7, 8] }, + 'NR' => { :code => '674', :length => [7] }, + 'NU' => { :code => '683', :length => [4] }, + 'NZ' => { :code => '64', :length => [8, 9] }, + 'OM' => { :code => '968', :length => [8] }, + 'PA' => { :code => '507', :length => [7] }, + 'PE' => { :code => '51', :length => [8, 9] }, + 'PF' => { :code => '689', :length => [6] }, + 'PG' => { :code => '675', :length => [7] }, + 'PH' => { :code => '63', :length => [8, 9, 10] }, + 'PK' => { :code => '92', :length => [9, 10] }, + 'PL' => { :code => '48', :length => [9] }, + 'PM' => { :code => '508', :length => [6] }, + 'PN' => { :code => '64', :length => [9] }, + 'PR' => { :code => '1', :length => [10] }, + 'PS' => { :code => '970', :length => [8] }, + 'PT' => { :code => '351', :length => [9] }, + 'PW' => { :code => '680', :length => [7] }, + 'PY' => { :code => '595', :length => [9] }, + 'QA' => { :code => '974', :length => [7] }, + 'RE' => { :code => '262', :length => [10] }, + 'RO' => { :code => '40', :length => [9] }, + 'RS' => { :code => '381', :length => [9] }, + 'RU' => { :code => '7', :length => [10] }, + 'RW' => { :code => '250', :length => [8, 9] }, + 'SA' => { :code => '966', :length => [8, 9] }, + 'SB' => { :code => '677', :length => [5] }, + 'SC' => { :code => '248', :length => [6] }, + 'SD' => { :code => '249', :length => [9] }, + 'SE' => { :code => '46', :length => [9] }, + 'SG' => { :code => '65', :length => [8, 9] }, + 'SH' => { :code => '290', :length => [4] }, + 'SI' => { :code => '386', :length => [8] }, + 'SJ' => { :code => '47', :length => [8] }, + 'SK' => { :code => '421', :length => [9] }, + 'SL' => { :code => '232', :length => [8] }, + 'SM' => { :code => '378', :length => [9, 10, 11, 12] }, + 'SN' => { :code => '221', :length => [7] }, + 'SO' => { :code => '252', :length => [7, 8] }, + 'SR' => { :code => '597', :length => [6] }, + 'SS' => { :code => '211', :length => [9] }, + 'ST' => { :code => '239', :length => [6, 7] }, + 'SV' => { :code => '503', :length => [8] }, + 'SX' => { :code => '1', :length => [10] }, + 'SY' => { :code => '963', :length => [7, 8] }, + 'SZ' => { :code => '268', :length => [7] }, + 'TC' => { :code => '1', :length => [10] }, + 'TD' => { :code => '235', :length => [7] }, + 'TF' => { :code => '262', :length => [] }, + 'TG' => { :code => '228', :length => [7] }, + 'TH' => { :code => '66', :length => [9, 10] }, + 'TJ' => { :code => '992', :length => [9] }, + 'TK' => { :code => '690', :length => [4] }, + 'TL' => { :code => '670', :length => [7] }, + 'TM' => { :code => '993', :length => [8] }, + 'TN' => { :code => '216', :length => [8] }, + 'TO' => { :code => '676', :length => [5, 6, 7] }, + 'TR' => { :code => '90', :length => [10] }, + 'TT' => { :code => '1', :length => [10] }, + 'TV' => { :code => '688', :length => [5] }, + 'TW' => { :code => '886', :length => [7, 8] }, + 'TZ' => { :code => '255', :length => [9] }, + 'UA' => { :code => '380', :length => [8, 9] }, + 'UG' => { :code => '256', :length => [9] }, + 'UM' => { :code => '1', :length => [] }, + 'US' => { :code => '1', :length => [10] }, + 'UY' => { :code => '598', :length => [7, 8] }, + 'UZ' => { :code => '998', :length => [9] }, + 'VA' => { :code => '39', :length => [9] }, + 'VC' => { :code => '1', :length => [10] }, + 'VE' => { :code => '58', :length => [10] }, + 'VG' => { :code => '1', :length => [10] }, + 'VI' => { :code => '1', :length => [10] }, + 'VN' => { :code => '84', :length => [7, 8, 9, 10] }, + 'VU' => { :code => '678', :length => [5, 6, 7] }, + 'WF' => { :code => '681', :length => [6] }, + 'WS' => { :code => '685', :length => [6, 7] }, + 'YE' => { :code => '967', :length => [7, 8, 9] }, + 'YT' => { :code => '262', :length => [7] }, + 'ZA' => { :code => '27', :length => [9] }, + 'ZM' => { :code => '260', :length => [9] }, + 'ZW' => { :code => '263', :length => [8, 9, 10, 11] } + } def create_signature(fields, secret) data = fields.join('.') @@ -171,27 +421,65 @@ def extract_digits(value) value.scan(/\d+/).join('') end + # This method is used for generating the "BILLING_CODE" field, + # this field is generated by concatenating the zip field and + # the first line of address with a pipe(|) between them + # if the country is GB, we remove the non-numeric characters def extract_avs_code(params={}) - [extract_digits(params[:zip]), extract_digits(params[:address1])].join('|') + return unless params[:zip] && params[:address1] + code = [params[:zip], params[:address1]] + code = code.collect{|p| extract_digits(p) } if params[:country] == 'GB' + code.reject{|p| p.empty? }.join('|') end def extract_address_match_indicator(value) value ? 'TRUE' : 'FALSE' end + def adjust_phone_number_length(country_calling_code, phone_number) + country_calling_code[0...3] + '|' + phone_number[0...15] + end + # The home phone number provided by the Cardholder. Should be In format: # of 'CountryCallingCode|Number' for example, '1|123456789'. - def format_phone_number(phone_number) + def format_phone_number(phone_number, country_code) return nil if phone_number.nil? - clean_number = phone_number.gsub(/\D/, '') + country_number = COUNTRY_PHONE_NUMBERS[country_code] || { :code => '0', :length => [] } + + # Remove non-digit characters + processed_number = phone_number.gsub(/\D/, '') + return '0|0' if [[], ['0']].include? processed_number.chars.uniq - return phone_number if clean_number.length < 10 + # Allow Italy and Ivory Coast to have leading zero, as they use it as a part of some phone numbers + if ['IT', 'CI'].include?(country_code) && /\A0[1-9]\d*/.match(processed_number) + return adjust_phone_number_length(country_number[:code], processed_number) + end + + return '0|0' if processed_number == country_number[:code] + + # Remove leading zero(s) + processed_number = processed_number.gsub(/\A0*/, '') + + # Check if the potential Singapore calling code is not the local prefix + if country_code == 'SG' && + processed_number.start_with?(country_number[:code]) && + country_number[:length].include?(processed_number.length) + then + return adjust_phone_number_length(country_number[:code], processed_number) + end - country_code = clean_number[0, clean_number.length - 9] - number = clean_number[clean_number.length - 9, clean_number.length] + # Remove country calling code from the processed number and try to fix trivial mistakes + if processed_number.start_with?(country_number[:code]) || + (!(country_number[:length].include?(processed_number.length)) && + country_number[:length].include?(processed_number.length - country_number[:code].length) && + (country_number[:code].chars.sort == processed_number[0...country_number[:code].length].chars.sort)) + then + processed_number = processed_number[country_number[:code].length..-1] + end - "#{country_code}|#{number}" + # Limit returned string to 3 characters + | + 15 characters + adjust_phone_number_length(country_number[:code], processed_number) end def lookup_state_code(country_code, state) @@ -213,6 +501,48 @@ def copy_billing_address add_field("HPP_SHIPPING_#{k.split('HPP_BILLING_')[1]}", v) end end + + # Validations + def get_pattern(key) + case key + when 'HPP_CUSTOMER_EMAIL' then /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,24})*$/ + when 'HPP_CUSTOMER_PHONENUMBER_MOBILE' then /^([0-9 +]){1,3}(\|){0,1}([0-9 +]){1,15}$/ + when 'HPP_BILLING_STREET1', 'HPP_SHIPPING_STREET1', 'HPP_BILLING_STREET2', 'HPP_SHIPPING_STREET2' then /^[\p{L}\p{M}\p{Blank}\p{N}\/\.\-\_\'\,]{1,50}$/ + when 'HPP_BILLING_CITY', 'HPP_SHIPPING_CITY' then /^[\p{L}\p{M}\p{Blank}\p{N}\/\.\-\_\'\,]{1,40}$/ + when 'HPP_BILLING_COUNTRY', 'HPP_SHIPPING_COUNTRY' then /^([0-9])*$/ + when 'HPP_BILLING_POSTALCODE', 'HPP_SHIPPING_POSTALCODE' then /^[a-zA-Z0-9\-\s]{1,16}$/ + when 'HPP_BILLING_STATE', 'HPP_SHIPPING_STATE' then /^([A-Z])*$/ + end + end + + def get_message(key) + case key + when 'HPP_CUSTOMER_EMAIL' then 'Invalid E-mail address.' + when 'HPP_CUSTOMER_PHONENUMBER_MOBILE' then 'Invalid Telephone. The selected payment method only allows numbers, spaces or punctuation (+, |), and no more than 19 characters.' + when 'HPP_BILLING_STREET1', 'HPP_SHIPPING_STREET1', 'HPP_BILLING_STREET2', 'HPP_SHIPPING_STREET2' then 'Invalid Street address. The selected payment method only allows letters, numbers, spaces or punctuation, and no more than 50 characters per line.' + when 'HPP_BILLING_CITY', 'HPP_SHIPPING_CITY' then 'Invalid City. The selected payment method only allows letters, numbers, spaces or punctuation, and no more than 40 characters.' + when 'HPP_BILLING_COUNTRY', 'HPP_SHIPPING_COUNTRY' then 'Invalid Country code.' + when 'HPP_BILLING_POSTALCODE', 'HPP_SHIPPING_POSTALCODE' then 'Invalid Zip/Postal Code. The selected payment method only allows letters, numbers, spaces or punctuation, and no more than 16 characters.' + when 'HPP_BILLING_STATE', 'HPP_SHIPPING_STATE' then 'Invalid State.' + end + end + + def validate(key, value) + pattern = get_pattern(key) + + return value unless pattern.present? + + if value =~pattern + return value + else + raise ArgumentError, get_message(key) + end + end + + def add_field(name, value) + return if name.blank? || value.blank? + @fields[name.to_s] = validate(name.to_s, value.to_s) + end end class Helper < OffsitePayments::Helper @@ -254,32 +584,55 @@ def amount=(amount) def billing_address(params={}) country = params[:country] country_code = lookup_country_code(country, :alpha2) + avs_code = extract_avs_code(params) + params[:state] = lookup_state_code(country_code, params[:state]) + super - add_field(mappings[:billing_address][:zip], extract_avs_code(params)) add_field(mappings[:billing_address][:country], lookup_country_code(country)) + add_field(mappings[:billing_address][:code], avs_code) + + unless ['US', 'CA'].include?(country_code) + # HPP_BILLING_STATE is required only for US and CA, otherwise is deleted + @fields.delete_if do |k, _| + k == 'HPP_BILLING_STATE' + end + end - if ['US', 'CA'].include?(country_code) && params[:state].length > 2 - add_field(mappings[:billing_address][:state], lookup_state_code(country_code, params[:state])) + if @fields[mappings[:customer][:phone]] + add_field(mappings[:customer][:phone], format_phone_number(@phone_number, country_code)) end end def shipping_address(params={}) country = params[:country] country_code = lookup_country_code(country, :alpha2) + params[:state] = lookup_state_code(country_code, params[:state]) + super - add_field(mappings[:shipping_address][:zip], extract_avs_code(params)) - add_field(mappings[:shipping_address][:country], lookup_country_code(params[:country])) + add_field(mappings[:shipping_address][:country], lookup_country_code(country)) + # the mapping for 'SHIPPING_CODE' field, which has the same value as the 'HPP_SHIPPING_POSTALCODE' + add_field(mappings[:shipping_address][:code], params[:zip]) - if ['US', 'CA'].include?(country_code) && params[:state].length > 2 - add_field(mappings[:shipping_address][:state], lookup_state_code(country_code, params[:state])) + unless ['US', 'CA'].include?(country_code) + # HPP_SHIPPING_STATE is required only for US and CA, otherwise is deleted + @fields.delete_if do |k, _| + k == 'HPP_SHIPPING_STATE' + end + end + + if @fields[mappings[:customer][:phone]]&.[](0..1) == '0|' + add_field(mappings[:customer][:phone], format_phone_number(@phone_number, country_code)) end end def customer(params={}) + country = @fields[mappings[:billing_address][:country]] + @phone_number = params[:phone] + params[:phone] = format_phone_number(@phone_number, lookup_country_code(country, :alpha2)) + super - add_field(mappings[:customer][:phone], format_phone_number(params[:phone])) end def addresses_match(address_match = nil) @@ -339,7 +692,8 @@ def generate_signature :address2 => 'HPP_SHIPPING_STREET2', :address3 => 'HPP_SHIPPING_STREET3', :city => 'HPP_SHIPPING_CITY', - :state => 'HPP_SHIPPING_STATE' + :state => 'HPP_SHIPPING_STATE', + :code => 'SHIPPING_CODE' mapping :billing_address, :zip => 'HPP_BILLING_POSTALCODE', :country => 'HPP_BILLING_COUNTRY', @@ -347,7 +701,8 @@ def generate_signature :address2 => 'HPP_BILLING_STREET2', :address3 => 'HPP_BILLING_STREET3', :city => 'HPP_BILLING_CITY', - :state => 'HPP_BILLING_STATE' + :state => 'HPP_BILLING_STATE', + :code => 'BILLING_CODE' mapping :addresses_match, 'HPP_ADDRESS_MATCH_INDICATOR' mapping :comment, 'COMMENT2' diff --git a/test/unit/integrations/realex_offsite/realex_offsite_helper_test.rb b/test/unit/integrations/realex_offsite/realex_offsite_helper_test.rb index a8ef206ad..77f2e90a3 100644 --- a/test/unit/integrations/realex_offsite/realex_offsite_helper_test.rb +++ b/test/unit/integrations/realex_offsite/realex_offsite_helper_test.rb @@ -45,7 +45,70 @@ def test_customer_mapping :phone => '(555)555-5555' assert_field 'HPP_CUSTOMER_EMAIL', 'cody@example.com' - assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '5|555555555' + end + + def test_raises_invalid_customer + assert_raise ArgumentError do + @helper.customer(:email => 'cody@example') + end + assert_nothing_raised ArgumentError do + @helper.customer :phone => '(000)000-0000' + end + assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '0|0' + end + + def test_phone_formatting + @helper.customer :phone => '+48 12 345 67 89' + + @helper.billing_address :country => 'PL' + + assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '48|123456789' + end + + def test_phone_formatting_when_no_country_specified + @helper.customer :phone => '123-456-789' + + assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '0|123456789' + end + + def test_phone_formatting_for_italy_when_leading_zero_exists + @helper.customer :phone => '06 123 4567' + + @helper.billing_address :country => 'IT' + + assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '39|061234567' + end + + def test_phone_formatting_for_italy_when_leading_zero_does_not_exist + @helper.customer :phone => '330 1234567' + + @helper.billing_address :country => 'IT' + + assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '39|3301234567' + end + + def test_phone_formatting_for_singapore_when_no_country_code_is_given + @helper.customer :phone => '0 6500 0000' + + @helper.billing_address :country => 'SG' + + assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '65|65000000' + end + + def test_phone_formatting_for_singapore_when_country_code_is_given + @helper.customer :phone => '65 6500 0000' + + @helper.billing_address :country => 'SG' + + assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '65|65000000' + end + + def test_fixing_phone_calling_code + @helper.customer :phone => '+84 12 345 67 89' + + @helper.billing_address :country => 'PL' + + assert_field 'HPP_CUSTOMER_PHONENUMBER_MOBILE', '48|123456789' end def test_address_mapping @@ -57,13 +120,25 @@ def test_address_mapping :zip => 'LS2 7EE', :country => 'CA' - assert_field 'HPP_BILLING_POSTALCODE', '27|1' + assert_field 'HPP_BILLING_POSTALCODE', 'LS2 7EE' assert_field 'HPP_BILLING_COUNTRY', '124' assert_field 'HPP_BILLING_STREET1', '1 My Street' assert_field 'HPP_BILLING_STREET2', 'Apt. 1' assert_field 'HPP_BILLING_STREET3', 'Entrance B' assert_field 'HPP_BILLING_CITY', 'Leeds' assert_field 'HPP_BILLING_STATE', 'NL' + assert_field 'BILLING_CODE', 'LS2 7EE|1 My Street' + end + + def test_address_mapping_gb + @helper.billing_address :address1 => '1 My Street', + :address2 => 'Apt. 1', + :address3 => 'Entrance B', + :city => 'Leeds', + :zip => 'LS2 7EE', + :country => 'GB' + + assert_field 'BILLING_CODE', '27|1' end def test_us_country_state @@ -71,6 +146,7 @@ def test_us_country_state :address2 => 'Apt. 1', :address3 => 'Entrance B', :city => 'Pasadena', + :zip => 'LS2 7EE', :country => 'United States', :state => 'California' @@ -83,6 +159,7 @@ def test_canada_country_state :address2 => 'Apt. 1', :address3 => 'Entrance B', :city => 'Pasadena', + :zip => 'LS2 7EE', :country => 'Canada', :state => 'Newfoundland' @@ -90,6 +167,36 @@ def test_canada_country_state assert_field 'HPP_BILLING_COUNTRY', '124' end + def test_raises_invalid_billing_address + assert_raise ArgumentError do + @helper.billing_address :address1 => '1 My Streetâ–“' + end + assert_raise ArgumentError do + @helper.billing_address :address1 => 'Lorem Ipsum is simply dummy text for testing length' + end + assert_raise ArgumentError do + @helper.billing_address :city => 'Lorem Ipsum is simply dummy text for testing length' + end + assert_raise ArgumentError do + @helper.billing_address :zip => 'LS2 7EE | 555' + end + assert_raise ArgumentError do + @helper.billing_address :country => 'ZZ' + end + assert_raise ArgumentError do + @helper.billing_address :state => '8888', + :country => 'Canada' + end + assert_raise ArgumentError do + @helper.billing_address :state => '8888', + :country => 'United States' + end + assert_nothing_raised ArgumentError do + @helper.billing_address :state => '8888', + :country => 'United Kingdom' + end + end + def test_shipping_address @helper.shipping_address :name => 'Testing Tester', :address1 => '1 My Street', @@ -100,13 +207,67 @@ def test_shipping_address :zip => 'LS2 7E1', :country => 'GB' - assert_field 'HPP_SHIPPING_POSTALCODE', '271|1' + assert_field 'HPP_SHIPPING_POSTALCODE', 'LS2 7E1' assert_field 'HPP_SHIPPING_COUNTRY', '826' assert_field 'HPP_SHIPPING_STREET1', '1 My Street' assert_field 'HPP_SHIPPING_STREET2', 'Apt. 1' assert_field 'HPP_SHIPPING_STREET3', 'Entrance B' assert_field 'HPP_SHIPPING_CITY', 'London' - assert_field 'HPP_SHIPPING_STATE', 'Whales' + assert_field 'HPP_SHIPPING_STATE', nil + assert_field 'SHIPPING_CODE', 'LS2 7E1' + end + + def test_shipping_us_country_state + @helper.shipping_address :address1 => '1 My Street', + :address2 => 'Apt. 1', + :address3 => 'Entrance B', + :city => 'Pasadena', + :zip => 'LS2 7EE', + :country => 'United States', + :state => 'California' + + assert_field 'HPP_SHIPPING_STATE', 'CA' + assert_field 'HPP_SHIPPING_COUNTRY', '840' + end + + def test_shipping_canada_country_state + @helper.shipping_address :address1 => '1 My Street', + :address2 => 'Apt. 1', + :address3 => 'Entrance B', + :city => 'Pasadena', + :zip => 'LS2 7EE', + :country => 'Canada', + :state => 'Newfoundland' + + assert_field 'HPP_SHIPPING_STATE', 'NL' + assert_field 'HPP_SHIPPING_COUNTRY', '124' + end + + def test_raises_invalid_shipping_address + assert_raise ArgumentError do + @helper.shipping_address :address1 => '1 My Streetâ–“' + end + assert_raise ArgumentError do + @helper.shipping_address :city => 'Lorem Ipsum is simply dummy text for testing length' + end + assert_raise ArgumentError do + @helper.shipping_address :zip => 'LS2 7EE | 555' + end + assert_raise ArgumentError do + @helper.shipping_address :country => 'ZZ' + end + assert_raise ArgumentError do + @helper.shipping_address :state => '8888', + :country => 'Canada' + end + assert_raise ArgumentError do + @helper.shipping_address :state => '8888', + :country => 'United States' + end + assert_nothing_raised ArgumentError do + @helper.shipping_address :state => '8888', + :country => 'United Kingdom' + end end def test_address_match_indicator @@ -122,13 +283,13 @@ def test_address_match_indicator assert_field 'HPP_ADDRESS_MATCH_INDICATOR', 'TRUE' - assert_field 'HPP_SHIPPING_POSTALCODE', '271|1' + assert_field 'HPP_SHIPPING_POSTALCODE', 'LS2 7E1' assert_field 'HPP_SHIPPING_COUNTRY', '826' assert_field 'HPP_SHIPPING_STREET1', '1 My Street' assert_field 'HPP_SHIPPING_STREET2', 'Apt. 1' assert_field 'HPP_SHIPPING_STREET3', 'Entrance B' assert_field 'HPP_SHIPPING_CITY', 'Leeds' - assert_field 'HPP_SHIPPING_STATE', 'Yorkshire' + assert_field 'HPP_SHIPPING_STATE', nil end def test_address_match_indicator_false