valvat 0.8.1 → 1.0.1
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +2 -1
- data/.travis.yml +30 -16
- data/CHANGES.md +45 -2
- data/Gemfile +2 -3
- data/README.md +96 -46
- data/certs/yolk.pem +24 -20
- data/gemfiles/activemodel-3-2 +3 -4
- data/gemfiles/activemodel-4 +3 -4
- data/gemfiles/activemodel-5 +4 -5
- data/gemfiles/activemodel-6 +7 -0
- data/gemfiles/before-ruby21/activemodel-3-2 +3 -4
- data/gemfiles/before-ruby21/activemodel-4 +3 -4
- data/gemfiles/before-ruby21/standalone +3 -4
- data/gemfiles/standalone +3 -5
- data/lib/active_model/validations/valvat_validator.rb +20 -5
- data/lib/valvat.rb +3 -1
- data/lib/valvat/checksum/gb.rb +30 -13
- data/lib/valvat/checksum/ie.rb +1 -1
- data/lib/valvat/checksum/nl.rb +5 -0
- data/lib/valvat/checksum/si.rb +2 -2
- data/lib/valvat/error.rb +28 -0
- data/lib/valvat/local.rb +2 -1
- data/lib/valvat/locales/en.yml +1 -1
- data/lib/valvat/locales/fr.yml +17 -17
- data/lib/valvat/locales/pt.yml +28 -28
- data/lib/valvat/lookup.rb +11 -43
- data/lib/valvat/lookup/fault.rb +30 -0
- data/lib/valvat/lookup/request.rb +33 -12
- data/lib/valvat/lookup/response.rb +36 -0
- data/lib/valvat/utils.rb +11 -3
- data/lib/valvat/version.rb +1 -1
- data/spec/active_model/validations/valvat_validator_spec.rb +92 -66
- data/spec/valvat/checksum/at_spec.rb +2 -2
- data/spec/valvat/checksum/be_spec.rb +2 -2
- data/spec/valvat/checksum/bg_spec.rb +2 -2
- data/spec/valvat/checksum/cy_spec.rb +2 -2
- data/spec/valvat/checksum/de_spec.rb +2 -2
- data/spec/valvat/checksum/dk_spec.rb +2 -2
- data/spec/valvat/checksum/ee_spec.rb +2 -2
- data/spec/valvat/checksum/es_spec.rb +2 -2
- data/spec/valvat/checksum/fi_spec.rb +2 -2
- data/spec/valvat/checksum/fr_spec.rb +2 -2
- data/spec/valvat/checksum/gb_spec.rb +5 -3
- data/spec/valvat/checksum/gr_spec.rb +2 -2
- data/spec/valvat/checksum/hr_spec.rb +2 -2
- data/spec/valvat/checksum/hu_spec.rb +2 -2
- data/spec/valvat/checksum/ie_spec.rb +8 -2
- data/spec/valvat/checksum/it_spec.rb +4 -4
- data/spec/valvat/checksum/lt_spec.rb +2 -2
- data/spec/valvat/checksum/lu_spec.rb +2 -2
- data/spec/valvat/checksum/mt_spec.rb +2 -2
- data/spec/valvat/checksum/nl_spec.rb +4 -4
- data/spec/valvat/checksum/pl_spec.rb +3 -3
- data/spec/valvat/checksum/pt_spec.rb +2 -2
- data/spec/valvat/checksum/ro_spec.rb +2 -2
- data/spec/valvat/checksum/se_spec.rb +3 -3
- data/spec/valvat/checksum/si_spec.rb +7 -7
- data/spec/valvat/checksum_spec.rb +2 -2
- data/spec/valvat/lockup/fault_spec.rb +32 -0
- data/spec/valvat/lockup/request_spec.rb +15 -0
- data/spec/valvat/lockup/response_spec.rb +27 -0
- data/spec/valvat/lookup_spec.rb +168 -35
- data/spec/valvat/syntax_spec.rb +29 -29
- data/spec/valvat/utils_spec.rb +28 -8
- data/spec/valvat_spec.rb +18 -18
- data/valvat.gemspec +1 -0
- metadata +52 -25
- metadata.gz.sig +0 -0
- data/lib/valvat/lookup/request_with_id.rb +0 -31
@@ -0,0 +1,30 @@
|
|
1
|
+
class Valvat
|
2
|
+
class Lookup
|
3
|
+
class Fault < Response
|
4
|
+
private
|
5
|
+
|
6
|
+
def self.cleanup(hash)
|
7
|
+
fault = hash[:fault][:faultstring]
|
8
|
+
return {valid: false} if fault == "INVALID_INPUT"
|
9
|
+
{error: fault_to_error(fault)}
|
10
|
+
end
|
11
|
+
|
12
|
+
FAULTS = {
|
13
|
+
"SERVICE_UNAVAILABLE" => ServiceUnavailable,
|
14
|
+
"MS_UNAVAILABLE" => MemberStateUnavailable,
|
15
|
+
"INVALID_REQUESTER_INFO" => InvalidRequester,
|
16
|
+
"TIMEOUT" => Timeout,
|
17
|
+
"VAT_BLOCKED" => BlockedError,
|
18
|
+
"IP_BLOCKED" => BlockedError,
|
19
|
+
"GLOBAL_MAX_CONCURRENT_REQ" => RateLimitError,
|
20
|
+
"GLOBAL_MAX_CONCURRENT_REQ_TIME" => RateLimitError,
|
21
|
+
"MS_MAX_CONCURRENT_REQ" => RateLimitError,
|
22
|
+
"MS_MAX_CONCURRENT_REQ_TIME" => RateLimitError
|
23
|
+
}
|
24
|
+
|
25
|
+
def self.fault_to_error(fault)
|
26
|
+
(FAULTS[fault] || UnknownViesError).new(fault)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,30 +1,51 @@
|
|
1
|
+
require 'savon'
|
2
|
+
|
1
3
|
class Valvat
|
2
4
|
class Lookup
|
3
5
|
class Request
|
4
|
-
|
5
|
-
|
6
|
+
VIES_WSDL_URL = 'https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl'
|
7
|
+
|
8
|
+
def initialize(vat, options)
|
9
|
+
@vat = Valvat(vat)
|
10
|
+
@options = options || {}
|
11
|
+
@requester = @options[:requester] && Valvat(@options[:requester])
|
6
12
|
end
|
7
13
|
|
8
|
-
def perform
|
9
|
-
|
14
|
+
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
|
10
22
|
end
|
11
23
|
|
12
24
|
private
|
13
25
|
|
14
|
-
def
|
15
|
-
{
|
26
|
+
def client
|
27
|
+
Savon::Client.new({
|
28
|
+
wsdl: VIES_WSDL_URL, log: false, follow_redirects: true
|
29
|
+
}.merge(@options[:savon] || {}))
|
16
30
|
end
|
17
31
|
|
18
|
-
def
|
19
|
-
|
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
|
+
)
|
20
41
|
end
|
21
42
|
|
22
|
-
def
|
23
|
-
:
|
43
|
+
def message_tag
|
44
|
+
@requester ? :checkVatApprox : :checkVat
|
24
45
|
end
|
25
46
|
|
26
|
-
def
|
27
|
-
:
|
47
|
+
def action
|
48
|
+
@requester ? :check_vat_approx : :check_vat
|
28
49
|
end
|
29
50
|
end
|
30
51
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Valvat
|
2
|
+
class Lookup
|
3
|
+
class Response
|
4
|
+
def initialize(raw)
|
5
|
+
@raw = raw
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](key)
|
9
|
+
to_hash[key]
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_hash
|
13
|
+
@hash ||= self.class.cleanup(@raw.to_hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
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
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
TRADER_PREFIX = /\Atrader_/
|
26
|
+
|
27
|
+
def self.cleanup_key(key)
|
28
|
+
key.to_s.sub(TRADER_PREFIX, "").to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.cleanup_value(value)
|
32
|
+
value == "---" ? nil : value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/valvat/utils.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
1
3
|
class Valvat
|
2
4
|
module Utils
|
3
5
|
|
4
|
-
|
6
|
+
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)
|
7
|
+
SUPPORTED_STATES = EU_MEMBER_STATES + %w(GB)
|
8
|
+
EU_COUNTRIES = EU_MEMBER_STATES # TODO: Remove constant
|
5
9
|
COUNTRY_PATTERN = /\A([A-Z]{2})(.+)\Z/
|
6
|
-
NORMALIZE_PATTERN = /[
|
10
|
+
NORMALIZE_PATTERN = /[[:space:][:punct:][:cntrl:]]+/
|
7
11
|
|
8
12
|
def self.split(vat)
|
9
13
|
COUNTRY_PATTERN =~ vat
|
10
14
|
result = [$1, $2]
|
11
15
|
iso_country = vat_country_to_iso_country(result[0])
|
12
|
-
|
16
|
+
country_is_supported?(iso_country) ? result : [nil, nil]
|
13
17
|
end
|
14
18
|
|
15
19
|
def self.normalize(vat)
|
@@ -23,5 +27,9 @@ class Valvat
|
|
23
27
|
def self.iso_country_to_vat_country(iso_country)
|
24
28
|
iso_country == "GR" ? "EL" : iso_country
|
25
29
|
end
|
30
|
+
|
31
|
+
def self.country_is_supported?(iso_country)
|
32
|
+
SUPPORTED_STATES.include?(iso_country)
|
33
|
+
end
|
26
34
|
end
|
27
35
|
end
|
data/lib/valvat/version.rb
CHANGED
@@ -2,27 +2,27 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
if defined?(ActiveModel)
|
4
4
|
class Invoice < ModelBase
|
5
|
-
validates :vat_number, :
|
5
|
+
validates :vat_number, valvat: true
|
6
6
|
end
|
7
7
|
|
8
8
|
class InvoiceWithLookup < ModelBase
|
9
|
-
validates :vat_number, :
|
9
|
+
validates :vat_number, valvat: {lookup: true}
|
10
10
|
end
|
11
11
|
|
12
12
|
class InvoiceWithLookupAndFailIfDown < ModelBase
|
13
|
-
validates :vat_number, :
|
13
|
+
validates :vat_number, valvat: {lookup: :fail_if_down}
|
14
14
|
end
|
15
15
|
|
16
16
|
class InvoiceAllowBlank < ModelBase
|
17
|
-
validates :vat_number, :
|
17
|
+
validates :vat_number, valvat: {allow_blank: true}
|
18
18
|
end
|
19
19
|
|
20
20
|
class InvoiceAllowBlankOnAll < ModelBase
|
21
|
-
validates :vat_number, :
|
21
|
+
validates :vat_number, valvat: true, allow_blank: true
|
22
22
|
end
|
23
23
|
|
24
24
|
class InvoiceCheckCountry < ModelBase
|
25
|
-
validates :vat_number, :
|
25
|
+
validates :vat_number, valvat: {match_country: :country}
|
26
26
|
|
27
27
|
def country
|
28
28
|
@attributes[:country]
|
@@ -30,7 +30,7 @@ if defined?(ActiveModel)
|
|
30
30
|
end
|
31
31
|
|
32
32
|
class InvoiceCheckCountryWithLookup < ModelBase
|
33
|
-
validates :vat_number, :
|
33
|
+
validates :vat_number, valvat: {match_country: :country, lookup: true}
|
34
34
|
|
35
35
|
def country
|
36
36
|
@attributes[:country]
|
@@ -38,18 +38,22 @@ if defined?(ActiveModel)
|
|
38
38
|
end
|
39
39
|
|
40
40
|
class InvoiceWithChecksum < ModelBase
|
41
|
-
validates :vat_number, :
|
41
|
+
validates :vat_number, valvat: {checksum: true}
|
42
42
|
end
|
43
43
|
|
44
44
|
describe Invoice do
|
45
|
-
|
45
|
+
before do
|
46
|
+
I18n.locale = :en
|
47
|
+
end
|
48
|
+
|
49
|
+
context "with valid VAT number" do
|
46
50
|
it "should be valid" do
|
47
|
-
expect(Invoice.new(:
|
51
|
+
expect(Invoice.new(vat_number: "DE259597697")).to be_valid
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
51
|
-
context "with invalid
|
52
|
-
let(:invoice) { Invoice.new(:
|
55
|
+
context "with invalid VAT number" do
|
56
|
+
let(:invoice) { Invoice.new(vat_number: "DE259597697123") }
|
53
57
|
|
54
58
|
it "should not be valid" do
|
55
59
|
expect(invoice).not_to be_valid
|
@@ -57,13 +61,35 @@ if defined?(ActiveModel)
|
|
57
61
|
|
58
62
|
it "should add default (country specific) error message" do
|
59
63
|
invoice.valid?
|
60
|
-
expect(invoice.errors[:vat_number]).to eql(["is not a valid German
|
64
|
+
expect(invoice.errors[:vat_number]).to eql(["is not a valid German VAT number"])
|
65
|
+
end
|
66
|
+
|
67
|
+
context "on DE locale" do
|
68
|
+
before do
|
69
|
+
I18n.locale = :de
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should add translated error message" do
|
73
|
+
invoice.valid?
|
74
|
+
expect(invoice.errors[:vat_number]).to eql(["ist keine gültige deutsche USt-IdNr."])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "on PT locale" do
|
79
|
+
before do
|
80
|
+
I18n.locale = :pt
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should add translated error message" do
|
84
|
+
invoice.valid?
|
85
|
+
expect(invoice.errors[:vat_number]).to eql(["O NIF alemão não é válido."])
|
86
|
+
end
|
61
87
|
end
|
62
88
|
|
63
89
|
context "with i18n translation in place" do
|
64
90
|
before do
|
65
|
-
I18n.backend.store_translations(:en, :
|
66
|
-
:
|
91
|
+
I18n.backend.store_translations(:en, activemodel: {
|
92
|
+
errors: {models: {invoice: {invalid_vat: "is ugly."}}}
|
67
93
|
})
|
68
94
|
end
|
69
95
|
|
@@ -77,165 +103,165 @@ if defined?(ActiveModel)
|
|
77
103
|
|
78
104
|
context "with i18n translation with country adjective placeholder in place" do
|
79
105
|
before do
|
80
|
-
I18n.backend.store_translations(:en, :
|
81
|
-
:
|
106
|
+
I18n.backend.store_translations(:en, activemodel: {
|
107
|
+
errors: {models: {invoice: {invalid_vat: "is not a %{country_adjective} vat"}}}
|
82
108
|
})
|
83
109
|
end
|
84
110
|
|
85
111
|
after { I18n.reload! }
|
86
112
|
|
87
113
|
it "should replace country adjective placeholder" do
|
88
|
-
invoice = Invoice.new(:
|
114
|
+
invoice = Invoice.new(vat_number: "IE123")
|
89
115
|
invoice.valid?
|
90
116
|
expect(invoice.errors[:vat_number]).to eql(["is not a Irish vat"])
|
91
117
|
end
|
92
118
|
|
93
119
|
it "should fall back to 'European' if country is missing" do
|
94
|
-
invoice = Invoice.new(:
|
120
|
+
invoice = Invoice.new(vat_number: "XX123")
|
95
121
|
invoice.valid?
|
96
122
|
expect(invoice.errors[:vat_number]).to eql(["is not a European vat"])
|
97
123
|
end
|
98
124
|
end
|
99
125
|
end
|
100
126
|
|
101
|
-
context "with blank
|
127
|
+
context "with blank VAT number" do
|
102
128
|
it "should not be valid" do
|
103
|
-
expect(Invoice.new(:
|
104
|
-
expect(Invoice.new(:
|
129
|
+
expect(Invoice.new(vat_number: "")).not_to be_valid
|
130
|
+
expect(Invoice.new(vat_number: nil)).not_to be_valid
|
105
131
|
end
|
106
132
|
end
|
107
133
|
end
|
108
134
|
|
109
135
|
describe InvoiceWithLookup do
|
110
|
-
context "with valid but not existing
|
136
|
+
context "with valid but not existing VAT number" do
|
111
137
|
before do
|
112
|
-
allow(Valvat::Syntax).to receive_messages(:
|
113
|
-
allow(Valvat::Lookup).to receive_messages(:
|
138
|
+
allow(Valvat::Syntax).to receive_messages(validate: true)
|
139
|
+
allow(Valvat::Lookup).to receive_messages(validate: false)
|
114
140
|
end
|
115
141
|
|
116
142
|
it "should not be valid" do
|
117
|
-
expect(InvoiceWithLookup.new(:
|
143
|
+
expect(InvoiceWithLookup.new(vat_number: "DE123")).not_to be_valid
|
118
144
|
end
|
119
145
|
end
|
120
146
|
|
121
|
-
context "with valid and existing
|
147
|
+
context "with valid and existing VAT number" do
|
122
148
|
before do
|
123
|
-
allow(Valvat::Syntax).to receive_messages(:
|
124
|
-
allow(Valvat::Lookup).to receive_messages(:
|
149
|
+
allow(Valvat::Syntax).to receive_messages(validate: true)
|
150
|
+
allow(Valvat::Lookup).to receive_messages(validate: true)
|
125
151
|
end
|
126
152
|
|
127
153
|
it "should be valid" do
|
128
|
-
expect(InvoiceWithLookup.new(:
|
154
|
+
expect(InvoiceWithLookup.new(vat_number: "DE123")).to be_valid
|
129
155
|
end
|
130
156
|
end
|
131
157
|
|
132
|
-
context "with valid
|
158
|
+
context "with valid VAT number and VIES country service down" do
|
133
159
|
before do
|
134
|
-
allow(Valvat::Syntax).to receive_messages(:
|
135
|
-
allow(Valvat::Lookup).to receive_messages(:
|
160
|
+
allow(Valvat::Syntax).to receive_messages(validate: true)
|
161
|
+
allow(Valvat::Lookup).to receive_messages(validate: nil)
|
136
162
|
end
|
137
163
|
|
138
164
|
it "should be valid" do
|
139
|
-
expect(InvoiceWithLookup.new(:
|
165
|
+
expect(InvoiceWithLookup.new(vat_number: "DE123")).to be_valid
|
140
166
|
end
|
141
167
|
end
|
142
168
|
end
|
143
169
|
|
144
170
|
describe InvoiceWithLookupAndFailIfDown do
|
145
|
-
context "with valid
|
171
|
+
context "with valid VAT number and VIES country service down" do
|
146
172
|
before do
|
147
|
-
allow(Valvat::Syntax).to receive_messages(:
|
148
|
-
allow(Valvat::Lookup).to receive_messages(:
|
173
|
+
allow(Valvat::Syntax).to receive_messages(validate: true)
|
174
|
+
allow(Valvat::Lookup).to receive_messages(validate: nil)
|
149
175
|
end
|
150
176
|
|
151
177
|
it "should not be valid" do
|
152
|
-
expect(InvoiceWithLookupAndFailIfDown.new(:
|
178
|
+
expect(InvoiceWithLookupAndFailIfDown.new(vat_number: "DE123")).not_to be_valid
|
153
179
|
end
|
154
180
|
end
|
155
181
|
end
|
156
182
|
|
157
183
|
describe InvoiceAllowBlank do
|
158
|
-
context "with blank
|
184
|
+
context "with blank VAT number" do
|
159
185
|
it "should be valid" do
|
160
|
-
expect(InvoiceAllowBlank.new(:
|
161
|
-
expect(InvoiceAllowBlank.new(:
|
186
|
+
expect(InvoiceAllowBlank.new(vat_number: "")).to be_valid
|
187
|
+
expect(InvoiceAllowBlank.new(vat_number: nil)).to be_valid
|
162
188
|
end
|
163
189
|
end
|
164
190
|
end
|
165
191
|
|
166
192
|
describe InvoiceAllowBlankOnAll do
|
167
|
-
context "with blank
|
193
|
+
context "with blank VAT number" do
|
168
194
|
it "should be valid" do
|
169
|
-
expect(InvoiceAllowBlankOnAll.new(:
|
170
|
-
expect(InvoiceAllowBlankOnAll.new(:
|
195
|
+
expect(InvoiceAllowBlankOnAll.new(vat_number: "")).to be_valid
|
196
|
+
expect(InvoiceAllowBlankOnAll.new(vat_number: nil)).to be_valid
|
171
197
|
end
|
172
198
|
end
|
173
199
|
end
|
174
200
|
|
175
201
|
describe InvoiceCheckCountry do
|
176
202
|
it "should be not valid on blank country" do
|
177
|
-
expect(InvoiceCheckCountry.new(:
|
178
|
-
expect(InvoiceCheckCountry.new(:
|
203
|
+
expect(InvoiceCheckCountry.new(country: nil, vat_number: "DE259597697")).not_to be_valid
|
204
|
+
expect(InvoiceCheckCountry.new(country: "", vat_number: "DE259597697")).not_to be_valid
|
179
205
|
end
|
180
206
|
|
181
207
|
it "should be not valid on wired country" do
|
182
|
-
expect(InvoiceCheckCountry.new(:
|
183
|
-
expect(InvoiceCheckCountry.new(:
|
208
|
+
expect(InvoiceCheckCountry.new(country: "XAXXX", vat_number: "DE259597697")).not_to be_valid
|
209
|
+
expect(InvoiceCheckCountry.new(country: "ZO", vat_number: "DE259597697")).not_to be_valid
|
184
210
|
end
|
185
211
|
|
186
212
|
it "should be not valid on mismatching (eu) country" do
|
187
|
-
expect(InvoiceCheckCountry.new(:
|
188
|
-
expect(InvoiceCheckCountry.new(:
|
189
|
-
expect(InvoiceCheckCountry.new(:
|
213
|
+
expect(InvoiceCheckCountry.new(country: "FR", vat_number: "DE259597697")).not_to be_valid
|
214
|
+
expect(InvoiceCheckCountry.new(country: "AT", vat_number: "DE259597697")).not_to be_valid
|
215
|
+
expect(InvoiceCheckCountry.new(country: "DE", vat_number: "ATU65931334")).not_to be_valid
|
190
216
|
end
|
191
217
|
|
192
218
|
it "should be valid on matching country" do
|
193
|
-
expect(InvoiceCheckCountry.new(:
|
194
|
-
expect(InvoiceCheckCountry.new(:
|
219
|
+
expect(InvoiceCheckCountry.new(country: "DE", vat_number: "DE259597697")).to be_valid
|
220
|
+
expect(InvoiceCheckCountry.new(country: "AT", vat_number: "ATU65931334")).to be_valid
|
195
221
|
end
|
196
222
|
|
197
223
|
it "should give back error message with country from :country_match" do
|
198
|
-
invoice = InvoiceCheckCountry.new(:
|
224
|
+
invoice = InvoiceCheckCountry.new(country: "FR", vat_number: "DE259597697")
|
199
225
|
invoice.valid?
|
200
|
-
expect(invoice.errors[:vat_number]).to eql(["is not a valid French
|
226
|
+
expect(invoice.errors[:vat_number]).to eql(["is not a valid French VAT number"])
|
201
227
|
end
|
202
228
|
|
203
|
-
it "should give back error message with country from :country_match even on invalid
|
204
|
-
invoice = InvoiceCheckCountry.new(:
|
229
|
+
it "should give back error message with country from :country_match even on invalid VAT number" do
|
230
|
+
invoice = InvoiceCheckCountry.new(country: "FR", vat_number: "DE259597697123")
|
205
231
|
invoice.valid?
|
206
|
-
expect(invoice.errors[:vat_number]).to eql(["is not a valid French
|
232
|
+
expect(invoice.errors[:vat_number]).to eql(["is not a valid French VAT number"])
|
207
233
|
end
|
208
234
|
end
|
209
235
|
|
210
236
|
describe InvoiceCheckCountryWithLookup do
|
211
237
|
before do
|
212
|
-
allow(Valvat::Syntax).to receive_messages(:
|
213
|
-
allow(Valvat::Lookup).to receive_messages(:
|
238
|
+
allow(Valvat::Syntax).to receive_messages(validate: true)
|
239
|
+
allow(Valvat::Lookup).to receive_messages(validate: true)
|
214
240
|
end
|
215
241
|
|
216
242
|
it "avoids lookup or syntax check on failed because of mismatching country" do
|
217
243
|
expect(Valvat::Syntax).not_to receive(:validate)
|
218
244
|
expect(Valvat::Lookup).not_to receive(:validate)
|
219
|
-
InvoiceCheckCountryWithLookup.new(:
|
245
|
+
InvoiceCheckCountryWithLookup.new(country: "FR", vat_number: "DE259597697").valid?
|
220
246
|
end
|
221
247
|
|
222
248
|
it "check syntax and looup on matching country" do
|
223
249
|
expect(Valvat::Syntax).to receive(:validate).and_return(true)
|
224
250
|
expect(Valvat::Lookup).to receive(:validate).and_return(true)
|
225
|
-
InvoiceCheckCountryWithLookup.new(:
|
251
|
+
InvoiceCheckCountryWithLookup.new(country: "DE", vat_number: "DE259597697").valid?
|
226
252
|
end
|
227
253
|
end
|
228
254
|
|
229
255
|
describe InvoiceWithChecksum do
|
230
|
-
context "with valid
|
256
|
+
context "with valid VAT number" do
|
231
257
|
it "should be valid" do
|
232
|
-
expect(InvoiceWithChecksum.new(:
|
258
|
+
expect(InvoiceWithChecksum.new(vat_number: "DE259597697")).to be_valid
|
233
259
|
end
|
234
260
|
end
|
235
261
|
|
236
|
-
context "with invalid
|
262
|
+
context "with invalid VAT number" do
|
237
263
|
it "should not be valid" do
|
238
|
-
expect(InvoiceWithChecksum.new(:
|
264
|
+
expect(InvoiceWithChecksum.new(vat_number: "DE259597687")).not_to be_valid
|
239
265
|
end
|
240
266
|
end
|
241
267
|
end
|