valvat 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Valvat
4
- class Lookup
5
- class Fault < Response
6
- def to_hash
7
- @to_hash ||= case @raw
8
- when Savon::HTTPError
9
- { error: HTTPError.new(nil, @raw) }
10
- when Savon::UnknownOperationError
11
- { error: OperationUnknown.new(nil, @raw) }
12
- else
13
- fault = @raw.to_hash[:fault][:faultstring]
14
-
15
- if fault == 'INVALID_INPUT'
16
- { valid: false }
17
- else
18
- error = (FAULTS[fault] || UnknownViesError).new(fault)
19
- { error: error }
20
- end
21
- end
22
- end
23
-
24
- FAULTS = {
25
- 'SERVICE_UNAVAILABLE' => ServiceUnavailable,
26
- 'MS_UNAVAILABLE' => MemberStateUnavailable,
27
- 'INVALID_REQUESTER_INFO' => InvalidRequester,
28
- 'TIMEOUT' => Timeout,
29
- 'VAT_BLOCKED' => BlockedError,
30
- 'IP_BLOCKED' => BlockedError,
31
- 'GLOBAL_MAX_CONCURRENT_REQ' => RateLimitError,
32
- 'GLOBAL_MAX_CONCURRENT_REQ_TIME' => RateLimitError,
33
- 'MS_MAX_CONCURRENT_REQ' => RateLimitError,
34
- 'MS_MAX_CONCURRENT_REQ_TIME' => RateLimitError
35
- }.freeze
36
- end
37
- end
38
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'savon'
4
-
5
- class Valvat
6
- class Lookup
7
- class Request
8
- VIES_WSDL_URL = 'https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl'
9
-
10
- def initialize(vat, options)
11
- @vat = Valvat(vat)
12
- @options = options || {}
13
- @requester = @options[:requester] && Valvat(@options[:requester])
14
- end
15
-
16
- def perform
17
- Response.new(
18
- client.call(action, message: message, message_tag: message_tag, soap_action: nil)
19
- )
20
- rescue Savon::SOAPFault, Savon::HTTPError, Savon::UnknownOperationError => e
21
- Fault.new(e)
22
- end
23
-
24
- private
25
-
26
- def client
27
- Savon::Client.new({
28
- wsdl: VIES_WSDL_URL, log: false, follow_redirects: true
29
- }.merge(@options[:savon] || {}))
30
- end
31
-
32
- def message
33
- add_requester({
34
- country_code: @vat.vat_country_code,
35
- vat_number: @vat.to_s_wo_country
36
- })
37
- end
38
-
39
- def message_tag
40
- @requester ? :checkVatApprox : :checkVat
41
- end
42
-
43
- def action
44
- @requester ? :check_vat_approx : :check_vat
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
55
- end
56
- end
57
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Valvat
4
- class Lookup
5
- class Response
6
- def initialize(raw)
7
- @raw = raw
8
- end
9
-
10
- def [](key)
11
- to_hash[key]
12
- end
13
-
14
- def to_hash
15
- @to_hash ||= self.class.cleanup(@raw.to_hash)
16
- end
17
-
18
- def self.cleanup(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"
23
- end
24
- end
25
-
26
- TRADER_PREFIX = /\Atrader_/.freeze
27
-
28
- def self.cleanup_key(key)
29
- key.to_s.sub(TRADER_PREFIX, '').to_sym
30
- end
31
-
32
- def self.cleanup_value(value)
33
- value == '---' ? nil : value
34
- end
35
- end
36
- end
37
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Valvat::Lookup::Fault do
6
- it "returns {valid: false} on fault 'INVALID_INPUT'" do
7
- expect(described_class.new({
8
- fault: { faultstring: 'INVALID_INPUT' }
9
- }).to_hash).to eql({ valid: false })
10
- end
11
-
12
- {
13
- 'SERVICE_UNAVAILABLE' => Valvat::ServiceUnavailable,
14
- 'MS_UNAVAILABLE' => Valvat::MemberStateUnavailable,
15
- 'INVALID_REQUESTER_INFO' => Valvat::InvalidRequester,
16
- 'TIMEOUT' => Valvat::Timeout,
17
- 'VAT_BLOCKED' => Valvat::BlockedError,
18
- 'IP_BLOCKED' => Valvat::BlockedError,
19
- 'GLOBAL_MAX_CONCURRENT_REQ' => Valvat::RateLimitError,
20
- 'GLOBAL_MAX_CONCURRENT_REQ_TIME' => Valvat::RateLimitError,
21
- 'MS_MAX_CONCURRENT_REQ' => Valvat::RateLimitError,
22
- 'MS_MAX_CONCURRENT_REQ_TIME' => Valvat::RateLimitError,
23
- 'ANYTHING ELSE' => Valvat::UnknownViesError,
24
- 'REALLY ANYTHING' => Valvat::UnknownViesError
25
- }.each do |fault, error|
26
- it "returns error on fault '#{fault}'" do
27
- expect(described_class.new({
28
- fault: { faultstring: fault }
29
- }).to_hash).to eql({
30
- error: error.new(fault)
31
- })
32
- end
33
- end
34
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Valvat::Lookup::Request do
6
- it 'returns Response on success' do
7
- response = described_class.new('IE6388047V', {}).perform
8
- expect(response).to be_a(Valvat::Lookup::Response)
9
-
10
- # Skip if VIES is down
11
- expect(response.to_hash[:name]).to eql('GOOGLE IRELAND LIMITED') unless response.is_a?(Valvat::Lookup::Fault)
12
- end
13
-
14
- it 'returns Fault on failure' do
15
- response = described_class.new('XC123123', {}).perform
16
- expect(response).to be_a(Valvat::Lookup::Fault)
17
- expect(response.to_hash).to eql({ valid: false })
18
- end
19
-
20
- context 'when Savon::UnknownOperationError is (wrongly) thrown' do
21
- before do
22
- dbl = double(Savon::Client)
23
- allow(Savon::Client).to receive(:new).and_return(dbl)
24
- allow(dbl).to receive(:call).and_raise(Savon::UnknownOperationError.new('from stub'))
25
- end
26
-
27
- it "does handle it like vies down" do
28
- response = described_class.new('IE6388047V', {}).perform
29
- expect(response.to_hash[:error]).to be_a(Valvat::OperationUnknown)
30
- end
31
- end
32
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Valvat::Lookup::Response do
6
- it 'removes @xmlns from :check_vat_response hash' do
7
- expect(described_class.new({
8
- check_vat_response: { :a => 1, :b => 2, :@xmlns => true }
9
- }).to_hash).to eql({ a: 1, b: 2 })
10
- end
11
-
12
- it "removes 'trader_'-Prefixes :check_vat_response hash" do
13
- expect(described_class.new({
14
- check_vat_response: { a: 1, trader_b: 2 }
15
- }).to_hash).to eql({ a: 1, b: 2 })
16
- end
17
-
18
- it 'accepts hash keyed as :check_vat_approx_response' do
19
- expect(described_class.new({
20
- check_vat_approx_response: { a: 1, b: 2 }
21
- }).to_hash).to eql({ a: 1, b: 2 })
22
- end
23
-
24
- it 'allows direct access to hash via []' do
25
- expect(described_class.new({
26
- check_vat_response: { a: 123, b: 2 }
27
- })[:a]).to be(123)
28
- end
29
- end