File: middleware_stack_test.rb

package info (click to toggle)
ruby-faraday 0.13.1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 596 kB
  • sloc: ruby: 5,821; sh: 136; makefile: 5
file content (260 lines) | stat: -rw-r--r-- 6,916 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
require File.expand_path('../helper', __FILE__)

class MiddlewareStackTest < Faraday::TestCase
  # mock handler classes
  class Handler < Struct.new(:app)
    def call(env)
      (env[:request_headers]['X-Middleware'] ||= '') << ":#{self.class.name.split('::').last}"
      app.call(env)
    end
  end
  class Apple < Handler; end
  class Orange < Handler; end
  class Banana < Handler; end

  class Broken < Faraday::Middleware
    dependency 'zomg/i_dont/exist'
  end

  def setup
    @conn = Faraday::Connection.new
    @builder = @conn.builder
  end

  def test_sets_default_adapter_if_none_set
    default_middleware = Faraday::Request.lookup_middleware :url_encoded
    default_adapter_klass = Faraday::Adapter.lookup_middleware Faraday.default_adapter
    assert @builder[0] == default_middleware
    assert @builder[1] == default_adapter_klass
  end

  def test_allows_rebuilding
    build_stack Apple
    build_stack Orange
    assert_handlers %w[Orange]
  end

  def test_allows_extending
    build_handlers_stack Apple
    @builder.use Orange
    @builder.adapter :test, &test_adapter
    assert_handlers %w[Apple Orange]
  end

  def test_builder_is_passed_to_new_faraday_connection
    new_conn = Faraday::Connection.new :builder => @builder
    assert_equal @builder, new_conn.builder
  end

  def test_insert_before
    build_handlers_stack Apple, Orange
    @builder.insert_before Apple, Banana
    @builder.adapter :test, &test_adapter
    assert_handlers %w[Banana Apple Orange]
  end

  def test_insert_after
    build_handlers_stack Apple, Orange
    @builder.insert_after Apple, Banana
    @builder.adapter :test, &test_adapter
    assert_handlers %w[Apple Banana Orange]
  end

  def test_swap_handlers
    build_handlers_stack Apple, Orange
    @builder.swap Apple, Banana
    @builder.adapter :test, &test_adapter
    assert_handlers %w[Banana Orange]
  end

  def test_delete_handler
    build_stack Apple, Orange
    @builder.delete Apple
    assert_handlers %w[Orange]
  end

  def test_stack_is_locked_after_making_requests
    build_stack Apple
    assert !@builder.locked?
    @conn.get('/')
    assert @builder.locked?

    assert_raises Faraday::RackBuilder::StackLocked do
      @conn.use Orange
    end
  end

  def test_duped_stack_is_unlocked
    build_stack Apple
    assert !@builder.locked?
    @builder.lock!
    assert @builder.locked?

    duped_connection = @conn.dup
    assert_equal @builder, duped_connection.builder
    assert !duped_connection.builder.locked?
  end

  def test_handler_comparison
    build_stack Apple
    assert_equal @builder.handlers.first, Apple
    assert_equal @builder.handlers[0,1], [Apple]
    assert_equal @builder.handlers.first, Faraday::RackBuilder::Handler.new(Apple)
  end

  def test_unregistered_symbol
    err = assert_raises(Faraday::Error){ build_stack :apple }
    assert_equal ":apple is not registered on Faraday::Middleware", err.message
  end

  def test_registered_symbol
    Faraday::Middleware.register_middleware :apple => Apple
    begin
      build_stack :apple
      assert_handlers %w[Apple]
    ensure
      unregister_middleware Faraday::Middleware, :apple
    end
  end

  def test_registered_symbol_with_proc
    Faraday::Middleware.register_middleware :apple => lambda { Apple }
    begin
      build_stack :apple
      assert_handlers %w[Apple]
    ensure
      unregister_middleware Faraday::Middleware, :apple
    end
  end

  def test_registered_symbol_with_array
    Faraday::Middleware.register_middleware File.expand_path("..", __FILE__),
      :strawberry => [lambda { Strawberry }, 'strawberry']
    begin
      build_stack :strawberry
      assert_handlers %w[Strawberry]
    ensure
      unregister_middleware Faraday::Middleware, :strawberry
    end
  end

  def test_missing_dependencies
    build_stack Broken
    err = assert_raises RuntimeError do
      @conn.get('/')
    end
    assert_match "missing dependency for MiddlewareStackTest::Broken: ", err.message
    assert_match "zomg/i_dont/exist", err.message
  end

  def test_env_stored_on_middleware_response_has_reference_to_the_response
    env = response = nil
    build_stack Struct.new(:app) {
      define_method(:call) { |e| env, response = e, app.call(e) }
    }
    @conn.get("/")
    assert_same env.response, response.env.response
  end

  private

  # make a stack with test adapter that reflects the order of middleware
  def build_stack(*handlers)
    @builder.build do |b|
      handlers.each { |handler| b.use(*handler) }
      yield(b) if block_given?

      @builder.adapter :test, &test_adapter
    end
  end

  def build_handlers_stack(*handlers)
    @builder.build do |b|
      handlers.each { |handler| b.use(*handler) }
    end
  end

  def test_adapter
    Proc.new do |stub|
      stub.get '/' do |env|
        # echo the "X-Middleware" request header in the body
        [200, {}, env[:request_headers]['X-Middleware'].to_s]
      end
    end
  end

  def assert_handlers(list)
    echoed_list = @conn.get('/').body.to_s.split(':')
    echoed_list.shift if echoed_list.first == ''
    assert_equal list, echoed_list
  end

  def unregister_middleware(component, key)
    # TODO: unregister API?
    component.instance_variable_get('@registered_middleware').delete(key)
  end
end

class MiddlewareStackOrderTest < Faraday::TestCase
  def test_adding_response_middleware_after_adapter
    response_after_adapter = lambda do
      Faraday::RackBuilder.new do |b|
        b.adapter :test
        b.response :raise_error
      end
    end

    assert_output("", expected_middleware_warning, &response_after_adapter)
  end

  def test_adding_request_middleware_after_adapter
    request_after_adapter = lambda do
      Faraday::RackBuilder.new do |b|
        b.adapter :test
        b.request :multipart
      end
    end

    assert_output("", expected_middleware_warning, &request_after_adapter)
  end

  def test_adding_request_middleware_after_adapter_via_use
    use_after_adapter = lambda do
      Faraday::RackBuilder.new do |b|
        b.adapter :test
        b.use Faraday::Request::Multipart
      end
    end

    assert_output("", expected_middleware_warning, &use_after_adapter)
  end

  def test_adding_request_middleware_after_adapter_via_insert
    insert_after_adapter = lambda do
      Faraday::RackBuilder.new do |b|
        b.adapter :test
        b.insert(1, Faraday::Request::Multipart)
      end
    end

    assert_output("", expected_middleware_warning, &insert_after_adapter)
  end

  def test_adding_request_middleware_before_adapter_via_insert_no_warning
    builder = Faraday::RackBuilder.new do |b|
      b.adapter :test
    end

    insert_before_adapter = lambda do
      builder.insert(0, Faraday::Request::Multipart)
    end

    assert_output("", "", &insert_before_adapter)
  end

  private

  def expected_middleware_warning
    /Unexpected middleware set after the adapter/
  end
end