valvat 1.0.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ruby.yml +35 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +15 -0
  6. data/CHANGES.md +29 -1
  7. data/Gemfile +2 -0
  8. data/Guardfile +6 -4
  9. data/README.md +10 -4
  10. data/Rakefile +3 -1
  11. data/certs/yolk.pem +21 -21
  12. data/gemfiles/activemodel-5 +1 -1
  13. data/gemfiles/activemodel-6 +1 -1
  14. data/lib/active_model/validations/valvat_validator.rb +65 -32
  15. data/lib/valvat/checksum/at.rb +3 -1
  16. data/lib/valvat/checksum/be.rb +3 -1
  17. data/lib/valvat/checksum/bg.rb +17 -17
  18. data/lib/valvat/checksum/cy.rb +2 -0
  19. data/lib/valvat/checksum/de.rb +5 -3
  20. data/lib/valvat/checksum/dk.rb +3 -1
  21. data/lib/valvat/checksum/ee.rb +2 -0
  22. data/lib/valvat/checksum/es.rb +14 -16
  23. data/lib/valvat/checksum/fi.rb +3 -1
  24. data/lib/valvat/checksum/fr.rb +4 -2
  25. data/lib/valvat/checksum/gb.rb +46 -31
  26. data/lib/valvat/checksum/gr.rb +4 -2
  27. data/lib/valvat/checksum/hr.rb +2 -0
  28. data/lib/valvat/checksum/hu.rb +2 -0
  29. data/lib/valvat/checksum/ie.rb +5 -6
  30. data/lib/valvat/checksum/it.rb +7 -5
  31. data/lib/valvat/checksum/lt.rb +2 -0
  32. data/lib/valvat/checksum/lu.rb +3 -1
  33. data/lib/valvat/checksum/mt.rb +2 -0
  34. data/lib/valvat/checksum/nl.rb +5 -3
  35. data/lib/valvat/checksum/pl.rb +3 -1
  36. data/lib/valvat/checksum/pt.rb +3 -1
  37. data/lib/valvat/checksum/ro.rb +2 -0
  38. data/lib/valvat/checksum/se.rb +5 -3
  39. data/lib/valvat/checksum/si.rb +4 -2
  40. data/lib/valvat/checksum.rb +24 -28
  41. data/lib/valvat/error.rb +5 -2
  42. data/lib/valvat/local.rb +8 -5
  43. data/lib/valvat/locales/de.yml +2 -1
  44. data/lib/valvat/locales/en.yml +2 -1
  45. data/lib/valvat/locales/es.yml +1 -0
  46. data/lib/valvat/locales/fr.yml +1 -0
  47. data/lib/valvat/locales/hu.yml +1 -0
  48. data/lib/valvat/locales/nl.yml +1 -0
  49. data/lib/valvat/locales/pl.yml +1 -0
  50. data/lib/valvat/locales/pt.yml +28 -28
  51. data/lib/valvat/lookup/fault.rb +17 -16
  52. data/lib/valvat/lookup/request.rb +21 -16
  53. data/lib/valvat/lookup/response.rb +11 -10
  54. data/lib/valvat/lookup.rb +5 -4
  55. data/lib/valvat/syntax.rb +31 -30
  56. data/lib/valvat/utils.rb +20 -9
  57. data/lib/valvat/version.rb +3 -1
  58. data/lib/valvat.rb +4 -2
  59. data/spec/active_model/validations/valvat_validator_spec.rb +119 -87
  60. data/spec/spec_helper.rb +8 -8
  61. data/spec/valvat/checksum/at_spec.rb +6 -4
  62. data/spec/valvat/checksum/be_spec.rb +6 -4
  63. data/spec/valvat/checksum/bg_spec.rb +7 -4
  64. data/spec/valvat/checksum/cy_spec.rb +3 -1
  65. data/spec/valvat/checksum/de_spec.rb +6 -4
  66. data/spec/valvat/checksum/dk_spec.rb +6 -4
  67. data/spec/valvat/checksum/ee_spec.rb +3 -1
  68. data/spec/valvat/checksum/es_spec.rb +7 -4
  69. data/spec/valvat/checksum/fi_spec.rb +6 -4
  70. data/spec/valvat/checksum/fr_spec.rb +6 -4
  71. data/spec/valvat/checksum/gb_spec.rb +4 -2
  72. data/spec/valvat/checksum/gr_spec.rb +6 -4
  73. data/spec/valvat/checksum/hr_spec.rb +3 -1
  74. data/spec/valvat/checksum/hu_spec.rb +3 -1
  75. data/spec/valvat/checksum/ie_spec.rb +8 -6
  76. data/spec/valvat/checksum/it_spec.rb +10 -8
  77. data/spec/valvat/checksum/lt_spec.rb +3 -1
  78. data/spec/valvat/checksum/lu_spec.rb +6 -4
  79. data/spec/valvat/checksum/mt_spec.rb +3 -1
  80. data/spec/valvat/checksum/nl_spec.rb +9 -7
  81. data/spec/valvat/checksum/pl_spec.rb +8 -6
  82. data/spec/valvat/checksum/pt_spec.rb +10 -11
  83. data/spec/valvat/checksum/ro_spec.rb +3 -1
  84. data/spec/valvat/checksum/se_spec.rb +8 -6
  85. data/spec/valvat/checksum/si_spec.rb +10 -8
  86. data/spec/valvat/checksum_spec.rb +24 -9
  87. data/spec/valvat/lookup/fault_spec.rb +34 -0
  88. data/spec/valvat/lookup/request_spec.rb +19 -0
  89. data/spec/valvat/lookup/response_spec.rb +29 -0
  90. data/spec/valvat/lookup_spec.rb +138 -153
  91. data/spec/valvat/syntax_spec.rb +59 -280
  92. data/spec/valvat/utils_spec.rb +77 -42
  93. data/spec/valvat_spec.rb +140 -152
  94. data/valvat.gemspec +17 -17
  95. data.tar.gz.sig +0 -0
  96. metadata +44 -47
  97. metadata.gz.sig +0 -0
  98. data/.travis.yml +0 -47
  99. data/gemfiles/activemodel-3-2 +0 -7
  100. data/gemfiles/activemodel-4 +0 -7
  101. data/gemfiles/before-ruby21/activemodel-3-2 +0 -8
  102. data/gemfiles/before-ruby21/activemodel-4 +0 -8
  103. data/gemfiles/before-ruby21/standalone +0 -7
  104. data/spec/valvat/lockup/fault_spec.rb +0 -32
  105. data/spec/valvat/lockup/request_spec.rb +0 -15
  106. data/spec/valvat/lockup/response_spec.rb +0 -27
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'savon'
2
4
 
3
5
  class Valvat
@@ -12,13 +14,11 @@ class Valvat
12
14
  end
13
15
 
14
16
  def perform
15
- begin
16
- Response.new(
17
- client.call(action, message: message, message_tag: message_tag)
18
- )
19
- rescue Savon::SOAPFault => fault
20
- Fault.new(fault)
21
- end
17
+ Response.new(
18
+ client.call(action, message: message, message_tag: message_tag, soap_action: nil)
19
+ )
20
+ rescue Savon::SOAPFault => e
21
+ Fault.new(e)
22
22
  end
23
23
 
24
24
  private
@@ -30,14 +30,10 @@ class Valvat
30
30
  end
31
31
 
32
32
  def message
33
- {
34
- country_code: @vat.vat_country_code,
35
- vat_number: @vat.to_s_wo_country
36
- }.merge(@requester ? {
37
- requester_country_code: @requester.vat_country_code,
38
- requester_vat_number: @requester.to_s_wo_country
39
- } : {}
40
- )
33
+ add_requester({
34
+ country_code: @vat.vat_country_code,
35
+ vat_number: @vat.to_s_wo_country
36
+ })
41
37
  end
42
38
 
43
39
  def message_tag
@@ -47,6 +43,15 @@ class Valvat
47
43
  def action
48
44
  @requester ? :check_vat_approx : :check_vat
49
45
  end
46
+
47
+ def add_requester(message)
48
+ return message unless @requester
49
+
50
+ message[:requester_country_code] = @requester.vat_country_code
51
+ message[:requester_vat_number] = @requester.to_s_wo_country
52
+
53
+ message
54
+ end
50
55
  end
51
56
  end
52
- end
57
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  class Lookup
3
5
  class Response
@@ -10,27 +12,26 @@ class Valvat
10
12
  end
11
13
 
12
14
  def to_hash
13
- @hash ||= self.class.cleanup(@raw.to_hash)
15
+ @to_hash ||= self.class.cleanup(@raw.to_hash)
14
16
  end
15
17
 
16
- private
17
-
18
18
  def self.cleanup(hash)
19
- (hash[:check_vat_approx_response] || hash[:check_vat_response] || {}).inject({}) do |hash, (key, value)|
20
- hash[cleanup_key(key)] = cleanup_value(value) unless key == :"@xmlns"
21
- hash
19
+ (
20
+ hash[:check_vat_approx_response] || hash[:check_vat_response] || {}
21
+ ).each_with_object({}) do |(key, value), result|
22
+ result[cleanup_key(key)] = cleanup_value(value) unless key == :"@xmlns"
22
23
  end
23
24
  end
24
25
 
25
- TRADER_PREFIX = /\Atrader_/
26
+ TRADER_PREFIX = /\Atrader_/.freeze
26
27
 
27
28
  def self.cleanup_key(key)
28
- key.to_s.sub(TRADER_PREFIX, "").to_sym
29
+ key.to_s.sub(TRADER_PREFIX, '').to_sym
29
30
  end
30
31
 
31
32
  def self.cleanup_value(value)
32
- value == "---" ? nil : value
33
+ value == '---' ? nil : value
33
34
  end
34
35
  end
35
36
  end
36
- end
37
+ end
data/lib/valvat/lookup.rb CHANGED
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  class Lookup
3
-
4
- def initialize(vat, options={})
5
+ def initialize(vat, options = {})
5
6
  @vat = Valvat(vat)
6
7
  @options = options || {}
7
8
  @options[:requester] ||= @options[:requester_vat]
@@ -15,7 +16,7 @@ class Valvat
15
16
  end
16
17
 
17
18
  class << self
18
- def validate(vat, options={})
19
+ def validate(vat, options = {})
19
20
  new(vat, options).validate
20
21
  end
21
22
  end
@@ -35,7 +36,7 @@ class Valvat
35
36
  end
36
37
 
37
38
  def handle_vies_error(error)
38
- if ViesMaintenanceError === error
39
+ if error.is_a?(ViesMaintenanceError)
39
40
  raise error if @options[:raise_error]
40
41
  else
41
42
  raise error unless @options[:raise_error] == false
data/lib/valvat/syntax.rb CHANGED
@@ -1,36 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
4
  module Syntax
3
-
4
5
  VAT_PATTERNS = {
5
- 'AT' => /\AATU[0-9]{8}\Z/, # Austria
6
- 'BE' => /\ABE0[0-9]{9}\Z/, # Belgium
7
- 'BG' => /\ABG[0-9]{9,10}\Z/, # Bulgaria
8
- 'CY' => /\ACY(?!12)[0-59][0-9]{7}[A-Z]\Z/, # Cyprus
9
- 'CZ' => /\ACZ[0-9]{8,10}\Z/, # Czech Republic
10
- 'DE' => /\ADE[0-9]{9}\Z/, # Germany
11
- 'DK' => /\ADK[0-9]{8}\Z/, # Denmark
12
- 'EE' => /\AEE10[0-9]{7}\Z/, # Estonia
13
- 'GR' => /\AEL[0-9]{9}\Z/, # Greece
14
- 'ES' => /\AES([A-Z][0-9]{8}|[0-9]{8}[A-Z]|[A-Z][0-9]{7}[A-Z])\Z/, # Spain
15
- 'FI' => /\AFI[0-9]{8}\Z/, # Finland
16
- 'FR' => /\AFR[A-Z0-9]{2}[0-9]{9}\Z/, # France
17
- 'GB' => /\AGB([0-9]{9}|[0-9]{12}|(HA|GD)[0-9]{3})\Z/, # United Kingdom
18
- 'HR' => /\AHR[0-9]{11}\Z/, # Croatia
19
- 'HU' => /\AHU[0-9]{8}\Z/, # Hungary
20
- 'IE' => /\AIE([0-9][A-Z][0-9]{5}|[0-9]{7}[A-Z]?)[A-Z]\Z/, # Ireland
21
- 'IT' => /\AIT[0-9]{11}\Z/, # Italy
22
- 'LT' => /\ALT([0-9]{7}1[0-9]|[0-9]{10}1[0-9])\Z/, # Lithuania
23
- 'LU' => /\ALU[0-9]{8}\Z/, # Luxembourg
24
- 'LV' => /\ALV[0-9]{11}\Z/, # Latvia
25
- 'MT' => /\AMT[0-9]{8}\Z/, # Malta
26
- 'NL' => /\ANL[0-9]{9}B[0-9]{2}\Z/, # Netherlands
27
- 'PL' => /\APL[0-9]{10}\Z/, # Poland
28
- 'PT' => /\APT[0-9]{9}\Z/, # Portugal
29
- 'RO' => /\ARO[1-9][0-9]{1,9}\Z/, # Romania
30
- 'SE' => /\ASE[0-9]{10}01\Z/, # Sweden
31
- 'SI' => /\ASI[0-9]{8}\Z/, # Slovenia
32
- 'SK' => /\ASK[0-9]{10}\Z/ # Slovakia
33
- }
6
+ 'AT' => /\AATU[0-9]{8}\Z/, # Austria
7
+ 'BE' => /\ABE0[0-9]{9}\Z/, # Belgium
8
+ 'BG' => /\ABG[0-9]{9,10}\Z/, # Bulgaria
9
+ 'CY' => /\ACY(?!12)[0-59][0-9]{7}[A-Z]\Z/, # Cyprus
10
+ 'CZ' => /\ACZ[0-9]{8,10}\Z/, # Czech Republic
11
+ 'DE' => /\ADE[0-9]{9}\Z/, # Germany
12
+ 'DK' => /\ADK[0-9]{8}\Z/, # Denmark
13
+ 'EE' => /\AEE10[0-9]{7}\Z/, # Estonia
14
+ 'GR' => /\AEL[0-9]{9}\Z/, # Greece
15
+ 'ES' => /\AES([A-Z][0-9]{8}|[0-9]{8}[A-Z]|[A-Z][0-9]{7}[A-Z])\Z/, # Spain
16
+ 'FI' => /\AFI[0-9]{8}\Z/, # Finland
17
+ 'FR' => /\AFR[A-Z0-9]{2}[0-9]{9}\Z/, # France
18
+ 'GB' => /\A(GB|XI)([0-9]{9}|[0-9]{12}|(HA|GD)[0-9]{3})\Z/, # United Kingdom
19
+ 'HR' => /\AHR[0-9]{11}\Z/, # Croatia
20
+ 'HU' => /\AHU[0-9]{8}\Z/, # Hungary
21
+ 'IE' => /\AIE([0-9][A-Z][0-9]{5}|[0-9]{7}[A-Z]?)[A-Z]\Z/, # Ireland
22
+ 'IT' => /\AIT[0-9]{11}\Z/, # Italy
23
+ 'LT' => /\ALT([0-9]{7}1[0-9]|[0-9]{10}1[0-9])\Z/, # Lithuania
24
+ 'LU' => /\ALU[0-9]{8}\Z/, # Luxembourg
25
+ 'LV' => /\ALV[0-9]{11}\Z/, # Latvia
26
+ 'MT' => /\AMT[0-9]{8}\Z/, # Malta
27
+ 'NL' => /\ANL[0-9]{9}B[0-9]{2}\Z/, # Netherlands
28
+ 'PL' => /\APL[0-9]{10}\Z/, # Poland
29
+ 'PT' => /\APT[0-9]{9}\Z/, # Portugal
30
+ 'RO' => /\ARO[1-9][0-9]{1,9}\Z/, # Romania
31
+ 'SE' => /\ASE[0-9]{10}01\Z/, # Sweden
32
+ 'SI' => /\ASI[0-9]{8}\Z/, # Slovenia
33
+ 'SK' => /\ASK[0-9]{10}\Z/ # Slovakia
34
+ }.freeze
34
35
 
35
36
  def self.validate(vat)
36
37
  vat = Valvat(vat)
data/lib/valvat/utils.rb CHANGED
@@ -1,27 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
1
5
  class Valvat
2
6
  module Utils
3
-
4
- EU_COUNTRIES = %w(AT BE BG CY CZ DE DK EE ES FI FR GB GR HR HU IE IT LT LU LV MT NL PL PT RO SE SI SK)
5
- COUNTRY_PATTERN = /\A([A-Z]{2})(.+)\Z/
6
- NORMALIZE_PATTERN = /[[:space:][:punct:][:cntrl:]]+/
7
+ EU_MEMBER_STATES = %w[AT BE BG CY CZ DE DK EE ES FI FR GR HR HU IE IT LT LU LV MT NL PL PT RO SE SI SK].freeze
8
+ SUPPORTED_STATES = EU_MEMBER_STATES + %w[GB]
9
+ EU_COUNTRIES = EU_MEMBER_STATES # TODO: Remove constant
10
+ COUNTRY_PATTERN = /\A([A-Z]{2})(.+)\Z/.freeze
11
+ NORMALIZE_PATTERN = /[[:space:][:punct:][:cntrl:]]+/.freeze
12
+ CONVERT_VAT_TO_ISO_COUNTRY = { 'EL' => 'GR', 'XI' => 'GB' }.freeze
13
+ CONVERT_ISO_TO_VAT_COUNTRY = CONVERT_VAT_TO_ISO_COUNTRY.invert.freeze
7
14
 
8
15
  def self.split(vat)
9
16
  COUNTRY_PATTERN =~ vat
10
- result = [$1, $2]
17
+ result = [Regexp.last_match(1), Regexp.last_match(2)]
11
18
  iso_country = vat_country_to_iso_country(result[0])
12
- EU_COUNTRIES.include?(iso_country) ? result : [nil, nil]
19
+ country_is_supported?(iso_country) ? result : [nil, nil]
13
20
  end
14
21
 
15
22
  def self.normalize(vat)
16
- vat.to_s.upcase.gsub(NORMALIZE_PATTERN, "")
23
+ vat.to_s.upcase.gsub(NORMALIZE_PATTERN, '')
17
24
  end
18
25
 
19
26
  def self.vat_country_to_iso_country(vat_country)
20
- vat_country == "EL" ? "GR" : vat_country
27
+ CONVERT_VAT_TO_ISO_COUNTRY[vat_country] || vat_country
21
28
  end
22
29
 
23
30
  def self.iso_country_to_vat_country(iso_country)
24
- iso_country == "GR" ? "EL" : iso_country
31
+ CONVERT_ISO_TO_VAT_COUNTRY[iso_country] || iso_country
32
+ end
33
+
34
+ def self.country_is_supported?(iso_country)
35
+ SUPPORTED_STATES.include?(iso_country)
25
36
  end
26
37
  end
27
38
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Valvat
2
- VERSION = "1.0.0"
4
+ VERSION = '1.1.2'
3
5
  end
data/lib/valvat.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'valvat/error'
2
4
  require 'valvat/local'
3
5
  require 'valvat/lookup'
@@ -7,8 +9,8 @@ require 'valvat/lookup/fault'
7
9
  require 'active_model/validations/valvat_validator' if defined?(ActiveModel)
8
10
 
9
11
  class Valvat
10
- def exists?(options={})
12
+ def exists?(options = {})
11
13
  Valvat::Lookup.validate(self, options)
12
14
  end
13
- alias_method :exist?, :exists?
15
+ alias exist? exists?
14
16
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  if defined?(ActiveModel)
@@ -6,15 +8,15 @@ if defined?(ActiveModel)
6
8
  end
7
9
 
8
10
  class InvoiceWithLookup < ModelBase
9
- validates :vat_number, valvat: {lookup: true}
11
+ validates :vat_number, valvat: { lookup: true }
10
12
  end
11
13
 
12
14
  class InvoiceWithLookupAndFailIfDown < ModelBase
13
- validates :vat_number, valvat: {lookup: :fail_if_down}
15
+ validates :vat_number, valvat: { lookup: :fail_if_down }
14
16
  end
15
17
 
16
18
  class InvoiceAllowBlank < ModelBase
17
- validates :vat_number, valvat: {allow_blank: true}
19
+ validates :vat_number, valvat: { allow_blank: true }
18
20
  end
19
21
 
20
22
  class InvoiceAllowBlankOnAll < ModelBase
@@ -22,7 +24,7 @@ if defined?(ActiveModel)
22
24
  end
23
25
 
24
26
  class InvoiceCheckCountry < ModelBase
25
- validates :vat_number, valvat: {match_country: :country}
27
+ validates :vat_number, valvat: { match_country: :country }
26
28
 
27
29
  def country
28
30
  @attributes[:country]
@@ -30,7 +32,7 @@ if defined?(ActiveModel)
30
32
  end
31
33
 
32
34
  class InvoiceCheckCountryWithLookup < ModelBase
33
- validates :vat_number, valvat: {match_country: :country, lookup: true}
35
+ validates :vat_number, valvat: { match_country: :country, lookup: true }
34
36
 
35
37
  def country
36
38
  @attributes[:country]
@@ -38,172 +40,202 @@ if defined?(ActiveModel)
38
40
  end
39
41
 
40
42
  class InvoiceWithChecksum < ModelBase
41
- validates :vat_number, valvat: {checksum: true}
43
+ validates :vat_number, valvat: { checksum: true }
42
44
  end
43
45
 
44
46
  describe Invoice do
45
- context "with valid VAT number" do
46
- it "should be valid" do
47
- expect(Invoice.new(vat_number: "DE259597697")).to be_valid
47
+ before do
48
+ I18n.locale = :en
49
+ end
50
+
51
+ context 'with valid VAT number' do
52
+ it 'is valid' do
53
+ expect(described_class.new(vat_number: 'DE259597697')).to be_valid
48
54
  end
49
55
  end
50
56
 
51
- context "with invalid VAT number" do
52
- let(:invoice) { Invoice.new(vat_number: "DE259597697123") }
57
+ context 'with invalid VAT number' do
58
+ let(:invoice) { described_class.new(vat_number: 'DE259597697123') }
53
59
 
54
- it "should not be valid" do
60
+ it 'is not valid' do
55
61
  expect(invoice).not_to be_valid
56
62
  end
57
63
 
58
- it "should add default (country specific) error message" do
64
+ it 'adds default (country specific) error message' do
59
65
  invoice.valid?
60
- expect(invoice.errors[:vat_number]).to eql(["is not a valid German VAT number"])
66
+ expect(invoice.errors[:vat_number]).to eql(['is not a valid German VAT number'])
67
+ end
68
+
69
+ context 'with DE locale' do
70
+ before do
71
+ I18n.locale = :de
72
+ end
73
+
74
+ it 'adds translated error message' do
75
+ invoice.valid?
76
+ expect(invoice.errors[:vat_number]).to eql(['ist keine gültige deutsche USt-IdNr.'])
77
+ end
78
+ end
79
+
80
+ context 'with PT locale' do
81
+ before do
82
+ I18n.locale = :pt
83
+ end
84
+
85
+ it 'adds translated error message' do
86
+ invoice.valid?
87
+ expect(invoice.errors[:vat_number]).to eql(['O NIF alemão não é válido.'])
88
+ end
61
89
  end
62
90
 
63
- context "with i18n translation in place" do
91
+ context 'with i18n translation in place' do
64
92
  before do
65
93
  I18n.backend.store_translations(:en, activemodel: {
66
- errors: {models: {invoice: {invalid_vat: "is ugly."}}}
67
- })
94
+ errors: { models: { invoice: { invalid_vat: 'is ugly.' } } }
95
+ })
68
96
  end
69
97
 
70
98
  after { I18n.reload! }
71
99
 
72
- it "should use translation" do
100
+ it 'uses translation' do
73
101
  invoice.valid?
74
- expect(invoice.errors[:vat_number]).to eql(["is ugly."])
102
+ expect(invoice.errors[:vat_number]).to eql(['is ugly.'])
75
103
  end
76
104
  end
77
105
 
78
- context "with i18n translation with country adjective placeholder in place" do
106
+ context 'with i18n translation with country_adjective placeholder in place' do
79
107
  before do
80
- I18n.backend.store_translations(:en, activemodel: {
81
- errors: {models: {invoice: {invalid_vat: "is not a %{country_adjective} vat"}}}
82
- })
108
+ msg = 'is not a %{country_adjective} vat' # rubocop:disable Style/FormatStringToken
109
+ translation = { activemodel: { errors: { models: { invoice: { invalid_vat: msg } } } } }
110
+ I18n.backend.store_translations(:en, translation)
83
111
  end
84
112
 
85
113
  after { I18n.reload! }
86
114
 
87
- it "should replace country adjective placeholder" do
88
- invoice = Invoice.new(vat_number: "IE123")
115
+ it 'replaces country_adjective placeholder' do
116
+ invoice = described_class.new(vat_number: 'IE123')
89
117
  invoice.valid?
90
- expect(invoice.errors[:vat_number]).to eql(["is not a Irish vat"])
118
+ expect(invoice.errors[:vat_number]).to eql(['is not a Irish vat'])
91
119
  end
92
120
 
93
- it "should fall back to 'European' if country is missing" do
94
- invoice = Invoice.new(vat_number: "XX123")
121
+ it "falls back to 'European' if country is missing" do
122
+ invoice = described_class.new(vat_number: 'XX123')
95
123
  invoice.valid?
96
- expect(invoice.errors[:vat_number]).to eql(["is not a European vat"])
124
+ expect(invoice.errors[:vat_number]).to eql(['is not a European vat'])
97
125
  end
98
126
  end
99
127
  end
100
128
 
101
- context "with blank VAT number" do
102
- it "should not be valid" do
103
- expect(Invoice.new(vat_number: "")).not_to be_valid
104
- expect(Invoice.new(vat_number: nil)).not_to be_valid
129
+ context 'with blank VAT number' do
130
+ it 'is not valid' do
131
+ expect(described_class.new(vat_number: '')).not_to be_valid
132
+ expect(described_class.new(vat_number: nil)).not_to be_valid
105
133
  end
106
134
  end
107
135
  end
108
136
 
109
137
  describe InvoiceWithLookup do
110
- context "with valid but not existing VAT number" do
138
+ context 'with valid but not existing VAT number' do
111
139
  before do
112
140
  allow(Valvat::Syntax).to receive_messages(validate: true)
113
141
  allow(Valvat::Lookup).to receive_messages(validate: false)
114
142
  end
115
143
 
116
- it "should not be valid" do
117
- expect(InvoiceWithLookup.new(vat_number: "DE123")).not_to be_valid
144
+ it 'is not valid' do
145
+ expect(described_class.new(vat_number: 'DE123')).not_to be_valid
118
146
  end
119
147
  end
120
148
 
121
- context "with valid and existing VAT number" do
149
+ context 'with valid and existing VAT number' do
122
150
  before do
123
151
  allow(Valvat::Syntax).to receive_messages(validate: true)
124
152
  allow(Valvat::Lookup).to receive_messages(validate: true)
125
153
  end
126
154
 
127
- it "should be valid" do
128
- expect(InvoiceWithLookup.new(vat_number: "DE123")).to be_valid
155
+ it 'is valid' do
156
+ expect(described_class.new(vat_number: 'DE123')).to be_valid
129
157
  end
130
158
  end
131
159
 
132
- context "with valid VAT number and VIES country service down" do
160
+ context 'with valid VAT number and VIES country service down' do
133
161
  before do
134
162
  allow(Valvat::Syntax).to receive_messages(validate: true)
135
163
  allow(Valvat::Lookup).to receive_messages(validate: nil)
136
164
  end
137
165
 
138
- it "should be valid" do
139
- expect(InvoiceWithLookup.new(vat_number: "DE123")).to be_valid
166
+ it 'is valid' do
167
+ expect(described_class.new(vat_number: 'DE123')).to be_valid
140
168
  end
141
169
  end
142
170
  end
143
171
 
144
172
  describe InvoiceWithLookupAndFailIfDown do
145
- context "with valid VAT number and VIES country service down" do
173
+ let(:record) { described_class.new }
174
+
175
+ context 'with valid VAT number and VIES country service down' do
146
176
  before do
147
177
  allow(Valvat::Syntax).to receive_messages(validate: true)
148
178
  allow(Valvat::Lookup).to receive_messages(validate: nil)
149
179
  end
150
180
 
151
- it "should not be valid" do
152
- expect(InvoiceWithLookupAndFailIfDown.new(vat_number: "DE123")).not_to be_valid
181
+ it 'is not valid' do
182
+ expect(record).not_to be_valid
183
+ msg = 'Unable to validate your VAT number: the VIES service is down. Please try again later.'
184
+ expect(record.errors[:vat_number]).to eql([msg])
153
185
  end
154
186
  end
155
187
  end
156
188
 
157
189
  describe InvoiceAllowBlank do
158
- context "with blank VAT number" do
159
- it "should be valid" do
160
- expect(InvoiceAllowBlank.new(vat_number: "")).to be_valid
161
- expect(InvoiceAllowBlank.new(vat_number: nil)).to be_valid
190
+ context 'with blank VAT number' do
191
+ it 'is valid' do
192
+ expect(described_class.new(vat_number: '')).to be_valid
193
+ expect(described_class.new(vat_number: nil)).to be_valid
162
194
  end
163
195
  end
164
196
  end
165
197
 
166
198
  describe InvoiceAllowBlankOnAll do
167
- context "with blank VAT number" do
168
- it "should be valid" do
169
- expect(InvoiceAllowBlankOnAll.new(vat_number: "")).to be_valid
170
- expect(InvoiceAllowBlankOnAll.new(vat_number: nil)).to be_valid
199
+ context 'with blank VAT number' do
200
+ it 'is valid' do
201
+ expect(described_class.new(vat_number: '')).to be_valid
202
+ expect(described_class.new(vat_number: nil)).to be_valid
171
203
  end
172
204
  end
173
205
  end
174
206
 
175
207
  describe InvoiceCheckCountry do
176
- it "should be not valid on blank country" do
177
- expect(InvoiceCheckCountry.new(country: nil, vat_number: "DE259597697")).not_to be_valid
178
- expect(InvoiceCheckCountry.new(country: "", vat_number: "DE259597697")).not_to be_valid
208
+ it 'is not valid on blank country' do
209
+ expect(described_class.new(country: nil, vat_number: 'DE259597697')).not_to be_valid
210
+ expect(described_class.new(country: '', vat_number: 'DE259597697')).not_to be_valid
179
211
  end
180
212
 
181
- it "should be not valid on wired country" do
182
- expect(InvoiceCheckCountry.new(country: "XAXXX", vat_number: "DE259597697")).not_to be_valid
183
- expect(InvoiceCheckCountry.new(country: "ZO", vat_number: "DE259597697")).not_to be_valid
213
+ it 'is not valid on wired country' do
214
+ expect(described_class.new(country: 'XAXXX', vat_number: 'DE259597697')).not_to be_valid
215
+ expect(described_class.new(country: 'ZO', vat_number: 'DE259597697')).not_to be_valid
184
216
  end
185
217
 
186
- it "should be not valid on mismatching (eu) country" do
187
- expect(InvoiceCheckCountry.new(country: "FR", vat_number: "DE259597697")).not_to be_valid
188
- expect(InvoiceCheckCountry.new(country: "AT", vat_number: "DE259597697")).not_to be_valid
189
- expect(InvoiceCheckCountry.new(country: "DE", vat_number: "ATU65931334")).not_to be_valid
218
+ it 'is not valid on mismatching (eu) country' do
219
+ expect(described_class.new(country: 'FR', vat_number: 'DE259597697')).not_to be_valid
220
+ expect(described_class.new(country: 'AT', vat_number: 'DE259597697')).not_to be_valid
221
+ expect(described_class.new(country: 'DE', vat_number: 'ATU65931334')).not_to be_valid
190
222
  end
191
223
 
192
- it "should be valid on matching country" do
193
- expect(InvoiceCheckCountry.new(country: "DE", vat_number: "DE259597697")).to be_valid
194
- expect(InvoiceCheckCountry.new(country: "AT", vat_number: "ATU65931334")).to be_valid
224
+ it 'is valid on matching country' do
225
+ expect(described_class.new(country: 'DE', vat_number: 'DE259597697')).to be_valid
226
+ expect(described_class.new(country: 'AT', vat_number: 'ATU65931334')).to be_valid
195
227
  end
196
228
 
197
- it "should give back error message with country from :country_match" do
198
- invoice = InvoiceCheckCountry.new(country: "FR", vat_number: "DE259597697")
229
+ it 'gives back error message with country from :country_match' do
230
+ invoice = described_class.new(country: 'FR', vat_number: 'DE259597697')
199
231
  invoice.valid?
200
- expect(invoice.errors[:vat_number]).to eql(["is not a valid French VAT number"])
232
+ expect(invoice.errors[:vat_number]).to eql(['is not a valid French VAT number'])
201
233
  end
202
234
 
203
- it "should give back error message with country from :country_match even on invalid VAT number" do
204
- invoice = InvoiceCheckCountry.new(country: "FR", vat_number: "DE259597697123")
235
+ it 'gives back error message with country from :country_match even on invalid VAT number' do
236
+ invoice = described_class.new(country: 'FR', vat_number: 'DE259597697123')
205
237
  invoice.valid?
206
- expect(invoice.errors[:vat_number]).to eql(["is not a valid French VAT number"])
238
+ expect(invoice.errors[:vat_number]).to eql(['is not a valid French VAT number'])
207
239
  end
208
240
  end
209
241
 
@@ -213,30 +245,30 @@ if defined?(ActiveModel)
213
245
  allow(Valvat::Lookup).to receive_messages(validate: true)
214
246
  end
215
247
 
216
- it "avoids lookup or syntax check on failed because of mismatching country" do
217
- expect(Valvat::Syntax).not_to receive(:validate)
218
- expect(Valvat::Lookup).not_to receive(:validate)
219
- InvoiceCheckCountryWithLookup.new(country: "FR", vat_number: "DE259597697").valid?
248
+ it 'avoids lookup or syntax check on failed because of mismatching country' do
249
+ described_class.new(country: 'FR', vat_number: 'DE259597697').valid?
250
+ expect(Valvat::Syntax).not_to have_received(:validate)
251
+ expect(Valvat::Lookup).not_to have_received(:validate)
220
252
  end
221
253
 
222
- it "check syntax and looup on matching country" do
223
- expect(Valvat::Syntax).to receive(:validate).and_return(true)
224
- expect(Valvat::Lookup).to receive(:validate).and_return(true)
225
- InvoiceCheckCountryWithLookup.new(country: "DE", vat_number: "DE259597697").valid?
254
+ it 'check syntax and looup on matching country' do
255
+ described_class.new(country: 'DE', vat_number: 'DE259597697').valid?
256
+ expect(Valvat::Syntax).to have_received(:validate)
257
+ expect(Valvat::Lookup).to have_received(:validate)
226
258
  end
227
259
  end
228
260
 
229
261
  describe InvoiceWithChecksum do
230
- context "with valid VAT number" do
231
- it "should be valid" do
232
- expect(InvoiceWithChecksum.new(vat_number: "DE259597697")).to be_valid
262
+ context 'with valid VAT number' do
263
+ it 'is valid' do
264
+ expect(described_class.new(vat_number: 'DE259597697')).to be_valid
233
265
  end
234
266
  end
235
267
 
236
- context "with invalid VAT number" do
237
- it "should not be valid" do
238
- expect(InvoiceWithChecksum.new(vat_number: "DE259597687")).not_to be_valid
268
+ context 'with invalid VAT number' do
269
+ it 'is not valid' do
270
+ expect(described_class.new(vat_number: 'DE259597687')).not_to be_valid
239
271
  end
240
272
  end
241
273
  end
242
- end
274
+ end