http_stub 0.21.0 → 0.22.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 (43) hide show
  1. checksums.yaml +5 -13
  2. data/lib/http_stub.rb +2 -1
  3. data/lib/http_stub/configurer/dsl/scenario_builder.rb +4 -4
  4. data/lib/http_stub/configurer/request/http/factory.rb +2 -2
  5. data/lib/http_stub/configurer/server/facade.rb +19 -9
  6. data/lib/http_stub/server/application.rb +22 -12
  7. data/lib/http_stub/server/{views → public}/favicon.ico +0 -0
  8. data/lib/http_stub/server/public/jquery-2.2.1.min.js +4 -0
  9. data/lib/http_stub/server/scenario/activator.rb +3 -3
  10. data/lib/http_stub/server/scenario/controller.rb +3 -3
  11. data/lib/http_stub/server/scenario/links.rb +22 -0
  12. data/lib/http_stub/server/scenario/scenario.rb +14 -11
  13. data/lib/http_stub/server/scenario/trigger.rb +18 -0
  14. data/lib/http_stub/server/stub/controller.rb +1 -1
  15. data/lib/http_stub/server/stub/registry.rb +2 -2
  16. data/lib/http_stub/server/views/_activate_scenario.haml +10 -0
  17. data/lib/http_stub/server/views/application.sass +4 -0
  18. data/lib/http_stub/server/views/index.haml +6 -0
  19. data/lib/http_stub/server/views/layout.haml +3 -2
  20. data/lib/http_stub/server/views/matches.haml +1 -0
  21. data/lib/http_stub/server/views/{_scenario.haml → scenario.haml} +4 -3
  22. data/lib/http_stub/server/views/scenarios.haml +10 -3
  23. data/lib/http_stub/server/views/stubs.haml +1 -0
  24. data/lib/http_stub/version.rb +1 -1
  25. data/spec/acceptance/endpoint_template_spec.rb +2 -2
  26. data/spec/acceptance/scenario_spec.rb +3 -3
  27. data/spec/lib/http_stub/configurer/request/http/factory_spec.rb +24 -4
  28. data/spec/lib/http_stub/configurer/request/scenario_spec.rb +2 -2
  29. data/spec/lib/http_stub/configurer/server/facade_spec.rb +18 -8
  30. data/spec/lib/http_stub/server/application_integration_spec.rb +270 -111
  31. data/spec/lib/http_stub/server/application_spec.rb +81 -15
  32. data/spec/lib/http_stub/server/scenario/activator_spec.rb +8 -3
  33. data/spec/lib/http_stub/server/scenario/controller_spec.rb +9 -7
  34. data/spec/lib/http_stub/server/scenario/links_spec.rb +41 -0
  35. data/spec/lib/http_stub/server/scenario/scenario_spec.rb +72 -30
  36. data/spec/lib/http_stub/server/scenario/trigger_spec.rb +36 -0
  37. data/spec/lib/http_stub/server/stub/controller_spec.rb +2 -2
  38. data/spec/lib/http_stub/server/stub/registry_spec.rb +23 -9
  39. data/spec/spec_helper.rb +1 -1
  40. data/spec/support/http_stub/scenario_fixture.rb +3 -3
  41. metadata +334 -342
  42. data/lib/http_stub/server/request_pipeline.rb +0 -27
  43. data/spec/lib/http_stub/server/request_pipeline_spec.rb +0 -80
@@ -4,14 +4,13 @@ describe HttpStub::Server::Application do
4
4
  let(:response) { last_response }
5
5
  let(:response_body) { response.body.to_s }
6
6
 
7
- let(:match_registry) { instance_double(HttpStub::Server::Stub::Registry).as_null_object }
8
- let(:stub_registry) { instance_double(HttpStub::Server::Stub::Registry).as_null_object }
9
- let(:scenario_registry) { instance_double(HttpStub::Server::Registry).as_null_object }
7
+ let(:match_registry) { instance_double(HttpStub::Server::Stub::Registry) }
8
+ let(:stub_registry) { instance_double(HttpStub::Server::Stub::Registry) }
9
+ let(:scenario_registry) { instance_double(HttpStub::Server::Registry) }
10
10
 
11
- let(:stub_controller) { instance_double(HttpStub::Server::Stub::Controller).as_null_object }
12
- let(:scenario_controller) { instance_double(HttpStub::Server::Scenario::Controller).as_null_object }
11
+ let(:stub_controller) { instance_double(HttpStub::Server::Stub::Controller) }
12
+ let(:scenario_controller) { instance_double(HttpStub::Server::Scenario::Controller) }
13
13
 
14
- let(:request_pipeline) { instance_double(HttpStub::Server::RequestPipeline, process: nil) }
15
14
  let(:response_pipeline) { instance_double(HttpStub::Server::ResponsePipeline, process: nil) }
16
15
 
17
16
  let(:app) { HttpStub::Server::Application.new! }
@@ -22,10 +21,21 @@ describe HttpStub::Server::Application do
22
21
  allow(HttpStub::Server::Stub::Registry).to receive(:new).and_return(stub_registry)
23
22
  allow(HttpStub::Server::Stub::Controller).to receive(:new).and_return(stub_controller)
24
23
  allow(HttpStub::Server::Scenario::Controller).to receive(:new).and_return(scenario_controller)
25
- allow(HttpStub::Server::RequestPipeline).to receive(:new).and_return(request_pipeline)
26
24
  allow(HttpStub::Server::ResponsePipeline).to receive(:new).and_return(response_pipeline)
27
25
  end
28
26
 
27
+ context "when the diagnostics landing page is retrieved" do
28
+
29
+ subject { get "/http_stub" }
30
+
31
+ it "responds without error" do
32
+ subject
33
+
34
+ expect(response.status).to eql(200)
35
+ end
36
+
37
+ end
38
+
29
39
  context "when a stub registration request is received" do
30
40
 
31
41
  let(:registration_response) { instance_double(HttpStub::Server::Stub::Response::Base) }
@@ -83,6 +93,8 @@ describe HttpStub::Server::Application do
83
93
 
84
94
  subject { delete "/http_stub/stubs" }
85
95
 
96
+ before(:example) { allow(stub_controller).to receive(:clear) }
97
+
86
98
  it "delegates clearing to the stub controller" do
87
99
  expect(stub_controller).to receive(:clear)
88
100
 
@@ -101,6 +113,8 @@ describe HttpStub::Server::Application do
101
113
 
102
114
  subject { post "/http_stub/stubs/memory" }
103
115
 
116
+ before(:example) { allow(stub_registry).to receive(:remember) }
117
+
104
118
  it "remembers the stubs in the stub registry" do
105
119
  expect(stub_registry).to receive(:remember)
106
120
 
@@ -119,6 +133,8 @@ describe HttpStub::Server::Application do
119
133
 
120
134
  subject { get "/http_stub/stubs/memory" }
121
135
 
136
+ before(:example) { allow(stub_registry).to receive(:recall) }
137
+
122
138
  it "recalls the stubs remembered by the stub registry" do
123
139
  expect(stub_registry).to receive(:recall)
124
140
 
@@ -168,7 +184,7 @@ describe HttpStub::Server::Application do
168
184
  subject
169
185
  end
170
186
 
171
- it "processes the scenarion controllers response via the response pipeline" do
187
+ it "processes the scenario controllers response via the response pipeline" do
172
188
  expect(response_pipeline).to receive(:process).with(registration_response)
173
189
 
174
190
  subject
@@ -176,6 +192,21 @@ describe HttpStub::Server::Application do
176
192
 
177
193
  end
178
194
 
195
+ context "when a request to show a scenario is received" do
196
+
197
+ let(:scenario_name) { "Some scenario name" }
198
+ let(:found_scenario) { HttpStub::Server::Scenario::ScenarioFixture.empty }
199
+
200
+ subject { get "/http_stub/scenarios?#{URI.encode_www_form(:name => scenario_name)}" }
201
+
202
+ it "retrieves the scenario from the scenario registry" do
203
+ expect(scenario_registry).to receive(:find).with(scenario_name, anything).and_return(found_scenario)
204
+
205
+ subject
206
+ end
207
+
208
+ end
209
+
179
210
  context "when a request to list the scenarios is received" do
180
211
 
181
212
  let(:found_scenarios) { [ HttpStub::Server::Scenario::ScenarioFixture.empty ] }
@@ -190,10 +221,35 @@ describe HttpStub::Server::Application do
190
221
 
191
222
  end
192
223
 
224
+ context "when a scenario activation request is received" do
225
+
226
+ let(:scenario_name) { "Some scenario name" }
227
+ let(:activation_response) { instance_double(HttpStub::Server::Stub::Response::Base) }
228
+
229
+ subject { post "/http_stub/scenarios/activate", :name => scenario_name }
230
+
231
+ before(:example) { allow(scenario_controller).to receive(:activate).and_return(activation_response) }
232
+
233
+ it "activates the scenario via the scenario controller" do
234
+ expect(scenario_controller).to receive(:activate).with(scenario_name, anything).and_return(activation_response)
235
+
236
+ subject
237
+ end
238
+
239
+ it "processes the scenario controllers response via the response pipeline" do
240
+ expect(response_pipeline).to receive(:process).with(activation_response)
241
+
242
+ subject
243
+ end
244
+
245
+ end
246
+
193
247
  context "when a request to clear the scenarios has been received" do
194
248
 
195
249
  subject { delete "/http_stub/scenarios" }
196
250
 
251
+ before(:example) { allow(scenario_controller).to receive(:clear) }
252
+
197
253
  it "delegates clearing to the scenario controller" do
198
254
  expect(scenario_controller).to receive(:clear)
199
255
 
@@ -208,24 +264,34 @@ describe HttpStub::Server::Application do
208
264
 
209
265
  end
210
266
 
267
+ context "when a request for the diagnostic pages stylesheet has been received" do
268
+
269
+ subject { get "/application.css" }
270
+
271
+ it "responds without error" do
272
+ subject
273
+
274
+ expect(response.status).to eql(200)
275
+ end
276
+
277
+ end
278
+
211
279
  context "when another type of request is received" do
212
280
 
213
- let(:request_pipeline_response) { instance_double(HttpStub::Server::Stub::Response::Base) }
281
+ let(:stub_response) { instance_double(HttpStub::Server::Stub::Response::Base) }
214
282
 
215
283
  subject { get "/a_path" }
216
284
 
217
- before(:example) { allow(request_pipeline).to receive(:process).and_return(request_pipeline_response) }
285
+ before(:example) { allow(stub_controller).to receive(:replay).and_return(stub_response) }
218
286
 
219
- it "determines the response via the request pipeline" do
220
- expect(request_pipeline).to(
221
- receive(:process).with(an_instance_of(HttpStub::Server::Request), anything)
222
- )
287
+ it "attempts to replay a stub response via the stub controller" do
288
+ expect(stub_controller).to receive(:replay).with(an_instance_of(HttpStub::Server::Request), anything)
223
289
 
224
290
  subject
225
291
  end
226
292
 
227
293
  it "processes the response via the response pipeline" do
228
- expect(response_pipeline).to receive(:process).with(request_pipeline_response)
294
+ expect(response_pipeline).to receive(:process).with(stub_response)
229
295
 
230
296
  subject
231
297
  end
@@ -3,9 +3,14 @@ describe HttpStub::Server::Scenario::Activator do
3
3
  let(:logger) { instance_double(Logger) }
4
4
  let(:stubs) { (1..3).map { instance_double(HttpStub::Server::Stub::Stub) } }
5
5
  let(:triggered_scenario_names) { [] }
6
+ let(:scenario_triggers) do
7
+ triggered_scenario_names.map do |scenario_name|
8
+ instance_double(HttpStub::Server::Scenario::Trigger, name: scenario_name)
9
+ end
10
+ end
6
11
  let(:scenario) do
7
12
  instance_double(
8
- HttpStub::Server::Scenario::Scenario, stubs: stubs, triggered_scenario_names: triggered_scenario_names
13
+ HttpStub::Server::Scenario::Scenario, stubs: stubs, triggered_scenarios: scenario_triggers
9
14
  )
10
15
  end
11
16
  let(:scenario_registry) { instance_double(HttpStub::Server::Registry).as_null_object }
@@ -26,10 +31,10 @@ describe HttpStub::Server::Scenario::Activator do
26
31
 
27
32
  context "when the scenario contains triggered scenarios" do
28
33
 
29
- let(:triggered_scenario_names) { (1..3).map { |i| "triggered_scenario_name/#{i}" } }
34
+ let(:triggered_scenario_names) { (1..3).map { |i| "Triggered scenario name #{i}" } }
30
35
  let(:triggered_scenarios) do
31
36
  triggered_scenario_names.map do
32
- instance_double(HttpStub::Server::Scenario::Scenario, stubs: [], triggered_scenario_names: [])
37
+ instance_double(HttpStub::Server::Scenario::Scenario, stubs: [], triggered_scenarios: [])
33
38
  end
34
39
  end
35
40
 
@@ -48,15 +48,17 @@ describe HttpStub::Server::Scenario::Controller do
48
48
 
49
49
  describe "#activate" do
50
50
 
51
- subject { controller.activate(request, logger) }
51
+ let(:scenario_name) { "Some Scenario Name" }
52
52
 
53
- it "finds a scenario whose name matches the request path omitting the '/' prefix" do
54
- expect(scenario_registry).to receive(:find).with("some/request/path", logger)
53
+ subject { controller.activate(scenario_name, logger) }
54
+
55
+ it "finds a scenario whose name matches the provided name" do
56
+ expect(scenario_registry).to receive(:find).with(scenario_name, logger)
55
57
 
56
58
  subject
57
59
  end
58
60
 
59
- describe "when a scenario is found that matches the request" do
61
+ describe "when a scenario is found" do
60
62
 
61
63
  before(:example) { allow(scenario_registry).to receive(:find).and_return(scenario) }
62
64
 
@@ -72,7 +74,7 @@ describe HttpStub::Server::Scenario::Controller do
72
74
 
73
75
  end
74
76
 
75
- describe "when no stub activator is activated by the request" do
77
+ describe "when no scenario is found" do
76
78
 
77
79
  before(:example) { allow(scenario_registry).to receive(:find).and_return(nil) }
78
80
 
@@ -82,8 +84,8 @@ describe HttpStub::Server::Scenario::Controller do
82
84
  subject
83
85
  end
84
86
 
85
- it "returns an empty response" do
86
- expect(subject).to eql(HttpStub::Server::Response::EMPTY)
87
+ it "returns a not found response" do
88
+ expect(subject).to eql(HttpStub::Server::Response::NOT_FOUND)
87
89
  end
88
90
 
89
91
  end
@@ -0,0 +1,41 @@
1
+ describe HttpStub::Server::Scenario::Links do
2
+
3
+ let(:name) { "without_esacpe_characters" }
4
+
5
+ let(:links) { described_class.new(name) }
6
+
7
+ describe "#detail" do
8
+
9
+ subject { links.detail }
10
+
11
+ it "returns a uri starting with '/http_stub/scenarios'" do
12
+ expect(subject).to start_with("/http_stub/scenarios")
13
+ end
14
+
15
+ it "returns a uri ending with a name parameter" do
16
+ expect(subject).to end_with("?name=#{name}")
17
+ end
18
+
19
+ context "when the name contains characters requiring uri escaping" do
20
+
21
+ let(:name) { "contains characters!to?be&escaped" }
22
+
23
+ it "returns a uri with the name uri escaped" do
24
+ expect(subject).to end_with("?name=contains+characters%21to%3Fbe%26escaped")
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ describe "#activate" do
32
+
33
+ subject { links.activate }
34
+
35
+ it "returns a generic activation link" do
36
+ expect(subject).to eql("/http_stub/scenarios/activate")
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -1,22 +1,31 @@
1
1
  describe HttpStub::Server::Scenario::Scenario do
2
2
 
3
- let(:name) { "some_scenario_name" }
4
- let(:number_of_stubs) { 3 }
5
- let(:stubs) { (1..number_of_stubs).map { instance_double(HttpStub::Server::Stub::Stub) } }
6
- let(:triggered_scenario_names) { (1..3).map { |i| "triggered/scenario/name/#{i}" } }
3
+ let(:name) { "Some scenario name" }
4
+ let(:number_of_stubs) { 3 }
5
+ let(:stubs) { (1..number_of_stubs).map { instance_double(HttpStub::Server::Stub::Stub) } }
6
+
7
+ let(:number_of_triggered_scenario_names) { 3 }
8
+ let(:triggered_scenario_names) do
9
+ (1..number_of_triggered_scenario_names).map { |i| "Triggered Scenario Name #{i}" }
10
+ end
11
+ let(:triggered_scenarios) do
12
+ (1..number_of_triggered_scenario_names).map { instance_double(HttpStub::Server::Scenario::Trigger) }
13
+ end
14
+
7
15
  let(:args) do
8
- HttpStub::ScenarioFixture.new.with_name!(name).
16
+ HttpStub::ScenarioFixture.new.
17
+ with_name!(name).
9
18
  with_stubs!(number_of_stubs).
10
19
  with_triggered_scenario_names!(triggered_scenario_names).
11
20
  server_payload
12
21
  end
13
22
 
14
- let(:scenario) { HttpStub::Server::Scenario::Scenario.new(args) }
15
-
16
- before(:example) { allow(HttpStub::Server::Stub).to receive(:create).and_return(*stubs) }
23
+ let(:scenario) { described_class.new(args) }
17
24
 
18
25
  describe "#constructor" do
19
26
 
27
+ subject { scenario }
28
+
20
29
  context "when many stub payloads are provided" do
21
30
 
22
31
  let(:number_of_stubs) { 3 }
@@ -24,7 +33,7 @@ describe HttpStub::Server::Scenario::Scenario do
24
33
  it "creates an underlying stub for each stub payload provided" do
25
34
  args["stubs"].each { |stub_args| expect(HttpStub::Server::Stub).to receive(:create).with(stub_args) }
26
35
 
27
- scenario
36
+ subject
28
37
  end
29
38
 
30
39
  end
@@ -33,10 +42,36 @@ describe HttpStub::Server::Scenario::Scenario do
33
42
 
34
43
  let(:number_of_stubs) { 1 }
35
44
 
36
- it "creates an underlying stub for each stub payload provided" do
45
+ it "creates an underlying stub for the stub payload provided" do
37
46
  expect(HttpStub::Server::Stub).to receive(:create).with(args["stubs"].first)
38
47
 
39
- scenario
48
+ subject
49
+ end
50
+
51
+ end
52
+
53
+ context "when many triggered scenario names are provided" do
54
+
55
+ let(:number_of_triggered_scenario_names) { 3 }
56
+
57
+ it "creates a scenario trigger for each trigger name provided" do
58
+ triggered_scenario_names.each do |scenario_name|
59
+ expect(HttpStub::Server::Scenario::Trigger).to receive(:new).with(scenario_name)
60
+ end
61
+
62
+ subject
63
+ end
64
+
65
+ end
66
+
67
+ context "when no triggered scenario names are provided" do
68
+
69
+ let(:number_of_triggered_scenario_names) { 0 }
70
+
71
+ it "does not create a scenario trigger" do
72
+ expect(HttpStub::Server::Scenario::Trigger).to_not receive(:new)
73
+
74
+ subject
40
75
  end
41
76
 
42
77
  end
@@ -49,7 +84,7 @@ describe HttpStub::Server::Scenario::Scenario do
49
84
 
50
85
  subject { scenario.matches?(other_name, logger) }
51
86
 
52
- describe "when the scenario's name exactly matches the provided name" do
87
+ describe "when the scenarios name exactly matches the provided name" do
53
88
 
54
89
  let(:other_name) { name }
55
90
 
@@ -59,9 +94,9 @@ describe HttpStub::Server::Scenario::Scenario do
59
94
 
60
95
  end
61
96
 
62
- describe "when the scenario's name is a substring of the provided name" do
97
+ describe "when the scenarios name is a substring of the provided name" do
63
98
 
64
- let(:other_name) { "#{name}_with_additional_context" }
99
+ let(:other_name) { "#{name} With Additional Context" }
65
100
 
66
101
  it "returns false" do
67
102
  expect(subject).to be(false)
@@ -69,9 +104,9 @@ describe HttpStub::Server::Scenario::Scenario do
69
104
 
70
105
  end
71
106
 
72
- describe "when the scenario's name is completely different to the provided name" do
107
+ describe "when the scenarios name is completely different to the provided name" do
73
108
 
74
- let(:other_name) { "completely_different_scenario_name" }
109
+ let(:other_name) { "Completely Different Scenario Name" }
75
110
 
76
111
  it "returns false" do
77
112
  expect(subject).to be(false)
@@ -81,36 +116,43 @@ describe HttpStub::Server::Scenario::Scenario do
81
116
 
82
117
  end
83
118
 
84
- describe "#uri" do
119
+ describe "#links" do
85
120
 
86
- it "returns the scenario's name with '/' prefixed" do
87
- expect(scenario.uri).to eql("/#{name}")
88
- end
121
+ subject { scenario.links }
89
122
 
90
- end
123
+ before(:example) { allow(HttpStub::Server::Scenario::Links).to receive(:new) }
91
124
 
92
- describe "#stubs" do
125
+ it "create links for the scenario name" do
126
+ expect(HttpStub::Server::Scenario::Links).to receive(:new).with(name)
93
127
 
94
- it "returns the HttpStub::Server::Stub's constructed from the scenario's arguments" do
95
- expect(scenario.stubs).to eql(stubs)
128
+ subject
129
+ end
130
+
131
+ it "returns the created links" do
132
+ links = instance_double(HttpStub::Server::Scenario::Links)
133
+ allow(HttpStub::Server::Scenario::Links).to receive(:new).and_return(links)
134
+
135
+ expect(subject).to eql(links)
96
136
  end
97
137
 
98
138
  end
99
139
 
100
- describe "#triggered_scenario_names" do
140
+ describe "#stubs" do
141
+
142
+ before(:example) { allow(HttpStub::Server::Stub).to receive(:create).and_return(*stubs) }
101
143
 
102
- it "returns the value provided in the payload" do
103
- expect(scenario.triggered_scenario_names).to eql(triggered_scenario_names)
144
+ it "returns the HttpStub::Server::Stub's constructed from the scenario's arguments" do
145
+ expect(scenario.stubs).to eql(stubs)
104
146
  end
105
147
 
106
148
  end
107
149
 
108
150
  describe "#triggered_scenarios" do
109
151
 
110
- it "returns an array containing the triggered scenario names and uris" do
111
- expected_details = triggered_scenario_names.reduce([]) { |result, name| result << [name, "/#{name}"] }
152
+ before(:example) { allow(HttpStub::Server::Scenario::Trigger).to receive(:new).and_return(*triggered_scenarios) }
112
153
 
113
- expect(scenario.triggered_scenarios).to eql(expected_details)
154
+ it "returns the triggered scenarios constructed from the scenario's arguments" do
155
+ expect(scenario.triggered_scenarios).to eql(triggered_scenarios)
114
156
  end
115
157
 
116
158
  end