mocktopus 0.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.
data/mocktopus.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'mocktopus'
5
+ s.version = '0.0.4'
6
+ s.date = '2015-03-14'
7
+ s.required_ruby_version = '>= 1.9.3'
8
+
9
+ s.summary = 'A configurable mock Web API'
10
+ s.description = 'The Mocktopus is a Sinatra/thin-based Web API that lets you mock your app dependencies'
11
+ s.author = 'Rackspace'
12
+ s.email = ['racksburg_automation@lists.rackspace.com']
13
+ s.homepage = 'https://github.com/rackspaceautomationco/mocktopus'
14
+
15
+ s.files = `git ls-files`.split($/)
16
+ s.executables = %w(mocktopus)
17
+
18
+ s.add_dependency 'sinatra', '~> 1.4', '>= 1.4.4'
19
+ s.add_dependency 'sinatra-contrib', '~> 1.4.2', '>= 1.4.2'
20
+ s.add_dependency 'thin', '~> 1.6.1', '>= 1.6.1'
21
+ s.add_dependency 'thor', '~> 0.19.1', '>= 0.19.1'
22
+ s.add_dependency 'rack', '~> 1.5.2', '>= 1.5.2'
23
+ s.add_dependency 'rake', '~> 10.1.0', '>= 10.1.0'
24
+ s.add_dependency 'minitest', '~> 5.2.0', '>= 5.2.0'
25
+ s.add_dependency 'fakeweb', '~> 1.3.0', '>= 1.3.0'
26
+ s.add_dependency 'mocha', '~> 0.14.0', '>= 0.14.0'
27
+ s.add_dependency 'simplecov', '~> 0.9.2', '>= 0.9.2'
28
+ s.add_dependency 'coveralls', '~> 0.7.11', '>= 0.7.11'
29
+ end
data/test/app_test.rb ADDED
@@ -0,0 +1,276 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ class AppTest < Mocktopus::Test
5
+
6
+ def setup
7
+
8
+ end
9
+
10
+ def app
11
+ Sinatra::Application
12
+ end
13
+
14
+ def test_inputs_nothing_raised
15
+ body = {
16
+ 'foo' => 'bar'
17
+ }
18
+ input_object = create_input('/v0/bar', 'GET', nil, JSON.pretty_generate(body), 200, nil, "")
19
+
20
+ response = post '/mocktopus/inputs/test_inputs_nothing_raised', JSON.pretty_generate(input_object)
21
+ assert_equal(200, response.status)
22
+ end
23
+
24
+ def test_bad_input_returns_400
25
+ post '/mocktopus/inputs/test_bad_input_returns_400', {}, {}
26
+ assert_equal 400, last_response.status
27
+ end
28
+
29
+ def test_all_inputs
30
+ input1 = create_input('/v0/test_all_inputs_foo', 'GET', nil, nil, 200, nil, "")
31
+ post '/mocktopus/inputs/test_all_inputs_foo', JSON.pretty_generate(input1)
32
+
33
+ input2 = create_input('/v0/test_all_inputs_bar', 'GET', nil, nil, 200, nil, "")
34
+ post '/mocktopus/inputs/test_all_inputs_bar', JSON.pretty_generate(input2)
35
+
36
+ inputs_response = get '/mocktopus/inputs'
37
+ json = JSON.parse(inputs_response.body)
38
+ refute_nil json['test_all_inputs_foo']
39
+ refute_nil json['test_all_inputs_bar']
40
+ end
41
+
42
+ def test_match_get
43
+ response_body_hash = {
44
+ "key1" => "value1",
45
+ "key2" => "value2"
46
+ }
47
+ input1 = create_input('/v0/test_match_get1', 'GET', { "host"=>"example.org", "cookie"=>"" }, nil, 200, nil, response_body_hash)
48
+ post '/mocktopus/inputs/test_match_get1', JSON.pretty_generate(input1)
49
+
50
+ response = get '/v0/test_match_get1'
51
+ assert_equal(200, response.status)
52
+ assert_equal(response_body_hash, JSON.parse(response.body))
53
+ end
54
+
55
+ def test_match_post
56
+ post_body_hash = {
57
+ "name" => "John",
58
+ "email" => "john@127.0.0.1"
59
+ }
60
+ response_body_hash = {
61
+ "response" => "ok!"
62
+ }
63
+ input1 = create_input('/v0/test_match_post1', 'POST', { "host"=>"example.org", "cookie"=>"" }, post_body_hash, 202, nil, response_body_hash)
64
+ post '/mocktopus/inputs/test_match_post1', input1.to_json
65
+
66
+ response = post '/v0/test_match_post1', post_body_hash.to_json
67
+ assert_equal(202, response.status)
68
+ assert_equal(response_body_hash, JSON.parse(response.body))
69
+ end
70
+
71
+ def test_input_by_name
72
+ input1 = create_input('/v0/test_input_by_name_foo', 'GET', nil, "", 200, nil, "")
73
+ post '/mocktopus/inputs/test_input_by_name_foo', input1.to_json
74
+
75
+ input2 = create_input('/v0/test_input_by_name_bar', 'GET', nil, "", 200, nil, "")
76
+ post '/mocktopus/inputs/test_input_by_name_bar', input2.to_json
77
+
78
+ input_by_name_response = get '/mocktopus/inputs/test_input_by_name_foo'
79
+ json = JSON.parse(input_by_name_response.body)
80
+ refute_nil json
81
+ assert_equal(input1, json)
82
+ assert (json != input2)
83
+ end
84
+
85
+ def test_delete_all
86
+ input1 = create_input('/v0/test_delete_all_foo', 'GET', nil, nil, 200, nil, "")
87
+ post '/mocktopus/inputs/test_delete_all_foo', JSON.pretty_generate(input1)
88
+
89
+ delete '/mocktopus/inputs'
90
+
91
+ inputs_response = get'/mocktopus/inputs'
92
+ json = JSON.parse(inputs_response.body)
93
+ assert_equal(0, json.size())
94
+ end
95
+
96
+ def test_delete_by_name
97
+ input1 = create_input('/v0/test_delete_by_name_foo', 'GET', nil, "", 200, nil, "")
98
+ post '/mocktopus/inputs/test_delete_by_name_foo', JSON.pretty_generate(input1)
99
+
100
+ input2 = create_input('/v0/test_delete_by_name_bar', 'GET', nil, "", 200, nil, "")
101
+ post '/mocktopus/inputs/test_delete_by_name_bar', JSON.pretty_generate(input2)
102
+
103
+ delete '/mocktopus/inputs/test_delete_by_name_foo'
104
+
105
+ inputs_response = get '/mocktopus/inputs/test_delete_by_name_bar'
106
+ json = JSON.parse(inputs_response.body)
107
+ refute_nil json
108
+ assert_equal(input2, json)
109
+ assert (json != input1)
110
+ end
111
+
112
+ def test_not_found_matching_input_found
113
+ input1 = create_input('/test_not_found_matching_input_found/1', 'POST', { "host" => "example.org", "cookie" => "" }, JSON.pretty_generate({ "foo" => "bar" }), 200, { "bar" => "foo" }, JSON.pretty_generate({ "body" => "foobar" }))
114
+ post '/mocktopus/inputs/test_not_found_matching_input_found', JSON.pretty_generate(input1)
115
+
116
+ response = post '/test_not_found_matching_input_found/1', JSON.pretty_generate({"foo" => "bar"})
117
+
118
+ assert_equal(200, response.status)
119
+ end
120
+
121
+ def test_mock_api_calls
122
+ uri = '/test_mock_api_calls/1'
123
+ verb = 'POST'
124
+ code = 200
125
+ body = {
126
+ "key1" => "value_one",
127
+ "key2" => "value_two"
128
+ }
129
+ input = create_input(uri, verb, body, '', code, {}, '')
130
+ post "/mocktopus/inputs/#{uri}", input
131
+
132
+ post uri, JSON.pretty_generate(body)
133
+ calls = get '/mocktopus/mock_api_calls'
134
+ json = JSON.parse(calls.body)
135
+ this_test_call = json.select{|k| k['path'] == uri }.first
136
+ refute_nil this_test_call
137
+ assert_equal(uri, this_test_call['path'])
138
+ assert_equal(verb, this_test_call['verb'])
139
+ assert_equal(body, this_test_call['body'])
140
+ end
141
+
142
+ def test_mock_api_calls_with_parameters
143
+ uri = '/test_mock_api_calls_with_parameters/foo?key=(domain=getstatus.com)&start=0&pageSize=100'
144
+ verb = 'GET'
145
+ code = 200
146
+ input = create_input(uri, verb, {}, '', code, {}, '')
147
+ post "/mocktopus/inputs/#{uri}", input
148
+
149
+ delete '/mocktopus/mock_api_calls'
150
+
151
+ get uri
152
+ calls = JSON.parse(get('/mocktopus/mock_api_calls').body)
153
+ this_test_call = calls.select{|k| k['path'] == uri }.first
154
+ refute_nil this_test_call
155
+ assert_equal(uri, this_test_call['path'])
156
+ assert_equal(verb, this_test_call['verb'])
157
+ end
158
+
159
+ def test_delete_mock_api_calls
160
+ uri = '/test_delete_mock_api_calls/1'
161
+ verb = 'POST'
162
+ code = 200
163
+ body = {
164
+ "key1" => "value_one",
165
+ "key2" => "value_two"
166
+ }
167
+ input = create_input(uri, verb, body, '', code, {}, '')
168
+ post "/mocktopus/inputs/#{uri}", input
169
+
170
+ post uri, JSON.pretty_generate(body)
171
+ calls = get '/mocktopus/mock_api_calls'
172
+ json = JSON.parse(calls.body)
173
+ assert(0 < json.size)
174
+ delete '/mocktopus/mock_api_calls'
175
+ calls = get '/mocktopus/mock_api_calls'
176
+ json = JSON.parse(calls.body)
177
+ assert(0 == json.size)
178
+ end
179
+
180
+ def test_get_missing_input_returns_405
181
+ response = get "/mocktopus/inputs/does_not_exist"
182
+ assert_equal(405, response.status)
183
+ end
184
+
185
+ def test_input_sequencing
186
+ uri = '/test_input_sequencing'
187
+ verb = 'GET'
188
+ code = 200
189
+ body1 = {
190
+ "status" => "pending"
191
+ }
192
+ body2 = {
193
+ "status" => "completed"
194
+ }
195
+
196
+ input1 = create_input(uri, verb, {}, nil, code, {}, body1)
197
+ input2 = create_input(uri, verb, {}, nil, code, {}, body1)
198
+ input3 = create_input(uri, verb, {}, nil, code, {}, body2)
199
+
200
+ post "/mocktopus/inputs/test_input_sequencing_1", JSON.pretty_generate(input1)
201
+ post "/mocktopus/inputs/test_input_sequencing_2", JSON.pretty_generate(input2)
202
+ post "/mocktopus/inputs/test_input_sequencing_3", JSON.pretty_generate(input3)
203
+
204
+ response = get uri, nil
205
+ assert_equal(body1, JSON.parse(response.body))
206
+ response = get uri, nil
207
+ assert_equal(body1, JSON.parse(response.body))
208
+ response = get uri, nil
209
+ assert_equal(body2, JSON.parse(response.body))
210
+ end
211
+
212
+ def test_nil_headers
213
+ uri = '/test_nil_headers?foo=bar&email=test@test.com'
214
+ verb = 'GET'
215
+ code = 200
216
+ input = create_input(uri, verb, nil, nil, code, nil, {})
217
+ post '/mocktopus/inputs/test_nil_headers', JSON.pretty_generate(input)
218
+
219
+ response = get uri, nil
220
+ assert_equal(code, response.status)
221
+ end
222
+
223
+ def test_unicode_in_body
224
+ uri = 'test_unicode'
225
+ verb = 'POST'
226
+ body =
227
+ {
228
+ "uri" => "¾öäëöäëü",
229
+ "msg" => "I am the unicöde monster"
230
+ }
231
+ code = 200
232
+ input = create_input(uri, verb, {}, body, code, {}, body)
233
+ post "/mocktopus/inputs/test_unicode_in_body", JSON.pretty_generate(input)
234
+
235
+ response = get "/mocktopus/inputs/test_unicode_in_body"
236
+ assert_equal(body, JSON.parse(JSON.parse(response.body)['body']))
237
+ end
238
+
239
+ def test_uri_encoding
240
+ uri = 'test_unicode'
241
+ verb = 'POST'
242
+ body =
243
+ {
244
+ "uri" => 'https://web.archive.org/web/20060204114947/http://www.googles.com/index_noflash.html'
245
+ }
246
+ code = 200
247
+ input = create_input(uri, verb, {}, body, code, {}, body)
248
+ post "/mocktopus/inputs/test_uri_encoding", JSON.pretty_generate(input)
249
+
250
+ response = get "/mocktopus/inputs/test_uri_encoding"
251
+ assert_equal(body, JSON.parse(JSON.parse(response.body)['body']))
252
+ end
253
+
254
+ def test_failed_match_returns_json
255
+ random_uri = "/#{SecureRandom.uuid}"
256
+ get random_uri
257
+ assert_equal 428, last_response.status
258
+ assert_equal random_uri, JSON.parse(last_response.body)['call']['path']
259
+ end
260
+
261
+ private
262
+ def create_input(uri, verb, headers, body, response_code, response_headers, response_body)
263
+ input = {}
264
+ input['uri'] = uri
265
+ input['headers'] = headers
266
+ input['body'] = body
267
+ input['verb'] = verb
268
+ input['response'] = {
269
+ "code" => response_code,
270
+ "headers" => response_headers,
271
+ "body" => response_body,
272
+ "delay" => 0
273
+ }
274
+ return input
275
+ end
276
+ end
data/test/cli_test.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ class CLITest < Mocktopus::Test
4
+ def setup
5
+ @cli = Mocktopus::CLI.new
6
+ end
7
+
8
+ def test_start_task_starts_mocktopus_with_default_port
9
+ command = 'bundle exec thin -R config.ru start -p 8081 '
10
+ @cli.stubs(:run_command).with(command).once
11
+ @cli.start
12
+ end
13
+
14
+ def test_start_task_starts_mocktopus_with_custom_port
15
+ command = 'bundle exec thin -R config.ru start -p 7071'
16
+ @cli.stubs(:run_command).with(command).once
17
+ @cli.start('-p', '7071')
18
+ end
19
+
20
+ def test_stop_task_stops_mocktopus
21
+ @cli.stubs(:run_command).with('bundle exec thin stop')
22
+ @cli.stop
23
+ end
24
+
25
+ end
@@ -0,0 +1,229 @@
1
+ require 'test_helper'
2
+
3
+ class InputContainerTest < Mocktopus::Test
4
+
5
+ def test_initialize_not_nil
6
+ container = Mocktopus::InputContainer.new
7
+ refute_nil container
8
+ end
9
+
10
+ def test_all_returns_zero_on_init
11
+ container = Mocktopus::InputContainer.new
12
+ all_inputs = container.all()
13
+ assert_equal(0, all_inputs.size())
14
+ end
15
+
16
+ def test_all_returns_count_after_add
17
+ container = Mocktopus::InputContainer.new
18
+ container.add("hash1", {})
19
+ container.add("hash2", {})
20
+ all_inputs = container.all()
21
+ assert_equal(2, all_inputs.size())
22
+ end
23
+
24
+ def test_get_by_returns_existing_input
25
+ container = Mocktopus::InputContainer.new
26
+ container.add("hash1", {})
27
+ hash1 = container.get_by("hash1")
28
+ refute_nil hash1
29
+ end
30
+
31
+ def test_get_by_returns_nil_for_missing_input
32
+ container = Mocktopus::InputContainer.new
33
+ container.add("hash1", {})
34
+ hash2 = container.get_by("hash2")
35
+ assert_nil(hash2)
36
+ end
37
+
38
+ def test_delete_all_returns_empty_hash
39
+ container = Mocktopus::InputContainer.new
40
+ container.add("hash1", {})
41
+ container.add("hash2", {})
42
+ container.delete_all()
43
+ all_after_delete = container.all()
44
+ assert_equal(0, all_after_delete.size())
45
+ end
46
+
47
+ def test_delete_by_deletes_input
48
+ container = Mocktopus::InputContainer.new
49
+ container.add("hash1", {})
50
+ container.add("hash2", {})
51
+ container.delete_by("hash2")
52
+ all = container.all()
53
+ assert_equal(1, all.size())
54
+ hash1 = container.get_by("hash1")
55
+ refute_nil hash1
56
+ end
57
+
58
+ def test_delete_by_missing_input_does_nothing
59
+ container = Mocktopus::InputContainer.new
60
+ container.add("hash1", {})
61
+ container.delete_by("hash2")
62
+ all = container.all()
63
+ assert_equal(1, all.size())
64
+ hash1 = container.get_by("hash1")
65
+ refute_nil hash1
66
+ end
67
+
68
+ def test_single_match_returns_match
69
+ response = Mocktopus::Response.new({
70
+ "code" => "200",
71
+ "headers" => {},
72
+ "body" => {
73
+ "foo" => "baz"
74
+ }
75
+ })
76
+
77
+ input = Mocktopus::Input.new({
78
+ "uri" => "/v0/test_single_match_returns_match",
79
+ "verb" => "POST",
80
+ "headers" => {},
81
+ "body" => {
82
+ "foo" => "bar"
83
+ }
84
+ }, response)
85
+
86
+ container = Mocktopus::InputContainer.new
87
+ container.add("input1", input)
88
+ match_result = container.match("/v0/test_single_match_returns_match", "POST", {}, JSON.pretty_generate({"foo" => "bar"}), {})
89
+ refute_nil match_result
90
+ assert_equal(response, match_result.response)
91
+ end
92
+
93
+ def test_single_match_returns_match_encoded
94
+ response = Mocktopus::Response.new({
95
+ "code" => "200",
96
+ "headers" => {},
97
+ "body" => {
98
+ "key" => "test_single_match_returns_match_encoded"
99
+ }
100
+ })
101
+
102
+ input = Mocktopus::Input.new({
103
+ "uri" => "/v0/test_single_match_returns_match_encoded/(key%3Dvalue)",
104
+ "verb" => "POST",
105
+ "headers" => {},
106
+ "body" => {
107
+ "key" => "test_single_match_returns_match_encoded"
108
+ }
109
+ }, response)
110
+
111
+ container = Mocktopus::InputContainer.new
112
+ container.add("input1", input)
113
+ match_result = container.match("/v0/test_single_match_returns_match_encoded/(key=value)", "POST", {}, JSON.pretty_generate({"key" => "test_single_match_returns_match_encoded"}), {})
114
+ refute_nil match_result
115
+ assert_equal(response, match_result.response)
116
+ end
117
+
118
+ def test_headers_match_returns_single_result_for_dashes
119
+ response = Mocktopus::Response.new({
120
+ "code" => "200",
121
+ "headers" => {},
122
+ "body" => {
123
+ "key" => "test_headers_match_returns_single_result_for_dashes"
124
+ }
125
+ })
126
+
127
+ input = Mocktopus::Input.new({
128
+ "uri" => "/v0/test_headers_match_returns_single_result_for_dashes",
129
+ "verb" => "GET",
130
+ "headers" => { 'g-sub-me' => 'fizz'},
131
+ 'body' => {}
132
+ }, response)
133
+
134
+ container = Mocktopus::InputContainer.new
135
+ container.add("input1", input)
136
+ match_result = container.match("/v0/test_headers_match_returns_single_result_for_dashes", "GET", {'g_sub_me' => 'fizz'}, {}, {})
137
+ refute_nil match_result
138
+ assert_equal(response, match_result.response)
139
+ end
140
+
141
+ def test_headers_different_value_no_result_for_dashes
142
+ response = Mocktopus::Response.new({
143
+ "code" => "200",
144
+ "headers" => {},
145
+ "body" => {
146
+ "key" => "test_headers_different_value_no_result_for_dashes"
147
+ }
148
+ })
149
+
150
+ input = Mocktopus::Input.new({
151
+ "uri" => "/v0/test_headers_different_value_no_result_for_dashes",
152
+ "verb" => "GET",
153
+ "headers" => { 'g-sub-mez' => 'fizz'},
154
+ 'body' => {}
155
+ }, response)
156
+
157
+ container = Mocktopus::InputContainer.new
158
+ container.add("input1", input)
159
+ match_result = container.match("/v0/test_headers_different_value_no_result_for_dashes", "GET", {'g_sub_me' => 'fizz'}, {}, {})
160
+ assert_nil match_result
161
+ end
162
+
163
+ def test_headers_no_match_returns_nil_result_for_dashes
164
+ response = Mocktopus::Response.new({
165
+ "code" => "200",
166
+ "headers" => {},
167
+ "body" => {
168
+ "key" => "test_headers_no_match_returns_nil_result_for_dashes"
169
+ }
170
+ })
171
+
172
+ input = Mocktopus::Input.new({
173
+ "uri" => "/v0/test_headers_no_match_returns_nil_result_for_dashes",
174
+ "verb" => "GET",
175
+ "headers" => { 'g-sub-me' => 'pop'}
176
+ }, response)
177
+
178
+ container = Mocktopus::InputContainer.new
179
+ container.add("input1", input)
180
+ match_result = container.match("/v0/test_headers_no_match_returns_nil_result_for_dashes", "GET", {'g_sub_me' => 'fizz'}, nil, nil)
181
+ assert_nil match_result
182
+ end
183
+
184
+ def test_single_match_no_inputs_returns_nil
185
+ container = Mocktopus::InputContainer.new
186
+ match_result = container.match("/v0/test_single_match_no_inputs_returns_nil", "POST", {}, JSON.pretty_generate({}), {})
187
+ assert_nil(match_result)
188
+ end
189
+
190
+ def test_multiple_inputs_returns_correct_sequence
191
+ response1 = Mocktopus::Response.new({
192
+ "code" => "200",
193
+ "headers" => {},
194
+ "body" => {
195
+ "status" => "pending"
196
+ }
197
+ })
198
+
199
+ response2 = Mocktopus::Response.new({
200
+ "code" => "200",
201
+ "headers" => {},
202
+ "body" => {
203
+ "status" => "complete"
204
+ }
205
+ })
206
+
207
+ input_hash = {
208
+ "uri" => "/v0/test_multiple_inputs_returns_correct_sequence",
209
+ "verb" => "GET",
210
+ "headers" => {},
211
+ "body" => nil
212
+ }
213
+
214
+ container = Mocktopus::InputContainer.new
215
+ container.add("first_input", Mocktopus::Input.new(input_hash, response1))
216
+ container.add("second_input", Mocktopus::Input.new(input_hash, response1))
217
+ container.add("last_input", Mocktopus::Input.new(input_hash, response2))
218
+
219
+ first_match = container.match("/v0/test_multiple_inputs_returns_correct_sequence", "GET", {}, "", {})
220
+ assert_equal(response1, first_match.response)
221
+
222
+ second_match = container.match("/v0/test_multiple_inputs_returns_correct_sequence", "GET", {}, "", {})
223
+ assert_equal(response1, second_match.response)
224
+
225
+ last_match = container.match("/v0/test_multiple_inputs_returns_correct_sequence", "GET", {}, "", {})
226
+ assert_equal(response2, last_match.response)
227
+ end
228
+
229
+ end