spec/valvat/lookup_spec.rb in valvat-1.1.5 vs spec/valvat/lookup_spec.rb in valvat-1.2.0
- old
+ new
@@ -2,104 +2,168 @@
require 'spec_helper'
describe Valvat::Lookup do
describe '#validate' do
- context 'with existing VAT number' do
+ context 'with existing EU VAT number' do
it 'returns true' do
result = described_class.validate('IE6388047V')
- # Skip if VIES is down
- expect(result).to be(true) unless result.nil?
+ skip 'VIES is down' if result.nil?
+ expect(result).to be(true)
end
it 'allows Valvat instance as input' do
result = described_class.validate(Valvat.new('IE6388047V'))
- # Skip if VIES is down
- expect(result).to be(true) unless result.nil?
+ skip 'VIES is down' if result.nil?
+ expect(result).to be(true)
end
+
+ context 'with details' do
+ it 'returns hash of details instead of true' do
+ result = described_class.validate('IE6388047V', detail: true)
+ skip 'VIES is down' if result.nil?
+
+ expect(result).to match({
+ request_date: kind_of(Date),
+ country_code: 'IE',
+ vat_number: '6388047V',
+ name: 'GOOGLE IRELAND LIMITED',
+ address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
+ valid: true
+ })
+ end
+ end
end
- context 'with not existing VAT number' do
+ context 'with existing GB VAT number' do
+ it 'returns true' do
+ result = described_class.validate('GB727255821', uk: true)
+ skip 'HMRC is down' if result.nil?
+ expect(result).to be(true)
+ end
+
+ it 'returns details in format similar to VIES' do
+ result = described_class.validate('GB727255821', detail: true, uk: true)
+ skip 'HMRC is down' if result.nil?
+ expect(result).to match({
+ request_date: kind_of(Time),
+ country_code: 'GB',
+ vat_number: '727255821',
+ name: 'AMAZON EU SARL',
+ address: "1 PRINCIPAL PLACE\nWORSHIP STREET\nLONDON\nEC2A 2FA\nGB",
+ valid: true
+ })
+ end
+ end
+
+ context 'with not existing EU VAT number' do
it 'returns false' do
result = described_class.validate('IE6388048V')
- # Skip if VIES is down
- expect(result).to be(false) unless result.nil?
+ skip 'VIES is down' if result.nil?
+ expect(result).to be(false)
end
+
+ context 'with details' do
+ it 'still returns false' do
+ result = described_class.validate('LU21416128', detail: true)
+ skip 'VIES is down' if result.nil?
+ expect(result).to be(false)
+ end
+ end
end
+ context 'with not existing GB VAT number' do
+ it 'returns false' do
+ result = described_class.validate('GB727255820', uk: true)
+ skip 'HMRC is down' if result.nil?
+ expect(result).to be(false)
+ end
+ end
+
context 'with invalid country code / input' do
it 'returns false' do
expect(described_class.validate('AE259597697')).to be(false)
expect(described_class.validate('')).to be(false)
end
end
- context 'with details' do
- let(:details) do
- {
- '@xmlns:ns2': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types',
- country_code: 'IE',
- vat_number: '6388047V',
- name: 'GOOGLE IRELAND LIMITED',
- address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
- valid: true
- }
- end
-
+ context 'with request identifier' do
it 'returns hash of details instead of true' do
- result = described_class.validate('IE6388047V', detail: true)
- # Skip if VIES is down
- if result
- expect(result.delete(:request_date)).to be_kind_of(Date)
- expect(result).to eql(details)
- end
- end
+ result = described_class.validate('IE6388047V', requester: 'IE6388047V')
- it 'still returns false on not existing VAT number' do
- result = described_class.validate('LU21416128', detail: true)
- # Skip if VIES is down
- expect(result).to be(false) unless result.nil?
+ skip 'VIES is down' if result.nil?
+
+ expect(result).to match({
+ request_date: kind_of(Date),
+ request_identifier: /\A[\w\W]{16}\Z/,
+ country_code: 'IE',
+ vat_number: '6388047V',
+ name: 'GOOGLE IRELAND LIMITED',
+ company_type: nil,
+ address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
+ valid: true
+ })
end
- end
- context 'with request identifier' do
- let(:response) { described_class.validate('IE6388047V', requester: 'IE6388047V') }
- let(:details) do
- {
- '@xmlns:ns2': 'urn:ec.europa.eu:taxud:vies:services:checkVat:types',
- country_code: 'IE',
- vat_number: '6388047V',
- name: 'GOOGLE IRELAND LIMITED',
- company_type: nil,
- address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
- valid: true
- }
+ it 'supports old :requester_vat option for backwards compatibility' do
+ result = described_class.validate('IE6388047V', requester_vat: 'LU21416127')
+
+ expect(result).to match({
+ request_date: kind_of(Date),
+ request_identifier: /\A[\w\W]{16}\Z/,
+ country_code: 'IE',
+ vat_number: '6388047V',
+ name: 'GOOGLE IRELAND LIMITED',
+ company_type: nil,
+ address: '3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4',
+ valid: true
+ })
end
- it 'returns hash of details instead of true' do
- # Skip if VIES is down
- if response
- expect(response.delete(:request_identifier).size).to be(16)
- expect(response.delete(:request_date)).to be_kind_of(Date)
- expect(response).to eql(details)
+ context 'with GB VAT number' do
+ it 'returns hash of details with request number' do
+ response = described_class.validate('GB727255821', requester: 'GB727255821', uk: true)
+ skip 'HMRC is down' if response.nil?
+ expect(response).to match({
+ request_date: kind_of(Time),
+ request_identifier: /\A\w\w\w-\w\w\w-\w\w\w\Z/,
+ country_code: 'GB',
+ vat_number: '727255821',
+ name: 'AMAZON EU SARL',
+ address: "1 PRINCIPAL PLACE\nWORSHIP STREET\nLONDON\nEC2A 2FA\nGB",
+ valid: true
+ })
end
- end
- it 'supports old :requester_vat option for backwards stability' do
- expect(
- described_class.new('IE6388047V', requester_vat: 'LU21416127').instance_variable_get(:@options)[:requester]
- ).to eql('LU21416127')
+ it 'raises exception if requester is not from GB' do
+ expect do
+ described_class.validate('GB727255821', requester: 'IE6388047V', uk: true)
+ end.to raise_error(Valvat::InvalidRequester,
+ 'The HMRC web service returned the error: '\
+ 'INVALID_REQUEST (Invalid requesterVrn - Vrn parameters should be 9 or 12 digits)')
+ end
+
+ it 'raises exception if requester is not valid' do
+ expect do
+ described_class.validate('GB727255821', requester: 'GB6388047', uk: true)
+ end.to raise_error(Valvat::InvalidRequester,
+ 'The HMRC web service returned the error: '\
+ 'INVALID_REQUEST (Invalid requesterVrn - Vrn parameters should be 9 or 12 digits)')
+ end
end
end
end
describe '#validate with VIES test enviroment' do
let(:options) do
- { savon: { wsdl: 'https://ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl' },
- skip_local_validation: true }
+ { skip_local_validation: true }
end
+ before do
+ stub_const('Valvat::Lookup::VIES::ENDPOINT_URI', URI('https://ec.europa.eu/taxation_customs/vies/test-services/checkVatTestService'))
+ end
+
context 'with valid request with valid VAT number' do
subject(:result) { described_class.validate('DE100', options) }
it 'returns true' do
expect(result).to be(true)
@@ -168,10 +232,26 @@
it 'returns nil with raise_error set to false' do
expect(described_class.validate('DE302', options.merge(raise_error: false))).to be_nil
end
end
+ describe 'Network timeout' do
+ subject(:result) { described_class.validate('DE200', options) }
+
+ before { stub_request(:post, /ec.europa.eu/).to_timeout }
+
+ it 'raises error' do
+ expect { result }.to raise_error(Net::OpenTimeout, 'execution expired')
+ end
+
+ it 'also raises error with raise_error set to false (not handled)' do
+ expect do
+ described_class.validate('DE302', options.merge(raise_error: false))
+ end.to raise_error(Net::OpenTimeout, 'execution expired')
+ end
+ end
+
describe 'Error : VAT_BLOCKED' do
subject(:result) { described_class.validate('DE400', options) }
it 'raises error' do
expect { result }.to raise_error(Valvat::BlockedError, /VAT_BLOCKED/)
@@ -240,42 +320,150 @@
it 'returns nil with raise_error set to false' do
expect(described_class.validate('DE601', options.merge(raise_error: false))).to be_nil
end
end
- describe 'Error : Savon::UnknownOperationError' do
+ describe 'Error : HTTP error' do
subject(:result) { described_class.validate('DE601', options) }
before do
- dbl = instance_double(Savon::Client)
- allow(Savon::Client).to receive(:new).and_return(dbl)
- allow(dbl).to receive(:call).and_raise(Savon::UnknownOperationError.new('from stub'))
+ stub_request(:post, %r{\Ahttps://ec\.europa\.eu}).to_return({ status: 405 })
end
it 'raises error' do
- expect { result }.to raise_error(Valvat::OperationUnknown, /#<Savon::UnknownOperationError: from stub>/)
+ expect { result }.to raise_error(Valvat::HTTPError, 'The VIES web service returned the error: 405')
end
it 'returns nil with raise_error set to false' do
expect(described_class.validate('DE601', options.merge(raise_error: false))).to be_nil
end
end
+ end
- describe 'Error : Savon::HTTPError' do
- subject(:result) { described_class.validate('DE601', options) }
+ describe '#validate with HMRC test enviroment' do
+ # https://developer.service.hmrc.gov.uk/api-documentation/docs/testing
+ # https://github.com/hmrc/vat-registered-companies-api/blob/master/public/api/conf/1.0/test-data/vrn.csv
+ subject(:result) { described_class.validate('GB123456789', uk: true) }
+ before do
+ stub_const('Valvat::Lookup::HMRC::ENDPOINT_URL', 'https://test-api.service.hmrc.gov.uk/organisations/vat/check-vat-number/lookup')
+ end
+
+ context 'with valid request with valid VAT number' do
+ it 'returns true' do
+ expect(described_class.validate('GB553557881', uk: true)).to be(true)
+ expect(described_class.validate('GB146295999727', uk: true)).to be(true)
+ end
+ end
+
+ context 'with valid request with an invalid VAT number' do
+ it 'returns false' do
+ expect(result).to be(false)
+ end
+ end
+
+ describe 'Error : MESSAGE_THROTTLED_OUT' do
before do
- dbl = instance_double(Savon::Client)
- allow(Savon::Client).to receive(:new).and_return(dbl)
- allow(dbl).to receive(:call).and_raise(Savon::HTTPError.new(Struct.new(:code, :body).new(403, 'from stub')))
+ stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
+ status: 429,
+ body: '{"code":"MESSAGE_THROTTLED_OUT"}'
+ )
end
it 'raises error' do
- expect { result }.to raise_error(Valvat::HTTPError, /#<Savon::HTTPError: HTTP error \(403\): from stub>/)
+ expect { result }.to raise_error(Valvat::RateLimitError, /MESSAGE_THROTTLED_OUT/)
end
it 'returns nil with raise_error set to false' do
- expect(described_class.validate('DE601', options.merge(raise_error: false))).to be_nil
+ expect(described_class.validate('GB123456789', raise_error: false, uk: true)).to be_nil
+ end
+ end
+
+ describe 'Error : SCHEDULED_MAINTENANCE' do
+ before do
+ stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
+ status: 503,
+ body: '{"code":"SCHEDULED_MAINTENANCE"}'
+ )
+ end
+
+ it 'returns nil' do
+ expect(result).to be_nil
+ end
+
+ it 'raises error with raise_error set to false' do
+ expect do
+ described_class.validate('GB123456789', raise_error: true, uk: true)
+ end.to raise_error(Valvat::ServiceUnavailable, 'The HMRC web service returned the error: SCHEDULED_MAINTENANCE')
+ end
+ end
+
+ describe 'Error : SERVER_ERROR' do
+ before do
+ stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
+ status: 503,
+ body: '{"code":"SERVER_ERROR"}'
+ )
+ end
+
+ it 'returns nil' do
+ expect(result).to be_nil
+ end
+
+ it 'raises error with raise_error set to false' do
+ expect do
+ described_class.validate('GB123456789', raise_error: true, uk: true)
+ end.to raise_error(Valvat::ServiceUnavailable, 'The HMRC web service returned the error: SERVER_ERROR')
+ end
+ end
+
+ describe 'Error : GATEWAY_TIMEOUT' do
+ before do
+ stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
+ status: 504,
+ body: '{"code":"GATEWAY_TIMEOUT"}'
+ )
+ end
+
+ it 'raises error' do
+ expect { result }.to raise_error(Valvat::Timeout, /GATEWAY_TIMEOUT/)
+ end
+
+ it 'returns nil with raise_error set to false' do
+ expect(described_class.validate('GB123456789', raise_error: false, uk: true)).to be_nil
+ end
+ end
+
+ describe 'Network timeout' do
+ before do
+ stub_request(:get, /test-api.service.hmrc.gov.uk/).to_timeout
+ end
+
+ it 'raises error' do
+ expect { result }.to raise_error(Net::OpenTimeout)
+ end
+
+ it 'also raises error with raise_error set to false (not handled)' do
+ expect do
+ described_class.validate('GB123456789', raise_error: false, uk: true)
+ end.to raise_error(Net::OpenTimeout)
+ end
+ end
+
+ describe 'Error : INTERNAL_SERVER_ERROR' do
+ before do
+ stub_request(:get, /test-api.service.hmrc.gov.uk/).to_return(
+ status: 500,
+ body: '{"code":"INTERNAL_SERVER_ERROR"}'
+ )
+ end
+
+ it 'raises error' do
+ expect { result }.to raise_error(Valvat::UnknownLookupError, /INTERNAL_SERVER_ERROR/)
+ end
+
+ it 'returns nil with raise_error set to false' do
+ expect(described_class.validate('GB123456789', raise_error: false, uk: true)).to be_nil
end
end
end
end