rack-test_app 1.0.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE.txt +21 -0
- data/README.md +122 -0
- data/Rakefile +49 -0
- data/lib/rack/test_app.rb +487 -0
- data/rack-test_app.gemspec +31 -0
- data/test/rack/test_app/MultipartBuilder_test.rb +158 -0
- data/test/rack/test_app/Result_test.rb +184 -0
- data/test/rack/test_app/TestApp_test.rb +238 -0
- data/test/rack/test_app/Util_test.rb +168 -0
- data/test/rack/test_app/Wrapper_test.rb +182 -0
- data/test/rack/test_app/data/example1.jpg +0 -0
- data/test/rack/test_app/data/example1.png +0 -0
- data/test/rack/test_app/data/multipart.form +0 -0
- data/test/test_helper.rb +4 -0
- metadata +116 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rack/test_app'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rack-test_app"
|
8
|
+
spec.version = Rack::TestApp::VERSION
|
9
|
+
spec.authors = ["makoto kuwata"]
|
10
|
+
spec.email = ["kwa@kuwata-lab.com"]
|
11
|
+
spec.summary = "more intuitive testing helper library for Rack app"
|
12
|
+
spec.description = <<END
|
13
|
+
Rack::TestApp is another testing helper library for Rack application.
|
14
|
+
IMO it is more intuitive than Rack::Test.
|
15
|
+
END
|
16
|
+
spec.homepage = "https://github.com/kwatch/rack-test_app"
|
17
|
+
spec.license = "MIT-LICENCE"
|
18
|
+
spec.files = Dir[*%w[
|
19
|
+
README.md MIT-LICENSE.txt Rakefile rack-test_app.gemspec
|
20
|
+
lib/rack/test_app.rb
|
21
|
+
test/test_helper.rb
|
22
|
+
test/rack/**/*_test.rb
|
23
|
+
test/rack/test_app/data/**/*.*
|
24
|
+
]]
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
spec.required_ruby_version = '>= 2.0'
|
27
|
+
spec.add_runtime_dependency 'rack'
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
29
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
30
|
+
spec.add_development_dependency "minitest"
|
31
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
###
|
4
|
+
### $Release: 1.0.0 $
|
5
|
+
### $Copyright: copyright(c) 2015 kuwata-lab.com all rights reserved $
|
6
|
+
### $License: MIT License $
|
7
|
+
###
|
8
|
+
|
9
|
+
|
10
|
+
require_relative '../../test_helper'
|
11
|
+
|
12
|
+
require 'tempfile'
|
13
|
+
require 'rack/multipart'
|
14
|
+
require 'rack/mock'
|
15
|
+
require 'rack/request'
|
16
|
+
|
17
|
+
|
18
|
+
describe Rack::TestApp::MultipartBuilder do
|
19
|
+
|
20
|
+
|
21
|
+
describe '#initialize()' do
|
22
|
+
|
23
|
+
it "[!ajfgl] sets random string as boundary when boundary is nil." do
|
24
|
+
arr = []
|
25
|
+
1000.times do
|
26
|
+
mp = Rack::TestApp::MultipartBuilder.new(nil)
|
27
|
+
refute_nil mp.boundary
|
28
|
+
assert_kind_of String, mp.boundary
|
29
|
+
arr << mp.boundary
|
30
|
+
end
|
31
|
+
assert_equal 1000, arr.sort.uniq.length
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
describe '#add()' do
|
38
|
+
|
39
|
+
it "[!tp4bk] detects content type from filename when filename is not nil." do
|
40
|
+
mp = Rack::TestApp::MultipartBuilder.new
|
41
|
+
mp.add("name1", "value1")
|
42
|
+
mp.add("name2", "value2", "foo.csv")
|
43
|
+
mp.add("name3", "value3", "bar.csv", "text/plain")
|
44
|
+
expected = [
|
45
|
+
["name1", "value1", nil, nil],
|
46
|
+
#["name2", "value2", "foo.csv", "text/comma-separated-values"],
|
47
|
+
["name2", "value2", "foo.csv", "text/csv"],
|
48
|
+
["name3", "value3", "bar.csv", "text/plain"],
|
49
|
+
]
|
50
|
+
assert_equal expected, mp.instance_variable_get('@params')
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
describe '#add_file()' do
|
57
|
+
|
58
|
+
data_dir = File.join(File.dirname(__FILE__), 'data')
|
59
|
+
filename1 = File.join(data_dir, 'example1.png')
|
60
|
+
filename2 = File.join(data_dir, 'example1.jpg')
|
61
|
+
datafile = File.join(data_dir, 'multipart.form')
|
62
|
+
multipart_data = File.open(datafile, 'rb') {|f| f.read }
|
63
|
+
|
64
|
+
it "[!uafqa] detects content type from filename when content type is not provided." do
|
65
|
+
file1 = File.open(filename1)
|
66
|
+
file2 = File.open(filename2)
|
67
|
+
begin
|
68
|
+
mp = Rack::TestApp::MultipartBuilder.new
|
69
|
+
mp.add_file('image1', file1)
|
70
|
+
mp.add_file('image2', file2)
|
71
|
+
params = mp.instance_variable_get('@params')
|
72
|
+
assert_equal "example1.png" , params[0][2]
|
73
|
+
assert_equal "image/png" , params[0][3]
|
74
|
+
assert_equal "example1.jpg" , params[1][2]
|
75
|
+
assert_equal "image/jpeg" , params[1][3]
|
76
|
+
ensure
|
77
|
+
[file1, file2].each {|f| f.close() unless f.closed? }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "[!b5811] reads file content and adds it as param value." do
|
82
|
+
file1 = File.open(filename1)
|
83
|
+
file2 = File.open(filename2)
|
84
|
+
begin
|
85
|
+
boundary = '---------------------------68927884511827559971471404947'
|
86
|
+
mp = Rack::TestApp::MultipartBuilder.new(boundary)
|
87
|
+
mp.add('text1', "test1")
|
88
|
+
mp.add('text2', "日本語\r\nあいうえお\r\n")
|
89
|
+
mp.add_file('file1', file1)
|
90
|
+
mp.add_file('file2', file2)
|
91
|
+
expected = multipart_data
|
92
|
+
assert expected, mp.to_s
|
93
|
+
ensure
|
94
|
+
[file1, file2].each {|f| f.close() unless f.closed? }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "[!36bsu] closes opened file automatically." do
|
99
|
+
file1 = File.open(filename1)
|
100
|
+
file2 = File.open(filename2)
|
101
|
+
begin
|
102
|
+
assert_equal false, file1.closed?
|
103
|
+
assert_equal false, file2.closed?
|
104
|
+
mp = Rack::TestApp::MultipartBuilder.new()
|
105
|
+
mp.add_file('file1', file1)
|
106
|
+
mp.add_file('file2', file2)
|
107
|
+
assert_equal true, file1.closed?
|
108
|
+
assert_equal true, file2.closed?
|
109
|
+
ensure
|
110
|
+
[file1, file2].each {|f| f.close() unless f.closed? }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
describe '#to_s()' do
|
118
|
+
|
119
|
+
it "[!61gc4] returns multipart form string." do
|
120
|
+
mp = Rack::TestApp::MultipartBuilder.new("abc123")
|
121
|
+
mp.add("name1", "value1")
|
122
|
+
mp.add("name2", "value2", "foo.txt", "text/plain")
|
123
|
+
s = mp.to_s
|
124
|
+
expected = [
|
125
|
+
"--abc123\r\n",
|
126
|
+
"Content-Disposition: form-data; name=\"name1\"\r\n",
|
127
|
+
"\r\n",
|
128
|
+
"value1\r\n",
|
129
|
+
"--abc123\r\n",
|
130
|
+
"Content-Disposition: form-data; name=\"name2\"; filename=\"foo.txt\"\r\n",
|
131
|
+
"Content-Type: text/plain\r\n",
|
132
|
+
"\r\n",
|
133
|
+
"value2\r\n",
|
134
|
+
"--abc123--\r\n",
|
135
|
+
].join()
|
136
|
+
s = mp.to_s
|
137
|
+
assert_equal expected, s
|
138
|
+
#
|
139
|
+
opts = {
|
140
|
+
:method => "POST",
|
141
|
+
:input => s,
|
142
|
+
"CONTENT_TYPE" => "multipart/form-data; boundary=abc123",
|
143
|
+
"CONTENT_LENGTH" => s.bytesize,
|
144
|
+
}
|
145
|
+
env = Rack::MockRequest.env_for('http://localhost/form', opts)
|
146
|
+
req = Rack::Request.new(env)
|
147
|
+
params = req.POST
|
148
|
+
assert_equal "value1", params["name1"]
|
149
|
+
assert_equal "name2", params["name2"][:name]
|
150
|
+
assert_equal "foo.txt", params["name2"][:filename]
|
151
|
+
assert_equal "text/plain", params["name2"][:type]
|
152
|
+
assert_kind_of Tempfile, params["name2"][:tempfile]
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
###
|
4
|
+
### $Release: 1.0.0 $
|
5
|
+
### $Copyright: copyright(c) 2015 kuwata-lab.com all rights reserved $
|
6
|
+
### $License: MIT License $
|
7
|
+
###
|
8
|
+
|
9
|
+
|
10
|
+
require_relative '../../test_helper'
|
11
|
+
|
12
|
+
|
13
|
+
describe Rack::TestApp::Result do
|
14
|
+
|
15
|
+
|
16
|
+
describe '#initialize()' do
|
17
|
+
|
18
|
+
it "[!3lcsj] accepts response status, headers and body." do
|
19
|
+
r = Rack::TestApp::Result.new(200, {"Content-Type"=>"text/plain"}, ["Hello"])
|
20
|
+
assert 200, r.status
|
21
|
+
assert({"Content-Type"=>"text/plain"}, r.headers)
|
22
|
+
assert ["Hello"], r.body
|
23
|
+
end
|
24
|
+
|
25
|
+
it "[!n086q] parses 'Set-Cookie' header." do
|
26
|
+
headers = {
|
27
|
+
"Content-Type"=>"text/plain",
|
28
|
+
"Set-Cookie"=>("key1=value1; Path=/; Domain=example.com; HttpOnly; Secure\n" +
|
29
|
+
"key2=value2"),
|
30
|
+
}
|
31
|
+
expected = {
|
32
|
+
'key1' => {
|
33
|
+
:name => 'key1',
|
34
|
+
:value => 'value1',
|
35
|
+
:path => '/',
|
36
|
+
:domain => 'example.com',
|
37
|
+
:httponly => true,
|
38
|
+
:secure => true,
|
39
|
+
},
|
40
|
+
'key2' => {
|
41
|
+
:name => 'key2',
|
42
|
+
:value => 'value2',
|
43
|
+
},
|
44
|
+
}
|
45
|
+
r = Rack::TestApp::Result.new(200, headers, ["Hello"])
|
46
|
+
assert_equal expected, r.cookies
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
describe '#body_binary' do
|
53
|
+
|
54
|
+
it "[!mb0i4] returns body as binary string." do
|
55
|
+
r = Rack::TestApp::Result.new(200, {}, ["Hello"])
|
56
|
+
assert_equal "Hello", r.body_binary
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
describe '#body_text' do
|
63
|
+
|
64
|
+
it "[!vkj9h] returns body as text string, according to 'charset' in 'Content-Type'." do
|
65
|
+
headers = {'Content-Type' => 'text/plain; charset=utf-8'}
|
66
|
+
r = Rack::TestApp::Result.new(200, headers, ["Hello"])
|
67
|
+
assert_equal "Hello", r.body_text
|
68
|
+
end
|
69
|
+
|
70
|
+
it "[!rr18d] error when 'Content-Type' header is missing." do
|
71
|
+
headers = {}
|
72
|
+
r = Rack::TestApp::Result.new(200, headers, ["Hello"])
|
73
|
+
ex = assert_raises(TypeError) { r.body_text }
|
74
|
+
assert_equal "body_text(): missing 'Content-Type' header.", ex.message
|
75
|
+
end
|
76
|
+
|
77
|
+
it "[!dou1n] converts body text according to 'charset' in 'Content-Type' header." do
|
78
|
+
headers = {'Content-Type' => 'text/plain; charset=utf-8'}
|
79
|
+
binary = "\u3042\u3044\u3046\u3048\u304A"
|
80
|
+
assert_equal binary, "あいうえお".encode('utf-8')
|
81
|
+
r = Rack::TestApp::Result.new(200, headers, [binary])
|
82
|
+
assert_equal "あいうえお", r.body_text
|
83
|
+
assert_equal 'UTF-8', r.body_text.encoding.name
|
84
|
+
end
|
85
|
+
|
86
|
+
it "[!cxje7] assumes charset as 'utf-8' when 'Content-Type' is json." do
|
87
|
+
headers = {'Content-Type' => 'application/json'}
|
88
|
+
binary = %Q`{"msg":"\u3042\u3044\u3046\u3048\u304A"}`
|
89
|
+
assert_equal binary, %Q`{"msg":"あいうえお"}`.encode('utf-8')
|
90
|
+
r = Rack::TestApp::Result.new(200, headers, [binary])
|
91
|
+
assert_equal %Q`{"msg":"あいうえお"}`, r.body_text
|
92
|
+
assert_equal 'UTF-8', r.body_text.encoding.name
|
93
|
+
end
|
94
|
+
|
95
|
+
it "[!n4c71] error when non-json 'Content-Type' header has no 'charset'." do
|
96
|
+
headers = {'Content-Type' => 'text/plain'}
|
97
|
+
binary = "\u3042\u3044\u3046\u3048\u304A"
|
98
|
+
assert_equal binary, "あいうえお".encode('utf-8')
|
99
|
+
r = Rack::TestApp::Result.new(200, headers, [binary])
|
100
|
+
ex = assert_raises(TypeError) { r.body_text }
|
101
|
+
assert_equal "body_text(): missing 'charset' in 'Content-Type' header.", ex.message
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
describe '#body_json' do
|
108
|
+
|
109
|
+
it "[!qnic1] returns Hash object representing JSON string." do
|
110
|
+
headers = {'Content-Type' => 'application/json'}
|
111
|
+
binary = %Q`{"msg":"\u3042\u3044\u3046\u3048\u304A"}`
|
112
|
+
assert_equal binary, %Q`{"msg":"あいうえお"}`.encode('utf-8')
|
113
|
+
r = Rack::TestApp::Result.new(200, headers, [binary])
|
114
|
+
assert_equal({"msg"=>"あいうえお"}, r.body_json)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
describe '#content_type' do
|
121
|
+
|
122
|
+
it "[!40hcz] returns 'Content-Type' header value." do
|
123
|
+
headers = {'Content-Type' => 'application/json'}
|
124
|
+
r = Rack::TestApp::Result.new(200, headers, [])
|
125
|
+
assert_equal "application/json", r.content_type
|
126
|
+
#
|
127
|
+
headers = {'content-type' => 'application/json'}
|
128
|
+
r = Rack::TestApp::Result.new(200, headers, [])
|
129
|
+
assert_equal "application/json", r.content_type
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
describe '' do
|
136
|
+
|
137
|
+
it "[!5lb19] returns 'Content-Length' header value as integer." do
|
138
|
+
headers = {'Content-Length' => '123'}
|
139
|
+
r = Rack::TestApp::Result.new(200, headers, [])
|
140
|
+
assert_equal 123, r.content_length
|
141
|
+
#
|
142
|
+
headers = {'content-length' => '123'}
|
143
|
+
r = Rack::TestApp::Result.new(200, headers, [])
|
144
|
+
assert_equal 123, r.content_length
|
145
|
+
end
|
146
|
+
|
147
|
+
it "[!qjktz] returns nil when 'Content-Length' is not set." do
|
148
|
+
headers = {'Content-Type' => 'text/plain'}
|
149
|
+
r = Rack::TestApp::Result.new(200, headers, ["Hello"])
|
150
|
+
assert_nil r.content_length
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
describe '#location' do
|
157
|
+
|
158
|
+
it "[!8y8lg] returns 'Location' header value." do
|
159
|
+
headers = {'Location' => '/foo'}
|
160
|
+
r = Rack::TestApp::Result.new(302, headers, [])
|
161
|
+
assert_equal '/foo', r.location
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
describe '#cookie_value' do
|
168
|
+
|
169
|
+
it "[!neaf8] returns cookie value if exists." do
|
170
|
+
headers = {'Set-Cookie' => 'name1=value1'}
|
171
|
+
r = Rack::TestApp::Result.new(200, headers, [])
|
172
|
+
assert_equal 'value1', r.cookie_value('name1')
|
173
|
+
end
|
174
|
+
|
175
|
+
it "[!oapns] returns nil if cookie not exists." do
|
176
|
+
headers = {'Set-Cookie' => 'name1=value1'}
|
177
|
+
r = Rack::TestApp::Result.new(200, headers, [])
|
178
|
+
assert_equal nil, r.cookie_value('name2')
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
end
|
@@ -0,0 +1,238 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
###
|
4
|
+
### $Release: 1.0.0 $
|
5
|
+
### $Copyright: copyright(c) 2015 kuwata-lab.com all rights reserved $
|
6
|
+
### $License: MIT License $
|
7
|
+
###
|
8
|
+
|
9
|
+
|
10
|
+
require_relative '../../test_helper'
|
11
|
+
|
12
|
+
|
13
|
+
describe Rack::TestApp do
|
14
|
+
|
15
|
+
class << self
|
16
|
+
alias context describe # minitest doesn't provide 'context' method
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
describe '::VERSION' do
|
21
|
+
|
22
|
+
it "represents release version number." do
|
23
|
+
expected = '$Release: 1.0.0 $'.split()[1]
|
24
|
+
assert_equal expected, Rack::TestApp::VERSION
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe '.new_env()' do
|
31
|
+
|
32
|
+
it "[!b3ts8] returns environ hash object." do
|
33
|
+
env = Rack::TestApp.new_env()
|
34
|
+
assert_kind_of Hash, env
|
35
|
+
assert_equal 'GET', env['REQUEST_METHOD']
|
36
|
+
assert_equal '/', env['PATH_INFO']
|
37
|
+
end
|
38
|
+
|
39
|
+
it "[!j879z] sets 'HTTPS' with 'on' when 'rack.url_scheme' is 'https'." do
|
40
|
+
env = Rack::TestApp.new_env(env: {'rack.url_scheme'=>'https'})
|
41
|
+
assert_equal 'on', env['HTTPS']
|
42
|
+
assert_equal 'https', env['rack.url_scheme']
|
43
|
+
end
|
44
|
+
|
45
|
+
it "[!vpwvu] sets 'HTTPS' with 'on' when 'HTTPS' is 'on'." do
|
46
|
+
env = Rack::TestApp.new_env(env: {'HTTPS'=>'on'})
|
47
|
+
assert_equal 'on', env['HTTPS']
|
48
|
+
assert_equal 'https', env['rack.url_scheme']
|
49
|
+
end
|
50
|
+
|
51
|
+
it "[!2uvyb] raises ArgumentError when both query string and 'query' kwarg specified." do
|
52
|
+
ex = assert_raises(ArgumentError) do
|
53
|
+
Rack::TestApp.new_env(:GET, '/path?x=1', query: {'y'=>2})
|
54
|
+
end
|
55
|
+
assert_equal "new_env(): not allowed both query string and 'query' kwarg at a time.", ex.message
|
56
|
+
end
|
57
|
+
|
58
|
+
it "[!8tq3m] accepts query string in path string." do
|
59
|
+
env = Rack::TestApp.new_env(:GET, '/path?x=1')
|
60
|
+
assert_equal 'x=1', env['QUERY_STRING']
|
61
|
+
end
|
62
|
+
|
63
|
+
context "[!d1c83] when 'form' kwarg specified..." do
|
64
|
+
|
65
|
+
it "[!c779l] raises ArgumentError when both 'form' and 'json' are specified." do
|
66
|
+
ex = assert_raises(ArgumentError) do
|
67
|
+
Rack::TestApp.new_env(form: {}, json: {})
|
68
|
+
end
|
69
|
+
assert_equal "new_env(): not allowed both 'form' and 'json' at a time.", ex.message
|
70
|
+
end
|
71
|
+
|
72
|
+
it "[!5iv35] sets content type with 'application/x-www-form-urlencoded'." do
|
73
|
+
env = Rack::TestApp.new_env(form: {'x'=>1})
|
74
|
+
assert_equal 'application/x-www-form-urlencoded', env['CONTENT_TYPE']
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
context "[!prv5z] when 'json' kwarg specified..." do
|
80
|
+
|
81
|
+
it "[!2o0ph] raises ArgumentError when both 'json' and 'multipart' are specified." do
|
82
|
+
ex = assert_raises(ArgumentError) do
|
83
|
+
Rack::TestApp.new_env(json: {}, multipart: {})
|
84
|
+
end
|
85
|
+
assert_equal "new_env(): not allowed both 'json' and 'multipart' at a time.", ex.message
|
86
|
+
end
|
87
|
+
|
88
|
+
it "[!ta24a] sets content type with 'application/json'." do
|
89
|
+
env = Rack::TestApp.new_env(json: {'x'=>1})
|
90
|
+
assert_equal 'application/json', env['CONTENT_TYPE']
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
context "[!dnvgj] when 'multipart' kwarg specified..." do
|
96
|
+
|
97
|
+
it "[!b1d1t] raises ArgumentError when both 'multipart' and 'form' are specified." do
|
98
|
+
ex = assert_raises(ArgumentError) do
|
99
|
+
Rack::TestApp.new_env(multipart: {}, form: {})
|
100
|
+
end
|
101
|
+
assert_equal "new_env(): not allowed both 'multipart' and 'form' at a time.", ex.message
|
102
|
+
end
|
103
|
+
|
104
|
+
it "[!dq33d] sets content type with 'multipart/form-data'." do
|
105
|
+
env = Rack::TestApp.new_env(multipart: {})
|
106
|
+
assert_match /\Amultipart\/form-data; boundary=\S+\z/, env['CONTENT_TYPE']
|
107
|
+
end
|
108
|
+
|
109
|
+
it "[!gko8g] 'multipart:' kwarg accepts Hash object (which is converted into multipart data)." do
|
110
|
+
fpath = File.join(File.dirname(__FILE__), "data", "example1.jpg")
|
111
|
+
file = File.open(fpath, 'rb')
|
112
|
+
env = Rack::TestApp.new_env(multipart: {
|
113
|
+
"value" => 123,
|
114
|
+
"upload" => file,
|
115
|
+
})
|
116
|
+
assert_equal true, file.closed?
|
117
|
+
req = Rack::Request.new(env)
|
118
|
+
params = req.POST
|
119
|
+
assert_equal "123", params['value']
|
120
|
+
assert_equal "upload", params['upload'][:name]
|
121
|
+
assert_equal "example1.jpg", params['upload'][:filename]
|
122
|
+
assert_equal "image/jpeg", params['upload'][:type]
|
123
|
+
assert_kind_of Tempfile, params['upload'][:tempfile]
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
it "[!iamrk] uses 'application/x-www-form-urlencoded' as default content type of input." do
|
129
|
+
env = Rack::TestApp.new_env(:POST, '/', input: 'x=1')
|
130
|
+
assert_equal 'application/x-www-form-urlencoded', env['CONTENT_TYPE']
|
131
|
+
end
|
132
|
+
|
133
|
+
it "[!7hfri] converts input string into binary." do
|
134
|
+
form = {"x"=>"あいうえお"}
|
135
|
+
env = Rack::TestApp.new_env(:POST, '/api/hello', form: form)
|
136
|
+
s = env['rack.input'].read()
|
137
|
+
assert_equal Encoding::ASCII_8BIT, s.encoding
|
138
|
+
end
|
139
|
+
|
140
|
+
it "[!r3soc] converts query string into binary." do
|
141
|
+
query = {"x"=>"あいうえお"}
|
142
|
+
env = Rack::TestApp.new_env(:POST, '/api/hello', query: query)
|
143
|
+
s = env['QUERY_STRING']
|
144
|
+
assert_equal Encoding::ASCII_8BIT, s.encoding
|
145
|
+
end
|
146
|
+
|
147
|
+
it "[!na9w6] builds environ hash object." do
|
148
|
+
env = Rack::TestApp.new_env(:POST, '/api/session?q=test')
|
149
|
+
#
|
150
|
+
assert_equal Rack::VERSION , env['rack.version']
|
151
|
+
assert_kind_of Array , env['rack.version']
|
152
|
+
assert_match /\A\[1, \d+\]\z/, env['rack.version'].inspect
|
153
|
+
assert_kind_of StringIO , env['rack.input']
|
154
|
+
assert_kind_of StringIO , env['rack.errors']
|
155
|
+
assert_equal true , env['rack.multithread']
|
156
|
+
assert_equal true , env['rack.multiprocess']
|
157
|
+
assert_equal false , env['rack.run_once']
|
158
|
+
assert_equal 'http' , env['rack.url_scheme']
|
159
|
+
#
|
160
|
+
assert_equal 'POST' , env['REQUEST_METHOD']
|
161
|
+
assert_equal 'q=test' , env['QUERY_STRING']
|
162
|
+
assert_equal 'localhost' , env['SERVER_NAME']
|
163
|
+
assert_equal '80' , env['SERVER_PORT']
|
164
|
+
assert_equal 'q=test' , env['QUERY_STRING']
|
165
|
+
assert_equal '/api/session' , env['PATH_INFO']
|
166
|
+
assert_equal 'off' , env['HTTPS']
|
167
|
+
assert_equal '' , env['SCRIPT_NAME']
|
168
|
+
assert_equal '0' , env['CONTENT_LENGTH']
|
169
|
+
assert_equal nil , env['CONTENT_TYPE']
|
170
|
+
end
|
171
|
+
|
172
|
+
it "[!ezvdn] unsets CONTENT_TYPE when not input." do
|
173
|
+
env = Rack::TestApp.new_env(:POST, '/api/session?q=test')
|
174
|
+
assert_nil env['CONTENT_TYPE']
|
175
|
+
assert_equal false, env.key?('CONTENT_TYPE')
|
176
|
+
end
|
177
|
+
|
178
|
+
it "[!r4jz8] copies 'headers' kwarg content into environ with 'HTTP_' prefix." do
|
179
|
+
headers = {
|
180
|
+
'If-Modified-Since' => 'Mon, 02 Feb 2015 19:05:06 GMT',
|
181
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
182
|
+
}
|
183
|
+
env = Rack::TestApp.new_env(:PUT, '/', headers: headers)
|
184
|
+
assert_equal 'Mon, 02 Feb 2015 19:05:06 GMT', env['HTTP_IF_MODIFIED_SINCE']
|
185
|
+
assert_equal 'XMLHttpRequest', env['HTTP_X_REQUESTED_WITH']
|
186
|
+
end
|
187
|
+
|
188
|
+
it "[!ai9t3] don't add 'HTTP_' to Content-Length and Content-Type headers." do
|
189
|
+
headers = {
|
190
|
+
'Content-Type' => 'application/json',
|
191
|
+
'Content-Length' => '123',
|
192
|
+
}
|
193
|
+
env = Rack::TestApp.new_env(:PUT, '/', headers: headers)
|
194
|
+
assert_equal 'application/json', env['CONTENT_TYPE']
|
195
|
+
assert_equal '123', env['CONTENT_LENGTH']
|
196
|
+
assert_equal false, env.key?('HTTP_CONTENT_TYPE')
|
197
|
+
assert_equal false, env.key?('HTTP_CONTENT_LENGTH')
|
198
|
+
end
|
199
|
+
|
200
|
+
it "[!a47n9] copies 'env' kwarg content into environ." do
|
201
|
+
environ = {
|
202
|
+
'rack.session' => {'k1'=>'v1'},
|
203
|
+
}
|
204
|
+
env = Rack::TestApp.new_env(:PUT, '/', env: environ)
|
205
|
+
expected = {'k1'=>'v1'}
|
206
|
+
assert_equal expected, env['rack.session']
|
207
|
+
end
|
208
|
+
|
209
|
+
it "[!pmefk] sets 'HTTP_COOKIE' when 'cookie' kwarg specified." do
|
210
|
+
env = Rack::TestApp.new_env(cookies: 'c1=v1')
|
211
|
+
assert_equal 'c1=v1', env['HTTP_COOKIE']
|
212
|
+
env = Rack::TestApp.new_env(cookies: {'c2'=>'v2'})
|
213
|
+
assert_equal 'c2=v2', env['HTTP_COOKIE']
|
214
|
+
end
|
215
|
+
|
216
|
+
it "[!qj7b8] cookie value can be {:name=>'name', :value=>'value'}." do
|
217
|
+
env = Rack::TestApp.new_env(cookies: {'c3'=>{name: 'c3', value: 'v3'}})
|
218
|
+
assert_equal 'c3=v3', env['HTTP_COOKIE']
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
describe '.wrap()' do
|
225
|
+
|
226
|
+
it "[!grqlf] creates new Wrapper object." do
|
227
|
+
app = proc {|env| [200, {}, []] }
|
228
|
+
env = {"HTTPS"=>"on"}
|
229
|
+
wrapper = Rack::TestApp.wrap(app, env)
|
230
|
+
assert_kind_of Rack::TestApp::Wrapper, wrapper
|
231
|
+
assert_equal app, wrapper.instance_variable_get('@app')
|
232
|
+
assert_equal env, wrapper.instance_variable_get('@env')
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
end
|