blix-rest 0.1.30

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'cucumber'
4
+ require 'blix/rest'
5
+ require 'blix/rest/cucumber/world'
6
+ require 'blix/rest/cucumber/hooks'
7
+ require 'blix/rest/cucumber/request_steps'
8
+ require 'blix/rest/cucumber/resource_steps'
@@ -0,0 +1,5 @@
1
+ Before do
2
+ #@_app = Blix::Rest::Server.new
3
+ #@_srv = Rack::MockRequest.new(@_app)
4
+ Blix::Rest::RequestMapper.set_path_root(nil)
5
+ end
@@ -0,0 +1,207 @@
1
+ #========== requests with tokens
2
+
3
+ Given(/^(.*?) requests token for service "(.*?)"$/) do |user,service|
4
+ path = "/myservices/" + service + "/token"
5
+ send_request('POST',user,path,nil)
6
+ @_token = valid_response.data["token"]
7
+ end
8
+
9
+ Given(/^(.*?) validates the token for service "(.*?)"$/) do |user,service|
10
+ path = "/services/" + service + "/validate/" + @_token
11
+ send_request('GET',user,path,nil)
12
+ end
13
+
14
+
15
+ # Given(/^guest gets "(.*?)"( .*)?$/) do |path,condition|
16
+ # path = add_token_to_path(path,@_token) if condition == " with token"
17
+ # send_request('GET',"guest",path,nil)
18
+ # end
19
+
20
+ # general requests
21
+
22
+ Given(/^(.*?) gets ["'](.*?)["']( with token)?$/) do |user, path, condition|
23
+ path = add_token_to_path(path,@_token) if condition == " with token"
24
+ send_request('GET',user,path,nil)
25
+ end
26
+
27
+ Given(/^(.*?) options ["'](.*?)["']( with token)?$/) do |user, path, condition|
28
+ path = add_token_to_path(path,@_token) if condition == " with token"
29
+ send_request('OPTIONS',user,path,nil)
30
+ end
31
+
32
+ Given(/^(.*?) posts ["'](.*?)["'] with (.*?)$/) do |user, path, json|
33
+ send_request('POST',user,path,json)
34
+ end
35
+
36
+ # doc string version
37
+ Given(/^(.*?) posts ["'](.*?)["'] with$/) do |user, path, json|
38
+ send_request('POST',user,path,json)
39
+ end
40
+
41
+ Given(/^(.*?) deletes ["'](.*?)["']$/) do |user, path|
42
+ send_request('DELETE',user,path,nil)
43
+ end
44
+
45
+ Given(/^(.*?) puts ["'](.*?)["'] with (.*?)$/) do |user, path, json|
46
+ send_request('PUT',user,path,json)
47
+ end
48
+
49
+ # doc string version
50
+ Given(/^(.*?) puts ["'](.*?)["'] with$/) do |user, path, json|
51
+ send_request('PUT',user,path,json)
52
+ end
53
+
54
+ # alternative format
55
+
56
+ Given(/^I am (.*?)$/) do | string |
57
+ @_current_user = string.split(' ')[-1]
58
+ end
59
+
60
+ Given(/^I get ["'](.*?)["']$/) do |path|
61
+ send_request('GET',@_current_user,path,nil)
62
+ end
63
+
64
+ Given(/^I post ["'](.*?)["'] with (.*?)$/) do |path, json|
65
+ send_request('POST',@_current_user,path,json)
66
+ end
67
+
68
+ Given(/^I delete ["'](.*?)["']$/) do | path|
69
+ send_request('DELETE',@_current_user,path,nil)
70
+ end
71
+
72
+ Given(/^I put ["'](.*?)["'] with (.*?)$/) do |path, json|
73
+ send_request('PUT',@_current_user,path,json)
74
+ end
75
+
76
+ # response steps ==============================
77
+
78
+ Then(/^the status should be (\d+)$/) do |code|
79
+ expect(valid_response.status).to eq code.to_i
80
+ end
81
+
82
+ Then(/^there should be an error$/) do
83
+ expect(valid_response.status.to_s[0,1]).not_to eq '2'
84
+ expect(valid_response.error).not_to be_nil
85
+ end
86
+
87
+ Then(/^the error message should include ["'](.*?)["']$/) do |field|
88
+ expect(valid_response.error && (valid_response.error =~ %r/#{field}/)).to_not be nil
89
+ end
90
+
91
+ Given(/^explain$/) do
92
+ explain
93
+ end
94
+
95
+ Then(/^the data type should be ["'](.*?)["']$/) do |type|
96
+ if valid_response.data.kind_of? Array
97
+ expect(valid_response.data[0]["_type"]).to eq type
98
+ else
99
+ expect(valid_response.data["_type"]).to eq type
100
+ end
101
+ end
102
+
103
+
104
+ Then(/^the data length should be (\d+)$/) do |len|
105
+ if valid_response.data.kind_of? Array
106
+ expect(valid_response.data.length).to eq len.to_i
107
+ else
108
+ 1
109
+ end
110
+ end
111
+
112
+ Then(/^the data length should equal (\d+)$/) do |len|
113
+ if valid_response.data.kind_of? Array
114
+ expect(valid_response.data.length).to eq len.to_i
115
+ else
116
+ 1
117
+ end
118
+ end
119
+
120
+ Then(/^the data "(.*?)" should == (.*?)$/) do |field,val|
121
+ if valid_data.kind_of? Array
122
+ data = valid_data[0]
123
+ else
124
+ data = valid_data
125
+ end
126
+ v = data[field].to_s
127
+
128
+ if val =~ %r{^@([^@]*)$}
129
+ expect(v).to eq store[$1].to_s
130
+ elsif val =~ %r{^(::)?[A-Z][A-z_a-z:]*$}
131
+ expect(v).to eq Module.const_get(val).to_s
132
+ elsif val =~ %r{^['"](.*)['"]$}
133
+ expect(v).to eq $1
134
+ end
135
+
136
+ end
137
+
138
+ Then(/^the data "(.*?)" should equal ["'](.*?)["']$/) do |field,val|
139
+ if valid_response.data.kind_of? Array
140
+ data = valid_response.data[0]
141
+ else
142
+ data = valid_response.data
143
+ end
144
+ expect(data[field].to_s).to eq val
145
+ end
146
+
147
+ Then(/^the data ["'](.*?)["'] should == nil$/) do |field|
148
+ if valid_response.data.kind_of? Array
149
+ data = valid_response.data[0]
150
+ else
151
+ data = valid_response.data
152
+ end
153
+ expect(data[field]).to be nil
154
+ end
155
+
156
+ Then(/^the data ["'](.*?)["'] should equal nil$/) do |field|
157
+ if valid_response.data.kind_of? Array
158
+ data = valid_response.data[0]
159
+ else
160
+ data =valid_response.data
161
+ end
162
+ expect(data[field]).to be nil
163
+ end
164
+
165
+ Then(/^the body should eq ["'](.*?)["']$/) do |val|
166
+ val.gsub!("\\n","\n")
167
+ expect(valid_response.body).to eq val
168
+ end
169
+
170
+
171
+
172
+ Then(/^the data should( not)? include ["'](.*?)["']$/) do |state, field|
173
+ if valid_response.data.kind_of? Array
174
+ data = valid_response.data[0]
175
+ else
176
+ data = valid_response.data
177
+ end
178
+ if state == " not"
179
+ expect(data.key?(field)).to eq false
180
+ else
181
+ expect(data.key?(field)).to eq true
182
+ end
183
+ end
184
+
185
+
186
+
187
+ Then(/^store the ["'](.*?)["'] as ["'](.*?)["']$/) do |name,key|
188
+ if valid_response.data.kind_of?(Array)
189
+ data = valid_response.data[0]
190
+ else
191
+ data = valid_response.data
192
+ end
193
+ if data.kind_of?(Hash) && data.key?(name)
194
+ store[key] = data[name]
195
+ end
196
+ end
197
+
198
+ Given(/^save the "([^"]*)"$/) do |name|
199
+ if valid_response.data.kind_of?(Array)
200
+ data = valid_response.data[0]
201
+ else
202
+ data = valid_response.data
203
+ end
204
+ if data.kind_of?(Hash) && data.key?(name)
205
+ store[name] = data[name]
206
+ end
207
+ end
@@ -0,0 +1,28 @@
1
+ class UserHash < Hash
2
+ def set(k,v)
3
+ self[k.to_s] = v
4
+ end
5
+
6
+ def get(k)
7
+ self[k.to_s]
8
+ end
9
+ end
10
+
11
+ Given(/^the following users exist:$/) do |table|
12
+ table.hashes.each do |h|
13
+
14
+ name = h["name"] || h["login"]
15
+
16
+ next if name=="guest"
17
+
18
+ u = UserHash.new.merge!(h)
19
+
20
+
21
+
22
+ u.set(:pw,h["secret"] || h["password"] || name+"@12345678")
23
+
24
+ before_user_create(u,h)
25
+ users[name] = u
26
+ after_user_create(u,h)
27
+ end
28
+ end
@@ -0,0 +1,273 @@
1
+ # the step definitions are executed in an instance of world so
2
+ # we can add helper methods for use in the step definitions.
3
+
4
+ class RestWorld
5
+ # the entry point to the rack application to be tested
6
+ def self.app
7
+ @_app ||= Rack::Builder.parse_file('config.ru').first
8
+ end
9
+
10
+ # a dummy request to sent to the server
11
+ def self.request
12
+ @_req ||= Rack::MockRequest.new(app)
13
+ end
14
+
15
+ # a class to represent a response from the server
16
+ class Response
17
+ def initialize(resp)
18
+ @resp = resp
19
+ if @resp.header['Content-Type'] == 'application/json'
20
+ begin
21
+ @h = MultiJson.load(@resp.body) || {}
22
+ rescue Exception => e
23
+ puts 'INVALID RESPONSE BODY=>' + @resp.body
24
+ raise
25
+ end
26
+ else
27
+ @h = { 'html' => @resp.body }
28
+ end
29
+
30
+ # get_ids_from_hash
31
+ end
32
+
33
+ def [](k)
34
+ @h[k]
35
+ end
36
+
37
+ def body
38
+ @resp.body
39
+ end
40
+
41
+ def data
42
+ @h['data']
43
+ end
44
+
45
+ def error
46
+ @h['error']
47
+ end
48
+
49
+ def status
50
+ @resp.status.to_i
51
+ end
52
+
53
+ def header
54
+ @resp.header || {}
55
+ end
56
+
57
+ def content_type
58
+ header['Content-Type']
59
+ end
60
+
61
+ def inspect
62
+ @resp.inspect
63
+ end
64
+ end
65
+
66
+ # store cookies for each user here
67
+ def cookies
68
+ @_cookies ||= {}
69
+ @_cookies[@_current_user] ||= []
70
+ end
71
+
72
+ # store current user information here
73
+ def users
74
+ @_users ||= {}
75
+ end
76
+
77
+ # store current user tokens here
78
+ def tokens
79
+ @_tokens ||= {}
80
+ end
81
+
82
+ # store general information here
83
+ def store
84
+ @_store ||= {}
85
+ end
86
+
87
+ def valid_response
88
+ @_response || raise('no valid response from service')
89
+ end
90
+
91
+ def valid_data
92
+ @_response && @_response.data || raise("no valid data returned from service:#{@_response.error}")
93
+ end
94
+
95
+ def explain
96
+ puts "request ==> #{@_verb} #{@_request}"
97
+ puts "cookies ==> #{cookies.join('; ')}" if cookies.length > 0
98
+ puts "body ==> #{@_body}" if @_body
99
+ puts "response ==> #{@_response.inspect}"
100
+ end
101
+
102
+ def before_parse_path(path); end
103
+
104
+ def before_parse_body(json); end
105
+
106
+ def parse_path(path)
107
+ path = path.dup
108
+
109
+ before_parse_path(path)
110
+
111
+ path = path.gsub /\/(@[a-z0-9_]+)/ do |str|
112
+ str = str[2..-1]
113
+ id = store[str]
114
+ raise ":#{str} has not been stored" unless id
115
+ if id[0] == '/'
116
+ "#{id}"
117
+ else
118
+ "/#{id}"
119
+ end
120
+ end
121
+ # and the query part
122
+ path.gsub /\=(@[a-z0-9_]+)/ do |str|
123
+ str = str[2..-1]
124
+ id = store[str]
125
+ raise ":#{str} has not been stored" unless id
126
+
127
+ "=#{id}"
128
+ end
129
+ end
130
+
131
+ def parse_json(json)
132
+ # replace original format
133
+ json = json.gsub /:@([a-z0-9_]+)/ do |str|
134
+ str = str[2..-1]
135
+ id = store[str]
136
+ raise ":#{str} has not been stored" unless id
137
+
138
+ if id.is_a?(String)
139
+ ":\"#{id}\""
140
+ else
141
+ ":#{id}"
142
+ end
143
+ end
144
+
145
+ # replace alternative format
146
+ json = json.gsub /#\{([a-z0-9_]+)\}/ do |str|
147
+ str = str[2..-2]
148
+ id = store[str]
149
+ raise ":#{str} has not been stored" unless id
150
+
151
+ if id.is_a?(String)
152
+ "\"#{id}\""
153
+ else
154
+ "#{id}"
155
+ end
156
+ end
157
+ end
158
+
159
+ def parse_body(json)
160
+ json = json.dup
161
+ before_parse_body(json)
162
+ parse_json(json)
163
+ end
164
+
165
+ def add_token_to_request
166
+ return if @_request.include?('token=')
167
+ if @_user
168
+ token = @_user.get(:token) || "token12345678-#{@_user.get(:login)}"
169
+ @_request = if @_request.include?('?')
170
+ @_request + "&token=#{token}"
171
+ else
172
+ @_request + "?token=#{token}"
173
+ end
174
+ end
175
+ end
176
+
177
+ def add_token_to_path(path,token)
178
+ return unless token
179
+ if path.include?('?')
180
+ path + "&token=" + token
181
+ else
182
+ path + "?token=" + token
183
+ end
184
+ end
185
+
186
+ def rack_request_headers
187
+ env = {}
188
+ env['REMOTE_ADDR'] = '10.0.0.1'
189
+ env['HTTP_COOKIE'] = cookies.join('; ')
190
+ env["HTTP_AUTHORIZATION"] = @_auth if @_auth
191
+ env["HTTP_HOST"] = @_host if @_host
192
+ env
193
+ end
194
+
195
+ def request
196
+ RestWorld.request
197
+ end
198
+
199
+ def set_host(name)
200
+ @_host = name
201
+ end
202
+
203
+ def set_auth_headers(user)
204
+ raise "invalid user name:#{user}" unless u = users[user]
205
+ pw = u.get(:pw)
206
+ raise "iuser name:#{user} has no password!" unless pw
207
+ str = user + ":" + pw
208
+ str = Base64.encode64(str)
209
+ str = "Basic " + str
210
+ #Rack::MockRequest::DEFAULT_ENV["HTTP_AUTHORIZATION"] = str
211
+ @_auth = str
212
+ end
213
+
214
+ # save the response for furthur enquiries and store any cookies.
215
+ def handle_response(raw_response)
216
+ @_auth = nil
217
+ @_response = Response.new(raw_response)
218
+ # add cookies to the cookie jar.
219
+ #unless @_current_user=="guest"
220
+ if cookie = @_response.header["Set-Cookie"]
221
+ parts = cookie.split(';')
222
+ cookies << parts[0].strip
223
+ end
224
+ #end
225
+ end
226
+
227
+ def parse_user(user)
228
+ user.split(' ')[-1]
229
+ end
230
+
231
+ def send_request(verb, username, path, json)
232
+ username = parse_user(username)
233
+ @_verb = verb
234
+ @_body = json && parse_body(json)
235
+ @_request = parse_path(path)
236
+ @_current_user = username
237
+
238
+ if username == 'guest'
239
+ @_user = nil
240
+ else
241
+ @_user = users[username]
242
+ raise "user :#{username} has not been initialized" unless @_user
243
+
244
+ pw = @_user.get(:pw)
245
+ add_token_to_request
246
+ set_auth_headers(username)
247
+ end
248
+ case verb
249
+ when 'GET'
250
+ handle_response(request.get(@_request, rack_request_headers))
251
+ when 'OPTIONS'
252
+ handle_response(request.options(@_request, rack_request_headers))
253
+ when 'POST'
254
+ handle_response(request.post(@_request, rack_request_headers.merge(input: @_body)))
255
+ when 'PUT'
256
+ handle_response(request.put(@_request, rack_request_headers.merge(input: @_body)))
257
+ when 'DELETE'
258
+ handle_response(request.delete(@_request, rack_request_headers.merge(input: @_body)))
259
+ end
260
+ end
261
+
262
+ # a hook that is called before creating a user
263
+ def before_user_create(user, hash); end
264
+
265
+ # a hook that is called before creating a user
266
+ def after_user_create(user, hash); end
267
+ end
268
+
269
+
270
+
271
+ World do
272
+ RestWorld.new
273
+ end