afipws 1.0.3 → 1.0.4
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
- data/.rubocop.yml +102 -0
- data/.travis.yml +1 -0
- data/Gemfile.lock +22 -4
- data/LICENSE.txt +22 -0
- data/README.md +11 -5
- data/afipws.gemspec +1 -0
- data/lib/afipws.rb +2 -0
- data/lib/afipws/client.rb +4 -17
- data/lib/afipws/core_ext/hash.rb +2 -2
- data/lib/afipws/excepciones.rb +1 -1
- data/lib/afipws/type_conversions.rb +19 -16
- data/lib/afipws/version.rb +1 -1
- data/lib/afipws/ws_base.rb +12 -0
- data/lib/afipws/ws_constancia_inscripcion.rb +33 -0
- data/lib/afipws/wsaa.rb +9 -13
- data/lib/afipws/{wsfev1.wsdl → wsdl/wsfev1.wsdl} +1371 -1371
- data/lib/afipws/wsfe.rb +57 -38
- data/spec/afipws/core_ext/hash_spec.rb +6 -6
- data/spec/afipws/type_conversions_spec.rb +11 -12
- data/spec/afipws/ws_constancia_inscripcion_spec.rb +65 -0
- data/spec/afipws/wsaa_spec.rb +66 -58
- data/spec/afipws/wsfe_spec.rb +272 -259
- data/spec/fixtures/constancia_inscripcion_dummy/success.xml +11 -0
- data/spec/fixtures/constancia_inscripcion_get_persona/failure.xml +35 -0
- data/spec/fixtures/constancia_inscripcion_get_persona/success.xml +53 -0
- data/spec/fixtures/ws_constancia_inscripcion.wsdl +230 -0
- metadata +31 -5
- data/.autotest +0 -2
- data/autotest/discover.rb +0 -1
data/lib/afipws/wsfe.rb
CHANGED
@@ -1,68 +1,69 @@
|
|
1
1
|
module Afipws
|
2
|
-
class WSFE
|
3
|
-
extend Forwardable
|
2
|
+
class WSFE < WSBase
|
4
3
|
include TypeConversions
|
5
|
-
attr_reader :wsaa, :client, :env
|
6
|
-
def_delegators :wsaa, :ta, :auth, :cuit
|
7
4
|
|
8
5
|
WSDL = {
|
9
|
-
development:
|
10
|
-
# production:
|
11
|
-
production: Root +
|
12
|
-
test: Root +
|
13
|
-
}
|
6
|
+
development: 'https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL',
|
7
|
+
# production: 'https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL',
|
8
|
+
production: Root + '/lib/afipws/wsdl/wsfev1.wsdl',
|
9
|
+
test: Root + '/spec/fixtures/wsfe.wsdl'
|
10
|
+
}.freeze
|
14
11
|
|
15
12
|
def initialize options = {}
|
16
|
-
|
17
|
-
@wsaa =
|
18
|
-
@client = Client.new Hash(options[:savon]).reverse_merge(wsdl: WSDL[
|
13
|
+
super
|
14
|
+
@wsaa = WSAA.new options.merge(service: 'wsfe')
|
15
|
+
@client = Client.new Hash(options[:savon]).reverse_merge(wsdl: WSDL[env], convert_request_keys_to: :camelcase)
|
19
16
|
end
|
20
17
|
|
21
18
|
def dummy
|
22
|
-
|
19
|
+
request :fe_dummy
|
23
20
|
end
|
24
21
|
|
25
22
|
def tipos_comprobantes
|
26
|
-
r =
|
23
|
+
r = request :fe_param_get_tipos_cbte, auth
|
27
24
|
x2r get_array(r, :cbte_tipo), id: :integer, fch_desde: :date, fch_hasta: :date
|
28
25
|
end
|
29
26
|
|
30
27
|
def tipos_documentos
|
31
|
-
r =
|
28
|
+
r = request :fe_param_get_tipos_doc, auth
|
32
29
|
x2r get_array(r, :doc_tipo), id: :integer, fch_desde: :date, fch_hasta: :date
|
33
30
|
end
|
34
31
|
|
35
32
|
def tipos_monedas
|
36
|
-
r =
|
33
|
+
r = request :fe_param_get_tipos_monedas, auth
|
37
34
|
x2r get_array(r, :moneda), fch_desde: :date, fch_hasta: :date
|
38
35
|
end
|
39
36
|
|
40
37
|
def tipos_iva
|
41
|
-
r =
|
38
|
+
r = request :fe_param_get_tipos_iva, auth
|
42
39
|
x2r get_array(r, :iva_tipo), id: :integer, fch_desde: :date, fch_hasta: :date
|
43
40
|
end
|
44
41
|
|
45
42
|
def tipos_tributos
|
46
|
-
r =
|
43
|
+
r = request :fe_param_get_tipos_tributos, auth
|
47
44
|
x2r get_array(r, :tributo_tipo), id: :integer, fch_desde: :date, fch_hasta: :date
|
48
45
|
end
|
49
46
|
|
50
47
|
def puntos_venta
|
51
|
-
r =
|
48
|
+
r = request :fe_param_get_ptos_venta, auth
|
52
49
|
x2r get_array(r, :pto_venta), nro: :integer, fch_baja: :date, bloqueado: :boolean
|
53
50
|
end
|
54
51
|
|
55
52
|
def cotizacion moneda_id
|
56
|
-
|
53
|
+
request(:fe_param_get_cotizacion, auth.merge(mon_id: moneda_id))[:result_get][:mon_cotiz].to_f
|
57
54
|
end
|
58
55
|
|
59
56
|
def autorizar_comprobantes opciones
|
60
57
|
comprobantes = opciones[:comprobantes]
|
61
|
-
|
62
|
-
'
|
63
|
-
|
64
|
-
|
65
|
-
|
58
|
+
mensaje = {
|
59
|
+
'FeCAEReq' => {
|
60
|
+
'FeCabReq' => opciones.select_keys(:cbte_tipo, :pto_vta).merge(cant_reg: comprobantes.size),
|
61
|
+
'FeDetReq' => {
|
62
|
+
'FECAEDetRequest' => comprobantes.map { |comprobante| comprobante_to_request comprobante }
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
r = request :fecae_solicitar, auth.merge(r2x(mensaje, cbte_fch: :date))
|
66
67
|
r = Array.wrap(r[:fe_det_resp][:fecae_det_response]).map do |h|
|
67
68
|
obs = Array.wrap(h[:observaciones] ? h[:observaciones][:obs] : nil)
|
68
69
|
h.select_keys(:cae, :cae_fch_vto, :resultado).merge(cbte_nro: h[:cbte_desde], observaciones: obs)
|
@@ -78,7 +79,7 @@ module Afipws
|
|
78
79
|
end
|
79
80
|
|
80
81
|
def solicitar_caea
|
81
|
-
convertir_rta_caea
|
82
|
+
convertir_rta_caea request(:fecaea_solicitar, auth.merge(periodo_para_solicitud_caea))
|
82
83
|
rescue Afipws::WSError => e
|
83
84
|
if e.errors.any? { |e| e[:code] == '15008' }
|
84
85
|
consultar_caea fecha_inicio_quincena_siguiente
|
@@ -88,18 +89,22 @@ module Afipws
|
|
88
89
|
end
|
89
90
|
|
90
91
|
def consultar_caea fecha
|
91
|
-
convertir_rta_caea
|
92
|
+
convertir_rta_caea request(:fecaea_consultar, auth.merge(periodo_para_consulta_caea(fecha)))
|
92
93
|
end
|
93
94
|
|
94
95
|
def informar_comprobantes_caea opciones
|
95
96
|
comprobantes = opciones[:comprobantes]
|
96
|
-
|
97
|
-
'
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
97
|
+
mensaje = {
|
98
|
+
'FeCAEARegInfReq' => {
|
99
|
+
'FeCabReq' => opciones.select_keys(:cbte_tipo, :pto_vta).merge(cant_reg: comprobantes.size),
|
100
|
+
'FeDetReq' => {
|
101
|
+
'FECAEADetRequest' => comprobantes.map do |comprobante|
|
102
|
+
comprobante_to_request comprobante.merge('CAEA' => comprobante.delete(:caea))
|
103
|
+
end
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
r = request :fecaea_reg_informativo, auth.merge(r2x(mensaje, cbte_fch: :date))
|
103
108
|
r = Array.wrap(r[:fe_det_resp][:fecaea_det_response]).map do |h|
|
104
109
|
obs = Array.wrap(h[:observaciones] ? h[:observaciones][:obs] : nil)
|
105
110
|
h.select_keys(:caea, :resultado).merge(cbte_nro: h[:cbte_desde], observaciones: obs)
|
@@ -108,19 +113,19 @@ module Afipws
|
|
108
113
|
end
|
109
114
|
|
110
115
|
def informar_caea_sin_movimientos caea, pto_vta
|
111
|
-
|
116
|
+
request :fecaea_sin_movimiento_informar, auth.merge('CAEA' => caea, 'PtoVta' => pto_vta)
|
112
117
|
end
|
113
118
|
|
114
119
|
def ultimo_comprobante_autorizado opciones
|
115
|
-
|
120
|
+
request(:fe_comp_ultimo_autorizado, auth.merge(opciones))[:cbte_nro].to_i
|
116
121
|
end
|
117
122
|
|
118
123
|
def consultar_comprobante opciones
|
119
|
-
|
124
|
+
request(:fe_comp_consultar, auth.merge(fe_comp_cons_req: opciones))[:result_get]
|
120
125
|
end
|
121
126
|
|
122
127
|
def cant_max_registros_x_lote
|
123
|
-
|
128
|
+
request(:fe_comp_tot_x_request, auth)[:reg_x_req].to_i
|
124
129
|
end
|
125
130
|
|
126
131
|
def periodo_para_solicitud_caea
|
@@ -137,7 +142,21 @@ module Afipws
|
|
137
142
|
hoy.day <= 15 ? hoy.change(day: 16) : hoy.next_month.change(day: 1)
|
138
143
|
end
|
139
144
|
|
145
|
+
def auth
|
146
|
+
{auth: wsaa.auth.merge(cuit: cuit)}
|
147
|
+
end
|
148
|
+
|
140
149
|
private
|
150
|
+
|
151
|
+
def request action, body = nil
|
152
|
+
response = @client.request(action, body).to_hash[:"#{action}_response"][:"#{action}_result"]
|
153
|
+
if response[:errors]
|
154
|
+
raise WSError, Array.wrap(response[:errors][:err])
|
155
|
+
else
|
156
|
+
response
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
141
160
|
def get_array response, array_element
|
142
161
|
Array.wrap response[:result_get][array_element]
|
143
162
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Hash do
|
4
|
-
context
|
5
|
-
it
|
4
|
+
context 'select_keys' do
|
5
|
+
it 'debería tomar los values de las keys indicadas' do
|
6
6
|
hash = Hash[1, 2, 3, 4]
|
7
7
|
hash.select_keys(1).should == {1 => 2}
|
8
8
|
hash.select_keys(1, 3).should == {1 => 2, 3 => 4}
|
@@ -10,11 +10,11 @@ describe Hash do
|
|
10
10
|
hash.select_keys(5, 3).should == {3 => 4}
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
14
|
-
context
|
13
|
+
|
14
|
+
context 'has_entries?' do
|
15
15
|
subject { Hash[1, 2, 3, 4] }
|
16
|
-
|
17
|
-
it
|
16
|
+
|
17
|
+
it 'debería devolver true cuando self incluye todas las entries del hash parametro' do
|
18
18
|
should have_entries 1 => 2
|
19
19
|
should have_entries 3 => 4, 1 => 2
|
20
20
|
should_not have_entries 1 => 3
|
@@ -1,29 +1,28 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
3
|
describe Afipws::TypeConversions do
|
5
4
|
include Afipws::TypeConversions
|
6
|
-
|
7
|
-
context
|
8
|
-
it
|
9
|
-
r2x({fecha: Date.new(2011, 1, 2), :
|
5
|
+
|
6
|
+
context 'r2x' do
|
7
|
+
it 'debería convertir values de hashes a xml types' do
|
8
|
+
r2x({fecha: Date.new(2011, 1, 2), id: 1}, fecha: :date).should == {fecha: '20110102', id: 1}
|
10
9
|
r2x({container: {fecha: Date.new(2011, 1, 2)}}, fecha: :date).should == {container: {fecha: '20110102'}}
|
11
10
|
end
|
12
11
|
|
13
|
-
it
|
12
|
+
it 'debería convertir values de hashes aunque estén en arrays' do
|
14
13
|
r2x([{fecha: Date.new(2011, 1, 2)}], fecha: :date).should == [{fecha: '20110102'}]
|
15
14
|
r2x({container: [{fecha: Date.new(2011, 1, 2)}, {fecha: Date.new(2011, 1, 3)}]}, fecha: :date).should == {container: [{fecha: '20110102'}, {fecha: '20110103'}]}
|
16
15
|
end
|
17
16
|
end
|
18
|
-
|
19
|
-
context
|
20
|
-
it
|
17
|
+
|
18
|
+
context 'x2r' do
|
19
|
+
it 'deberia convertir values de hashes de xml types a ruby' do
|
21
20
|
x2r({fecha: '20110102', id: '1', total: '1.23', obs: 'algo'}, fecha: :date, id: :integer, total: :float)
|
22
|
-
.should == {fecha: Date.new(2011,1,2), id: 1, total: 1.23, obs: 'algo'}
|
21
|
+
.should == {fecha: Date.new(2011, 1, 2), id: 1, total: 1.23, obs: 'algo'}
|
23
22
|
x2r({container: {id: '1'}}, id: :integer).should == {container: {id: 1}}
|
24
23
|
end
|
25
|
-
|
26
|
-
it
|
24
|
+
|
25
|
+
it 'debería hacer la conversión en arrays también' do
|
27
26
|
x2r({container: [{id: '1'}, {id: '2'}]}, id: :integer).should == {container: [{id: 1}, {id: 2}]}
|
28
27
|
end
|
29
28
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Afipws
|
4
|
+
describe WSConstanciaInscripcion do
|
5
|
+
let(:ta) { {token: 't', sign: 's'} }
|
6
|
+
let(:ws) { WSConstanciaInscripcion.new(cuit: '1').tap { |ws| ws.wsaa.stubs auth: ta } }
|
7
|
+
let(:auth) { ta.merge(cuit_representada: '1') }
|
8
|
+
|
9
|
+
context 'métodos API' do
|
10
|
+
it 'dummy' do
|
11
|
+
savon.expects(:dummy).returns(fixture('constancia_inscripcion_dummy/success'))
|
12
|
+
ws.dummy.should == { appserver: 'OK', dbserver: 'OK', authserver: 'OK' }
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'debería devolver un hash con los datos generales y regímenes impositivos' do
|
16
|
+
savon.expects(:get_persona)
|
17
|
+
.with(message: auth.merge(id_persona: '20294834487'))
|
18
|
+
.returns(fixture('constancia_inscripcion_get_persona/success'))
|
19
|
+
r = ws.get_persona '20294834487'
|
20
|
+
r[:datos_generales].should have_entries(
|
21
|
+
estado_clave: 'ACTIVO', mes_cierre: '6', razon_social: 'LA REGALERIA S A',
|
22
|
+
tipo_clave: 'CUIT', tipo_persona: 'JURIDICA'
|
23
|
+
)
|
24
|
+
r[:datos_generales][:domicilio_fiscal].should have_entries(
|
25
|
+
cod_postal: '2300', descripcion_provincia: 'SANTA FE',
|
26
|
+
direccion: 'AV SIEMPRE VIVA 123', localidad: 'NUEVA YORK', tipo_domicilio: 'FISCAL'
|
27
|
+
)
|
28
|
+
r[:datos_regimen_general][:actividad].should have_entries(
|
29
|
+
id_actividad: '477330', nomenclador: '883', orden: '2', periodo: '201311'
|
30
|
+
)
|
31
|
+
r[:datos_regimen_general][:impuesto][1].should have_entries(
|
32
|
+
descripcion_impuesto: 'IVA', id_impuesto: '30', periodo: '198903'
|
33
|
+
)
|
34
|
+
r[:datos_regimen_general][:regimen].should have_entries(
|
35
|
+
id_impuesto: '208', id_regimen: '159', periodo: '199403'
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'cuando hay errores en la constancia sigue la misma lógica' do
|
40
|
+
savon.expects(:get_persona).with(message: auth).returns(fixture('constancia_inscripcion_get_persona/failure'))
|
41
|
+
r = ws.get_persona '20294834487'
|
42
|
+
r[:error_regimen_general].should have_entries(
|
43
|
+
error: 'El contribuyente cuenta con impuestos con baja de oficio por Decreto 1299/98',
|
44
|
+
mensaje: 'No cumple con las condiciones para enviar datos del regimen general'
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'entorno' do
|
50
|
+
it 'debería usar las url para development cuando el env es development' do
|
51
|
+
Client.expects(:new).with(wsdl: 'https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl')
|
52
|
+
Client.expects(:new).with(wsdl: 'https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL', soap_version: 1)
|
53
|
+
wsci = WSConstanciaInscripcion.new env: :development
|
54
|
+
wsci.env.should == :development
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'debería usar las url para production cuando el env es production' do
|
58
|
+
Client.expects(:new).with(wsdl: 'https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl')
|
59
|
+
Client.expects(:new).with(wsdl: 'https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL', soap_version: 1)
|
60
|
+
wsci = WSConstanciaInscripcion.new env: 'production'
|
61
|
+
wsci.env.should == :production
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/spec/afipws/wsaa_spec.rb
CHANGED
@@ -1,75 +1,83 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
module Afipws
|
4
|
+
describe WSAA do
|
5
|
+
context 'generación documento tra' do
|
6
|
+
it 'debería generar xml' do
|
7
|
+
Time.stubs(:now).returns Time.new(2001, 12, 31, 12, 0, 0, '-03:00')
|
8
|
+
xml = subject.generar_tra 'wsfe', 2400
|
9
|
+
xml.should match_xpath '/loginTicketRequest/header/uniqueId', Time.now.to_i.to_s
|
10
|
+
xml.should match_xpath '/loginTicketRequest/header/generationTime', '2001-12-31T11:20:00-03:00'
|
11
|
+
xml.should match_xpath '/loginTicketRequest/header/expirationTime', '2001-12-31T12:40:00-03:00'
|
12
|
+
xml.should match_xpath '/loginTicketRequest/service', 'wsfe'
|
13
|
+
end
|
12
14
|
end
|
13
|
-
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
context 'firmado del tra' do
|
17
|
+
it 'debería firmar el tra usando el certificado y la clave privada' do
|
18
|
+
key = File.read(File.dirname(__FILE__) + '/test.key')
|
19
|
+
crt = File.read(File.dirname(__FILE__) + '/test.crt')
|
20
|
+
tra = subject.generar_tra 'wsfe', 2400
|
21
|
+
subject.firmar_tra(tra, key, crt).to_s.should =~ /BEGIN PKCS7/
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
context 'codificación del tra' do
|
26
|
+
it 'debería quitarle el header y footer' do
|
27
|
+
subject.codificar_tra(OpenSSL::PKCS7.new).should_not include 'BEGIN', 'END'
|
28
|
+
end
|
27
29
|
end
|
28
|
-
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
31
|
+
context 'login' do
|
32
|
+
it 'debería mandar el TRA al WS y obtener el TA' do
|
33
|
+
ws = WSAA.new key: 'key', cert: 'cert'
|
34
|
+
ws.expects(:tra).with('key', 'cert', 'wsfe', 2400).returns('tra')
|
35
|
+
savon.expects(:login_cms).with(message: {in0: 'tra'}).returns(fixture('login_cms/success'))
|
36
|
+
ta = ws.login
|
37
|
+
ta[:token].should == 'PD94='
|
38
|
+
ta[:sign].should == 'i9xDN='
|
39
|
+
ta[:generation_time].should == Time.new(2011, 1, 12, 18, 57, 4, '-03:00')
|
40
|
+
ta[:expiration_time].should == Time.new(2011, 1, 13, 6, 57, 4, '-03:00')
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
it 'debería encapsular SOAP Faults' do
|
44
|
+
subject.stubs(:tra).returns('')
|
45
|
+
savon.expects(:login_cms).with(message: :any).returns(fixture('login_cms/fault'))
|
46
|
+
-> { subject.login }.should raise_error WSError, /CMS no es valido/
|
47
|
+
end
|
46
48
|
end
|
47
|
-
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
context 'auth' do
|
51
|
+
before do
|
52
|
+
FileUtils.rm_rf Dir.glob('tmp/*ta.dump')
|
53
|
+
Time.stubs(:now).returns(Time.local(2010, 1, 1))
|
54
|
+
end
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
ws.ta.should equal ta
|
56
|
+
it 'debería devolver hash con token y sign' do
|
57
|
+
ws = WSAA.new
|
58
|
+
ws.expects(:login).once.returns(token: 'token', sign: 'sign', expiration_time: Time.now + 60)
|
59
|
+
ws.auth.should == {token: 'token', sign: 'sign'}
|
60
|
+
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
it 'debería cachear TA en la instancia y disco' do
|
63
|
+
ws = WSAA.new
|
64
|
+
ws.expects(:login).once.returns(ta = {token: 'token', sign: 'sign', expiration_time: Time.now + 60})
|
65
|
+
ws.auth
|
66
|
+
ws.auth
|
67
|
+
ws.ta.should equal ta
|
68
|
+
|
69
|
+
ws = WSAA.new
|
70
|
+
ws.auth
|
71
|
+
ws.ta.should == ta
|
72
|
+
end
|
66
73
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
74
|
+
it 'si el TA expiró debería ejecutar solicitar uno nuevo' do
|
75
|
+
subject.expects(:login).twice.returns(token: 't1', expiration_time: Time.now - 2).then.returns(token: 't2')
|
76
|
+
subject.auth
|
77
|
+
subject.ta[:token].should == 't1'
|
78
|
+
subject.auth
|
79
|
+
subject.ta[:token].should == 't2'
|
80
|
+
end
|
73
81
|
end
|
74
82
|
end
|
75
83
|
end
|