rack-radar 0.0.1
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.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.md +283 -0
- data/Rakefile +14 -0
- data/lib/rack-radar.rb +1 -0
- data/lib/rack/radar.rb +127 -0
- data/lib/rack/radar/cookies.rb +128 -0
- data/lib/rack/radar/session.rb +190 -0
- data/rack-radar.gemspec +21 -0
- data/test/app_test.rb +52 -0
- data/test/auth_test.rb +150 -0
- data/test/cookies_test.rb +280 -0
- data/test/follow_redirect_test.rb +44 -0
- data/test/headers_test.rb +82 -0
- data/test/map_test.rb +64 -0
- data/test/params_test.rb +45 -0
- data/test/request_methods_test.rb +52 -0
- data/test/session_test.rb +42 -0
- data/test/test_setup.rb +162 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 23f9bc19a648ac577edf7b2f24c3e93ce31abb40
|
4
|
+
data.tar.gz: 5c2be6ea839fdfd69203e5bbac586f60b0ab5d1d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1addf480f19db25a66c20f7e9856bc943fccb79916d5eb0b29e3ffaf05590702fdc5b44dd792b3f4ca32333010306713a1f2a8deb653b8d9198637ddb8130771
|
7
|
+
data.tar.gz: fa05dc0ec99d8cb6a506b8f0655bd08d91865aefaf74048fb462bd2fcc0730a780464195d7b4bcaadb2a856e21395207f72ee6ddfc9a7e729b16caa10d2224f3
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Slee Woo <mail@sleewoo.com>
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
|
2
|
+
## Rack::Radar
|
3
|
+
|
4
|
+
**A simple API for testing Rack applications via Rack::MockRequest**<br>
|
5
|
+
*inspired by [rack-test](https://github.com/brynary/rack-test)*
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'rack-radar'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
```bash
|
19
|
+
$ bundle
|
20
|
+
```
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
```bash
|
25
|
+
$ gem install rack-radar
|
26
|
+
```
|
27
|
+
|
28
|
+
then load it using `require 'rack-radar'`
|
29
|
+
|
30
|
+
|
31
|
+
## Use
|
32
|
+
|
33
|
+
Simply `include Rack::Radar` in your tests.
|
34
|
+
|
35
|
+
## App
|
36
|
+
|
37
|
+
Call `app RackApp` inside testing suite to set app to be tested.
|
38
|
+
|
39
|
+
**Minitest Example:**
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
require 'rack-radar'
|
43
|
+
|
44
|
+
class MyTests < MiniTest::Unit::TestCase
|
45
|
+
|
46
|
+
include Rack::Radar
|
47
|
+
|
48
|
+
def setup
|
49
|
+
app MyRackApp
|
50
|
+
end
|
51
|
+
|
52
|
+
def test
|
53
|
+
get '/url'
|
54
|
+
assert_equal last_response.status, 200
|
55
|
+
end
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
Multiple apps can be tested within same suite.<br/>
|
60
|
+
Each app will run own session.
|
61
|
+
|
62
|
+
**Minitest Example:**
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
require 'rack-radar'
|
66
|
+
|
67
|
+
class MyTests < MiniTest::Unit::TestCase
|
68
|
+
|
69
|
+
include Rack::Radar
|
70
|
+
|
71
|
+
def setup
|
72
|
+
app MyRackApp
|
73
|
+
end
|
74
|
+
|
75
|
+
def test
|
76
|
+
# querying default app
|
77
|
+
get '/url'
|
78
|
+
assert_equal last_response.status, 200
|
79
|
+
|
80
|
+
# testing ForumApp
|
81
|
+
app ForumApp
|
82
|
+
get '/posts'
|
83
|
+
assert_equal last_response.status, 200
|
84
|
+
|
85
|
+
# back to default app
|
86
|
+
app MyRackApp
|
87
|
+
get '/url'
|
88
|
+
assert_equal last_response.status, 200
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
|
94
|
+
## Resetting App
|
95
|
+
|
96
|
+
Sometimes you need to start over with a new app in pristine state, i.e. no cookies, no headers etc.
|
97
|
+
|
98
|
+
To achieve this, simply call `reset_app!` (or `reset_browser!`).
|
99
|
+
|
100
|
+
## Requests
|
101
|
+
|
102
|
+
Use one of `get`, `post`, `put`, `patch`, `delete`, `options`, `head`
|
103
|
+
to make requests via Rack::Radar
|
104
|
+
|
105
|
+
To make a secure request, add `s_` prefix:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
s_get '/path'
|
109
|
+
s_post '/path'
|
110
|
+
# etc.
|
111
|
+
```
|
112
|
+
|
113
|
+
To make a request via XHR, aka Ajax, add `_x` suffix:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
get_x '/path'
|
117
|
+
post_x '/path'
|
118
|
+
# etc.
|
119
|
+
```
|
120
|
+
|
121
|
+
To make a secure request via XHR, add both `s_` and `_x`:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
s_get_x '/path'
|
125
|
+
s_post_x '/path'
|
126
|
+
# etc.
|
127
|
+
```
|
128
|
+
|
129
|
+
In terms of arguments, making HTTP requests via Rack::Radar is identical to calling regular Ruby methods.<br/>
|
130
|
+
That's it, you do not need to join parameters into a string.<br/>
|
131
|
+
Just pass them as usual arguments:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
post '/news', :create, :title => rand
|
135
|
+
post '/news', :update, id, :title => rand
|
136
|
+
get '/news', :delete, id
|
137
|
+
```
|
138
|
+
|
139
|
+
## Map
|
140
|
+
|
141
|
+
Previous example works just fine, however it is redundant and inconsistent.<br/>
|
142
|
+
Just imagine that tested app changed its base URL from /news to /headlines.
|
143
|
+
|
144
|
+
The solution is simple.<br/>
|
145
|
+
Use `map` to define a base URL that will be prepended to each request,<br/>
|
146
|
+
except ones starting with a slash or a protocol(http://, https:// etc.) of course.
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
app MyRackApp
|
150
|
+
map '/news'
|
151
|
+
|
152
|
+
post :create, :title => rand
|
153
|
+
post :update, id, :title => rand
|
154
|
+
get :delete, id
|
155
|
+
```
|
156
|
+
|
157
|
+
**Note:** requests starting with a slash or protocol(http://, https:// etc.)
|
158
|
+
wont use base URL defined by `map`.<br/>
|
159
|
+
|
160
|
+
**Note:** when you switching tested app, make sure you also change the map.
|
161
|
+
|
162
|
+
To disable mapping, simply call `map nil`
|
163
|
+
|
164
|
+
## Cookies
|
165
|
+
|
166
|
+
**Set cookies:**
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
cookies['name'] = 'value'
|
170
|
+
```
|
171
|
+
|
172
|
+
**Read cookies:**
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
cookie = cookies['name']
|
176
|
+
```
|
177
|
+
|
178
|
+
**Delete a cookie:**
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
cookies.delete 'name'
|
182
|
+
```
|
183
|
+
|
184
|
+
|
185
|
+
**Clear all cookies:**
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
cookies.clear
|
189
|
+
```
|
190
|
+
|
191
|
+
Each app uses its own cookies jar.
|
192
|
+
|
193
|
+
## Headers
|
194
|
+
|
195
|
+
Rack::Radar allow to set headers that will be sent to app on all consequent requests.
|
196
|
+
|
197
|
+
**Set headers:**
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
header['User-Agent'] = 'Rack::Radar'
|
201
|
+
header['Content-Type'] = 'text/plain'
|
202
|
+
header['rack.input'] = 'someString'
|
203
|
+
# etc.
|
204
|
+
```
|
205
|
+
|
206
|
+
**Read headers:**
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
header = headers['User-Agent']
|
210
|
+
# etc.
|
211
|
+
```
|
212
|
+
|
213
|
+
**Delete a header:**
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
headers.delete 'User-Agent'
|
217
|
+
```
|
218
|
+
|
219
|
+
**Clear all headers:**
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
headers.clear
|
223
|
+
```
|
224
|
+
|
225
|
+
Each app uses its own headers.
|
226
|
+
|
227
|
+
## Authorization
|
228
|
+
|
229
|
+
**Basic Auth:**
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
authorize 'user', 'pass'
|
233
|
+
```
|
234
|
+
|
235
|
+
**Reset earlier set Basic authorization header:**
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
reset_basic_auth!
|
239
|
+
```
|
240
|
+
|
241
|
+
**Digest Auth:**
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
digest_authorize 'user', 'pass'
|
245
|
+
```
|
246
|
+
|
247
|
+
**Reset earlier set Digest authorization header:**
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
reset_digest_auth!
|
251
|
+
```
|
252
|
+
|
253
|
+
**Reset ANY earlier set authorization header:**
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
reset_auth!
|
257
|
+
```
|
258
|
+
|
259
|
+
## Follow Redirects
|
260
|
+
|
261
|
+
By default, Rack::Radar wont follow redirects.
|
262
|
+
|
263
|
+
If last response is a redirect and you want Rack::Radar to follow it, use `follow_redirect!`
|
264
|
+
|
265
|
+
|
266
|
+
## Contributors
|
267
|
+
|
268
|
+
Want to contribute? Great! Contributors highly wanted and welcome!
|
269
|
+
|
270
|
+
1. Fork it
|
271
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
272
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
273
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
274
|
+
5. Create new Pull Request
|
275
|
+
|
276
|
+
|
277
|
+
## License
|
278
|
+
|
279
|
+
Copyright © 2014 Slee Woo <mail@sleewoo.com>
|
280
|
+
|
281
|
+
Distributed under the **[MIT License](https://github.com/sleewoo/rack-radar/blob/master/LICENSE)**
|
282
|
+
|
283
|
+
|
data/Rakefile
ADDED
data/lib/rack-radar.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rack/radar'
|
data/lib/rack/radar.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'rack'
|
4
|
+
|
5
|
+
module Rack
|
6
|
+
module Radar
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
RACK_RADAR__REQUEST_METHODS = %w[
|
10
|
+
GET
|
11
|
+
POST
|
12
|
+
PUT
|
13
|
+
PATCH
|
14
|
+
DELETE
|
15
|
+
OPTIONS
|
16
|
+
HEAD
|
17
|
+
TRACE
|
18
|
+
LINK
|
19
|
+
UNLINK
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
%w[
|
23
|
+
header headers cookies last_request last_response
|
24
|
+
auth authorize basic_authorize digest_auth digest_authorize token_auth token_authorize
|
25
|
+
reset_auth! reset_basic_auth! reset_digest_auth! reset_token_auth!
|
26
|
+
].each do |m|
|
27
|
+
def_delegator :__r__session, m
|
28
|
+
end
|
29
|
+
|
30
|
+
RACK_RADAR__DEFAULT_HOST = 'rack.radar'.freeze
|
31
|
+
RACK_RADAR__DEFAULT_ENV = {
|
32
|
+
'REMOTE_ADDR' => '127.0.0.1',
|
33
|
+
'HTTP_HOST' => RACK_RADAR__DEFAULT_HOST
|
34
|
+
}.freeze
|
35
|
+
RACK_RADAR__XHR_KEY = 'HTTP_X_REQUESTED_WITH'.freeze
|
36
|
+
RACK_RADAR__XHR_VAL = 'XMLHttpRequest'.freeze
|
37
|
+
|
38
|
+
# switch session
|
39
|
+
#
|
40
|
+
# Rack::Radar using app based sessions, that's it, creates sessions based on app __id__.
|
41
|
+
# you can test various apps by using `app RackApp` to switch between them.
|
42
|
+
#
|
43
|
+
def app app = nil
|
44
|
+
if block_given?
|
45
|
+
@__r__app = yield
|
46
|
+
elsif app
|
47
|
+
@__r__app = app
|
48
|
+
end
|
49
|
+
@__r__app
|
50
|
+
end
|
51
|
+
|
52
|
+
def map *args
|
53
|
+
@__r__base_url = args[0] if args.size > 0
|
54
|
+
@__r__base_url
|
55
|
+
end
|
56
|
+
|
57
|
+
def env
|
58
|
+
@__r__env ||= {}
|
59
|
+
end
|
60
|
+
|
61
|
+
def params
|
62
|
+
@__r__params ||= {}
|
63
|
+
end
|
64
|
+
|
65
|
+
def session
|
66
|
+
env["rack.session"] ||= {}
|
67
|
+
end
|
68
|
+
|
69
|
+
# reset session for current app.
|
70
|
+
# everything will be reset - cookies, headers, authorizations etc.
|
71
|
+
def reset_app!
|
72
|
+
__r__session :reset
|
73
|
+
end
|
74
|
+
|
75
|
+
alias reset_browser! reset_app!
|
76
|
+
|
77
|
+
RACK_RADAR__REQUEST_METHODS.each do |request_method|
|
78
|
+
define_method request_method.downcase do |*args|
|
79
|
+
request(:http, request_method, *args)
|
80
|
+
end
|
81
|
+
# secure
|
82
|
+
define_method 's_%s' % request_method.downcase do |*args|
|
83
|
+
request(:https, request_method, *args)
|
84
|
+
end
|
85
|
+
# xhr
|
86
|
+
define_method '%s_x' % request_method.downcase do |*args|
|
87
|
+
__r__with_xhr { request(:http, request_method, *args) }
|
88
|
+
end
|
89
|
+
# secure xhr
|
90
|
+
define_method 's_%s_x' % request_method.downcase do |*args|
|
91
|
+
__r__with_xhr { request(:https, request_method, *args) }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def request scheme, request_method, *args
|
96
|
+
rest, path = args.partition {|a| a.is_a?(Hash)}
|
97
|
+
params = self.params.merge(rest[0] || {})
|
98
|
+
env = self.env.merge(rest[1] || {})
|
99
|
+
__r__session.invoke_request(scheme, request_method, @__r__base_url, path, params, env)
|
100
|
+
end
|
101
|
+
|
102
|
+
def follow_redirect!
|
103
|
+
last_response.redirect? || raise(RuntimeError, 'Last response is not an redirect!')
|
104
|
+
scheme = last_request.env['HTTPS'] == 'on' ? 'https' : 'http'
|
105
|
+
request(scheme, 'GET', [last_response['Location']], {}, {
|
106
|
+
'HTTP_REFERER' => last_request.url,
|
107
|
+
'rack.session' => last_request.env['rack.session'],
|
108
|
+
'rack.session.options' => last_request.env['rack.session.options']
|
109
|
+
})
|
110
|
+
end
|
111
|
+
|
112
|
+
def __r__session reset = false
|
113
|
+
(@__r__session ||= {})[app.__id__] = RackRadarSession.new(app) if reset
|
114
|
+
(@__r__session ||= {})[app.__id__] ||= RackRadarSession.new(app)
|
115
|
+
end
|
116
|
+
|
117
|
+
def __r__with_xhr
|
118
|
+
env_xhr = env.has_key?(RACK_RADAR__XHR_KEY) && env[RACK_RADAR__XHR_KEY]
|
119
|
+
env[RACK_RADAR__XHR_KEY] = RACK_RADAR__XHR_VAL unless env_xhr == RACK_RADAR__XHR_VAL
|
120
|
+
yield
|
121
|
+
env[RACK_RADAR__XHR_KEY] = env_xhr if env_xhr
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
require 'rack/radar/cookies'
|
127
|
+
require 'rack/radar/session'
|