josh-rack-test 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ require "fake_app"
2
+
3
+ run Rack::Test::FakeApp
@@ -0,0 +1,115 @@
1
+ require "sinatra/base"
2
+
3
+ module Rack
4
+ module Test
5
+
6
+ class FakeApp < Sinatra::Default
7
+ head "/" do
8
+ "meh"
9
+ end
10
+
11
+ get "/" do
12
+ "Hello, GET: #{params.inspect}"
13
+ end
14
+
15
+ get "/redirect" do
16
+ redirect "/redirected"
17
+ end
18
+
19
+ get "/redirected" do
20
+ "You've been redirected"
21
+ end
22
+
23
+ get "/void" do
24
+ [200, {}, ""]
25
+ end
26
+
27
+ get "/cookies/show" do
28
+ request.cookies.inspect
29
+ end
30
+
31
+ get "/COOKIES/show" do
32
+ request.cookies.inspect
33
+ end
34
+
35
+ get "/not-cookies/show" do
36
+ request.cookies.inspect
37
+ end
38
+
39
+ get "/cookies/set-secure" do
40
+ raise if params["value"].nil?
41
+
42
+ response.set_cookie("secure-cookie", :value => params["value"], :secure => true)
43
+ "Set"
44
+ end
45
+
46
+ get "/cookies/set-simple" do
47
+ raise if params["value"].nil?
48
+
49
+ response.set_cookie "simple", params["value"]
50
+ "Set"
51
+ end
52
+
53
+ get "/cookies/delete" do
54
+ response.delete_cookie "value"
55
+ end
56
+
57
+ get "/cookies/count" do
58
+ old_value = request.cookies["count"].to_i || 0
59
+ new_value = (old_value + 1).to_s
60
+
61
+ response.set_cookie("count", :value => new_value)
62
+ new_value
63
+ end
64
+
65
+ get "/cookies/set" do
66
+ raise if params["value"].nil?
67
+
68
+ response.set_cookie("value", {
69
+ :value => params["value"],
70
+ :path => "/cookies",
71
+ :expires => Time.now + 10
72
+ })
73
+ "Set"
74
+ end
75
+
76
+ get "/cookies/domain" do
77
+ old_value = request.cookies["count"].to_i || 0
78
+ new_value = (old_value + 1).to_s
79
+
80
+ response.set_cookie("count", :value => new_value, :domain => "localhost.com")
81
+ new_value
82
+ end
83
+
84
+ get "/cookies/set-uppercase" do
85
+ raise if params["value"].nil?
86
+
87
+ response.set_cookie("VALUE", {
88
+ :value => params["value"],
89
+ :path => "/cookies",
90
+ :expires => Time.now + 10
91
+ })
92
+ "Set"
93
+ end
94
+
95
+ get "/cookies/set-multiple" do
96
+ response.set_cookie("key1", :value => "value1")
97
+ response.set_cookie("key2", :value => "value2")
98
+ "Set"
99
+ end
100
+
101
+ post "/" do
102
+ "Hello, POST: #{params.inspect}"
103
+ end
104
+
105
+ put "/" do
106
+ "Hello, PUT: #{params.inspect}"
107
+ end
108
+
109
+ delete "/" do
110
+ "Hello, DELETE: #{params.inspect}"
111
+ end
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1 @@
1
+ bar
@@ -0,0 +1,182 @@
1
+ require "spec_helper"
2
+
3
+ describe Rack::Test::Session do
4
+ def have_body(string)
5
+ simple_matcher "have body #{string.inspect}" do |response|
6
+ response.body.should == string
7
+ end
8
+ end
9
+
10
+ context "cookies" do
11
+ it "keeps a cookie jar" do
12
+ get "/cookies/show"
13
+ last_request.cookies.should == {}
14
+
15
+ get "/cookies/set", "value" => "1"
16
+ get "/cookies/show"
17
+ last_request.cookies.should == { "value" => "1" }
18
+ end
19
+
20
+ it "doesn't send expired cookies" do
21
+ get "/cookies/set", "value" => "1"
22
+ now = Time.now
23
+ Time.stub!(:now => now + 60)
24
+ get "/cookies/show"
25
+ last_request.cookies.should == {}
26
+ end
27
+
28
+ it "doesn't send cookies with the wrong domain" do
29
+ get "http://www.example.com/cookies/set", "value" => "1"
30
+ get "http://www.other.example/cookies/show"
31
+ last_request.cookies.should == {}
32
+ end
33
+
34
+ it "doesn't send cookies with the wrong path" do
35
+ get "/cookies/set", "value" => "1"
36
+ get "/not-cookies/show"
37
+ last_request.cookies.should == {}
38
+ end
39
+
40
+ it "persists cookies across requests that don't return any cookie headers" do
41
+ get "/cookies/set", "value" => "1"
42
+ get "/void"
43
+ get "/cookies/show"
44
+ last_request.cookies.should == { "value" => "1" }
45
+ end
46
+
47
+ it "deletes cookies" do
48
+ get "/cookies/set", "value" => "1"
49
+ get "/cookies/delete"
50
+ get "/cookies/show"
51
+ last_request.cookies.should == { }
52
+ end
53
+
54
+ xit "respects cookie domains when no domain is explicitly set" do
55
+ request("http://example.org/cookies/count").should have_body("1")
56
+ request("http://www.example.org/cookies/count").should have_body("1")
57
+ request("http://example.org/cookies/count").should have_body("2")
58
+ request("http://www.example.org/cookies/count").should have_body("2")
59
+ end
60
+
61
+ it "treats domains case insensitively" do
62
+ get "http://example.com/cookies/set", "value" => "1"
63
+ get "http://EXAMPLE.COM/cookies/show"
64
+ last_request.cookies.should == { "value" => "1" }
65
+ end
66
+
67
+ it "treats paths case sensitively" do
68
+ get "/cookies/set", "value" => "1"
69
+ get "/COOKIES/show"
70
+ last_request.cookies.should == {}
71
+ end
72
+
73
+ it "prefers more specific cookies" do
74
+ get "http://example.com/cookies/set", "value" => "domain"
75
+ get "http://sub.example.com/cookies/set", "value" => "sub"
76
+
77
+ get "http://sub.example.com/cookies/show"
78
+ last_request.cookies.should == { "value" => "sub" }
79
+
80
+ get "http://example.com/cookies/show"
81
+ last_request.cookies.should == { "value" => "domain" }
82
+ end
83
+
84
+ it "treats cookie names case insensitively" do
85
+ get "/cookies/set", "value" => "lowercase"
86
+ get "/cookies/set-uppercase", "value" => "UPPERCASE"
87
+ get "/cookies/show"
88
+ last_request.cookies.should == { "VALUE" => "UPPERCASE" }
89
+ end
90
+
91
+ it "defaults the domain to the request domain" do
92
+ get "http://example.com/cookies/set-simple", "value" => "cookie"
93
+ get "http://example.com/cookies/show"
94
+ last_request.cookies.should == { "simple" => "cookie" }
95
+
96
+ get "http://other.example/cookies/show"
97
+ last_request.cookies.should == {}
98
+ end
99
+
100
+ it "defaults the domain to the request path up to the last slash" do
101
+ get "/cookies/set-simple", "value" => "1"
102
+ get "/not-cookies/show"
103
+ last_request.cookies.should == {}
104
+ end
105
+
106
+ it "supports secure cookies" do
107
+ get "https://example.com/cookies/set-secure", "value" => "set"
108
+ get "http://example.com/cookies/show"
109
+ last_request.cookies.should == {}
110
+
111
+ get "https://example.com/cookies/show"
112
+ last_request.cookies.should == { "secure-cookie" => "set" }
113
+ end
114
+
115
+ it "keeps separate cookie jars for different domains" do
116
+ get "http://example.com/cookies/set", "value" => "example"
117
+ get "http://example.com/cookies/show"
118
+ last_request.cookies.should == { "value" => "example" }
119
+
120
+ get "http://other.example/cookies/set", "value" => "other"
121
+ get "http://other.example/cookies/show"
122
+ last_request.cookies.should == { "value" => "other" }
123
+
124
+ get "http://example.com/cookies/show"
125
+ last_request.cookies.should == { "value" => "example" }
126
+ end
127
+
128
+ it "allows cookies to be cleared" do
129
+ get "/cookies/set", "value" => "1"
130
+ clear_cookies
131
+ get "/cookies/show"
132
+ last_request.cookies.should == {}
133
+ end
134
+
135
+ it "allow cookies to be set" do
136
+ set_cookie "value=10"
137
+ get "/cookies/show"
138
+ last_request.cookies.should == { "value" => "10" }
139
+ end
140
+
141
+ it "allows an array of cookies to be set" do
142
+ set_cookie ["value=10", "foo=bar"]
143
+ get "/cookies/show"
144
+ last_request.cookies.should == { "value" => "10", "foo" => "bar" }
145
+ end
146
+
147
+ it "parses multiple cookies properly" do
148
+ get "/cookies/set-multiple"
149
+ get "/cookies/show"
150
+ last_request.cookies.should == { "key1" => "value1", "key2" => "value2" }
151
+ end
152
+
153
+ it "supports multiple sessions" do
154
+ with_session(:first) do
155
+ get "/cookies/set", "value" => "1"
156
+ get "/cookies/show"
157
+ last_request.cookies.should == { "value" => "1" }
158
+ end
159
+
160
+ with_session(:second) do
161
+ get "/cookies/show"
162
+ last_request.cookies.should == { }
163
+ end
164
+ end
165
+
166
+ it "uses :default as the default session name" do
167
+ get "/cookies/set", "value" => "1"
168
+ get "/cookies/show"
169
+ last_request.cookies.should == { "value" => "1" }
170
+
171
+ with_session(:default) do
172
+ get "/cookies/show"
173
+ last_request.cookies.should == { "value" => "1" }
174
+ end
175
+ end
176
+
177
+ it "accepts explicitly provided cookies" do
178
+ request "/cookies/show", :cookie => "value=1"
179
+ last_request.cookies.should == { "value" => "1" }
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+
3
+ describe Rack::Test::Session do
4
+ context "HTTP Digest authentication" do
5
+
6
+ def app
7
+ app = Rack::Auth::Digest::MD5.new(Rack::Test::FakeApp.new) do |username|
8
+ { 'alice' => 'correct-password' }[username]
9
+ end
10
+ app.realm = 'WallysWorld'
11
+ app.opaque = 'this-should-be-secret'
12
+ app
13
+ end
14
+
15
+ def be_challenge
16
+ simple_matcher "a HTTP Digest challenge response" do |response|
17
+ response.status == 401 &&
18
+ response['WWW-Authenticate'] =~ /^Digest / &&
19
+ response.body.empty?
20
+ end
21
+ end
22
+
23
+ it 'incorrectly authenticates GETs' do
24
+ digest_authorize 'foo', 'bar'
25
+ get '/'
26
+ last_response.should be_challenge
27
+ end
28
+
29
+ it "correctly authenticates GETs" do
30
+ digest_authorize "alice", "correct-password"
31
+ response = get "/"
32
+ response.should be_ok
33
+ end
34
+
35
+ it "correctly authenticates POSTs" do
36
+ digest_authorize "alice", "correct-password"
37
+ response = post "/"
38
+ response.should be_ok
39
+ end
40
+
41
+ it "returns a re-challenge if authenticating incorrectly" do
42
+ digest_authorize "alice", "incorrect-password"
43
+ response = get "/"
44
+ response.should be_challenge
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,85 @@
1
+ require "spec_helper"
2
+
3
+ describe Rack::Test::Session do
4
+
5
+ def test_file_path
6
+ File.dirname(__FILE__) + "/../../fixtures/foo.txt"
7
+ end
8
+
9
+ def uploaded_file
10
+ Rack::Test::UploadedFile.new(test_file_path)
11
+ end
12
+
13
+ context "uploading a file" do
14
+ it "sends the multipart/form-data content type" do
15
+ post "/", "photo" => uploaded_file
16
+ last_request.env["CONTENT_TYPE"].should include("multipart/form-data;")
17
+ end
18
+
19
+ it "sends regular params" do
20
+ post "/", "photo" => uploaded_file, "foo" => "bar"
21
+ last_request.POST["foo"].should == "bar"
22
+ end
23
+
24
+ it "sends nested params" do
25
+ post "/", "photo" => uploaded_file, "foo" => {"bar" => "baz"}
26
+ last_request.POST["foo"]["bar"].should == "baz"
27
+ end
28
+
29
+ it "sends multiple nested params" do
30
+ post "/", "photo" => uploaded_file, "foo" => {"bar" => {"baz" => "bop"}}
31
+ last_request.POST["foo"]["bar"]["baz"].should == "bop"
32
+ end
33
+
34
+ xit "sends params with arrays" do
35
+ post "/", "photo" => uploaded_file, "foo" => ["1", "2"]
36
+ last_request.POST["foo[]"].should == ["1", "2"]
37
+ end
38
+
39
+ it "sends params with encoding sensitive values" do
40
+ post "/", "photo" => uploaded_file, "foo" => "bar? baz"
41
+ last_request.POST["foo"].should == "bar? baz"
42
+ end
43
+
44
+ it "sends params with parens in names" do
45
+ post "/", "photo" => uploaded_file, "foo(1i)" => "bar"
46
+ last_request.POST["foo(1i)"].should == "bar"
47
+ end
48
+
49
+ it "sends params with encoding sensitive names" do
50
+ post "/", "photo" => uploaded_file, "foo bar" => "baz"
51
+ last_request.POST["foo bar"].should == "baz"
52
+ end
53
+
54
+ it "sends files with the filename" do
55
+ post "/", "photo" => uploaded_file
56
+ last_request.POST["photo"][:filename].should == "foo.txt"
57
+ end
58
+
59
+ it "sends files with the text/plain MIME type by default" do
60
+ post "/", "photo" => uploaded_file
61
+ last_request.POST["photo"][:type].should == "text/plain"
62
+ end
63
+
64
+ it "sends files with the right name" do
65
+ post "/", "photo" => uploaded_file
66
+ last_request.POST["photo"][:name].should == "photo"
67
+ end
68
+
69
+ it "allows overriding the content type" do
70
+ post "/", "photo" => Rack::Test::UploadedFile.new(test_file_path, "image/jpeg")
71
+ last_request.POST["photo"][:type].should == "image/jpeg"
72
+ end
73
+
74
+ it "sends files with a Content-Length in the header" do
75
+ post "/", "photo" => uploaded_file
76
+ last_request.POST["photo"][:head].should include("Content-Length: 4")
77
+ end
78
+
79
+ it "sends files as Tempfiles" do
80
+ post "/", "photo" => uploaded_file
81
+ last_request.POST["photo"][:tempfile].should be_a(::Tempfile)
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,93 @@
1
+ require "spec_helper"
2
+
3
+ describe Rack::Test::Utils do
4
+ include Rack::Test::Utils
5
+
6
+ describe "build_nested_query" do
7
+ it "converts empty strings to =" do
8
+ build_nested_query("").should == "="
9
+ end
10
+
11
+ it "converts nil to =" do
12
+ build_nested_query(nil).should == "="
13
+ end
14
+
15
+ it "converts hashes" do
16
+ build_nested_query(:a => 1).should == "a=1"
17
+ end
18
+
19
+ it "converts hashes with multiple keys" do
20
+ hash = { :a => 1, :b => 2 }
21
+ ["a=1&b=2", "b=2&a=1"].should include(build_nested_query(hash))
22
+ end
23
+
24
+ it "converts arrays with one element" do
25
+ build_nested_query(:a => [1]).should == "a[]=1"
26
+ end
27
+
28
+ it "converts arrays with multiple elements" do
29
+ build_nested_query(:a => [1, 2]).should == "a[]=1&a[]=2"
30
+ end
31
+
32
+ it "converts nested hashes" do
33
+ build_nested_query(:a => { :b => 1 }).should == "a[b]=1"
34
+ end
35
+
36
+ it "converts arrays nested in a hash" do
37
+ build_nested_query(:a => { :b => [1, 2] }).should == "a[b][]=1&a[b][]=2"
38
+ end
39
+
40
+ it "converts arrays of hashes" do
41
+ build_nested_query(:a => [{ :b => 2}, { :c => 3}]).should == "a[][b]=2&a[][c]=3"
42
+ end
43
+ end
44
+
45
+ describe "build_multipart" do
46
+ it "builds multipart bodies" do
47
+ files = Rack::Test::UploadedFile.new(multipart_file("foo.txt"))
48
+ data = build_multipart("submit-name" => "Larry", "files" => files)
49
+
50
+ options = {
51
+ "CONTENT_TYPE" => "multipart/form-data; boundary=#{Rack::Test::MULTIPART_BOUNDARY}",
52
+ "CONTENT_LENGTH" => data.length.to_s,
53
+ :input => StringIO.new(data)
54
+ }
55
+ env = Rack::MockRequest.env_for("/", options)
56
+ params = Rack::Utils::Multipart.parse_multipart(env)
57
+ params["submit-name"].should == "Larry"
58
+ params["files"][:filename].should == "foo.txt"
59
+ params["files"][:tempfile].read.should == "bar\n"
60
+ end
61
+
62
+ it "builds nested multipart bodies" do
63
+ files = Rack::Test::UploadedFile.new(multipart_file("foo.txt"))
64
+ data = build_multipart("people" => [{"submit-name" => "Larry", "files" => files}])
65
+
66
+ options = {
67
+ "CONTENT_TYPE" => "multipart/form-data; boundary=#{Rack::Test::MULTIPART_BOUNDARY}",
68
+ "CONTENT_LENGTH" => data.length.to_s,
69
+ :input => StringIO.new(data)
70
+ }
71
+ env = Rack::MockRequest.env_for("/", options)
72
+ params = Rack::Utils::Multipart.parse_multipart(env)
73
+ params["people"][0]["submit-name"].should == "Larry"
74
+ params["people"][0]["files"][:filename].should == "foo.txt"
75
+ params["people"][0]["files"][:tempfile].read.should == "bar\n"
76
+ end
77
+
78
+ it "should return nil if no UploadedFiles were used" do
79
+ data = build_multipart("people" => [{"submit-name" => "Larry", "files" => "contents"}])
80
+ data.should be_nil
81
+ end
82
+
83
+ it "raises ArgumentErrors if params is not a Hash" do
84
+ lambda {
85
+ build_multipart("foo=bar")
86
+ }.should raise_error(ArgumentError, "value must be a Hash")
87
+ end
88
+
89
+ def multipart_file(name)
90
+ File.join(File.dirname(__FILE__), "..", "..", "fixtures", name.to_s)
91
+ end
92
+ end
93
+ end