ld-eventsource 1.0.2 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,263 +0,0 @@
1
- require "ld-eventsource/impl/streaming_http"
2
- require "socketry"
3
- require "http_stub"
4
-
5
- #
6
- # End-to-end tests of HTTP requests against a real server
7
- #
8
- describe SSE::Impl::StreamingHTTPConnection do
9
- subject { SSE::Impl::StreamingHTTPConnection }
10
-
11
- def with_connection(cxn)
12
- begin
13
- yield cxn
14
- ensure
15
- cxn.close
16
- end
17
- end
18
-
19
- it "makes HTTP connection and sends request" do
20
- with_server do |server|
21
- requests = Queue.new
22
- server.setup_response("/foo") do |req,res|
23
- requests << req
24
- res.status = 200
25
- end
26
- headers = {
27
- "Accept" => "text/plain"
28
- }
29
- with_connection(subject.new(server.base_uri.merge("/foo?bar"), headers: headers)) do
30
- received_req = requests.pop
31
- expect(received_req.unparsed_uri).to eq("/foo?bar")
32
- expect(received_req.header).to eq({
33
- "accept" => ["text/plain"],
34
- "host" => [server.base_uri.host]
35
- })
36
- end
37
- end
38
- end
39
-
40
- it "receives response status" do
41
- with_server do |server|
42
- server.setup_response("/foo") do |req,res|
43
- res.status = 204
44
- end
45
- with_connection(subject.new(server.base_uri.merge("/foo"))) do |cxn|
46
- expect(cxn.status).to eq(204)
47
- end
48
- end
49
- end
50
-
51
- it "receives response headers" do
52
- with_server do |server|
53
- server.setup_response("/foo") do |req,res|
54
- res["Content-Type"] = "application/json"
55
- end
56
- with_connection(subject.new(server.base_uri.merge("/foo"))) do |cxn|
57
- expect(cxn.headers["content-type"]).to eq("application/json")
58
- end
59
- end
60
- end
61
-
62
- it "can read response as lines" do
63
- body = <<-EOT
64
- This is
65
- a response
66
- EOT
67
- with_server do |server|
68
- server.setup_response("/foo") do |req,res|
69
- res.body = body
70
- end
71
- with_connection(subject.new(server.base_uri.merge("/foo"))) do |cxn|
72
- lines = cxn.read_lines
73
- expect(lines.next).to eq("This is\n")
74
- expect(lines.next).to eq("a response\n")
75
- end
76
- end
77
- end
78
-
79
- it "can read entire response body" do
80
- body = <<-EOT
81
- This is
82
- a response
83
- EOT
84
- with_server do |server|
85
- server.setup_response("/foo") do |req,res|
86
- res.body = body
87
- end
88
- with_connection(subject.new(server.base_uri.merge("/foo"))) do |cxn|
89
- read_body = cxn.read_all
90
- expect(read_body).to eq("This is\na response\n")
91
- end
92
- end
93
- end
94
-
95
- it "enforces read timeout" do
96
- with_server do |server|
97
- server.setup_response("/") do |req,res|
98
- sleep(2)
99
- res.status = 200
100
- end
101
- expect { subject.new(server.base_uri, read_timeout: 0.25) }.to raise_error(SSE::Errors::ReadTimeoutError)
102
- end
103
- end
104
-
105
- it "connects to HTTP server through proxy" do
106
- body = "hi"
107
- with_server do |server|
108
- server.setup_response("/") do |req,res|
109
- res.body = body
110
- end
111
- with_server(StubProxyServer.new) do |proxy|
112
- with_connection(subject.new(server.base_uri, proxy: proxy.base_uri)) do |cxn|
113
- read_body = cxn.read_all
114
- expect(read_body).to eq("hi")
115
- expect(proxy.request_count).to eq(1)
116
- end
117
- end
118
- end
119
- end
120
-
121
- it "throws error if proxy responds with error status" do
122
- with_server do |server|
123
- server.setup_response("/") do |req,res|
124
- res.body = body
125
- end
126
- with_server(StubProxyServer.new) do |proxy|
127
- proxy.connect_status = 403
128
- expect { subject.new(server.base_uri, proxy: proxy.base_uri) }.to raise_error(SSE::Errors::HTTPProxyError)
129
- end
130
- end
131
- end
132
-
133
- # The following 2 tests were originally written to connect to an embedded HTTPS server made with
134
- # WEBrick. Unfortunately, some unknown problem prevents WEBrick's self-signed certificate feature
135
- # from working in JRuby 9.1 (but not in any other Ruby version). Therefore these tests currently
136
- # hit an external URL.
137
-
138
- it "connects to HTTPS server" do
139
- with_connection(subject.new(URI("https://app.launchdarkly.com"))) do |cxn|
140
- expect(cxn.status).to eq 200
141
- end
142
- end
143
-
144
- it "connects to HTTPS server through proxy" do
145
- with_server(StubProxyServer.new) do |proxy|
146
- with_connection(subject.new(URI("https://app.launchdarkly.com"), proxy: proxy.base_uri)) do |cxn|
147
- expect(cxn.status).to eq 200
148
- expect(proxy.request_count).to eq(1)
149
- end
150
- end
151
- end
152
- end
153
-
154
- #
155
- # Tests of response parsing functionality without a real HTTP request
156
- #
157
- describe SSE::Impl::HTTPResponseReader do
158
- subject { SSE::Impl::HTTPResponseReader }
159
-
160
- let(:simple_response) { <<-EOT
161
- HTTP/1.1 200 OK
162
- Cache-Control: no-cache
163
- Content-Type: text/event-stream
164
-
165
- line1\r
166
- line2
167
- \r
168
- EOT
169
- }
170
-
171
- def make_chunks(str)
172
- # arbitrarily split content into 5-character blocks
173
- str.scan(/.{1,5}/m).to_enum
174
- end
175
-
176
- def mock_socket_without_timeout(chunks)
177
- mock_socket(chunks) { :eof }
178
- end
179
-
180
- def mock_socket_with_timeout(chunks)
181
- mock_socket(chunks) { raise Socketry::TimeoutError }
182
- end
183
-
184
- def mock_socket(chunks)
185
- sock = double
186
- allow(sock).to receive(:readpartial) do
187
- begin
188
- chunks.next
189
- rescue StopIteration
190
- yield
191
- end
192
- end
193
- sock
194
- end
195
-
196
- it "parses status code" do
197
- socket = mock_socket_without_timeout(make_chunks(simple_response))
198
- reader = subject.new(socket, 0)
199
- expect(reader.status).to eq(200)
200
- end
201
-
202
- it "parses headers" do
203
- socket = mock_socket_without_timeout(make_chunks(simple_response))
204
- reader = subject.new(socket, 0)
205
- expect(reader.headers).to eq({
206
- 'cache-control' => 'no-cache',
207
- 'content-type' => 'text/event-stream'
208
- })
209
- end
210
-
211
- it "can read entire response body" do
212
- socket = mock_socket_without_timeout(make_chunks(simple_response))
213
- reader = subject.new(socket, 0)
214
- expect(reader.read_all).to eq("line1\r\nline2\n\r\n")
215
- end
216
-
217
- it "can read response body as lines" do
218
- socket = mock_socket_without_timeout(make_chunks(simple_response))
219
- reader = subject.new(socket, 0)
220
- expect(reader.read_lines.to_a).to eq([
221
- "line1\r\n",
222
- "line2\n",
223
- "\r\n"
224
- ])
225
- end
226
-
227
- it "handles chunked encoding" do
228
- chunked_response = <<-EOT
229
- HTTP/1.1 200 OK
230
- Content-Type: text/plain
231
- Transfer-Encoding: chunked
232
-
233
- 6\r
234
- things\r
235
- A\r
236
- and stuff\r
237
- 0\r
238
- \r
239
- EOT
240
- socket = mock_socket_without_timeout(make_chunks(chunked_response))
241
- reader = subject.new(socket, 0)
242
- expect(reader.read_all).to eq("things and stuff")
243
- end
244
-
245
- it "raises error if response ends without complete headers" do
246
- malformed_response = <<-EOT
247
- HTTP/1.1 200 OK
248
- Cache-Control: no-cache
249
- EOT
250
- socket = mock_socket_without_timeout(make_chunks(malformed_response))
251
- expect { subject.new(socket, 0) }.to raise_error(EOFError)
252
- end
253
-
254
- it "throws timeout if thrown by socket read" do
255
- socket = mock_socket_with_timeout(make_chunks(simple_response))
256
- reader = subject.new(socket, 0)
257
- lines = reader.read_lines
258
- lines.next
259
- lines.next
260
- lines.next
261
- expect { lines.next }.to raise_error(SSE::Errors::ReadTimeoutError)
262
- end
263
- end