phony_rails 0.13.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6000f96b00258917b5399b860088a5d1d11d1fff
4
- data.tar.gz: 666250cc63932a0d10563cd122ea2a8835032d90
3
+ metadata.gz: ebc2d2e0d7c8552d406ca7527590181a8d7f1437
4
+ data.tar.gz: 6e0ca4a8dd0e4447bd6d31469de69cc3e0781d3d
5
5
  SHA512:
6
- metadata.gz: 935b0168ab070efdef52c294a886c8ac1c8e9a50c9e8a428be7762a449c63fd57ce3275b4b1f91e5772966ceb40c525101afc73e517bf3c82ca1d132d49511d8
7
- data.tar.gz: cd99b5a59f9a1478480380b2df006b5f7869809fa2b520d669b5477188f70ff6e47e69df311782760ddb8652c868ab70338a046ac2ea34d77a4b9bb419818524
6
+ metadata.gz: 0f615e9274fca0cadab38bcbac8e58172c4102450d2f79e285c34dbcd88a2cf6c4c6ba476be24cfbb8e866113819daceb96f93d1e9c800e1c91656eceaf1de80
7
+ data.tar.gz: 5c6d09cb08448d47462afce4f448f6e3e15e46bd9c46f4016c4e961802cb231aff5ee4a2ecd9a49211b1d1caaba347a364cb5262ddfe9206a3573e88f2b4b953
data/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.14.0](https://github.com/joost/phony_rails/tree/v0.14.0) (2016-04-21)
4
+
5
+ [Full Changelog](https://github.com/joost/phony_rails/compare/v0.13.0...v0.14.0)
6
+
7
+ **Closed issues:**
8
+
9
+ - In normalize\_number, .clone is being used, which preserves "frozenness", causing method to fail sometimes [\#136](https://github.com/joost/phony_rails/issues/136)
10
+
11
+ - question Is thr any way to find country code from mobile no? [\#135](https://github.com/joost/phony_rails/issues/135)
12
+
13
+ - invalid number assumed to be valid [\#130](https://github.com/joost/phony_rails/issues/130)
14
+
15
+ - Split fails when a + is present [\#123](https://github.com/joost/phony_rails/issues/123)
16
+
17
+ **Merged pull requests:**
18
+
19
+ - Adds ability to pass symbols as option values to phony model helpers [\#139](https://github.com/joost/phony_rails/pull/139) ([jonathan-wheeler](https://github.com/jonathan-wheeler))
20
+
21
+ - Add support for phone numbers with extensions [\#138](https://github.com/joost/phony_rails/pull/138) ([jerryclinesmith](https://github.com/jerryclinesmith))
22
+
23
+ - Add support for a default country code [\#137](https://github.com/joost/phony_rails/pull/137) ([jerryclinesmith](https://github.com/jerryclinesmith))
24
+
25
+ - Added first RuboCop stuff. [\#134](https://github.com/joost/phony_rails/pull/134) ([joost](https://github.com/joost))
26
+
3
27
  ## [v0.13.0](https://github.com/joost/phony_rails/tree/v0.13.0) (2016-03-12)
4
28
 
5
29
  [Full Changelog](https://github.com/joost/phony_rails/compare/v0.12.11...v0.13.0)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- phony_rails (0.13.0)
4
+ phony_rails (0.14.0)
5
5
  activesupport (>= 3.0)
6
6
  phony (~> 2.12)
7
7
 
@@ -139,3 +139,6 @@ DEPENDENCIES
139
139
  rspec
140
140
  rubocop
141
141
  sqlite3
142
+
143
+ BUNDLED WITH
144
+ 1.11.2
data/README.md CHANGED
@@ -79,6 +79,14 @@ PhonyRails.normalize_number('+4790909090', default_country_code: 'SE') # => '+47
79
79
 
80
80
  The country_code should always be a ISO 3166-1 alpha-2 (http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
81
81
 
82
+ #### Default for all models
83
+
84
+ You can set the default_country_code for all models using:
85
+
86
+ ```ruby
87
+ PhonyRails.default_country_code = "US"
88
+ ```
89
+
82
90
  ### Validation
83
91
 
84
92
  In your model use the Phony.plausible method to validate an attribute:
@@ -178,6 +186,15 @@ You can also easily normalize a phone number String:
178
186
  "(0)30 1234 123".phony_normalized(country_code: 'NL') # => '301234123'
179
187
  ```
180
188
 
189
+ Extensions are supported (identified by "ext", "ex", "x", "xt", "#", or ":") and will show at the end of the number:
190
+
191
+ ```ruby
192
+ "+31 (0)30 1234 123 x999".phony_normalized # => '31301234123 x999'
193
+ "+31 (0)30 1234 123 ext999".phony_normalized # => '31301234123 x999'
194
+ "+31 (0)30 1234 123 #999".phony_normalized # => '31301234123 x999'
195
+ ```
196
+
197
+
181
198
  ### Find by normalized number
182
199
 
183
200
  Say you want to find a record by a phone number. Best is to normalize user input and compare to an attribute stored in the db.
data/Rakefile CHANGED
@@ -4,3 +4,11 @@ require 'rspec/core/rake_task'
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
  task default: :spec
7
+
8
+ task :console do
9
+ require 'irb'
10
+ require 'irb/completion'
11
+ require 'phony_rails'
12
+ ARGV.clear
13
+ IRB.start
14
+ end
data/lib/phony_rails.rb CHANGED
@@ -5,6 +5,23 @@ require 'phony_rails/version'
5
5
  require 'yaml'
6
6
 
7
7
  module PhonyRails
8
+ def self.default_country_code
9
+ @default_country_code ||= nil
10
+ end
11
+
12
+ def self.default_country_code=(new_code)
13
+ @default_country_code = new_code
14
+ @default_country_number = nil # Reset default country number, will lookup next time its asked for
15
+ end
16
+
17
+ def self.default_country_number
18
+ @default_country_number ||= default_country_code.present? ? country_number_for(default_country_code) : nil
19
+ end
20
+
21
+ def self.default_country_number=(new_number)
22
+ @default_country_number = new_number
23
+ end
24
+
8
25
  def self.country_number_for(country_code)
9
26
  return if country_code.nil?
10
27
 
@@ -28,6 +45,7 @@ module PhonyRails
28
45
  return if number.nil?
29
46
  original_number = number
30
47
  number = number.dup # Just to be sure, we don't want to change the original.
48
+ number, ext = extract_extension(number)
31
49
  number.gsub!(/[^\(\)\d\+]/, '') # Strips weird stuff from the number
32
50
  return if number.blank?
33
51
  if _country_number = options[:country_number] || country_number_for(options[:country_code])
@@ -37,29 +55,40 @@ module PhonyRails
37
55
  if !Phony.plausible?(number) || _country_number != country_code_from_number(number)
38
56
  number = "#{_country_number}#{number}"
39
57
  end
40
- elsif _default_country_number = options[:default_country_number] || country_number_for(options[:default_country_code])
58
+ elsif _default_country_number = extract_default_country_number(options)
41
59
  options[:add_plus] = true if options[:add_plus].nil?
42
- # We try to add the default country number and see if it is a
43
- # correct phone number. See https://github.com/joost/phony_rails/issues/87#issuecomment-89324426
44
- unless number =~ /\A\+/ # if we don't have a +
45
- if Phony.plausible?("#{_default_country_number}#{number}") || !Phony.plausible?(number) || country_code_from_number(number).nil?
46
- number = "#{_default_country_number}#{number}"
47
- elsif (number =~ /^0[^0]/) && Phony.plausible?("#{_default_country_number}#{number.gsub(/^0/, '')}")
48
- # If the number starts with ONE zero (two might indicate a country code)
49
- # and this is a plausible number for the default_country
50
- # we prefer that one.
51
- number = "#{_default_country_number}#{number.gsub(/^0/, '')}"
52
- end
53
- end
54
- # number = "#{_default_country_number}#{number}" unless Phony.plausible?(number)
60
+ number = normalize_number_default_country(number, _default_country_number)
55
61
  end
56
62
  normalized_number = Phony.normalize(number)
57
63
  options[:add_plus] = true if options[:add_plus].nil? && Phony.plausible?(normalized_number)
58
- options[:add_plus] ? "+#{normalized_number}" : normalized_number
64
+ normalized_number = options[:add_plus] ? "+#{normalized_number}" : normalized_number
65
+ format_extension(normalized_number, ext)
59
66
  rescue
60
67
  original_number # If all goes wrong .. we still return the original input.
61
68
  end
62
69
 
70
+ def self.normalize_number_default_country(number, default_country_number)
71
+ # We try to add the default country number and see if it is a
72
+ # correct phone number. See https://github.com/joost/phony_rails/issues/87#issuecomment-89324426
73
+ unless number =~ /\A\+/ # if we don't have a +
74
+ if Phony.plausible?("#{default_country_number}#{number}") || !Phony.plausible?(number) || country_code_from_number(number).nil?
75
+ return "#{default_country_number}#{number}"
76
+ elsif (number =~ /^0[^0]/) && Phony.plausible?("#{default_country_number}#{number.gsub(/^0/, '')}")
77
+ # If the number starts with ONE zero (two might indicate a country code)
78
+ # and this is a plausible number for the default_country
79
+ # we prefer that one.
80
+ return "#{default_country_number}#{number.gsub(/^0/, '')}"
81
+ end
82
+ end
83
+ # number = "#{default_country_number}#{number}" unless Phony.plausible?(number)
84
+ # Just return the number unchanged
85
+ number
86
+ end
87
+
88
+ def self.extract_default_country_number(options = {})
89
+ options[:default_country_number] || country_number_for(options[:default_country_code]) || default_country_number
90
+ end
91
+
63
92
  def self.country_code_from_number(number)
64
93
  return nil unless Phony.plausible?(number)
65
94
  Phony.split(Phony.normalize(number)).first
@@ -69,14 +98,33 @@ module PhonyRails
69
98
  # NB: This method calls #normalize_number and passes _options_ directly to that method.
70
99
  def self.plausible_number?(number, options = {})
71
100
  return false if number.nil? || number.blank?
101
+ number = extract_extension(number).first
72
102
  number = normalize_number(number, options)
73
103
  country_number = options[:country_number] || country_number_for(options[:country_code]) ||
74
- options[:default_country_number] || country_number_for(options[:default_country_code])
104
+ options[:default_country_number] || country_number_for(options[:default_country_code]) ||
105
+ default_country_number
75
106
  Phony.plausible? number, cc: country_number
76
107
  rescue
77
108
  false
78
109
  end
79
110
 
111
+ COMMON_EXTENSIONS = /[ ]*(ext|ex|x|xt|#|:)+[^0-9]*\(*([-0-9]{1,})\)*#?$/i
112
+
113
+ def self.extract_extension(number_and_ext)
114
+ return [nil, nil] if number_and_ext.nil?
115
+ # :nocov:
116
+ if subbed = number_and_ext.sub(COMMON_EXTENSIONS, '')
117
+ [subbed, Regexp.last_match(2)]
118
+ else
119
+ [number_and_ext, nil]
120
+ end
121
+ # :nocov:
122
+ end
123
+
124
+ def self.format_extension(number, ext)
125
+ ext.present? ? "#{number} x#{ext}" : number
126
+ end
127
+
80
128
  module Extension
81
129
  extend ActiveSupport::Concern
82
130
 
@@ -87,6 +135,7 @@ module PhonyRails
87
135
  # It also adds the country_code (number), eg. 31 for NL numbers.
88
136
  def set_phony_normalized_numbers(attributes, options = {})
89
137
  options = options.dup
138
+ assign_values_for_phony_symbol_options(options)
90
139
  if respond_to?(:country_code)
91
140
  set_country_as = options[:enforce_record_country] ? :country_code : :default_country_code
92
141
  options[set_country_as] ||= country_code
@@ -98,6 +147,13 @@ module PhonyRails
98
147
  send("#{attribute_name}=", new_value) if new_value
99
148
  end
100
149
  end
150
+
151
+ def assign_values_for_phony_symbol_options(options)
152
+ symbol_options = [:country_number, :default_country_number, :country_code, :default_country_code]
153
+ symbol_options.each do |option|
154
+ options[option] = send(options[option]) if options[option].is_a?(Symbol)
155
+ end
156
+ end
101
157
  end
102
158
 
103
159
  module ClassMethods
@@ -130,10 +186,11 @@ module PhonyRails
130
186
  attributes.each do |attribute|
131
187
  raise(StandardError, "Instance method normalized_#{attribute} already exists on #{name} (PhonyRails)") if method_defined?(:"normalized_#{attribute}")
132
188
  define_method :"normalized_#{attribute}" do |*args|
133
- options = args.first || {}
189
+ options = main_options.merge(args.first || {})
190
+ assign_values_for_phony_symbol_options(options)
134
191
  raise(ArgumentError, "No attribute/method #{attribute} found on #{self.class.name} (PhonyRails)") unless respond_to?(attribute)
135
192
  options[:country_code] ||= country_code if respond_to?(:country_code)
136
- PhonyRails.normalize_number(send(attribute), main_options.merge(options))
193
+ PhonyRails.normalize_number(send(attribute), options)
137
194
  end
138
195
  end
139
196
  end
@@ -24,10 +24,11 @@ class String
24
24
  raise ArgumentError, "Expected options to be a Hash, got #{options.inspect}" unless options.is_a?(Hash)
25
25
  options = options.dup
26
26
  normalize_country_code = options.delete(:normalize)
27
- s = (normalize_country_code ? PhonyRails.normalize_number(self, default_country_code: normalize_country_code.to_s, add_plus: false) : gsub(/\D/, ''))
27
+ s, ext = PhonyRails.extract_extension(self)
28
+ s = (normalize_country_code ? PhonyRails.normalize_number(s, default_country_code: normalize_country_code.to_s, add_plus: false) : s.gsub(/\D/, ''))
28
29
  return if s.blank?
29
30
  return if options[:strict] && !Phony.plausible?(s)
30
- Phony.format(s, options.reverse_merge(format: :national))
31
+ PhonyRails.format_extension(Phony.format(s, options.reverse_merge(format: :national)), ext)
31
32
  rescue
32
33
  raise if options[:raise]
33
34
  s
@@ -1,3 +1,3 @@
1
1
  module PhonyRails
2
- VERSION = '0.13.1'.freeze
2
+ VERSION = '0.14.0'.freeze
3
3
  end
@@ -8,7 +8,6 @@ class PhonyPlausibleValidator < ActiveModel::EachValidator
8
8
  return if value.blank?
9
9
 
10
10
  @record = record
11
-
12
11
  value = PhonyRails.normalize_number(value.dup, default_country_code: normalized_country_code) if normalized_country_code
13
12
  @record.errors.add(attribute, error_message) unless Phony.plausible?(value, cc: country_number)
14
13
  end
@@ -16,15 +15,15 @@ class PhonyPlausibleValidator < ActiveModel::EachValidator
16
15
  private
17
16
 
18
17
  def error_message
19
- options[:message] || :improbable_phone
18
+ options_value(:message) || :improbable_phone
20
19
  end
21
20
 
22
21
  def country_number
23
- options[:country_number] || record_country_number || country_number_from_country_code
22
+ options_value(:country_number) || record_country_number || country_number_from_country_code
24
23
  end
25
24
 
26
25
  def record_country_number
27
- @record.country_number if @record.respond_to?(:country_number) && !options[:ignore_record_country_number]
26
+ @record.country_number if @record.respond_to?(:country_number) && !options_value(:ignore_record_country_number)
28
27
  end
29
28
 
30
29
  def country_number_from_country_code
@@ -32,15 +31,23 @@ class PhonyPlausibleValidator < ActiveModel::EachValidator
32
31
  end
33
32
 
34
33
  def country_code
35
- options[:country_code] || record_country_code
34
+ options_value(:country_code) || record_country_code
36
35
  end
37
36
 
38
37
  def record_country_code
39
- @record.country_code if @record.respond_to?(:country_code) && !options[:ignore_record_country_code]
38
+ @record.country_code if @record.respond_to?(:country_code) && !options_value(:ignore_record_country_code)
40
39
  end
41
40
 
42
41
  def normalized_country_code
43
- options[:normalized_country_code]
42
+ options_value(:normalized_country_code)
43
+ end
44
+
45
+ def options_value(option)
46
+ if options[option].is_a?(Symbol)
47
+ @record.send(options[option])
48
+ else
49
+ options[option]
50
+ end
44
51
  end
45
52
  end
46
53
 
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe PhonyRails do
4
+ EXT_PREFIXES = %w(ext ex x xt # :).freeze
5
+
4
6
  it 'should not pollute the global namespace with a Country class' do
5
7
  should_not be_const_defined 'Country'
6
8
  end
@@ -81,6 +83,19 @@ describe PhonyRails do
81
83
  end
82
84
  end
83
85
 
86
+ describe 'with extensions' do
87
+ EXT_PREFIXES.each do |prefix|
88
+ it "should format number with #{prefix} extension" do
89
+ expect("+319090#{prefix}123".phony_formatted(strict: true)).to eql(nil)
90
+ expect("101234123#{prefix}123".phony_formatted(normalize: :NL)).to eql('010 123 4123 x123')
91
+ expect("101234123#{prefix}123".phony_formatted(normalize: :NL, format: :international)).to eql('+31 10 123 4123 x123')
92
+ expect("31101234123#{prefix}123".phony_formatted(normalize: :NL)).to eql('010 123 4123 x123')
93
+ expect("8887716095#{prefix}123".phony_formatted(format: :international, normalize: 'US', raise: true)).to eq('+1 (888) 771-6095 x123')
94
+ expect("+12145551212#{prefix}123".phony_formatted).to eq('(214) 555-1212 x123')
95
+ end
96
+ end
97
+ end
98
+
84
99
  describe 'specific tests from issues' do
85
100
  # https://github.com/joost/phony_rails/issues/79
86
101
  it 'should pass Github issue #42' do
@@ -297,6 +312,30 @@ describe PhonyRails do
297
312
  end
298
313
  end
299
314
 
315
+ context 'number with an extension' do
316
+ EXT_PREFIXES.each do |prefix|
317
+ it "should handle some edge cases (with country_code) and #{prefix} extension" do
318
+ expect(PhonyRails.normalize_number("some nasty stuff in this +31 number 10-1234123 string #{prefix}123", country_code: 'NL')).to eql('+31101234123 x123')
319
+ expect(PhonyRails.normalize_number("070-4157134#{prefix}123", country_code: 'NL')).to eql('+31704157134 x123')
320
+ expect(PhonyRails.normalize_number("0031-70-4157134#{prefix}123", country_code: 'NL')).to eql('+31704157134 x123')
321
+ expect(PhonyRails.normalize_number("+31-70-4157134#{prefix}123", country_code: 'NL')).to eql('+31704157134 x123')
322
+ expect(PhonyRails.normalize_number("0322-69497#{prefix}123", country_code: 'BE')).to eql('+3232269497 x123')
323
+ expect(PhonyRails.normalize_number("+32 3 226 94 97#{prefix}123", country_code: 'BE')).to eql('+3232269497 x123')
324
+ expect(PhonyRails.normalize_number("0450 764 000#{prefix}123", country_code: 'AU')).to eql('+61450764000 x123')
325
+ end
326
+
327
+ it "should handle some edge cases (with default_country_code) and #{prefix}" do
328
+ expect(PhonyRails.normalize_number("some nasty stuff in this +31 number 10-1234123 string #{prefix}123", country_code: 'NL')).to eql('+31101234123 x123')
329
+ expect(PhonyRails.normalize_number("070-4157134#{prefix}123", default_country_code: 'NL')).to eql('+31704157134 x123')
330
+ expect(PhonyRails.normalize_number("0031-70-4157134#{prefix}123", default_country_code: 'NL')).to eql('+31704157134 x123')
331
+ expect(PhonyRails.normalize_number("+31-70-4157134#{prefix}123", default_country_code: 'NL')).to eql('+31704157134 x123')
332
+ expect(PhonyRails.normalize_number("0322-69497#{prefix}123", default_country_code: 'BE')).to eql('+3232269497 x123')
333
+ expect(PhonyRails.normalize_number("+32 3 226 94 97#{prefix}123", default_country_code: 'BE')).to eql('+3232269497 x123')
334
+ expect(PhonyRails.normalize_number("0450 764 000#{prefix}123", default_country_code: 'AU')).to eql('+61450764000 x123')
335
+ end
336
+ end
337
+ end
338
+
300
339
  it 'should handle some edge cases (with country_code)' do
301
340
  expect(PhonyRails.normalize_number('some nasty stuff in this +31 number 10-1234123 string', country_code: 'NL')).to eql('+31101234123')
302
341
  expect(PhonyRails.normalize_number('070-4157134', country_code: 'NL')).to eql('+31704157134')
@@ -320,6 +359,29 @@ describe PhonyRails do
320
359
  it 'should normalize even an implausible number' do
321
360
  expect(PhonyRails.normalize_number('01')).to eql('1')
322
361
  end
362
+
363
+ context 'with default_country_code set' do
364
+ before { PhonyRails.default_country_code = 'NL' }
365
+ after { PhonyRails.default_country_code = nil }
366
+
367
+ it 'normalize using the default' do
368
+ expect(PhonyRails.normalize_number('010-1234123')).to eql('+31101234123')
369
+ expect(PhonyRails.normalize_number('010-1234123')).to eql('+31101234123')
370
+ expect(PhonyRails.normalize_number('070-4157134')).to eql('+31704157134')
371
+ expect(PhonyRails.normalize_number('0031-70-4157134')).to eql('+31704157134')
372
+ expect(PhonyRails.normalize_number('+31-70-4157134')).to eql('+31704157134')
373
+ end
374
+
375
+ it 'allows default_country_code to be overridden' do
376
+ expect(PhonyRails.normalize_number('0322-69497', country_code: 'BE')).to eql('+3232269497')
377
+ expect(PhonyRails.normalize_number('+32 3 226 94 97', country_code: 'BE')).to eql('+3232269497')
378
+ expect(PhonyRails.normalize_number('0450 764 000', country_code: 'AU')).to eql('+61450764000')
379
+
380
+ expect(PhonyRails.normalize_number('0322-69497', default_country_code: 'BE')).to eql('+3232269497')
381
+ expect(PhonyRails.normalize_number('+32 3 226 94 97', default_country_code: 'BE')).to eql('+3232269497')
382
+ expect(PhonyRails.normalize_number('0450 764 000', default_country_code: 'AU')).to eql('+61450764000')
383
+ end
384
+ end
323
385
  end
324
386
 
325
387
  describe 'PhonyRails.plausible_number?' do
@@ -367,6 +429,65 @@ describe PhonyRails do
367
429
  expect(Phony).to receive(:plausible?).twice.and_raise('unexpected error')
368
430
  is_expected.not_to be_plausible_number normalizable_number, country_code: 'US'
369
431
  end
432
+
433
+ context 'with default_country_code set' do
434
+ before { PhonyRails.default_country_code = 'FR' }
435
+ after { PhonyRails.default_country_code = nil }
436
+
437
+ it 'uses the default' do
438
+ is_expected.not_to be_plausible_number normalizable_number
439
+ is_expected.to be_plausible_number formatted_french_number_with_country_code
440
+ end
441
+
442
+ it 'allows default_country_code to be overridden' do
443
+ is_expected.not_to be_plausible_number empty_number, country_code: 'US'
444
+ is_expected.not_to be_plausible_number nil_number, country_code: 'US'
445
+ end
446
+ end
447
+ end
448
+
449
+ describe 'PhonyRails.default_country' do
450
+ before { PhonyRails.default_country_code = 'US' }
451
+ after { PhonyRails.default_country_code = nil }
452
+
453
+ it 'can set a global default country code' do
454
+ expect(PhonyRails.default_country_code). to eq 'US'
455
+ end
456
+
457
+ it 'can set a global default country code' do
458
+ PhonyRails.default_country_number = '1'
459
+ expect(PhonyRails.default_country_number).to eq '1'
460
+ end
461
+
462
+ it 'default country code affects default country number' do
463
+ expect(PhonyRails.default_country_number).to eq '1'
464
+ end
465
+ end
466
+
467
+ describe 'PhonyRails#extract_extension' do
468
+ it 'returns [nil, nil] on nil input' do
469
+ expect(PhonyRails.extract_extension(nil)).to eq [nil, nil]
470
+ end
471
+
472
+ it 'returns [number, nil] when number does not have an extension' do
473
+ expect(PhonyRails.extract_extension('123456789')).to eq ['123456789', nil]
474
+ end
475
+
476
+ EXT_PREFIXES.each do |prefix|
477
+ it "returns [number, ext] when number has a #{prefix} extension" do
478
+ expect(PhonyRails.extract_extension("123456789#{prefix}123")).to eq %w(123456789 123)
479
+ end
480
+ end
481
+ end
482
+
483
+ describe 'PhonyRails#format_extension' do
484
+ it 'returns just number if no extension' do
485
+ expect(PhonyRails.format_extension('+123456789', nil)).to eq '+123456789'
486
+ end
487
+
488
+ it 'returns number with extension if extension exists' do
489
+ expect(PhonyRails.format_extension('+123456789', '123')).to eq '+123456789 x123'
490
+ end
370
491
  end
371
492
 
372
493
  shared_examples_for 'model with PhonyRails' do
@@ -499,6 +620,11 @@ describe PhonyRails do
499
620
  model.country_code = nil
500
621
  expect(model.normalized_phone1_method(country_code: nil)).to eql('+49308612906')
501
622
  end
623
+
624
+ it 'should accept a symbol when setting country_code options' do
625
+ model = model_klass.new(symboled_phone_method: '02031234567', country_code_attribute: 'GB')
626
+ expect(model.normalized_symboled_phone_method).to eql('+442031234567')
627
+ end
502
628
  end
503
629
 
504
630
  describe 'using model#phony_normalize' do
@@ -537,6 +663,12 @@ describe PhonyRails do
537
663
  dummy.valid?
538
664
  end).to raise_error(RuntimeError)
539
665
  end
666
+
667
+ it 'should accept a symbol when setting country_code options' do
668
+ model = model_klass.new(symboled_phone: '0606060606', country_code_attribute: 'FR')
669
+ expect(model).to be_valid
670
+ expect(model.symboled_phone).to eql('+33606060606')
671
+ end
540
672
  end
541
673
  end
542
674
 
@@ -560,8 +692,8 @@ describe PhonyRails do
560
692
  end
561
693
 
562
694
  context 'when enforce_record_country is turned off' do
563
- let(:model_klass) { RelaxedActiveRecordModel }
564
- let(:record) { model_klass.new }
695
+ let(:model_klass) { RelaxedActiveRecordModel }
696
+ let(:record) { model_klass.new }
565
697
 
566
698
  before do
567
699
  record.phone_number = phone_number
@@ -54,6 +54,11 @@ ActiveRecord::Schema.define do
54
54
  create_table :invalid_country_code_helpful_homes do |table|
55
55
  table.column :phone_number, :string
56
56
  end
57
+
58
+ create_table :symbolizable_helpful_homes do |table|
59
+ table.column :phone_number, :string
60
+ table.column :phone_number_country_code, :string
61
+ end
57
62
  end
58
63
 
59
64
  #--------------------
@@ -132,6 +137,12 @@ class InvalidCountryCodeHelpfulHome < ActiveRecord::Base
132
137
  '--'
133
138
  end
134
139
  end
140
+
141
+ #--------------------
142
+ class SymbolizableHelpfulHome < ActiveRecord::Base
143
+ attr_accessor :phone_number, :phone_number_country_code
144
+ validates_plausible_phone :phone_number, country_code: :phone_number_country_code
145
+ end
135
146
  #-----------------------------------------------------------------------------------------------------------------------
136
147
  # Tests
137
148
  #-----------------------------------------------------------------------------------------------------------------------
@@ -502,5 +513,36 @@ describe ActiveModel::Validations::HelperMethods do
502
513
  end.to_not raise_error
503
514
  end
504
515
  end
516
+
517
+ #--------------------
518
+ context 'when a country code is passed as a symbol' do
519
+ before(:each) do
520
+ @home = SymbolizableHelpfulHome.new
521
+ end
522
+
523
+ it 'should validate an empty number' do
524
+ expect(@home).to be_valid
525
+ end
526
+
527
+ it 'should validate a valid number with the right country code' do
528
+ @home.phone_number = POLISH_NUMBER_WITH_COUNTRY_CODE
529
+ @home.phone_number_country_code = 'PL'
530
+ expect(@home).to be_valid
531
+ end
532
+
533
+ it 'should invalidate a valid number with the wrong country code' do
534
+ @home.phone_number = FRENCH_NUMBER_WITH_COUNTRY_CODE
535
+ @home.phone_number_country_code = 'PL'
536
+ expect(@home).to_not be_valid
537
+ expect(@home.errors.messages).to include(phone_number: ['is an invalid number'])
538
+ end
539
+
540
+ it 'should invalidate a valid number without a country code' do
541
+ @home.phone_number = VALID_NUMBER
542
+ @home.phone_number_country_code = 'PL'
543
+ expect(@home).to_not be_valid
544
+ expect(@home.errors.messages).to include(phone_number: ['is an invalid number'])
545
+ end
546
+ end
505
547
  end
506
548
  end
data/spec/spec_helper.rb CHANGED
@@ -21,18 +21,22 @@ ActiveRecord::Schema.define do
21
21
  table.column :phone_number, :string
22
22
  table.column :phone_number_as_normalized, :string
23
23
  table.column :fax_number, :string
24
+ table.column :country_code_attribute, :string
25
+ table.column :symboled_phone, :string
24
26
  end
25
27
  end
26
28
 
27
29
  module SharedModelMethods
28
30
  extend ActiveSupport::Concern
29
31
  included do
30
- attr_accessor :phone_method, :phone1_method, :country_code
32
+ attr_accessor :phone_method, :phone1_method, :symboled_phone_method, :country_code, :country_code_attribute
31
33
  phony_normalized_method :phone_attribute # adds normalized_phone_attribute method
32
34
  phony_normalized_method :phone_method # adds normalized_phone_method method
33
35
  phony_normalized_method :phone1_method, default_country_code: 'DE' # adds normalized_phone_method method
36
+ phony_normalized_method :symboled_phone_method, country_code: :country_code_attribute # adds phone_with_symboled_options method
34
37
  phony_normalize :phone_number # normalized on validation
35
38
  phony_normalize :fax_number, default_country_code: 'AU'
39
+ phony_normalize :symboled_phone, default_country_code: :country_code_attribute
36
40
  end
37
41
  end
38
42
 
@@ -57,6 +61,8 @@ class MongoidModel
57
61
  field :phone_number, type: String
58
62
  field :phone_number_as_normalized, type: String
59
63
  field :fax_number
64
+ field :country_code_attribute, type: String
65
+ field :symboled_phone, type: String
60
66
  include SharedModelMethods
61
67
  end
62
68
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phony_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joost Hietbrink
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-01 00:00:00.000000000 Z
11
+ date: 2016-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phony