afipws 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af0aba9e6eb57dd5305a4c8836a1a589b7001f89
4
- data.tar.gz: 9a0f95b8ef6c03b321652802791a83cdcb0fc1ab
3
+ metadata.gz: f0430f1994cf2d6f6afe098bda447441df15f7bb
4
+ data.tar.gz: 519d1e3e5ea15497d131905c9b1e37e2959b26b0
5
5
  SHA512:
6
- metadata.gz: c1d1f1441ad8d505028b3c3908583381627952ba538913b38d5c5ac80bc562f501dfc903a2bd7976ee85857c6bf1780f2c2c28759ea1577c08c8c688bf108ce5
7
- data.tar.gz: 18cb3316c1d763e0172a676c78e2e960f09114953ec3b50fe30482f97aa630eadc74ccf665a322f96146a9c40f2edc5986c1958a6e40928cbfc2e3e6c495aa16
6
+ metadata.gz: 3fa823ccd4f74a535dce9893b9df3277a82f944789e8c75be937c4fc277afc32fdc6e9136359b13fab08c839b063a0bc71b34a89053eb448c3bc654babc5f756
7
+ data.tar.gz: 9a40c8d4855d4b0d5eb3ea0112c38f282213ecf727f1a3963026670fcd3f76f2fd433a535140eb7ae0a9d53b7011e20fad172e812e83095195c630608d3969f4
@@ -1,14 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- afipws (0.2.0)
4
+ afipws (1.0.0)
5
5
  activesupport
6
6
  builder
7
7
  httpclient
8
- httpi (>= 2.4.2)
9
8
  i18n
10
9
  nokogiri
11
- savon
10
+ savon (~> 2.11.0)
12
11
 
13
12
  GEM
14
13
  remote: http://rubygems.org/
@@ -18,57 +17,108 @@ GEM
18
17
  i18n (~> 0.7)
19
18
  minitest (~> 5.1)
20
19
  tzinfo (~> 1.1)
21
- builder (3.0.0)
20
+ akami (1.3.1)
21
+ gyoku (>= 0.4.0)
22
+ nokogiri
23
+ builder (3.2.2)
24
+ byebug (1.1.1)
25
+ columnize (~> 0.3.6)
26
+ debugger-linecache (~> 1.2.0)
27
+ coderay (1.1.1)
28
+ columnize (0.3.6)
22
29
  concurrent-ruby (1.0.2)
23
- crack (0.1.8)
24
- diff-lcs (1.1.2)
25
- gyoku (0.2.0)
30
+ debugger-linecache (1.2.0)
31
+ diff-lcs (1.2.5)
32
+ ffi (1.9.14)
33
+ formatador (0.2.5)
34
+ guard (2.14.0)
35
+ formatador (>= 0.2.4)
36
+ listen (>= 2.7, < 4.0)
37
+ lumberjack (~> 1.0)
38
+ nenv (~> 0.1)
39
+ notiffany (~> 0.0)
40
+ pry (>= 0.9.12)
41
+ shellany (~> 0.0)
42
+ thor (>= 0.18.1)
43
+ guard-rspec (4.3.1)
44
+ guard (~> 2.1)
45
+ rspec (>= 2.14, < 4.0)
46
+ gyoku (1.3.1)
26
47
  builder (>= 2.1.2)
27
48
  httpclient (2.8.2.4)
28
49
  httpi (2.4.2)
29
50
  rack
30
51
  socksify
31
52
  i18n (0.7.0)
53
+ listen (3.1.5)
54
+ rb-fsevent (~> 0.9, >= 0.9.4)
55
+ rb-inotify (~> 0.9, >= 0.9.7)
56
+ ruby_dep (~> 1.2)
57
+ lumberjack (1.0.10)
58
+ method_source (0.8.2)
32
59
  mini_portile2 (2.1.0)
33
60
  minitest (5.9.1)
34
61
  mocha (0.9.10)
35
62
  rake
63
+ nenv (0.3.0)
36
64
  nokogiri (1.6.8)
37
65
  mini_portile2 (~> 2.1.0)
38
66
  pkg-config (~> 1.1.7)
67
+ nori (2.6.0)
68
+ notiffany (0.1.1)
69
+ nenv (~> 0.1)
70
+ shellany (~> 0.0)
39
71
  pkg-config (1.1.7)
72
+ pry (0.10.4)
73
+ coderay (~> 1.1.0)
74
+ method_source (~> 0.8.1)
75
+ slop (~> 3.4)
76
+ pry-byebug (1.0.1)
77
+ byebug (~> 1.1.1)
78
+ pry (>= 0.9.10)
40
79
  rack (2.0.1)
41
80
  rake (10.4.2)
42
- rspec (2.4.0)
43
- rspec-core (~> 2.4.0)
44
- rspec-expectations (~> 2.4.0)
45
- rspec-mocks (~> 2.4.0)
46
- rspec-core (2.4.0)
47
- rspec-expectations (2.4.0)
48
- diff-lcs (~> 1.1.2)
49
- rspec-mocks (2.4.0)
50
- savon (0.8.3)
81
+ rb-fsevent (0.9.7)
82
+ rb-inotify (0.9.7)
83
+ ffi (>= 0.5.0)
84
+ rspec (2.14.1)
85
+ rspec-core (~> 2.14.0)
86
+ rspec-expectations (~> 2.14.0)
87
+ rspec-mocks (~> 2.14.0)
88
+ rspec-core (2.14.8)
89
+ rspec-expectations (2.14.5)
90
+ diff-lcs (>= 1.1.3, < 2.0)
91
+ rspec-mocks (2.14.6)
92
+ ruby_dep (1.4.0)
93
+ savon (2.11.1)
94
+ akami (~> 1.2)
51
95
  builder (>= 2.1.2)
52
- crack (~> 0.1.8)
53
- gyoku (>= 0.2.0)
54
- httpi (>= 0.7.8)
55
- savon_spec (0.1.2)
56
- mocha (>= 0.9.8)
57
- rspec (>= 2.0.0)
58
- savon (~> 0.8.0)
96
+ gyoku (~> 1.2)
97
+ httpi (~> 2.3)
98
+ nokogiri (>= 1.4.0)
99
+ nori (~> 2.4)
100
+ wasabi (~> 3.4)
101
+ shellany (0.0.1)
102
+ slop (3.6.0)
59
103
  socksify (1.7.0)
104
+ thor (0.19.1)
60
105
  thread_safe (0.3.5)
61
106
  tzinfo (1.2.2)
62
107
  thread_safe (~> 0.1)
108
+ wasabi (3.5.0)
109
+ httpi (~> 2.0)
110
+ nokogiri (>= 1.4.2)
63
111
 
64
112
  PLATFORMS
65
113
  ruby
66
114
 
67
115
  DEPENDENCIES
68
116
  afipws!
117
+ guard-rspec (~> 4.3.1)
118
+ mocha (~> 0.9.10)
119
+ pry-byebug
69
120
  rake (~> 10.4.2)
70
- rspec
71
- savon_spec
121
+ rspec (~> 2.14.1)
72
122
 
73
123
  BUNDLED WITH
74
124
  1.12.3
data/Guardfile CHANGED
@@ -1,19 +1,3 @@
1
- # A sample Guardfile
2
- # More info at https://github.com/guard/guard#readme
3
-
4
- ## Uncomment and set this to only include directories you want to watch
5
- # directories %w(app lib config test spec features) \
6
- # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
-
8
- ## Note: if you are using the `directories` clause above and you are not
9
- ## watching the project directory ('.'), then you will want to move
10
- ## the Guardfile to a watched dir and symlink it back, e.g.
11
- #
12
- # $ mkdir config
13
- # $ mv Guardfile config/
14
- # $ ln -s config/Guardfile .
15
- #
16
- # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
1
  guard :rspec, cmd: 'rspec' do
18
2
  watch(%r{^spec/.+_spec\.rb$})
19
3
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
@@ -18,14 +18,15 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_development_dependency "rspec"
22
- s.add_development_dependency "savon_spec"
23
- s.add_development_dependency "rake", '~> 10.4.2'
21
+ s.add_development_dependency 'rspec', '~> 2.14.1'
22
+ s.add_development_dependency 'rake', '~> 10.4.2'
23
+ s.add_development_dependency 'mocha', '~> 0.9.10'
24
+ s.add_development_dependency 'guard-rspec', '~> 4.3.1'
25
+ s.add_development_dependency 'pry-byebug'
24
26
  s.add_dependency "builder"
25
- s.add_dependency "savon"
27
+ s.add_dependency "savon", '~> 2.11.0'
26
28
  s.add_dependency "nokogiri"
27
29
  s.add_dependency "activesupport"
28
30
  s.add_dependency "i18n"
29
31
  s.add_dependency "httpclient"
30
- s.add_dependency "httpi", '>= 2.4.2'
31
32
  end
@@ -15,8 +15,3 @@ require 'afipws/type_conversions'
15
15
  require 'afipws/client'
16
16
  require 'afipws/wsaa'
17
17
  require 'afipws/wsfe'
18
-
19
- Savon.configure do |config|
20
- config.soap_version = 2
21
- config.log = false
22
- end
@@ -1,11 +1,7 @@
1
1
  module Afipws
2
2
  class Client
3
- def initialize wsdl_url, env
4
- @client = Savon::Client.new do
5
- wsdl.document = wsdl_url
6
- http.auth.ssl.verify_mode = :none if env == :development # Esto está porque el certificado del WSAA había vencido durante las pruebas
7
- http.auth.ssl.ssl_version = :SSLv3 if env == :development || Date.today >= Date.new(2016,11,1) # Esto es porque la afip cambió el algoritmo de cifrado de los certificados y sin esto no conectaba al WSFE. En el entorno de homologación ya está realizado el cambio pero en production recién el 1/11/2016.
8
- end
3
+ def initialize savon_options
4
+ @client = Savon.client savon_options.reverse_merge(soap_version: 2)
9
5
  end
10
6
 
11
7
  def request action, body = nil
@@ -18,36 +14,15 @@ module Afipws
18
14
  end
19
15
 
20
16
  def raw_request action, body = nil
21
- @client.request(namespace, action) { soap.body = add_ns_to_keys(body) }
17
+ @client.call action, message: body
22
18
  end
23
19
 
24
- def soap_actions
25
- @client.wsdl.soap_actions
20
+ def operations
21
+ @client.operations
26
22
  end
27
23
 
28
24
  def method_missing method_sym, *args
29
25
  request method_sym, *args
30
26
  end
31
-
32
- private
33
-
34
- def add_ns_to_keys body
35
- case body
36
- when Hash
37
- Hash[body.map { |k, v| ["#{namespace}:#{camelize(k)}", add_ns_to_keys(v)] }]
38
- when Array
39
- body.map { |x| add_ns_to_keys x }
40
- else
41
- body
42
- end
43
- end
44
-
45
- def namespace
46
- :wsdl
47
- end
48
-
49
- def camelize k
50
- k.is_a?(String) ? k : k.to_s.camelize
51
- end
52
27
  end
53
28
  end
@@ -1,18 +1,6 @@
1
1
  module Afipws
2
2
  module CoreExt
3
3
  module Hash
4
- def fetch_path path
5
- path.split('/').drop(1).inject(self) do |hash, key|
6
- if scan = key.scan(/\[[\d+]\]/).first
7
- key.sub! scan, ''
8
- idx = scan.scan(/\d+/).first.to_i
9
- hash.respond_to?(:has_key?) && hash.has_key?(key) ? hash[key][idx] : break
10
- else
11
- hash.respond_to?(:has_key?) && hash.has_key?(key) ? hash[key] : break
12
- end
13
- end
14
- end
15
-
16
4
  def select_keys *keys
17
5
  select { |k, _| keys.include? k }
18
6
  end
@@ -1,3 +1,3 @@
1
1
  module Afipws
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -15,7 +15,7 @@ module Afipws
15
15
  @service = options[:service] || 'wsfe'
16
16
  @ttl = options[:ttl] || 2400
17
17
  @cuit = options[:cuit]
18
- @client = Client.new WSDL[@env], @env
18
+ @client = Client.new Hash(options[:savon]).reverse_merge(wsdl: WSDL[@env])
19
19
  end
20
20
 
21
21
  def generar_tra service, ttl
@@ -47,12 +47,12 @@ module Afipws
47
47
  end
48
48
 
49
49
  def login
50
- response = @client.raw_request :login_cms, 'in0' => tra(@key, @cert, @service, @ttl)
50
+ response = @client.raw_request :login_cms, in0: tra(@key, @cert, @service, @ttl)
51
51
  ta = Nokogiri::XML(Nokogiri::XML(response.to_xml).text)
52
52
  { token: ta.css('token').text, sign: ta.css('sign').text,
53
53
  generation_time: from_xsd_datetime(ta.css('generationTime').text),
54
54
  expiration_time: from_xsd_datetime(ta.css('expirationTime').text) }
55
- rescue Savon::SOAP::Fault => f
55
+ rescue Savon::SOAPFault => f
56
56
  raise WSError, f.message
57
57
  end
58
58
 
@@ -15,7 +15,8 @@ module Afipws
15
15
  def initialize options = {}
16
16
  @env = (options[:env] || :test).to_sym
17
17
  @wsaa = options[:wsaa] || WSAA.new(options.merge(service: 'wsfe'))
18
- @client = Client.new WSDL[@env], @env
18
+ ssl_version = env == :development || Date.today >= Date.new(2016,11,1) ? :SSLv3 : :TLSv1
19
+ @client = Client.new Hash(options[:savon]).reverse_merge(wsdl: WSDL[@env], ssl_version: ssl_version, convert_request_keys_to: :camelcase)
19
20
  end
20
21
 
21
22
  def dummy
@@ -1,27 +1,6 @@
1
- # coding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
3
2
 
4
3
  describe Hash do
5
- context "fetch_path" do
6
- it "deberia aceptar un path como /../.. y retornar el value" do
7
- hash = { '1' => 2, '3' => { '4' => '5', '6' => { '7' => '8' } } }
8
- hash.fetch_path('/1').should == 2
9
- hash.fetch_path('/1/2').should == nil
10
- hash.fetch_path('/2').should == nil
11
- hash.fetch_path('/3/4').should == '5'
12
- hash.fetch_path('/3/6').should == { '7' => '8' }
13
- hash.fetch_path('/3/6/7').should == '8'
14
- end
15
-
16
- it "debería permitir acceder a values tipo array con subindice" do
17
- hash = { '1' => [{ '2' => 3 }, { '4' => 5 }] }
18
- hash.fetch_path('/1[0]/2').should == 3
19
- hash.fetch_path('/1[1]/4').should == 5
20
- hash.fetch_path('/1[0]').should == { '2' => 3 }
21
- hash.fetch_path('/1[2]').should == nil
22
- end
23
- end
24
-
25
4
  context "select_keys" do
26
5
  it "debería tomar los values de las keys indicadas" do
27
6
  hash = Hash[1, 2, 3, 4]
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'spec_helper'
3
3
 
4
4
  describe Afipws::TypeConversions do
5
5
  include Afipws::TypeConversions
@@ -1,5 +1,4 @@
1
- # coding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
3
2
 
4
3
  describe Afipws::WSAA do
5
4
  context "generación documento tra" do
@@ -30,9 +29,9 @@ describe Afipws::WSAA do
30
29
 
31
30
  context "login" do
32
31
  it "debería mandar el TRA al WS y obtener el TA" do
33
- ws = Afipws::WSAA.new :key => 'key', :cert => 'cert'
32
+ ws = Afipws::WSAA.new key: 'key', cert: 'cert'
34
33
  ws.expects(:tra).with('key', 'cert', 'wsfe', 2400).returns('tra')
35
- savon.expects('loginCms').with('wsdl:in0' => 'tra').returns(:success)
34
+ savon.expects(:login_cms).with(message: {in0: 'tra'}).returns(fixture('login_cms/success'))
36
35
  ta = ws.login
37
36
  ta[:token].should == 'PD94='
38
37
  ta[:sign].should == 'i9xDN='
@@ -42,8 +41,8 @@ describe Afipws::WSAA do
42
41
 
43
42
  it "debería encapsular SOAP Faults" do
44
43
  subject.stubs(:tra).returns('')
45
- savon.stubs('loginCms').returns(:fault)
46
- expect { subject.login }.to raise_error Afipws::WSError, /CMS no es valido/
44
+ savon.expects(:login_cms).with(message: :any).returns(fixture('login_cms/fault'))
45
+ lambda { subject.login }.should raise_error Afipws::WSError, /CMS no es valido/
47
46
  end
48
47
  end
49
48
 
@@ -1,223 +1,222 @@
1
- # coding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
3
2
 
4
3
  describe Afipws::WSFE do
5
- let :ws do
6
- wsaa = Afipws::WSAA.new
7
- wsaa.stubs :login => { :token => 't', :sign => 's', :expiration_time => 12.hours.from_now }
8
- Afipws::WSFE.new :cuit => '1', :wsaa => wsaa
9
- end
4
+ let(:auth) { {auth: {token: 't', sign: 's', expiration_time: 12.hours.from_now}} }
5
+ let(:ws) { Afipws::WSFE.new cuit: '1', wsaa: Afipws::WSAA.new.tap { |wsaa| wsaa.stubs auth: auth } }
10
6
 
11
7
  context "Métodos de negocio" do
12
8
  it "dummy" do
13
- savon.expects('FEDummy').returns(:success)
14
- ws.dummy.should == { :app_server => "OK", :db_server => "OK", :auth_server => "OK" }
9
+ savon.expects(:fe_dummy).returns(fixture('fe_dummy/success'))
10
+ ws.dummy.should == { app_server: "OK", db_server: "OK", auth_server: "OK" }
15
11
  end
16
12
 
17
13
  it "tipos_comprobantes" do
18
- savon.expects('FEParamGetTiposCbte').returns(:success)
14
+ savon.expects(:fe_param_get_tipos_cbte).with(message: auth).returns(fixture('fe_param_get_tipos_cbte/success'))
19
15
  ws.tipos_comprobantes.should == [
20
- { :id => 1, :desc => "Factura A", :fch_desde => Date.new(2010,9,17), :fch_hasta => nil },
21
- { :id => 2, :desc => "Nota de Débito A", :fch_desde => Date.new(2010,9,18), :fch_hasta => Date.new(2011,9,18) }]
16
+ { id: 1, desc: "Factura A", fch_desde: Date.new(2010,9,17), fch_hasta: nil },
17
+ { id: 2, desc: "Nota de Débito A", fch_desde: Date.new(2010,9,18), fch_hasta: Date.new(2011,9,18) }]
22
18
  end
23
19
 
24
20
  it "tipos_documentos" do
25
- savon.expects('FEParamGetTiposDoc').returns(:success)
26
- ws.tipos_documentos.should == [{ :id => 80, :desc => "CUIT", :fch_desde => Date.new(2008,7,25), :fch_hasta => nil }]
21
+ savon.expects(:fe_param_get_tipos_doc).with(message: auth).returns(fixture('fe_param_get_tipos_doc/success'))
22
+ ws.tipos_documentos.should == [{ id: 80, desc: "CUIT", fch_desde: Date.new(2008,7,25), fch_hasta: nil }]
27
23
  end
28
24
 
29
25
  it "tipos_monedas" do
30
- savon.expects('FEParamGetTiposMonedas').returns(:success)
26
+ savon.expects(:fe_param_get_tipos_monedas).with(message: auth).returns(fixture('fe_param_get_tipos_monedas/success'))
31
27
  ws.tipos_monedas.should == [
32
- { :id => 'PES', :desc => "Pesos Argentinos", :fch_desde => Date.new(2009,4,3), :fch_hasta => nil },
33
- { :id => '002', :desc => "Dólar Libre EEUU", :fch_desde => Date.new(2009,4,16), :fch_hasta => nil }]
28
+ { id: 'PES', desc: "Pesos Argentinos", fch_desde: Date.new(2009,4,3), fch_hasta: nil },
29
+ { id: '002', desc: "Dólar Libre EEUU", fch_desde: Date.new(2009,4,16), fch_hasta: nil }]
34
30
  end
35
31
 
36
32
  it "tipos_iva" do
37
- savon.expects('FEParamGetTiposIva').returns(:success)
38
- ws.tipos_iva.should == [{ :id => 5, :desc => "21%", :fch_desde => Date.new(2009,2,20), :fch_hasta => nil }]
33
+ savon.expects(:fe_param_get_tipos_iva).with(message: auth).returns(fixture('fe_param_get_tipos_iva/success'))
34
+ ws.tipos_iva.should == [{ id: 5, desc: "21%", fch_desde: Date.new(2009,2,20), fch_hasta: nil }]
39
35
  end
40
36
 
41
37
  it "tipos_tributos" do
42
- savon.expects('FEParamGetTiposTributos').returns(:success)
43
- ws.tipos_tributos.should == [{ :id => 2, :desc => "Impuestos provinciales", :fch_desde => Date.new(2010,9,17), :fch_hasta => nil }]
38
+ savon.expects(:fe_param_get_tipos_tributos).with(message: auth).returns(fixture('fe_param_get_tipos_tributos/success'))
39
+ ws.tipos_tributos.should == [{ id: 2, desc: "Impuestos provinciales", fch_desde: Date.new(2010,9,17), fch_hasta: nil }]
44
40
  end
45
41
 
46
42
  it "puntos_venta" do
47
- savon.expects('FEParamGetPtosVenta').returns(:success)
43
+ savon.expects(:fe_param_get_ptos_venta).with(message: auth).returns(fixture('fe_param_get_ptos_venta/success'))
48
44
  ws.puntos_venta.should == [
49
- { :nro => 1, :emision_tipo => "CAE", :bloqueado => false, :fch_baja => nil },
50
- { :nro => 2, :emision_tipo => "CAEA", :bloqueado => true, :fch_baja => Date.new(2011,1,31) }
51
- ]
45
+ { nro: 1, emision_tipo: "CAE", bloqueado: false, fch_baja: nil },
46
+ { nro: 2, emision_tipo: "CAEA", bloqueado: true, fch_baja: Date.new(2011,1,31) }]
52
47
  end
53
48
 
54
49
  context "cotizacion" do
55
50
  it "cuando la moneda solicitada existe" do
56
- savon.expects('FEParamGetCotizacion').with(has_path '/MonId' => 'DOL').returns(:dolar)
51
+ savon.expects(:fe_param_get_cotizacion).with(message: auth.merge(mon_id: 'DOL')).returns(fixture('fe_param_get_cotizacion/dolar'))
57
52
  ws.cotizacion('DOL').should == 3.976
58
53
  end
59
54
 
60
55
  it "cuando la moneda no existe" do
61
- savon.expects('FEParamGetCotizacion').with(has_path '/Auth/Token' => 't', '/MonId' => 'PES').returns(:inexistente)
62
- expect { ws.cotizacion('PES') }.to raise_error Afipws::WSError, /602: Sin Resultados/
56
+ savon.expects(:fe_param_get_cotizacion).with(message: auth.merge(mon_id: 'PES')).returns(fixture('fe_param_get_cotizacion/inexistente'))
57
+ lambda { ws.cotizacion('PES') }.should raise_error Afipws::WSError, /602: Sin Resultados/
63
58
  end
64
59
  end
65
60
 
66
61
  it "cant_max_registros_x_lote" do
67
- savon.expects('FECompTotXRequest').with(has_path '/Auth/Token' => 't').returns(:success)
62
+ savon.expects(:fe_comp_tot_x_request).with(message: auth).returns(fixture('fe_comp_tot_x_request/success'))
68
63
  ws.cant_max_registros_x_lote.should == 250
69
64
  end
70
65
 
71
66
  context "autorizar_comprobante" do
72
67
  it "debería devolver un hash con el CAE y su fecha de vencimiento" do
73
- savon.expects('FECAESolicitar').with(has_path '/Auth/Token' => 't',
74
- '/FeCAEReq/FeCabReq/CantReg' => 1,
75
- '/FeCAEReq/FeCabReq/PtoVta' => 2,
76
- '/FeCAEReq/FeCabReq/CbteTipo' => 1,
77
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/DocTipo' => 80,
78
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/DocNro' => 30521189203,
79
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/CbteFch' => '20110113',
80
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/ImpTotal' => 1270.48,
81
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/ImpIVA' => 220.5,
82
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Iva/AlicIva[0]/Id' => 5,
83
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Iva/AlicIva[0]/Importe' => 220.5,
84
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Tributos/Tributo[0]/Id' => 0,
85
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Tributos/Tributo[0]/BaseImp' => 150,
86
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Tributos/Tributo[0]/Alic' => 5.2,
87
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Tributos/Tributo[0]/Importe' => 7.8
88
- ).returns(:autorizacion_1_cbte)
89
- rta = ws.autorizar_comprobantes(:cbte_tipo => 1, :pto_vta => 2, :comprobantes => [{:cbte_nro => 1, :concepto => 1,
90
- :doc_nro => 30521189203, :doc_tipo => 80, :cbte_fch => Date.new(2011,01,13),
91
- :imp_total => 1270.48, :imp_neto => 1049.98, :imp_iva => 220.50, :mon_id => 'PES', :mon_cotiz => 1,
92
- :iva => { :alic_iva => [{ :id => 5, :base_imp => 1049.98, :importe => 220.50 }]},
93
- :tributos => { :tributo => [{ :id => 0, :base_imp => 150, :alic => 5.2, :importe => 7.8 }] }
68
+ savon.expects(:fecae_solicitar).with(message: has_path(
69
+ '//Auth/Token' => 't',
70
+ '//FeCAEReq/FeCabReq/CantReg' => 1,
71
+ '//FeCAEReq/FeCabReq/PtoVta' => 2,
72
+ '//FeCAEReq/FeCabReq/CbteTipo' => 1,
73
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/DocTipo' => 80,
74
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/DocNro' => 30521189203,
75
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/CbteFch' => 20110113,
76
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/ImpTotal' => 1270.48,
77
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/ImpIVA' => 220.5,
78
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Iva/AlicIva[1]/Id' => 5,
79
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Iva/AlicIva[1]/Importe' => 220.5,
80
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Tributos/Tributo[1]/Id' => 0,
81
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Tributos/Tributo[1]/BaseImp' => 150,
82
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Tributos/Tributo[1]/Alic' => 5.2,
83
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Tributos/Tributo[1]/Importe' => 7.8
84
+ )).returns(fixture('fecae_solicitar/autorizacion_1_cbte'))
85
+ rta = ws.autorizar_comprobantes(cbte_tipo: 1, pto_vta: 2, comprobantes: [{cbte_nro: 1, concepto: 1,
86
+ doc_nro: 30521189203, doc_tipo: 80, cbte_fch: Date.new(2011,01,13),
87
+ imp_total: 1270.48, imp_neto: 1049.98, imp_iva: 220.50, mon_id: 'PES', mon_cotiz: 1,
88
+ iva: { alic_iva: [{ id: 5, base_imp: 1049.98, importe: 220.50 }]},
89
+ tributos: { tributo: [{ id: 0, base_imp: 150, alic: 5.2, importe: 7.8 }] }
94
90
  }])
95
- rta[0].should have_entries :cae => '61023008595705', :cae_fch_vto => Date.new(2011,01,23), :cbte_nro => 1,
96
- :resultado => 'A', :observaciones => []
97
- rta.should have(1).item
91
+ rta[0].should have_entries cae: '61023008595705', cae_fch_vto: Date.new(2011,01,23), cbte_nro: 1,
92
+ resultado: 'A', observaciones: []
93
+ rta.size.should == 1
98
94
  end
99
95
 
100
96
  it "con varias alicuotas iva" do
101
- savon.expects('FECAESolicitar').with(has_path({
102
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Iva/AlicIva[0]/Id' => 5,
103
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Iva/AlicIva[0]/Importe' => 21,
104
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Iva/AlicIva[1]/Id' => 4,
105
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/Iva/AlicIva[1]/Importe' => 5.25
106
- })).returns(:autorizacion_1_cbte)
107
- ws.autorizar_comprobantes(:cbte_tipo => 1, :pto_vta => 2, :comprobantes => [{:iva => {:alic_iva => [
108
- { :id => 5, :base_imp => 100, :importe => 21 },
109
- { :id => 4, :base_imp => 50, :importe => 5.25 }
97
+ savon.expects(:fecae_solicitar).with(message: has_path(
98
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Iva/AlicIva[1]/Id' => 5,
99
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Iva/AlicIva[1]/Importe' => 21,
100
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Iva/AlicIva[2]/Id' => 4,
101
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/Iva/AlicIva[2]/Importe' => 5.25
102
+ )).returns(fixture('fecae_solicitar/autorizacion_1_cbte'))
103
+ ws.autorizar_comprobantes(cbte_tipo: 1, pto_vta: 2, comprobantes: [{iva: {alic_iva: [
104
+ { id: 5, base_imp: 100, importe: 21 },
105
+ { id: 4, base_imp: 50, importe: 5.25 }
110
106
  ]}}])
111
107
  end
112
108
 
113
109
  it "con varios comprobantes aprobados" do
114
- savon.expects('FECAESolicitar').with(has_path({
115
- '/FeCAEReq/FeCabReq/CantReg' => 2,
116
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/CbteDesde' => 5,
117
- '/FeCAEReq/FeDetReq/FECAEDetRequest[0]/CbteHasta' => 5,
118
- '/FeCAEReq/FeDetReq/FECAEDetRequest[1]/CbteDesde' => 6,
119
- '/FeCAEReq/FeDetReq/FECAEDetRequest[1]/CbteHasta' => 6,
120
- })).returns(:autorizacion_2_cbtes)
121
- rta = ws.autorizar_comprobantes(:cbte_tipo => 1, :pto_vta => 2, :comprobantes => [
122
- { :cbte_nro => 5 }, { :cbte_nro => 6 }
123
- ])
124
- rta[0].should have_entries :cbte_nro => 5, :cae => '61033008894096'
125
- rta[1].should have_entries :cbte_nro => 6, :cae => '61033008894101'
110
+ savon.expects(:fecae_solicitar).with(message: has_path(
111
+ '//FeCAEReq/FeCabReq/CantReg' => 2,
112
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/CbteDesde' => 5,
113
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[1]/CbteHasta' => 5,
114
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[2]/CbteDesde' => 6,
115
+ '//FeCAEReq/FeDetReq/FECAEDetRequest[2]/CbteHasta' => 6,
116
+ )).returns(fixture('fecae_solicitar/autorizacion_2_cbtes'))
117
+ rta = ws.autorizar_comprobantes(cbte_tipo: 1, pto_vta: 2, comprobantes: [{ cbte_nro: 5 }, { cbte_nro: 6 }])
118
+ rta[0].should have_entries cbte_nro: 5, cae: '61033008894096'
119
+ rta[1].should have_entries cbte_nro: 6, cae: '61033008894101'
126
120
  end
127
121
 
128
122
  it "con 2 observaciones" do
129
- savon.stubs('FECAESolicitar').returns(:dos_observaciones)
130
- rta = ws.autorizar_comprobantes :comprobantes => []
131
- rta[0].should have_entries :cbte_nro => 3, :cae => nil, :resultado => 'R', :observaciones => [
132
- {:code => 10048, :msg => 'Msg 1'}, {:code => 10018, :msg => 'Msg 2'}]
123
+ savon.expects(:fecae_solicitar).with(message: :any).returns(fixture 'fecae_solicitar/dos_observaciones')
124
+ rta = ws.autorizar_comprobantes comprobantes: []
125
+ rta[0].should have_entries cbte_nro: 3, cae: nil, resultado: 'R', observaciones: [
126
+ {code: 10048, msg: 'Msg 1'}, {code: 10018, msg: 'Msg 2'}]
133
127
  end
134
128
 
135
129
  it "con 1 observación" do
136
- savon.stubs('FECAESolicitar').returns(:una_observacion)
137
- rta = ws.autorizar_comprobantes :comprobantes => []
138
- rta[0].should have_entries :observaciones => [{:code => 10048, :msg => 'Msg 1'}]
130
+ savon.expects(:fecae_solicitar).with(message: :any).returns(fixture 'fecae_solicitar/una_observacion')
131
+ rta = ws.autorizar_comprobantes comprobantes: []
132
+ rta[0].should have_entries observaciones: [{code: 10048, msg: 'Msg 1'}]
139
133
  end
140
134
  end
141
135
 
142
136
  context "solicitar_caea" do
143
137
  it "debería mandar automáticamente el período y orden" do
144
- Date.stubs :today => Date.new(2011,1,27)
145
- savon.expects('FECAEASolicitar').with(has_path '/Periodo' => '201102', '/Orden' => 1).returns(:success)
146
- ws.solicitar_caea.should have_entries :caea => '21043476341977', :fch_tope_inf => Date.new(2011,03,17),
147
- :fch_vig_desde => Date.new(2011,02,01), :fch_vig_hasta => Date.new(2011,02,15)
138
+ Date.stubs today: Date.new(2011,1,27)
139
+ savon.expects(:fecaea_solicitar).with(message: has_path('//Periodo' => '201102', '//Orden' => 1)).returns(fixture 'fecaea_solicitar/success')
140
+ ws.solicitar_caea.should have_entries caea: '21043476341977', fch_tope_inf: Date.new(2011,03,17),
141
+ fch_vig_desde: Date.new(2011,02,01), fch_vig_hasta: Date.new(2011,02,15)
148
142
  end
149
143
 
150
144
  context "periodo_para_solicitud_caea" do
151
145
  it "cuando estoy en la primer quincena" do
152
- Date.stubs :today => Date.new(2011,1,12)
153
- ws.periodo_para_solicitud_caea.should == { :periodo => '201101', :orden => 2 }
154
- Date.stubs :today => Date.new(2011,1,15)
155
- ws.periodo_para_solicitud_caea.should == { :periodo => '201101', :orden => 2 }
146
+ Date.stubs today: Date.new(2011,1,12)
147
+ ws.periodo_para_solicitud_caea.should == { periodo: '201101', orden: 2 }
148
+ Date.stubs today: Date.new(2011,1,15)
149
+ ws.periodo_para_solicitud_caea.should == { periodo: '201101', orden: 2 }
156
150
  end
157
151
 
158
152
  it "cuando estoy en la segunda quincena" do
159
- Date.stubs :today => Date.new(2011,1,16)
160
- ws.periodo_para_solicitud_caea.should == { :periodo => '201102', :orden => 1 }
161
- Date.stubs :today => Date.new(2011,1,31)
162
- ws.periodo_para_solicitud_caea.should == { :periodo => '201102', :orden => 1 }
153
+ Date.stubs today: Date.new(2011,1,16)
154
+ ws.periodo_para_solicitud_caea.should == { periodo: '201102', orden: 1 }
155
+ Date.stubs today: Date.new(2011,1,31)
156
+ ws.periodo_para_solicitud_caea.should == { periodo: '201102', orden: 1 }
163
157
  end
164
158
  end
165
159
 
166
160
  it "cuando el caea ya fue otorgado debería consultarlo y devolverlo" do
167
- Date.stubs :today => Date.new(2011,1,27)
168
- savon.expects('FECAEASolicitar').with(has_path '/Periodo' => '201102', '/Orden' => 1).returns(:caea_ya_otorgado)
169
- savon.expects('FECAEAConsultar').with(has_path '/Periodo' => '201102', '/Orden' => 1).returns(:success)
170
- ws.solicitar_caea.should have_entries :caea => '21043476341977', :fch_vig_desde => Date.new(2011,02,01)
161
+ Date.stubs today: Date.new(2011,1,27)
162
+ savon.expects(:fecaea_solicitar).with(message: has_path('//Periodo' => '201102', '//Orden' => 1)).returns(fixture 'fecaea_solicitar/caea_ya_otorgado')
163
+ savon.expects(:fecaea_consultar).with(message: has_path('//Periodo' => '201102', '//Orden' => 1)).returns(fixture 'fecaea_consultar/success')
164
+ ws.solicitar_caea.should have_entries caea: '21043476341977', fch_vig_desde: Date.new(2011,02,01)
171
165
  end
172
166
 
173
167
  it "cuando hay otro error debería burbujearlo" do
174
- savon.expects('FECAEASolicitar').returns(:error_distinto)
175
- expect { ws.solicitar_caea }.to raise_error Afipws::WSError, /15007/
168
+ savon.expects(:fecaea_solicitar).with(message: :any).returns(fixture 'fecaea_solicitar/error_distinto')
169
+ lambda { ws.solicitar_caea }.should raise_error Afipws::WSError, /15007/
176
170
  end
177
171
  end
178
172
 
179
173
  it "informar_comprobantes_caea" do
180
- savon.expects('FECAEARegInformativo').with(has_path({ '/Auth/Token' => 't',
181
- '/FeCAEARegInfReq/FeCabReq/CantReg' => 2,
182
- '/FeCAEARegInfReq/FeCabReq/PtoVta' => 3,
183
- '/FeCAEARegInfReq/FeCabReq/CbteTipo' => 1,
184
- '/FeCAEARegInfReq/FeDetReq/FECAEADetRequest[0]/CbteDesde' => 1,
185
- '/FeCAEARegInfReq/FeDetReq/FECAEADetRequest[0]/CbteHasta' => 1,
186
- '/FeCAEARegInfReq/FeDetReq/FECAEADetRequest[0]/CAEA' => '21043476341977',
187
- '/FeCAEARegInfReq/FeDetReq/FECAEADetRequest[1]/CbteDesde' => 2,
188
- '/FeCAEARegInfReq/FeDetReq/FECAEADetRequest[1]/CbteHasta' => 2,
189
- '/FeCAEARegInfReq/FeDetReq/FECAEADetRequest[1]/CAEA' => '21043476341977',
190
- })).returns(:informe_rtdo_parcial)
191
- rta = ws.informar_comprobantes_caea(:cbte_tipo => 1, :pto_vta => 3, :comprobantes => [
192
- { :cbte_nro => 1, :caea => '21043476341977' }, { :cbte_nro => 2, :caea => '21043476341977' },
174
+ savon.expects(:fecaea_reg_informativo).with(message: has_path(
175
+ '//Auth/Token' => 't',
176
+ '//FeCAEARegInfReq/FeCabReq/CantReg' => 2,
177
+ '//FeCAEARegInfReq/FeCabReq/PtoVta' => 3,
178
+ '//FeCAEARegInfReq/FeCabReq/CbteTipo' => 1,
179
+ '//FeCAEARegInfReq/FeDetReq/FECAEADetRequest[1]/CbteDesde' => 1,
180
+ '//FeCAEARegInfReq/FeDetReq/FECAEADetRequest[1]/CbteHasta' => 1,
181
+ '//FeCAEARegInfReq/FeDetReq/FECAEADetRequest[1]/CAEA' => '21043476341977',
182
+ '//FeCAEARegInfReq/FeDetReq/FECAEADetRequest[2]/CbteDesde' => 2,
183
+ '//FeCAEARegInfReq/FeDetReq/FECAEADetRequest[2]/CbteHasta' => 2,
184
+ '//FeCAEARegInfReq/FeDetReq/FECAEADetRequest[2]/CAEA' => '21043476341977',
185
+ )).returns(fixture 'fecaea_reg_informativo/informe_rtdo_parcial')
186
+ rta = ws.informar_comprobantes_caea(cbte_tipo: 1, pto_vta: 3, comprobantes: [
187
+ { cbte_nro: 1, caea: '21043476341977' }, { cbte_nro: 2, caea: '21043476341977' },
193
188
  ])
194
- rta[0].should have_entries :cbte_nro => 1, :caea => '21043476341977', :resultado => 'A', :observaciones => []
195
- rta[1].should have_entries :cbte_nro => 2, :caea => '21043476341977', :resultado => 'R', :observaciones => [{:code => 724, :msg => 'Msg'}]
189
+ rta[0].should have_entries cbte_nro: 1, caea: '21043476341977', resultado: 'A', observaciones: []
190
+ rta[1].should have_entries cbte_nro: 2, caea: '21043476341977', resultado: 'R', observaciones: [{code: 724, msg: 'Msg'}]
196
191
  end
197
192
 
198
193
  it "informar_caea_sin_movimientos" do
199
- savon.expects('FECAEASinMovimientoInformar').with(has_path('/Auth/Token' => 't',
200
- '/PtoVta' => 4, '/CAEA' => '21043476341977')).returns(:success)
194
+ savon.expects(:fecaea_sin_movimiento_informar).with(message: has_path(
195
+ '//Auth/Token' => 't',
196
+ '//PtoVta' => 4,
197
+ '//CAEA' => '21043476341977'
198
+ )).returns(fixture 'fecaea_sin_movimiento_informar/success')
201
199
  rta = ws.informar_caea_sin_movimientos('21043476341977', 4)
202
- rta.should have_entries :caea => '21043476341977', :resultado => 'A'
200
+ rta.should have_entries caea: '21043476341977', resultado: 'A'
203
201
  end
204
202
 
205
203
  context "consultar_caea" do
206
204
  it "consultar_caea" do
207
- savon.expects('FECAEAConsultar').with(has_path '/Periodo' => '201101', '/Orden' => 1).returns(:success)
208
- ws.consultar_caea(Date.new(2011,1,1)).should have_entries :caea => '21043476341977', :fch_tope_inf => Date.new(2011,03,17)
205
+ savon.expects(:fecaea_consultar).with(message: has_path('//Periodo' => '201101', '//Orden' => 1)).returns(fixture 'fecaea_consultar/success')
206
+ ws.consultar_caea(Date.new(2011,1,1)).should have_entries caea: '21043476341977', fch_tope_inf: Date.new(2011,03,17)
209
207
  end
210
208
  end
211
209
 
212
210
  it "ultimo_comprobante_autorizado" do
213
- savon.expects('FECompUltimoAutorizado').with(has_path '/PtoVta' => 1, '/CbteTipo' => 1).returns(:success)
214
- ws.ultimo_comprobante_autorizado(:pto_vta => 1, :cbte_tipo => 1).should == 20
211
+ savon.expects(:fe_comp_ultimo_autorizado).with(message: has_path('//PtoVta' => 1, '//CbteTipo' => 1)).returns(fixture 'fe_comp_ultimo_autorizado/success')
212
+ ws.ultimo_comprobante_autorizado(pto_vta: 1, cbte_tipo: 1).should == 20
215
213
  end
216
214
 
217
215
  it "consultar_comprobante" do
218
- savon.expects('FECompConsultar').with(has_path '/Auth/Token' => 't',
219
- '/FeCompConsReq/PtoVta' => 1, '/FeCompConsReq/CbteTipo' => 2, '/FeCompConsReq/CbteNro' => 3).returns(:success)
220
- rta = ws.consultar_comprobante(:pto_vta => 1, :cbte_tipo => 2, :cbte_nro => 3)
216
+ savon.expects(:fe_comp_consultar).with(message: has_path(
217
+ '//Auth/Token' => 't', '//FeCompConsReq/PtoVta' => 1, '//FeCompConsReq/CbteTipo' => 2, '//FeCompConsReq/CbteNro' => 3
218
+ )).returns(fixture 'fe_comp_consultar/success')
219
+ rta = ws.consultar_comprobante(pto_vta: 1, cbte_tipo: 2, cbte_nro: 3)
221
220
  rta[:cod_autorizacion].should == '61023008595705'
222
221
  rta[:emision_tipo].should == 'CAE'
223
222
  end
@@ -225,48 +224,49 @@ describe Afipws::WSFE do
225
224
 
226
225
  context "autenticacion" do
227
226
  it "debería autenticarse usando el WSAA" do
228
- wsfe = Afipws::WSFE.new :cuit => '1', :cert => 'cert', :key => 'key'
227
+ wsfe = Afipws::WSFE.new cuit: '1', cert: 'cert', key: 'key'
229
228
  wsfe.wsaa.cert.should == 'cert'
230
229
  wsfe.wsaa.key.should == 'key'
231
230
  wsfe.wsaa.service.should == 'wsfe'
232
- wsfe.wsaa.expects(:login).returns({ :token => 't', :sign => 's' })
233
- savon.expects('FEParamGetTiposCbte').with('wsdl:Auth' => {'wsdl:Token' => 't', 'wsdl:Sign' => 's', 'wsdl:Cuit' => '1'}).returns(:success)
231
+ wsfe.wsaa.expects(:login).returns({ token: 't', sign: 's' })
232
+ savon.expects(:fe_param_get_tipos_cbte).with(message: has_path(
233
+ '//Auth/Token' => 't', '//Auth/Sign' => 's', '//Auth/Cuit' => '1'
234
+ )).returns(fixture 'fe_param_get_tipos_cbte/success')
234
235
  wsfe.tipos_comprobantes
235
236
  end
236
237
  end
237
238
 
238
239
  context "entorno" do
239
240
  it "debería usar las url para development cuando el env es development" do
240
- Afipws::Client.expects(:new).with("https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl", :development)
241
- Afipws::Client.expects(:new).with("https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL", :development)
242
- wsfe = Afipws::WSFE.new :env => :development
241
+ Afipws::Client.expects(:new).with(wsdl: 'https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl')
242
+ Afipws::Client.expects(:new).with(wsdl: 'https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL', ssl_version: :SSLv3, convert_request_keys_to: :camelcase)
243
+ wsfe = Afipws::WSFE.new env: :development
243
244
  wsfe.env.should == :development
244
245
  end
245
246
 
246
247
  it "debería usar las url para production cuando el env es production" do
247
- Afipws::Client.expects(:new).with("https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl", :production)
248
- # Afipws::Client.expects(:new).with("https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL", :production)
249
- Afipws::Client.expects(:new).with(File.expand_path(File.dirname(__FILE__) + '/../../') + "/lib/afipws/wsfev1.wsdl", :production)
250
- wsfe = Afipws::WSFE.new :env => 'production'
248
+ Afipws::Client.expects(:new).with(wsdl: 'https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl')
249
+ Afipws::Client.expects(:new).with(has_entries wsdl: File.expand_path(File.dirname(__FILE__) + '/../../') + "/lib/afipws/wsfev1.wsdl")
250
+ wsfe = Afipws::WSFE.new env: 'production'
251
251
  wsfe.env.should == :production
252
252
  end
253
253
  end
254
254
 
255
255
  context "manejo de errores" do
256
256
  it "cuando hay un error" do
257
- savon.expects('FEParamGetTiposCbte').returns(:failure_1_error)
258
- expect { ws.tipos_comprobantes }.to raise_error { |e|
257
+ savon.expects(:fe_param_get_tipos_cbte).with(message: :any).returns(fixture 'fe_param_get_tipos_cbte/failure_1_error')
258
+ lambda { ws.tipos_comprobantes }.should raise_error { |e|
259
259
  e.should be_a Afipws::WSError
260
- e.errors.should == [{ :code => "600", :msg => "No se corresponden token con firma" }]
260
+ e.errors.should == [{ code: "600", msg: "No se corresponden token con firma" }]
261
261
  e.message.should == "600: No se corresponden token con firma"
262
262
  }
263
263
  end
264
264
 
265
265
  it "cuando hay varios errores" do
266
- savon.expects('FEParamGetTiposCbte').returns(:failure_2_errors)
267
- expect { ws.tipos_comprobantes }.to raise_error { |e|
266
+ savon.expects(:fe_param_get_tipos_cbte).with(message: :any).returns(fixture 'fe_param_get_tipos_cbte/failure_2_errors')
267
+ lambda { ws.tipos_comprobantes }.should raise_error { |e|
268
268
  e.should be_a Afipws::WSError
269
- e.errors.should == [{ :code => "600", :msg => "No se corresponden token con firma" }, { :code => "601", :msg => "CUIT representada no incluida en token" }]
269
+ e.errors.should == [{ code: "600", msg: "No se corresponden token con firma" }, { code: "601", msg: "CUIT representada no incluida en token" }]
270
270
  e.message.should == "600: No se corresponden token con firma; 601: CUIT representada no incluida en token"
271
271
  }
272
272
  end
@@ -274,11 +274,11 @@ describe Afipws::WSFE do
274
274
 
275
275
  context "cálculo de fechas y períodos" do
276
276
  it "periodo_para_consulta_caea" do
277
- ws.periodo_para_consulta_caea(Date.new(2011,1,1)).should == { :periodo => '201101', :orden => 1 }
278
- ws.periodo_para_consulta_caea(Date.new(2011,1,15)).should == { :periodo => '201101', :orden => 1 }
279
- ws.periodo_para_consulta_caea(Date.new(2011,1,16)).should == { :periodo => '201101', :orden => 2 }
280
- ws.periodo_para_consulta_caea(Date.new(2011,1,31)).should == { :periodo => '201101', :orden => 2 }
281
- ws.periodo_para_consulta_caea(Date.new(2011,2,2)).should == { :periodo => '201102', :orden => 1 }
277
+ ws.periodo_para_consulta_caea(Date.new(2011,1,1)).should == { periodo: '201101', orden: 1 }
278
+ ws.periodo_para_consulta_caea(Date.new(2011,1,15)).should == { periodo: '201101', orden: 1 }
279
+ ws.periodo_para_consulta_caea(Date.new(2011,1,16)).should == { periodo: '201101', orden: 2 }
280
+ ws.periodo_para_consulta_caea(Date.new(2011,1,31)).should == { periodo: '201101', orden: 2 }
281
+ ws.periodo_para_consulta_caea(Date.new(2011,2,2)).should == { periodo: '201102', orden: 1 }
282
282
  end
283
283
 
284
284
  it "fecha_inicio_quincena_siguiente" do
@@ -293,7 +293,7 @@ describe Afipws::WSFE do
293
293
  end
294
294
 
295
295
  def fecha_inicio_quincena_siguiente fecha
296
- Date.stubs(:today => fecha)
296
+ Date.stubs(today: fecha)
297
297
  subject.fecha_inicio_quincena_siguiente
298
298
  end
299
299
  end
@@ -304,7 +304,7 @@ describe Afipws::WSFE do
304
304
  end
305
305
 
306
306
  it "no debería enviar tag tributos si el impTrib es 0" do
307
- c2r(:imp_trib => 0.0, :tributos => { :tributo => [] }).should_not have_key :tributos
307
+ c2r(imp_trib: 0.0, tributos: { tributo: [] }).should_not have_key :tributos
308
308
  end
309
309
  end
310
310
  end
@@ -1,8 +1,6 @@
1
1
  $LOAD_PATH.unshift(File.expand_path('lib')); require 'afipws'
2
2
 
3
- Savon.configure { |config| config.log = true }
4
-
5
- ws = Afipws::WSFE.new :env => :development, :cuit => '20300032673', :cert => File.read('spec/manual/test.crt'), :key => File.read('spec/manual/test.key')
3
+ ws = Afipws::WSFE.new env: :development, cuit: '20300032673', cert: File.read('spec/manual/test.crt'), key: File.read('spec/manual/test.key'), savon: {log: true}
6
4
 
7
5
  def obtener_ta ws
8
6
  ws.cotizacion 'DOL'
@@ -16,26 +14,22 @@ def obtener_ta ws
16
14
  end
17
15
 
18
16
  def autorizar_comprobante ws
19
- ultimo = ws.ultimo_comprobante_autorizado :pto_vta => 1, :cbte_tipo => 1
17
+ ultimo = ws.ultimo_comprobante_autorizado pto_vta: 1, cbte_tipo: 1
20
18
  # cant_informar = ws.cant_max_registros_x_lote
21
19
  cant_informar = 2
22
20
  puts "Informando #{cant_informar} comprobantes"
23
21
  comprobantes = (1..cant_informar).to_a.map do |i|
24
22
  {
25
- :cbte_nro => ultimo + i, :concepto => 1, :doc_nro => 30521189203, :doc_tipo => 80, :cbte_fch => Date.today,
26
- :imp_total => 1270.48, :imp_neto => 1049.98, :imp_iva => 220.50, :mon_id => 'PES', :mon_cotiz => 1,
27
- :iva => { :alic_iva => [{ :id => 5, :base_imp => 1049.98, :importe => 220.50 }]}
23
+ cbte_nro: ultimo + i, concepto: 1, doc_nro: 30521189203, doc_tipo: 80, cbte_fch: Date.today,
24
+ imp_total: 1270.48, imp_neto: 1049.98, imp_iva: 220.50, mon_id: 'PES', mon_cotiz: 1,
25
+ iva: { alic_iva: [{ id: 5, base_imp: 1049.98, importe: 220.50 }]}
28
26
  }
29
27
  end
30
- puts ws.autorizar_comprobantes(:cbte_tipo => 1, :pto_vta => 1, :comprobantes => comprobantes)
28
+ puts ws.autorizar_comprobantes(cbte_tipo: 1, pto_vta: 1, comprobantes: comprobantes)
31
29
  end
32
30
 
33
31
  def consultar_caea ws
34
32
  ws.consultar_caea Date.new(2011,2,3)
35
33
  end
36
34
 
37
- def soap_actions ws
38
- ws.client.soap_actions
39
- end
40
-
41
35
  obtener_ta ws
@@ -1,11 +1,24 @@
1
1
  require 'rspec'
2
2
  require 'afipws'
3
- require 'savon_spec'
3
+ require 'savon/mock/spec_helper'
4
+ require 'mocha'
5
+ require 'pry-byebug'
4
6
 
5
7
  Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each { |f| require f }
6
8
 
7
9
  RSpec.configure do |config|
8
- config.include Savon::Spec::Macros
10
+ config.include Savon::SpecHelper
11
+
12
+ config.mock_with :mocha
13
+ config.expect_with(:rspec) { |c| c.syntax = :should }
14
+ config.alias_example_to :fit, focused: true
15
+ config.filter_run focused: true
16
+ config.run_all_when_everything_filtered = true
17
+
18
+ config.before(:all) { savon.mock! }
19
+ config.after(:all) { savon.unmock! }
9
20
  end
10
21
 
11
- Savon::Spec::Fixture.path = File.expand_path("../fixtures", __FILE__)
22
+ def fixture file
23
+ File.read("#{Afipws::Root}/spec/fixtures/#{file}.xml")
24
+ end
@@ -1,37 +1,11 @@
1
- RSpec::Matchers.define :match_xpath do |xpath, expected_text|
1
+ RSpec::Matchers.define :match_xpath do |xpath, expected_value|
2
2
  match do |xml|
3
- xml = Nokogiri::XML xml
4
- xml.xpath(xpath).text.should == expected_text
3
+ @xml = Nokogiri::XML xml
4
+ @xml.remove_namespaces!
5
+ @xml.xpath(xpath).text.should == expected_value.to_s
5
6
  end
6
- end
7
7
 
8
- require 'mocha/parameter_matchers/base'
9
-
10
- module Mocha
11
- module ParameterMatchers
12
- def has_path(paths)
13
- HasPath.new(paths)
14
- end
15
-
16
- class HasPath < Base # :nodoc:
17
- def initialize(paths)
18
- @paths = paths
19
- end
20
-
21
- def matches?(available_parameters)
22
- parameter = available_parameters.shift
23
- return false unless parameter.is_a? Hash
24
- @paths.all? do |path|
25
- path, expected_value = path
26
- actual_value = parameter.fetch_path path.gsub('/', '/wsdl:')
27
- @failed_path, @failed_value, @actual_value = path, expected_value, actual_value
28
- expected_value == actual_value
29
- end
30
- end
31
-
32
- def mocha_inspect
33
- "has_path(#{@failed_path.mocha_inspect} => #{@failed_value.mocha_inspect} | Actual: #{@actual_value.mocha_inspect})"
34
- end
35
- end
8
+ failure_message_for_should do |actual|
9
+ "expected xpath '#{xpath}' with value '#{expected_value}' in doc:\n#{@xml}"
36
10
  end
37
11
  end
@@ -0,0 +1,39 @@
1
+ # Savon 2 sólo permite verificar los params del mensaje como un hash lo cual es poco flexible. Con esto permito pasarle xpaths.
2
+
3
+ module Savon
4
+ module MessageMatcher
5
+ def actual(operation_name, builder, globals, locals)
6
+ super.update request: builder.to_s
7
+ end
8
+
9
+ def verify_message!
10
+ if @expected[:message].respond_to? :verify!
11
+ @expected[:message].verify! @actual[:request]
12
+ else
13
+ super
14
+ end
15
+ end
16
+ end
17
+
18
+ MockExpectation.prepend MessageMatcher
19
+ end
20
+
21
+ def has_path(paths)
22
+ HasXPath.new(paths)
23
+ end
24
+
25
+ class HasXPath
26
+ include RSpec::Matchers
27
+
28
+ def initialize(paths)
29
+ @paths = paths
30
+ end
31
+
32
+ def verify! xml
33
+ @actual_xml = xml
34
+ @paths.each do |(path, value)|
35
+ @expected_xpath, @expected_value = path, value
36
+ @actual_xml.should match_xpath @expected_xpath, @expected_value
37
+ end
38
+ end
39
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: afipws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emmanuel Nicolau
@@ -14,52 +14,66 @@ dependencies:
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 2.14.1
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 2.14.1
27
27
  - !ruby/object:Gem::Dependency
28
- name: savon_spec
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 10.4.2
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 10.4.2
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake
42
+ name: mocha
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 10.4.2
47
+ version: 0.9.10
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 10.4.2
54
+ version: 0.9.10
55
55
  - !ruby/object:Gem::Dependency
56
- name: builder
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 4.3.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 4.3.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
60
74
  - !ruby/object:Gem::Version
61
75
  version: '0'
62
- type: :runtime
76
+ type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
@@ -67,7 +81,7 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: savon
84
+ name: builder
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
@@ -81,21 +95,21 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: nokogiri
98
+ name: savon
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - ">="
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '0'
103
+ version: 2.11.0
90
104
  type: :runtime
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - ">="
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '0'
110
+ version: 2.11.0
97
111
  - !ruby/object:Gem::Dependency
98
- name: activesupport
112
+ name: nokogiri
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
@@ -109,7 +123,7 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: i18n
126
+ name: activesupport
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
@@ -123,7 +137,7 @@ dependencies:
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
- name: httpclient
140
+ name: i18n
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - ">="
@@ -137,19 +151,19 @@ dependencies:
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
- name: httpi
154
+ name: httpclient
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - ">="
144
158
  - !ruby/object:Gem::Version
145
- version: 2.4.2
159
+ version: '0'
146
160
  type: :runtime
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - ">="
151
165
  - !ruby/object:Gem::Version
152
- version: 2.4.2
166
+ version: '0'
153
167
  description: ''
154
168
  email:
155
169
  - emmanicolau@gmail.com
@@ -216,6 +230,7 @@ files:
216
230
  - spec/manual/test.rb
217
231
  - spec/spec_helper.rb
218
232
  - spec/support/matchers.rb
233
+ - spec/support/savon_extensions.rb
219
234
  homepage: ''
220
235
  licenses: []
221
236
  metadata: {}
@@ -279,3 +294,4 @@ test_files:
279
294
  - spec/manual/test.rb
280
295
  - spec/spec_helper.rb
281
296
  - spec/support/matchers.rb
297
+ - spec/support/savon_extensions.rb