correios_sigep 0.3.1 → 0.4.0

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.
Files changed (33) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +1 -0
  3. data/README.md +5 -4
  4. data/correios_sigep.gemspec +1 -0
  5. data/lib/correios_sigep.rb +9 -0
  6. data/lib/correios_sigep/builders/collect.rb +15 -0
  7. data/lib/correios_sigep/builders/object.rb +15 -0
  8. data/lib/correios_sigep/builders/person.rb +15 -0
  9. data/lib/correios_sigep/builders/product.rb +15 -0
  10. data/lib/correios_sigep/builders/xml/collect_objects.rb +1 -1
  11. data/lib/correios_sigep/dsl/collect.rb +39 -0
  12. data/lib/correios_sigep/dsl/logistic_reverse.rb +13 -0
  13. data/lib/correios_sigep/dsl/object.rb +13 -0
  14. data/lib/correios_sigep/dsl/person.rb +14 -0
  15. data/lib/correios_sigep/dsl/product.rb +13 -0
  16. data/lib/correios_sigep/logistic_reverse/base_client.rb +2 -0
  17. data/lib/correios_sigep/models/collect.rb +7 -1
  18. data/lib/correios_sigep/models/logistic_reverse.rb +9 -2
  19. data/lib/correios_sigep/models/object.rb +6 -0
  20. data/lib/correios_sigep/models/product.rb +6 -0
  21. data/lib/correios_sigep/models/recipient.rb +7 -2
  22. data/lib/correios_sigep/models/sender.rb +6 -0
  23. data/lib/correios_sigep/version.rb +1 -1
  24. data/spec/correios_sigep/logistic_reverse/base_client_spec.rb +9 -2
  25. data/spec/correios_sigep/logistic_reverse/request_collect_number_spec.rb +3 -3
  26. data/spec/correios_sigep/logistic_reverse/request_sro_spec.rb +1 -1
  27. data/spec/correios_sigep/models/logistic_reverse_spec.rb +161 -0
  28. data/spec/fixtures/builders/logistic_reverse.xml +2 -2
  29. data/spec/fixtures/builders/request_collect_number.xml +2 -2
  30. data/spec/fixtures/correios/wsdl_test.xml +616 -0
  31. data/spec/fixtures/requests/collect_number_request.xml +2 -2
  32. data/spec/spec_helper.rb +2 -0
  33. metadata +27 -2
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjFiOTcyYTk2ZDY4ZTljOGZlMzBmZDM0ODllZTMwNjg0NjBmZDAwOA==
4
+ ZTkyNGM5YWJjODE5MmQwZjZjZGFmMzkwMWZhZDY4NzVjYzI3OWQ0OQ==
5
5
  data.tar.gz: !binary |-
6
- NmIyMWNhNzQzNzNjMmI5MzIxZGViOWI1MjVhMDg1OWVkYzgyOTk3MA==
6
+ Yjc4YjIzN2U4MTIxZTBjMDIwZTUwNWY0M2YwY2QwY2NmYmVhOGJjNA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzBmZGYzNjI1ZTgyZjkwZDZjNmUzMmNkN2UyODFiMTRlZmIyM2E2ODkzMjhl
10
- ZTRiMTNlZjlkMmY3NjUzYjQ2ZDU3M2FhNGUyNTA2MjhhYjdkZTQxMDBkOGFj
11
- ODc1NGExM2I0NjcyOTAwMGJkYzE0ZGM2Y2VmOTNiZGQ0NjExODU=
9
+ YmIzOTYzYzljYjBhZWUxMmY2YTczNGY4OTJmOTMzNmY1YmRlZWRjZjdhNTQ0
10
+ YjZkZmExYjZlY2QyZDQ3ZThjMzU2M2Q3M2ZjZmYxYjVmMTdhNmIzNTRiY2Uz
11
+ NDhiMWI5MzhjZjc1NzYxMWIzYzU0NDI4M2M5MDU0ZDEwODNkY2Y=
12
12
  data.tar.gz: !binary |-
13
- ZjI0ZmEzM2FiZjk2ZjRhMmI3MTM4MmRjNGJlODMyM2YxOWMwZDA5NzVmNTBi
14
- ZmExOWNiMWE0NTMyZDJhOTIwMGY4ODdjOWMxYmY5MzUyMGM3MTc4Y2JiOWFk
15
- ZWUzMmVmM2YxODdhNmY2MGZlNmM4ZWI4NWViMjY5MTY5YzExYzQ=
13
+ ZmYwOTM1MGY2ZTE4YTYyZGFmZjBiODE5NTBjYWRkMGM5ZGNkZDQyMzZlODlj
14
+ NzU4MDBkMzI0MTlkOGJiNmUxMmNhMGJjOGFjMmY2ZmE3YTViYjI0MjcyMjE2
15
+ MzFjM2M4ZDBiMzliYjhmZDI3MmM1NTdkOTIzYTBiNTg0YjQ5ZWQ=
@@ -5,6 +5,7 @@ rvm:
5
5
  - 2.0.0
6
6
  - 2.1.1
7
7
  - 2.2.2
8
+ - 2.3.0
8
9
  - jruby-19mode
9
10
  bundler_args: --without debug
10
11
  deploy:
data/README.md CHANGED
@@ -2,6 +2,7 @@ CorreiosSigep
2
2
  =============
3
3
 
4
4
  [![Build Status](https://travis-ci.org/duduribeiro/correios_sigep.svg?branch=master)](https://travis-ci.org/duduribeiro/correios_sigep)
5
+ [![Coverage Status](https://coveralls.io/repos/duduribeiro/correios_sigep/badge.svg?branch=master&service=github)](https://coveralls.io/github/duduribeiro/correios_sigep?branch=master)
5
6
 
6
7
  - Integrador responsável pela comunicação com o SigepWeb - http://goo.gl/z8VJjJ.
7
8
  - Excelente documentação do SigepWeb providenciada pelos Correios: http://goo.gl/6TWp2f :trollface:
@@ -83,18 +84,18 @@ Se for necessário, é possível adicionar também um proxy.
83
84
  state: 'Estado'
84
85
  })
85
86
  objects = [
86
- {
87
+ CorreiosSigep::Models::Object.new({
87
88
  item: 'Item',
88
89
  id: '1',
89
90
  description: 'Descricao',
90
91
  num: '',
91
- },
92
- {
92
+ }),
93
+ CorreiosSigep::Models::Object.new({
93
94
  item: 'Item',
94
95
  id: '2',
95
96
  description: 'Descricao',
96
97
  num: '',
97
- }
98
+ })
98
99
  ]
99
100
 
100
101
  # Produto: pag 67 da documentação oficial dos correios
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency 'savon', '~> 2.0'
23
23
 
24
24
  spec.add_development_dependency 'bundler', '~> 1.7'
25
+ spec.add_development_dependency 'coveralls'
25
26
  spec.add_development_dependency 'rake', '~> 10.0'
26
27
  spec.add_development_dependency 'rspec', '~> 3.0'
27
28
  spec.add_development_dependency 'simplecov', '~> 0.9'
@@ -1,6 +1,15 @@
1
1
  require 'correios_sigep/version'
2
2
  require 'correios_sigep/models/administrative_fields'
3
3
  require 'correios_sigep/configuration'
4
+ require 'correios_sigep/dsl/logistic_reverse'
5
+ require 'correios_sigep/dsl/person'
6
+ require 'correios_sigep/dsl/object'
7
+ require 'correios_sigep/dsl/product'
8
+ require 'correios_sigep/dsl/collect'
9
+ require 'correios_sigep/builders/person'
10
+ require 'correios_sigep/builders/object'
11
+ require 'correios_sigep/builders/product'
12
+ require 'correios_sigep/builders/collect'
4
13
  require 'correios_sigep/builders/xml/recipient'
5
14
  require 'correios_sigep/builders/xml/sender'
6
15
  require 'correios_sigep/builders/xml/product'
@@ -0,0 +1,15 @@
1
+ module CorreiosSigep
2
+ module Builders
3
+ class Collect
4
+ include DSL::Collect
5
+
6
+ def initialize
7
+ @instance = Models::Collect.new
8
+ end
9
+
10
+ def build
11
+ @instance
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module CorreiosSigep
2
+ module Builders
3
+ class Object
4
+ include DSL::Object
5
+
6
+ def initialize
7
+ @instance = Models::Object.new
8
+ end
9
+
10
+ def build
11
+ @instance
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module CorreiosSigep
2
+ module Builders
3
+ class Person
4
+ include DSL::Person
5
+
6
+ def initialize(klass)
7
+ @instance = klass.new
8
+ end
9
+
10
+ def build
11
+ @instance
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module CorreiosSigep
2
+ module Builders
3
+ class Product
4
+ include DSL::Product
5
+
6
+ def initialize
7
+ @instance = Models::Product.new
8
+ end
9
+
10
+ def build
11
+ @instance
12
+ end
13
+ end
14
+ end
15
+ end
@@ -20,7 +20,7 @@ module CorreiosSigep
20
20
  @builder.item object.item
21
21
  @builder.id object.id
22
22
  @builder.desc object.description
23
- @builder.ship object.ship
23
+ @builder.entrega object.ship
24
24
  @builder.num object.num
25
25
  end
26
26
  end
@@ -0,0 +1,39 @@
1
+ module CorreiosSigep
2
+ module DSL
3
+ module Collect
4
+ def self.included(_base)
5
+ %w(aditional_service ag ar card checklist declared_value description
6
+ number objects product_params type sender_params client_id).each do |property|
7
+ define_method(property) do |param|
8
+ @instance.send("#{property}=", param)
9
+ end
10
+ end
11
+ end
12
+
13
+ def add_object(object = nil, &block)
14
+ @instance.objects << if block_given?
15
+ Models::Object.build(&block)
16
+ else
17
+ object
18
+ end
19
+
20
+ end
21
+
22
+ def with_product(product = nil, &block)
23
+ @instance.product = if block_given?
24
+ Models::Product.build(&block)
25
+ else
26
+ product
27
+ end
28
+ end
29
+
30
+ def with_sender(sender = nil, &block)
31
+ @instance.sender = if block_given?
32
+ Models::Sender.build(&block)
33
+ else
34
+ sender
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ module CorreiosSigep
2
+ module DSL
3
+ module LogisticReverse
4
+ def with_collect(&block)
5
+ self.collect = Models::Collect.build(&block)
6
+ end
7
+
8
+ def with_recipient(&block)
9
+ self.recipient = Models::Recipient.build(&block)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module CorreiosSigep
2
+ module DSL
3
+ module Object
4
+ def self.included(_base)
5
+ %w(description id item num ship).each do |property|
6
+ define_method(property) do |param|
7
+ @instance.send("#{property}=", param)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module CorreiosSigep
2
+ module DSL
3
+ module Person
4
+ def self.included(_base)
5
+ %w(address area_code city complement email name neighborhood number
6
+ phone postal_code reference state).each do |property|
7
+ define_method(property) do |param|
8
+ @instance.send("#{property}=", param)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module CorreiosSigep
2
+ module DSL
3
+ module Product
4
+ def self.included(_base)
5
+ %w(code type quantity).each do |property|
6
+ define_method(property) do |param|
7
+ @instance.send("#{property}=", param)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -5,6 +5,8 @@ module CorreiosSigep
5
5
  options = { adapter: :net_http_persistent, proxy: CorreiosSigep.configuration.proxy, wsdl: wsdl }
6
6
  options.delete(:proxy) unless options[:proxy]
7
7
 
8
+ options.merge!({ headers: { 'SOAPAction' => '' }}) if ENV['GEM_ENV'] == 'test'
9
+
8
10
  @client = Savon.client(options)
9
11
  end
10
12
 
@@ -5,7 +5,13 @@ module CorreiosSigep
5
5
  :declared_value, :description, :number, :objects, :product,
6
6
  :product_params, :type, :sender, :sender_params, :client_id
7
7
 
8
- def initialize(options={})
8
+ def self.build(&block)
9
+ builder = Builders::Collect.new
10
+ builder.instance_eval(&block)
11
+ builder.build
12
+ end
13
+
14
+ def initialize(options = {})
9
15
  @aditional_service = options[:aditional_service]
10
16
  @ag = options[:ag]
11
17
  @ar = options[:ar]
@@ -1,9 +1,17 @@
1
1
  module CorreiosSigep
2
2
  module Models
3
3
  class LogisticReverse
4
+ include DSL::LogisticReverse
5
+
4
6
  attr_accessor :collect, :recipient
5
7
 
6
- def initialize(options={})
8
+ def self.build(&block)
9
+ instance = new
10
+ instance.instance_eval(&block)
11
+ instance
12
+ end
13
+
14
+ def initialize(options = {})
7
15
  @collect = options[:collect] || Models::Collect.new
8
16
  @recipient = options[:recipient] || Models::Recipient.new
9
17
  end
@@ -16,7 +24,6 @@ module CorreiosSigep
16
24
  end
17
25
  end
18
26
  builder.to_xml
19
-
20
27
  end
21
28
  end
22
29
  end
@@ -3,6 +3,12 @@ module CorreiosSigep
3
3
  class Object
4
4
  attr_accessor :description, :id, :item, :num, :ship
5
5
 
6
+ def self.build(&block)
7
+ builder = Builders::Object.new
8
+ builder.instance_eval(&block)
9
+ builder.build
10
+ end
11
+
6
12
  def initialize(options={})
7
13
  @description = options[:description]
8
14
  @id = options[:id]
@@ -3,6 +3,12 @@ module CorreiosSigep
3
3
  class Product
4
4
  attr_accessor :code, :type, :quantity
5
5
 
6
+ def self.build(&block)
7
+ builder = Builders::Product.new
8
+ builder.instance_eval(&block)
9
+ builder.build
10
+ end
11
+
6
12
  def initialize(options={})
7
13
  @code = options[:code]
8
14
  @type = options[:type]
@@ -5,7 +5,13 @@ module CorreiosSigep
5
5
  :neighborhood, :number, :phone, :postal_code, :reference,
6
6
  :state
7
7
 
8
- def initialize(options={})
8
+ def self.build(&block)
9
+ builder = Builders::Person.new(self)
10
+ builder.instance_eval(&block)
11
+ builder.build
12
+ end
13
+
14
+ def initialize(options = {})
9
15
  @address = options[:address]
10
16
  @area_code = options[:area_code]
11
17
  @city = options[:city]
@@ -19,7 +25,6 @@ module CorreiosSigep
19
25
  @reference = options[:reference]
20
26
  @state = options[:state]
21
27
  end
22
-
23
28
  end
24
29
  end
25
30
  end
@@ -6,6 +6,12 @@ module CorreiosSigep
6
6
  :neighborhood, :number, :phone, :postal_code, :reference,
7
7
  :sms, :state
8
8
 
9
+ def self.build(&block)
10
+ builder = Builders::Person.new(self)
11
+ builder.instance_eval(&block)
12
+ builder.build
13
+ end
14
+
9
15
  def initialize(options={})
10
16
  @area_code = options[:area_code]
11
17
  @address = options[:address]
@@ -1,3 +1,3 @@
1
1
  module CorreiosSigep
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -12,7 +12,8 @@ module CorreiosSigep
12
12
  {
13
13
  adapter: :net_http_persistent,
14
14
  proxy: CorreiosSigep.configuration.proxy,
15
- wsdl: described_class.new.wsdl
15
+ wsdl: described_class.new.wsdl,
16
+ headers: { 'SOAPAction' => '' }
16
17
  }
17
18
  end
18
19
 
@@ -24,7 +25,13 @@ module CorreiosSigep
24
25
 
25
26
  context 'without a proxy' do
26
27
  before { CorreiosSigep.configuration.proxy = nil }
27
- let(:params) { { adapter: :net_http_persistent, wsdl: described_class.new.wsdl } }
28
+ let(:params) do
29
+ {
30
+ adapter: :net_http_persistent,
31
+ wsdl: described_class.new.wsdl,
32
+ headers: { 'SOAPAction' => '' }
33
+ }
34
+ end
28
35
 
29
36
  it 'initializes @client without proxy' do
30
37
  expect(Savon).to receive(:client).with(params) { true }
@@ -13,14 +13,14 @@ module CorreiosSigep
13
13
  # WSDL
14
14
  stub_request(:get, "http://webservicescolhomologacao.correios.com.br/ScolWeb/WebServiceScol?wsdl").
15
15
  with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
16
- to_return(:status => 200, :body => correios_fixture('wsdl.xml'), :headers => {})
16
+ to_return(:status => 200, :body => correios_fixture('wsdl_test.xml'), :headers => {})
17
17
 
18
18
  # REQUEST
19
19
  stub_request(:post, "http://webservicescolhomologacao.correios.com.br/ScolWeb/WebServiceScol").
20
20
  with(:body => body, :headers => { 'Accept'=>'*/*',
21
21
  'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
22
- 'Content-Length'=>'2267', 'Content-Type'=>'text/xml;charset=UTF-8',
23
- 'Soapaction'=>'"solicitarPostagemReversa"', 'User-Agent'=>'Ruby' }).
22
+ 'Content-Length'=>'2279', 'Content-Type'=>'text/xml;charset=UTF-8',
23
+ 'Soapaction'=>'', 'User-Agent'=>'Ruby' }).
24
24
  to_return(:status => 200, :body => correios_fixture("request_collect_number/#{response_body}"), :headers => {})
25
25
  end
26
26
 
@@ -18,7 +18,7 @@ module CorreiosSigep
18
18
  with(:body => body, :headers => { 'Accept'=>'*/*',
19
19
  'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
20
20
  'Content-Length'=>'633', 'Content-Type'=>'text/xml;charset=UTF-8',
21
- 'Soapaction'=>'"acompanharPedido"', 'User-Agent'=>'Ruby' }).
21
+ 'Soapaction'=>'', 'User-Agent'=>'Ruby' }).
22
22
  to_return(:status => 200, :body => correios_fixture("request_sro/#{response_body}"), :headers => {})
23
23
  end
24
24
 
@@ -4,6 +4,167 @@ module CorreiosSigep
4
4
  it { should respond_to :collect }
5
5
  it { should respond_to :recipient }
6
6
 
7
+ describe ".build" do
8
+ let(:recipient) do
9
+ CorreiosSigep::Models::Recipient.new({
10
+ address: 'Endereco',
11
+ area_code: 'DDD',
12
+ city: 'Cidade',
13
+ complement: 'Complemento',
14
+ email: 'Email',
15
+ name: 'Nome',
16
+ neighborhood: 'Bairro',
17
+ number: 'Numero',
18
+ phone: 'Telefone',
19
+ postal_code: 'CEP',
20
+ reference: 'Referencia',
21
+ state: 'Estado'
22
+ })
23
+ end
24
+
25
+ let(:sender) do
26
+ CorreiosSigep::Models::Sender.new({
27
+ address: 'Endereco',
28
+ area_code: 'DDD',
29
+ city: 'Cidade',
30
+ complement: 'Complemento',
31
+ email: 'Email',
32
+ name: 'Nome',
33
+ neighborhood: 'Bairro',
34
+ number: 'Numero',
35
+ phone: 'Telefone',
36
+ postal_code: 'CEP',
37
+ reference: 'Referencia',
38
+ state: 'Estado'
39
+ })
40
+ end
41
+
42
+ let(:collect) do
43
+ CorreiosSigep::Models::Collect.new({
44
+ aditional_service: '10.00',
45
+ ag: '5',
46
+ ar: '1',
47
+ card: '',
48
+ checklist: '2',
49
+ client_id: '102030',
50
+ declared_value: '1000.00',
51
+ description: 'Descricao',
52
+ number: '',
53
+ type: 'A'
54
+ })
55
+ end
56
+
57
+ let(:product) do
58
+ CorreiosSigep::Models::Product.new({
59
+ code: '116600403',
60
+ type: '0',
61
+ quantity: 1
62
+ })
63
+ end
64
+
65
+ subject do
66
+ described_class.build do
67
+ with_recipient do
68
+ address 'Endereco'
69
+ area_code 'DDD'
70
+ city 'Cidade'
71
+ complement 'Complemento'
72
+ email 'Email'
73
+ name 'Nome'
74
+ neighborhood 'Bairro'
75
+ number 'Numero'
76
+ phone 'Telefone'
77
+ postal_code 'CEP'
78
+ reference 'Referencia'
79
+ state 'Estado'
80
+ end
81
+
82
+ with_collect do
83
+ aditional_service '10.00'
84
+ ag '5'
85
+ ar '1'
86
+ card ''
87
+ checklist '2'
88
+ client_id '102030'
89
+ declared_value '1000.00'
90
+ description 'Descricao'
91
+ number ''
92
+ type 'A'
93
+
94
+ with_sender do
95
+ address 'Endereco'
96
+ area_code 'DDD'
97
+ city 'Cidade'
98
+ complement 'Complemento'
99
+ email 'Email'
100
+ name 'Nome'
101
+ neighborhood 'Bairro'
102
+ number 'Numero'
103
+ phone 'Telefone'
104
+ postal_code 'CEP'
105
+ reference 'Referencia'
106
+ state 'Estado'
107
+ end
108
+
109
+ with_product do
110
+ code '116600403'
111
+ type '0'
112
+ quantity 1
113
+ end
114
+
115
+ add_object do
116
+ item 'Item'
117
+ id '1'
118
+ description 'Descricao'
119
+ num ''
120
+ end
121
+
122
+ add_object do
123
+ item 'Item'
124
+ id '2'
125
+ description 'Descricao'
126
+ num ''
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ it 'initializes with the correct recipient' do
133
+ %i(address area_code city complement email name neighborhood number
134
+ phone postal_code reference state).each do |property|
135
+ expect(subject.recipient.send(property)).to eq(recipient.send(property))
136
+ end
137
+ end
138
+
139
+ it 'initializes with the correct collect' do
140
+ %i(aditional_service ag ar card checklist declared_value description
141
+ number type client_id).each do |property|
142
+ expect(subject.collect.send(property)).to eq(collect.send(property))
143
+ end
144
+ end
145
+
146
+ it 'initializes with the correct sender' do
147
+ %i(address area_code city complement email name neighborhood number
148
+ phone postal_code reference state).each do |property|
149
+ expect(subject.collect.sender.send(property)).to eq(sender.send(property))
150
+ end
151
+ end
152
+
153
+ it 'initializes with the correct product' do
154
+ %i(code type quantity).each do |property|
155
+ expect(subject.collect.product.send(property)).to eq(product.send(property))
156
+ end
157
+ end
158
+
159
+ it 'initializes with the correct objects' do
160
+ expect(subject.collect.objects.length).to eq(2)
161
+ expect(subject.collect.objects.first.id).to eq('1')
162
+ expect(subject.collect.objects.first.item).to eq('Item')
163
+ expect(subject.collect.objects.first.description).to eq('Descricao')
164
+ expect(subject.collect.objects.last.id).to eq('2')
165
+ end
166
+ end
167
+
7
168
  describe '#initialize' do
8
169
  let(:logistic_reverse) { described_class.new params }
9
170