sockjs 0.2.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.
- data/LICENCE +19 -0
- data/README.textile +118 -0
- data/lib/meta-state.rb +151 -0
- data/lib/rack/sockjs.rb +173 -0
- data/lib/sockjs.rb +59 -0
- data/lib/sockjs/callbacks.rb +19 -0
- data/lib/sockjs/connection.rb +45 -0
- data/lib/sockjs/delayed-response-body.rb +99 -0
- data/lib/sockjs/duck-punch-rack-mount.rb +12 -0
- data/lib/sockjs/duck-punch-thin-response.rb +15 -0
- data/lib/sockjs/examples/protocol_conformance_test.rb +73 -0
- data/lib/sockjs/faye.rb +15 -0
- data/lib/sockjs/protocol.rb +97 -0
- data/lib/sockjs/servers/request.rb +136 -0
- data/lib/sockjs/servers/response.rb +169 -0
- data/lib/sockjs/session.rb +388 -0
- data/lib/sockjs/transport.rb +354 -0
- data/lib/sockjs/transports/eventsource.rb +30 -0
- data/lib/sockjs/transports/htmlfile.rb +69 -0
- data/lib/sockjs/transports/iframe.rb +68 -0
- data/lib/sockjs/transports/info.rb +48 -0
- data/lib/sockjs/transports/jsonp.rb +84 -0
- data/lib/sockjs/transports/websocket.rb +166 -0
- data/lib/sockjs/transports/welcome_screen.rb +17 -0
- data/lib/sockjs/transports/xhr.rb +75 -0
- data/lib/sockjs/version.rb +13 -0
- data/spec/sockjs/protocol_spec.rb +49 -0
- data/spec/sockjs/session_spec.rb +51 -0
- data/spec/sockjs/transport_spec.rb +73 -0
- data/spec/sockjs/transports/eventsource_spec.rb +56 -0
- data/spec/sockjs/transports/htmlfile_spec.rb +72 -0
- data/spec/sockjs/transports/iframe_spec.rb +66 -0
- data/spec/sockjs/transports/jsonp_spec.rb +252 -0
- data/spec/sockjs/transports/websocket_spec.rb +101 -0
- data/spec/sockjs/transports/welcome_screen_spec.rb +36 -0
- data/spec/sockjs/transports/xhr_spec.rb +314 -0
- data/spec/sockjs/version_spec.rb +18 -0
- data/spec/sockjs_spec.rb +8 -0
- data/spec/spec_helper.rb +121 -0
- data/spec/support/async-test.rb +42 -0
- metadata +171 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SockJS
|
4
|
+
# SockJS protocol version.
|
5
|
+
PROTOCOL_VERSION = [0, 2, 1]
|
6
|
+
|
7
|
+
PROTOCOL_VERSION_STRING = PROTOCOL_VERSION.join(".")
|
8
|
+
|
9
|
+
# Patch version of the gem.
|
10
|
+
PATCH_VERSION = []
|
11
|
+
|
12
|
+
GEM_VERSION = (PROTOCOL_VERSION + PATCH_VERSION).join(".")
|
13
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env bundle exec rspec
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "spec_helper"
|
5
|
+
require "sockjs/protocol"
|
6
|
+
|
7
|
+
describe SockJS::Protocol do
|
8
|
+
it "OpeningFrame should be 'o'" do
|
9
|
+
described_class::OpeningFrame.instance.to_s.should eql("o")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "HeartbeatFrame should be 'h'" do
|
13
|
+
described_class::HeartbeatFrame.instance.to_s.should eql("h")
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "ArrayFrame" do
|
17
|
+
it "should take only an array as the first argument" do
|
18
|
+
expect {
|
19
|
+
SockJS::Protocol::ArrayFrame.new(Hash.new)
|
20
|
+
}.to raise_error(TypeError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return a valid array frame" do
|
24
|
+
SockJS::Protocol::ArrayFrame.new([1, 2, 3]).to_s.should eql("a[1,2,3]")
|
25
|
+
SockJS::Protocol::ArrayFrame.new(["tests"]).to_s.should eql('a["tests"]')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "ClosingFrame" do
|
30
|
+
it "should take only integer as the first argument" do
|
31
|
+
expect {
|
32
|
+
SockJS::Protocol::ClosingFrame.new("2010", "message")
|
33
|
+
}.to raise_error(TypeError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should take only string as the second argument" do
|
37
|
+
expect {
|
38
|
+
SockJS::Protocol::ClosingFrame.new(2010, :message)
|
39
|
+
}.to raise_error(TypeError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return a valid closing frame" do
|
43
|
+
expect {
|
44
|
+
frame = SockJS::Protocol::ClosingFrame.new(2010, "message")
|
45
|
+
frame.to_s.should eql('c[2010,"message"]')
|
46
|
+
}.not_to raise_error
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env bundle exec rspec
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "spec_helper"
|
5
|
+
|
6
|
+
require "sockjs"
|
7
|
+
require "sockjs/session"
|
8
|
+
require "sockjs/transports/xhr"
|
9
|
+
|
10
|
+
#Comment:
|
11
|
+
#These specs came to me way to interested in the internals of Session
|
12
|
+
#Policy has got to be that any spec that fails because e.g. it wants to know
|
13
|
+
#what state Session is in is a fail. Okay to spec that Session should be able
|
14
|
+
#to respond to message X after Y, though.
|
15
|
+
|
16
|
+
describe SockJS::Session do
|
17
|
+
around :each do |example|
|
18
|
+
EM.run do
|
19
|
+
example.run
|
20
|
+
EM.stop
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let :connection do
|
25
|
+
SockJS::Connection.new {}
|
26
|
+
end
|
27
|
+
|
28
|
+
let :transport do
|
29
|
+
xprt = SockJS::Transports::XHRPost.new(connection, Hash.new)
|
30
|
+
|
31
|
+
def xprt.send
|
32
|
+
end
|
33
|
+
|
34
|
+
xprt
|
35
|
+
end
|
36
|
+
|
37
|
+
let :request do
|
38
|
+
FakeRequest.new.tap do|req|
|
39
|
+
req.data = ""
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
let :response do
|
44
|
+
transport.response_class.new(request, 200)
|
45
|
+
end
|
46
|
+
|
47
|
+
let :session do
|
48
|
+
sess = described_class.new({:open => []})
|
49
|
+
sess
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "sockjs"
|
4
|
+
require "sockjs/transport"
|
5
|
+
|
6
|
+
describe SockJS::Transport do
|
7
|
+
describe "CONTENT_TYPES" do
|
8
|
+
[:plain, :html, :javascript, :event_stream].each do |type|
|
9
|
+
it "should define #{type}" do
|
10
|
+
described_class::CONTENT_TYPES[type].should_not be_nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
subject do
|
16
|
+
described_class.new(Object.new, Hash.new)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#disabled?", :pending => "valid?" do
|
20
|
+
it "should be false if the current class isn't in disabled_transports" do
|
21
|
+
subject.should_not be_disabled
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be false if the current class is in disabled_transports" do
|
25
|
+
subject.options[:disabled_transports] = [subject.class]
|
26
|
+
subject.should be_disabled
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#session_class" do
|
31
|
+
it "should be a valid class" do
|
32
|
+
subject.session_class.should be_kind_of(Class)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#response_class" do
|
37
|
+
it "should be a valid class" do
|
38
|
+
subject.response_class.should be_kind_of(Class)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
let :session do
|
43
|
+
mock("Session")
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#format_frame(payload)" do
|
47
|
+
it "should fail if payload is nil" do
|
48
|
+
expect do
|
49
|
+
subject.format_frame(session, nil)
|
50
|
+
end.to raise_error(TypeError)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return payload followed by \\n otherwise" do
|
54
|
+
subject.format_frame(session, "o").should eql("o\n")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#response(request, status)" do
|
59
|
+
# TODO
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#respond(request, status, options = Hash.new, &block)" do
|
63
|
+
# TODO
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#error(http_status, content_type, body)" do
|
67
|
+
# TODO
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#get_session(request, response, preamble = nil)" do
|
71
|
+
# TODO
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env bundle exec rspec
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "spec_helper"
|
5
|
+
|
6
|
+
require "sockjs"
|
7
|
+
require "sockjs/transports/eventsource"
|
8
|
+
|
9
|
+
describe SockJS::Transports::EventSource, :type => :transport, :em => true do
|
10
|
+
transport_handler_eql "/eventsource", "GET"
|
11
|
+
|
12
|
+
describe "#handle(request)" do
|
13
|
+
let(:request) do
|
14
|
+
@request ||= begin
|
15
|
+
request = FakeRequest.new
|
16
|
+
request.path_info = "/echo/a/b/eventsource"
|
17
|
+
request
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:response) do
|
22
|
+
def transport.try_timer_if_valid(*)
|
23
|
+
end
|
24
|
+
|
25
|
+
transport.handle(request)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should respond with HTTP 200" do
|
29
|
+
response.status.should eql(200)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should respond with event stream MIME type" do
|
33
|
+
response.headers["Content-Type"].should match("text/event-stream")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should disable caching" do
|
37
|
+
response.headers["Cache-Control"].should eql("no-store, no-cache, must-revalidate, max-age=0")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should write two empty lines for Opera" do
|
41
|
+
response # Run the handler.
|
42
|
+
|
43
|
+
pending 'We do split("\r\n"), remember?' do
|
44
|
+
response.chunks[0].should eql("")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#format_frame(payload)" do
|
50
|
+
it "should format payload"
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#escape_selected(*args)" do
|
54
|
+
it "should escape given payload"
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env bundle exec rspec
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "spec_helper"
|
5
|
+
|
6
|
+
require "sockjs"
|
7
|
+
require "sockjs/transports/htmlfile"
|
8
|
+
|
9
|
+
describe SockJS::Transports::HTMLFile, :em => true, :type => :transport do
|
10
|
+
transport_handler_eql "/htmlfile", "GET"
|
11
|
+
|
12
|
+
describe "#handle(request)" do
|
13
|
+
let(:request) do
|
14
|
+
FakeRequest.new
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:response) do
|
18
|
+
def transport.try_timer_if_valid(*)
|
19
|
+
end
|
20
|
+
|
21
|
+
transport.handle(request)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "with callback specified" do
|
25
|
+
let(:request) do
|
26
|
+
@request ||= FakeRequest.new.tap do |request|
|
27
|
+
request.query_string = {"c" => "clbk"}
|
28
|
+
request.path_info = '/a/b/htmlfile'
|
29
|
+
request.session_key = 'b'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should respond with HTTP 200" do
|
34
|
+
response.status.should eql(200)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should respond with HTML MIME type" do
|
38
|
+
response.headers["Content-Type"].should match("text/html")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should disable caching" do
|
42
|
+
response.headers["Cache-Control"].should eql("no-store, no-cache, must-revalidate, max-age=0")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return HTML wrapper in the body" do
|
46
|
+
response.chunks.find{|chunk| chunk =~ (/document.domain = document.domain/)}.should_not be_nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have at least 1024 bytes"
|
50
|
+
it "should replace {{ callback }} with the actual callback name"
|
51
|
+
end
|
52
|
+
|
53
|
+
context "without callback specified" do
|
54
|
+
it "should respond with HTTP 500" do
|
55
|
+
response.status.should eql(500)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should respond with HTML MIME type" do
|
59
|
+
response.headers["Content-Type"].should match("text/html")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return error message in the body" do
|
63
|
+
response # Run the handler.
|
64
|
+
response.chunks.last.should match(/"callback" parameter required/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#format_frame(payload)" do
|
70
|
+
it "should format payload"
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "sockjs"
|
4
|
+
require "sockjs/transports/iframe"
|
5
|
+
|
6
|
+
describe SockJS::Transports::IFrame, :type => :transport do
|
7
|
+
describe "#handle(request)" do
|
8
|
+
let(:transport) do
|
9
|
+
described_class.new(connection, sockjs_url: "http://sock.js/sock.js")
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:response) do
|
13
|
+
transport.handle(request)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "If-None-Match header matches ETag of current body" do
|
17
|
+
let(:request) do
|
18
|
+
@request ||= FakeRequest.new.tap do |request|
|
19
|
+
etag = '"af0ca7deb5298aeb946c4f7b96d1501b"'
|
20
|
+
request.if_none_match = etag
|
21
|
+
request.path_info = "/iframe.html"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should respond with HTTP 304" do
|
26
|
+
response.status.should eql(304)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "If-None-Match header doesn't match ETag of current body" do
|
31
|
+
let(:request) do
|
32
|
+
@request ||= FakeRequest.new.tap do |request|
|
33
|
+
request.path_info = "/iframe.html"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should respond with HTTP 200" do
|
38
|
+
response.status.should eql(200)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should respond with HTML MIME type" do
|
42
|
+
response.headers["Content-Type"].should match("text/html")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should set ETag header"
|
46
|
+
|
47
|
+
it "should set cache control to be valid for the next year" do
|
48
|
+
time = Time.now + 31536000
|
49
|
+
|
50
|
+
response.headers["Cache-Control"].should eql("public, max-age=31536000")
|
51
|
+
response.headers["Expires"].should eql(time.gmtime.to_s)
|
52
|
+
response.headers["Access-Control-Max-Age"].should eql("1000001")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return HTML wrapper in the body" do
|
56
|
+
response # Run the handler.
|
57
|
+
response.chunks.last.should match(/document.domain = document.domain/)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set sockjs_url" do
|
61
|
+
response # Run the handler.
|
62
|
+
response.chunks.last.should match(transport.options[:sockjs_url])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
#!/usr/bin/env bundle exec rspec
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "spec_helper"
|
5
|
+
|
6
|
+
require "sockjs"
|
7
|
+
require "sockjs/transports/jsonp"
|
8
|
+
|
9
|
+
describe "JSONP", :em => true, :type => :transport do
|
10
|
+
let(:open_request) do
|
11
|
+
FakeRequest.new.tap do |request|
|
12
|
+
request.path_info = "/jsonp"
|
13
|
+
request.query_string = {"c" => "clbk"}
|
14
|
+
request.data = "ok"
|
15
|
+
request.session_key = "b"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe SockJS::Transports::JSONP do
|
20
|
+
transport_handler_eql "/jsonp", "GET"
|
21
|
+
|
22
|
+
describe "#handle(request)" do
|
23
|
+
let(:request) do
|
24
|
+
FakeRequest.new.tap do |request|
|
25
|
+
request.path_info = "/echo/a/b/jsonp"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with callback specified" do
|
30
|
+
let(:request) do
|
31
|
+
FakeRequest.new.tap do |request|
|
32
|
+
request.path_info = "/jsonp"
|
33
|
+
request.query_string = {"c" => "clbk"}
|
34
|
+
request.session_key = "b"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with a session" do
|
39
|
+
let(:prior_transport) do
|
40
|
+
described_class.new(connection, {})
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should respond with HTTP 200" do
|
44
|
+
response.status.should eql(200)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should respond with plain text MIME type" do
|
48
|
+
response.headers["Content-Type"].should match("application/javascript")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should respond with a body"
|
52
|
+
end
|
53
|
+
|
54
|
+
context "without any session" do
|
55
|
+
it "should respond with HTTP 200" do
|
56
|
+
response.status.should eql(200)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should respond with javascript MIME type" do
|
60
|
+
response.headers["Content-Type"].should match("application/javascript")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should set access control" do
|
64
|
+
response.headers["Access-Control-Allow-Origin"].should eql(request.origin)
|
65
|
+
response.headers["Access-Control-Allow-Credentials"].should eql("true")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should disable caching" do
|
69
|
+
response.headers["Cache-Control"].should eql("no-store, no-cache, must-revalidate, max-age=0")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should open a new session"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "without callback specified" do
|
77
|
+
it "should respond with HTTP 500" do
|
78
|
+
response.status.should eql(500)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should respond with HTML MIME type" do
|
82
|
+
response.headers["Content-Type"].should match("text/html")
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should return error message in the body" do
|
86
|
+
response.chunks.last.should match(/"callback" parameter required/)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#format_frame(payload)" do
|
92
|
+
it "should format payload"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe SockJS::Transports::JSONPSend do
|
97
|
+
transport_handler_eql "/jsonp_send", "POST"
|
98
|
+
|
99
|
+
describe "#handle(request)" do
|
100
|
+
let(:request) do
|
101
|
+
FakeRequest.new.tap do |request|
|
102
|
+
request.path_info = "/a/_/jsonp_send"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "with valid data" do
|
107
|
+
context "with application/x-www-form-urlencoded" do
|
108
|
+
# TODO: test with invalid data like d=sth, we should get Broken encoding.
|
109
|
+
context "with a valid session" do
|
110
|
+
before :each do
|
111
|
+
session
|
112
|
+
end
|
113
|
+
|
114
|
+
let(:request) do
|
115
|
+
FakeRequest.new.tap do |request|
|
116
|
+
request.path_info = "/jsonp_send"
|
117
|
+
request.session_key = existing_session_key
|
118
|
+
request.content_type = "application/x-www-form-urlencoded"
|
119
|
+
request.data = "d=%5B%22x%22%5D"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should respond with HTTP 200" do
|
124
|
+
response.status.should eql(200)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should set session ID" do
|
128
|
+
cookie = response.headers["Set-Cookie"]
|
129
|
+
cookie.should match("JSESSIONID=#{request.session_id}; path=/")
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should write 'ok' to the body stream" do
|
133
|
+
response # Run the handler.
|
134
|
+
response.chunks.last.should eql("ok")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "without a valid session" do
|
139
|
+
let :session do
|
140
|
+
end
|
141
|
+
|
142
|
+
let(:request) do
|
143
|
+
FakeRequest.new.tap do |request|
|
144
|
+
request.path_info = "/a/_/jsonp_send"
|
145
|
+
request.content_type = "application/x-www-form-urlencoded"
|
146
|
+
request.data = "d=sth"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should respond with HTTP 404" do
|
151
|
+
SockJS::debug!
|
152
|
+
response.status.should eql(404)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should respond with plain text MIME type" do
|
156
|
+
response.headers["Content-Type"].should match("text/plain")
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should return error message in the body" do
|
160
|
+
response # Run the handler.
|
161
|
+
response.chunks.last.should match(/Session is not open\!/)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "with any other MIME type" do
|
167
|
+
context "with a valid session" do
|
168
|
+
before :each do
|
169
|
+
session
|
170
|
+
end
|
171
|
+
|
172
|
+
let(:request) do
|
173
|
+
FakeRequest.new.tap do |request|
|
174
|
+
request.path_info = "/jsonp_send"
|
175
|
+
request.data = '["data"]'
|
176
|
+
request.session_key = existing_session_key
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should respond with HTTP 200" do
|
181
|
+
response.status.should eql(200)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should set session ID" do
|
185
|
+
cookie = response.headers["Set-Cookie"]
|
186
|
+
cookie.should match("JSESSIONID=#{request.session_id}; path=/")
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should write 'ok' to the body stream" do
|
190
|
+
response # Run the handler.
|
191
|
+
response.chunks.last.should eql("ok")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "without a valid session" do
|
196
|
+
let :session do
|
197
|
+
end
|
198
|
+
|
199
|
+
let(:request) do
|
200
|
+
FakeRequest.new.tap do |request|
|
201
|
+
request.path_info = "/a/_/jsonp_send"
|
202
|
+
request.data = "data"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should respond with HTTP 404" do
|
207
|
+
response.status.should eql(404)
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should respond with plain text MIME type" do
|
211
|
+
response.headers["Content-Type"].should match("text/plain")
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should return error message in the body" do
|
215
|
+
response.chunks.last.should match(/Session is not open\!/)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
[nil, "", "d=", "f=test"].each do |data|
|
222
|
+
context "with data = #{data.inspect}" do
|
223
|
+
before :each do
|
224
|
+
session
|
225
|
+
end
|
226
|
+
|
227
|
+
let(:request) do
|
228
|
+
FakeRequest.new.tap do |request|
|
229
|
+
request.path_info = "/jsonp_send"
|
230
|
+
request.session_key = "b"
|
231
|
+
request.content_type = "application/x-www-form-urlencoded"
|
232
|
+
request.data = data
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should respond with HTTP 500" do
|
237
|
+
response.status.should eql(500)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should respond with HTML MIME type" do
|
241
|
+
response.headers["Content-Type"].should match("text/html")
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should return error message in the body" do
|
245
|
+
response # Run the handler.
|
246
|
+
response.chunks.last.should match(/Payload expected./)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|