mocktopus 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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