http_stub 0.23.1 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/http_stub.rb +4 -3
  3. data/lib/http_stub/configurer/dsl/server.rb +9 -0
  4. data/lib/http_stub/configurer/server/command.rb +1 -1
  5. data/lib/http_stub/configurer/server/command_processor.rb +2 -2
  6. data/lib/http_stub/rake/server_tasks.rb +11 -7
  7. data/lib/http_stub/server/application/application.rb +115 -0
  8. data/lib/http_stub/server/application/cross_origin_support.rb +34 -0
  9. data/lib/http_stub/server/application/response_pipeline.rb +20 -0
  10. data/lib/http_stub/server/application/text_formatting_support.rb +21 -0
  11. data/lib/http_stub/server/public/jquery-2.2.4.min.js +4 -0
  12. data/lib/http_stub/server/stub/response/file.rb +2 -2
  13. data/lib/http_stub/server/stub/response/text.rb +2 -2
  14. data/lib/http_stub/server/views/_activate_scenario.haml +1 -1
  15. data/lib/http_stub/server/views/layout.haml +1 -1
  16. data/lib/http_stub/version.rb +1 -1
  17. data/spec/acceptance/cross_origin_support_spec.rb +127 -0
  18. data/spec/acceptance/stub_match_spec.rb +0 -1
  19. data/spec/lib/http_stub/configurer/dsl/stub_builder_spec.rb +0 -4
  20. data/spec/lib/http_stub/configurer/request/stub_spec.rb +0 -7
  21. data/spec/lib/http_stub/configurer/server/command_processor_integration_spec.rb +2 -1
  22. data/spec/lib/http_stub/rake/server_tasks_smoke_spec.rb +7 -4
  23. data/spec/lib/http_stub/server/{application_integration_spec.rb → application/application_integration_spec.rb} +1 -1
  24. data/spec/lib/http_stub/server/{application_spec.rb → application/application_spec.rb} +8 -4
  25. data/spec/lib/http_stub/server/application/cross_origin_support_spec.rb +114 -0
  26. data/spec/lib/http_stub/server/{response_pipeline_spec.rb → application/response_pipeline_spec.rb} +5 -5
  27. data/spec/lib/http_stub/server/{application_helpers_spec.rb → application/text_formatting_support_spec.rb} +4 -4
  28. data/spec/lib/http_stub/server/registry_spec.rb +0 -5
  29. data/spec/spec_helper.rb +5 -14
  30. data/spec/support/browser_integration.rb +9 -0
  31. data/spec/support/cross_origin_server/application.rb +5 -0
  32. data/spec/support/cross_origin_server/index_page.rb +26 -0
  33. data/spec/support/cross_origin_server/integration.rb +24 -0
  34. data/spec/support/cross_origin_server/public/index.html +33 -0
  35. data/spec/support/server_integration.rb +9 -3
  36. metadata +56 -41
  37. data/lib/http_stub/server/application.rb +0 -110
  38. data/lib/http_stub/server/application_helpers.rb +0 -19
  39. data/lib/http_stub/server/public/jquery-2.2.1.min.js +0 -4
  40. data/lib/http_stub/server/response_pipeline.rb +0 -18
@@ -75,7 +75,6 @@ describe "Stub match acceptance" do
75
75
  end
76
76
 
77
77
  context "when the request contains parameters" do
78
-
79
78
  include_context "issues requests with parameters"
80
79
 
81
80
  it "returns a response body that contains the parameters" do
@@ -217,7 +217,6 @@ describe HttpStub::Configurer::DSL::StubBuilder do
217
217
  end
218
218
 
219
219
  context "and a builder that is completely configured is provided" do
220
-
221
220
  include_context "a completely configured provided builder"
222
221
 
223
222
  it "replaces the uri" do
@@ -344,7 +343,6 @@ describe HttpStub::Configurer::DSL::StubBuilder do
344
343
  end
345
344
 
346
345
  context "when the builder has not been previously configured" do
347
-
348
346
  include_context "a completely configured provided builder"
349
347
 
350
348
  it "assumes the provided uri" do
@@ -443,7 +441,6 @@ describe HttpStub::Configurer::DSL::StubBuilder do
443
441
  describe "creates a stub payload with triggers that" do
444
442
 
445
443
  context "when a trigger is added" do
446
-
447
444
  include_context "triggers one stub"
448
445
 
449
446
  it "contain the provided trigger builder" do
@@ -455,7 +452,6 @@ describe HttpStub::Configurer::DSL::StubBuilder do
455
452
  end
456
453
 
457
454
  context "when many triggers are added" do
458
-
459
455
  include_context "triggers many stubs"
460
456
 
461
457
  it "contain the provided trigger builders" do
@@ -134,7 +134,6 @@ describe HttpStub::Configurer::Request::Stub do
134
134
  end
135
135
 
136
136
  context "when many triggers are provided" do
137
-
138
137
  include_context "triggers many stubs"
139
138
 
140
139
  it "builds the request object for each trigger" do
@@ -182,7 +181,6 @@ describe HttpStub::Configurer::Request::Stub do
182
181
  end
183
182
 
184
183
  context "when a trigger is added" do
185
-
186
184
  include_context "triggers one stub"
187
185
 
188
186
  it "has a triggers entry containing the stub trigger payload" do
@@ -192,7 +190,6 @@ describe HttpStub::Configurer::Request::Stub do
192
190
  end
193
191
 
194
192
  context "when many triggers are added" do
195
-
196
193
  include_context "triggers many stubs"
197
194
 
198
195
  it "has a triggers entry containing the stub trigger payloads" do
@@ -224,7 +221,6 @@ describe HttpStub::Configurer::Request::Stub do
224
221
  before(:example) { allow(stub_response).to receive(:file).and_return(response_file) }
225
222
 
226
223
  context "and the triggers contain files" do
227
-
228
224
  include_context "triggers many stubs"
229
225
 
230
226
  let(:triggers_files) do
@@ -238,7 +234,6 @@ describe HttpStub::Configurer::Request::Stub do
238
234
  end
239
235
 
240
236
  context "and the triggers contain no files" do
241
-
242
237
  include_context "triggers many stubs"
243
238
 
244
239
  let(:triggers_files) { trigger_payloads.map { (1..3).map { [] } } }
@@ -256,7 +251,6 @@ describe HttpStub::Configurer::Request::Stub do
256
251
  before(:example) { allow(stub_response).to receive(:file).and_return(nil) }
257
252
 
258
253
  context "and the triggers contain files" do
259
-
260
254
  include_context "triggers many stubs"
261
255
 
262
256
  let(:triggers_files) do
@@ -270,7 +264,6 @@ describe HttpStub::Configurer::Request::Stub do
270
264
  end
271
265
 
272
266
  context "and no triggers contain a file" do
273
-
274
267
  include_context "triggers many stubs"
275
268
 
276
269
  let(:triggers_files) { trigger_payloads.map { (1..3).map { [] } } }
@@ -17,7 +17,6 @@ describe HttpStub::Configurer::Server::CommandProcessor do
17
17
  subject { command_processor.process(command) }
18
18
 
19
19
  context "when the server is running" do
20
-
21
20
  include_context "server integration"
22
21
 
23
22
  describe "and the server responds with a 200 response" do
@@ -52,6 +51,8 @@ describe HttpStub::Configurer::Server::CommandProcessor do
52
51
 
53
52
  context "when the server is unavailable" do
54
53
 
54
+ subject { command_processor.process(command, open_timeout: 1) }
55
+
55
56
  let(:request) { create_get_request("/does/not/exist") }
56
57
 
57
58
  it "raises an exception that includes the server base URI" do
@@ -29,12 +29,15 @@ describe HttpStub::Rake::ServerTasks do
29
29
 
30
30
  def wait_until_server_has_started
31
31
  ::Wait.until!(description: "http stub server #{task_args[:name]} started") do
32
- Net::HTTP.get_response("localhost", "/", port)
32
+ HTTParty.get("http://localhost:#{port}")
33
33
  end
34
34
  end
35
35
 
36
36
  def wait_until_server_has_stopped
37
- HttpStub::Server::Application.stop!
37
+ HttpStub::Server::Application::Application.stop!
38
+ ::Wait.until_true!(description: "http stub server #{task_args[:name]} stopped") do
39
+ HTTParty.get("http://localhost:#{port}", timeout: 1) && false rescue true
40
+ end
38
41
  end
39
42
 
40
43
  end
@@ -45,9 +48,9 @@ describe HttpStub::Rake::ServerTasks do
45
48
 
46
49
  context "when a configurer is provided" do
47
50
 
48
- let(:port) { 8004 }
51
+ let(:port) { 8004 }
49
52
  let(:configurer) do
50
- configurer = Class.new.tap do |configurer|
53
+ Class.new.tap do |configurer|
51
54
  configurer.send(:include, HttpStub::Configurer)
52
55
  configurer.stub_server.host = "localhost"
53
56
  configurer.stub_server.port = port
@@ -1,4 +1,4 @@
1
- describe HttpStub::Server::Application, "when the server is running" do
1
+ describe HttpStub::Server::Application::Application, "when the server is running" do
2
2
  include_context "server integration"
3
3
 
4
4
  let(:response_document) { Nokogiri::HTML(response.body) }
@@ -1,4 +1,4 @@
1
- describe HttpStub::Server::Application do
1
+ describe HttpStub::Server::Application::Application do
2
2
  include Rack::Test::Methods
3
3
 
4
4
  let(:response) { last_response }
@@ -11,9 +11,9 @@ describe HttpStub::Server::Application do
11
11
  let(:stub_controller) { instance_double(HttpStub::Server::Stub::Controller) }
12
12
  let(:scenario_controller) { instance_double(HttpStub::Server::Scenario::Controller) }
13
13
 
14
- let(:response_pipeline) { instance_double(HttpStub::Server::ResponsePipeline, process: nil) }
14
+ let(:response_pipeline) { instance_double(HttpStub::Server::Application::ResponsePipeline, process: nil) }
15
15
 
16
- let(:app) { HttpStub::Server::Application.new! }
16
+ let(:app) { HttpStub::Server::Application::Application.new! }
17
17
 
18
18
  before(:example) do
19
19
  allow(HttpStub::Server::Registry).to receive(:new).with("match result").and_return(match_result_registry)
@@ -21,7 +21,7 @@ describe HttpStub::Server::Application do
21
21
  allow(HttpStub::Server::Stub::Registry).to receive(:new).and_return(stub_registry)
22
22
  allow(HttpStub::Server::Stub::Controller).to receive(:new).and_return(stub_controller)
23
23
  allow(HttpStub::Server::Scenario::Controller).to receive(:new).and_return(scenario_controller)
24
- allow(HttpStub::Server::ResponsePipeline).to receive(:new).and_return(response_pipeline)
24
+ allow(HttpStub::Server::Application::ResponsePipeline).to receive(:new).and_return(response_pipeline)
25
25
  end
26
26
 
27
27
  context "when the diagnostics landing page is retrieved" do
@@ -302,4 +302,8 @@ describe HttpStub::Server::Application do
302
302
  expect(app.settings.protection).to eql(false)
303
303
  end
304
304
 
305
+ it "disables cross origin support by default" do
306
+ expect(app.settings.cross_origin_support).to eql(false)
307
+ end
308
+
305
309
  end
@@ -0,0 +1,114 @@
1
+ describe HttpStub::Server::Application::CrossOriginSupport do
2
+ include Rack::Test::Methods
3
+
4
+ let(:header_names) { (1..3).map { |i| "HEADER_#{i}" } }
5
+ let(:request_headers) do
6
+ header_names.each_with_object({}) { |name, result| result["HTTP_#{name}"] = "#{name} value" }
7
+ end
8
+
9
+ let(:response) { last_response }
10
+
11
+ let(:app_class) { Class.new(Sinatra::Base) }
12
+
13
+ let(:app) { app_class.new! }
14
+
15
+ before(:example) do
16
+ app_class.before { @http_stub_request = HttpStub::Server::Request.create(request) }
17
+ end
18
+
19
+ describe "when registered in an application" do
20
+
21
+ before(:example) { app_class.register described_class }
22
+
23
+ shared_examples_for "a request whose response contains access control headers" do
24
+
25
+ it "responds with an access control origin header allowing requests from all origins" do
26
+ subject
27
+
28
+ expect(response.headers["Access-Control-Allow-Origin"]).to eql("*")
29
+ end
30
+
31
+ it "responds with an access control method header allowing the method of the current request" do
32
+ subject
33
+
34
+ expect(response.headers["Access-Control-Allow-Methods"]).to eql(request_method)
35
+ end
36
+
37
+ it "responds with an access control headers header allowing the headers of the current request" do
38
+ subject
39
+
40
+ header_names.each do |expected_header_name|
41
+ expect(response.headers["Access-Control-Allow-Headers"]).to include(expected_header_name)
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ context "and cross origin support is enabled" do
48
+
49
+ before(:example) { app_class.enable :cross_origin_support }
50
+
51
+ context "and a non-OPTIONS request is issued" do
52
+
53
+ let(:request_method) { "GET" }
54
+
55
+ subject { get "/some_resource", {}, request_headers }
56
+
57
+ it_behaves_like "a request whose response contains access control headers"
58
+
59
+ end
60
+
61
+
62
+ context "and an OPTIONS request is issued" do
63
+
64
+ let(:request_method) { "OPTIONS" }
65
+
66
+ subject { options "/some_resource", {}, request_headers }
67
+
68
+ it_behaves_like "a request whose response contains access control headers"
69
+
70
+ it "responds with a status of 200" do
71
+ subject
72
+
73
+ expect(response.status).to eql(200)
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+
80
+ context "and cross origin support is disabled" do
81
+
82
+ before(:example) do
83
+ app_class.disable :cross_origin_support
84
+ end
85
+
86
+ context "and a non-OPTIONS request is issued" do
87
+
88
+ subject { get "/some_resource", {}, request_headers }
89
+
90
+ it "does not add access control headers" do
91
+ subject
92
+
93
+ header_names.each { |header_name| expect(header_name).to_not match(/^Access-Control/) }
94
+ end
95
+
96
+ end
97
+
98
+ context "and an OPTIONS request is issued" do
99
+
100
+ subject { options "/some_resource" }
101
+
102
+ it "returns a not found response" do
103
+ subject
104
+
105
+ expect(response.status).to eql(404)
106
+ end
107
+
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+
114
+ end
@@ -1,8 +1,8 @@
1
- describe HttpStub::Server::ResponsePipeline do
1
+ describe HttpStub::Server::Application::ResponsePipeline do
2
2
 
3
- let(:server) { instance_double(HttpStub::Server) }
3
+ let(:application) { instance_double(Sinatra::Base) }
4
4
 
5
- let(:response_pipeline) { HttpStub::Server::ResponsePipeline.new(server) }
5
+ let(:response_pipeline) { described_class.new(application) }
6
6
 
7
7
  describe "#process" do
8
8
 
@@ -18,8 +18,8 @@ describe HttpStub::Server::ResponsePipeline do
18
18
  subject
19
19
  end
20
20
 
21
- it "serves the response via the server" do
22
- expect(response).to receive(:serve_on).with(server)
21
+ it "serves the response via the application" do
22
+ expect(response).to receive(:serve_on).with(application)
23
23
 
24
24
  subject
25
25
  end
@@ -1,12 +1,12 @@
1
- describe HttpStub::Server::ApplicationHelpers do
1
+ describe HttpStub::Server::Application::TextFormattingSupport do
2
2
 
3
- let(:helpers) { Class.new.extend(described_class) }
3
+ let(:text_formatting_support) { Class.new.extend(described_class) }
4
4
 
5
5
  describe "::h" do
6
6
 
7
7
  let(:text) { "<tag>Some text</tag>" }
8
8
 
9
- subject { helpers.h(text) }
9
+ subject { text_formatting_support.h(text) }
10
10
 
11
11
  it "should escape the provided HTML" do
12
12
  expect(subject).to eq("&lt;tag&gt;Some text&lt;&#x2F;tag&gt;")
@@ -16,7 +16,7 @@ describe HttpStub::Server::ApplicationHelpers do
16
16
 
17
17
  describe "::pp" do
18
18
 
19
- subject { helpers.pp(text) }
19
+ subject { text_formatting_support.pp(text) }
20
20
 
21
21
  context "when the text is JSON" do
22
22
 
@@ -69,7 +69,6 @@ describe HttpStub::Server::Registry do
69
69
  subject { registry.find(criteria, logger) }
70
70
 
71
71
  describe "when multiple models have been registered" do
72
-
73
72
  include_context "register multiple models"
74
73
 
75
74
  it "determines if the models satisfy the provided criteria" do
@@ -139,7 +138,6 @@ describe HttpStub::Server::Registry do
139
138
  describe "#last" do
140
139
 
141
140
  context "when multiple models have been registered" do
142
-
143
141
  include_context "register multiple models"
144
142
 
145
143
  it "returns the last added model" do
@@ -165,7 +163,6 @@ describe HttpStub::Server::Registry do
165
163
  describe "#all" do
166
164
 
167
165
  context "when multiple models have been registered" do
168
-
169
166
  include_context "register multiple models"
170
167
 
171
168
  it "returns the registered models in the order they were added" do
@@ -189,7 +186,6 @@ describe HttpStub::Server::Registry do
189
186
  subject { registry.rollback_to(model) }
190
187
 
191
188
  context "when models have been added" do
192
-
193
189
  include_context "register multiple models"
194
190
 
195
191
  context "and the rollback is to one of those models" do
@@ -243,7 +239,6 @@ describe HttpStub::Server::Registry do
243
239
  end
244
240
 
245
241
  context "when models have been added" do
246
-
247
242
  include_context "register multiple models"
248
243
 
249
244
  it "releases all knowledge of the models" do
data/spec/spec_helper.rb CHANGED
@@ -17,20 +17,8 @@ require 'http_server_manager/test_support'
17
17
 
18
18
  require_relative '../lib/http_stub/rake/task_generators'
19
19
  require_relative '../lib/http_stub'
20
- require_relative '../examples/configurer_with_trivial_stub'
21
- require_relative '../examples/configurer_with_deprecated_activator'
22
- require_relative '../examples/configurer_with_trivial_scenarios'
23
- require_relative '../examples/configurer_with_exhaustive_scenarios'
24
- require_relative '../examples/configurer_with_initialize_callback'
25
- require_relative '../examples/configurer_with_complex_initializer'
26
- require_relative '../examples/configurer_with_server_defaults'
27
- require_relative '../examples/configurer_with_stub_triggers'
28
- require_relative '../examples/configurer_with_file_responses'
29
- require_relative '../examples/configurer_with_stub_request_body'
30
- require_relative '../examples/configurer_with_parts'
31
- require_relative '../examples/configurer_with_endpoint_template'
32
- require_relative '../examples/configurer_with_request_references'
33
- require_relative '../examples/authentication_service/configurer'
20
+
21
+ Dir[File.expand_path('../../examples/**/*.rb', __FILE__)].each { |file| require file }
34
22
 
35
23
  HttpStub::Server::Daemon.log_dir = ::File.expand_path('../../tmp/log', __FILE__)
36
24
  HttpStub::Server::Daemon.pid_dir = ::File.expand_path('../../tmp/pids', __FILE__)
@@ -45,6 +33,8 @@ module HttpStub
45
33
 
46
34
  end
47
35
 
36
+ require_relative 'support/cross_origin_server/integration'
37
+ require_relative 'support/cross_origin_server/index_page'
48
38
  require_relative 'support/http_stub/server/request_fixture'
49
39
  require_relative 'support/http_stub/server/scenario/scenario_fixture'
50
40
  require_relative 'support/http_stub/server/stub/match/result_fixture'
@@ -52,5 +42,6 @@ require_relative 'support/http_stub/stub_fixture'
52
42
  require_relative 'support/http_stub/scenario_fixture'
53
43
  require_relative 'support/http_stub/empty_configurer'
54
44
  require_relative 'support/html_helpers'
45
+ require_relative 'support/browser_integration'
55
46
  require_relative 'support/server_integration'
56
47
  require_relative 'support/configurer_integration'
@@ -0,0 +1,9 @@
1
+ shared_context "browser integration" do
2
+
3
+ let(:browser) do
4
+ Selenium::WebDriver.for(:firefox).tap { @browser_launched = true }
5
+ end
6
+
7
+ after(:example) { browser.quit if @browser_launched }
8
+
9
+ end
@@ -0,0 +1,5 @@
1
+ require 'sinatra'
2
+
3
+ set :port, 8005
4
+
5
+ set :root, File.dirname(__FILE__)
@@ -0,0 +1,26 @@
1
+ module CrossOriginServer
2
+
3
+ class IndexPage
4
+
5
+ def initialize(browser)
6
+ @browser = browser
7
+ end
8
+
9
+ def load_and_wait_until_available
10
+ @browser.navigate.to("http://localhost:8005/index.html")
11
+ ::Wait.until!(description: "cross origin test page has loaded") { @browser.find_element(id: "scenario_name") }
12
+ end
13
+
14
+ def activate_scenario(name)
15
+ @browser.find_element(id: "scenario_name").send_keys(name)
16
+ @browser.find_element(id: "activate_scenario").click
17
+ end
18
+
19
+ def wait_for_response_indicator(indicator)
20
+ ::Wait.until_true!(description: "cross origin request '#{indicator}'") do
21
+ @browser.find_element(id: "response_indicator").text == indicator
22
+ end
23
+ end
24
+
25
+ end
26
+ end