Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: Source/modules/websockets/WebSocketTest.cpp

Issue 298893008: Add WebSocket unittests. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/modules/websockets/WebSocket.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6
7 #include "modules/websockets/WebSocket.h"
8
9 #include "bindings/v8/ExceptionState.h"
10 #include "bindings/v8/V8Binding.h"
11 #include "core/dom/ExceptionCode.h"
12 #include "core/fileapi/Blob.h"
13 #include "core/frame/ConsoleTypes.h"
14 #include "core/testing/DummyPageHolder.h"
15 #include "wtf/ArrayBuffer.h"
16 #include "wtf/OwnPtr.h"
17 #include "wtf/Uint8Array.h"
18 #include "wtf/Vector.h"
19 #include "wtf/testing/WTFTestHelpers.h"
20
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23
24 using testing::_;
25 using testing::InSequence;
26 using testing::Ref;
27 using testing::Return;
28
29 namespace WebCore {
30
31 namespace {
32
33 typedef testing::StrictMock<testing::MockFunction<void(int)> > Checkpoint; // N OLINT
tyoshino (SeeGerritForStatus) 2014/05/26 08:17:51 blank line
yhirano 2014/05/26 11:37:51 Done.
34 class MockWebSocketChannel : public WebSocketChannel {
35 public:
36 static PassRefPtrWillBeRawPtr<MockWebSocketChannel> create()
37 {
38 return adoptRefWillBeRefCountedGarbageCollected(new testing::StrictMock< MockWebSocketChannel>());
39 }
40
41 virtual ~MockWebSocketChannel()
42 {
43 }
44
45 MOCK_METHOD2(connect, bool(const KURL&, const String&));
46 MOCK_METHOD0(subprotocol, String());
47 MOCK_METHOD0(extensions, String());
48 MOCK_METHOD1(send, SendResult(const String&));
49 MOCK_METHOD3(send, SendResult(const ArrayBuffer&, unsigned, unsigned));
50 MOCK_METHOD1(send, SendResult(PassRefPtr<BlobDataHandle>));
51 MOCK_METHOD1(send, SendResult(PassOwnPtr<Vector<char> >));
52 MOCK_CONST_METHOD0(bufferedAmount, unsigned long());
53 MOCK_METHOD2(close, void(int, const String&));
54 MOCK_METHOD4(fail, void(const String&, MessageLevel, const String&, unsigned ));
55 MOCK_METHOD0(disconnect, void());
56 MOCK_METHOD0(suspend, void());
57 MOCK_METHOD0(resume, void());
58 MOCK_METHOD0(stop, void());
59
60 MockWebSocketChannel()
61 {
62 }
63 };
64
65 class WebSocketWithMockChannel : public WebSocket {
66 public:
67 static PassRefPtrWillBeRawPtr<WebSocketWithMockChannel> create(ExecutionCont ext* context)
68 {
69 RefPtrWillBeRawPtr<WebSocketWithMockChannel> websocket = adoptRefWillBeR efCountedGarbageCollected(new WebSocketWithMockChannel(context));
70 websocket->suspendIfNeeded();
71 return websocket;
72 }
73
74 MockWebSocketChannel* channel() { return m_channel.get(); }
75
76 virtual PassRefPtrWillBeRawPtr<WebSocketChannel> createChannel(ExecutionCont ext*, WebSocketChannelClient*) OVERRIDE
77 {
78 ASSERT(!m_hasCreated);
79 m_hasCreated = true;
80 return m_channel;
81 }
82
83 private:
84 WebSocketWithMockChannel(ExecutionContext* context)
85 : WebSocket(context), m_channel(MockWebSocketChannel::create()), m_hasCr eated(false) { }
86
87 RefPtrWillBeRawPtr<MockWebSocketChannel> m_channel;
88 bool m_hasCreated;
89 };
90
91 class WebSocketTestBase {
92 public:
93 WebSocketTestBase()
94 : m_pageHolder(DummyPageHolder::create())
95 , m_websocket(WebSocketWithMockChannel::create(&m_pageHolder->document() ))
96 , m_executionScope(V8ExecutionScope::create(v8::Isolate::GetCurrent()))
97 , m_constructionExceptionState(ExceptionState::ConstructionContext, "pro perty", "interface", m_executionScope->scriptState()->context()->Global(), m_exe cutionScope->isolate())
98 {
99 }
100
101 virtual ~WebSocketTestBase()
102 {
103 }
104
105 OwnPtr<DummyPageHolder> m_pageHolder;
106 RefPtrWillBeRawPtr<WebSocketWithMockChannel> m_websocket;
107 OwnPtr<V8ExecutionScope> m_executionScope;
108 ExceptionState m_constructionExceptionState;
109 };
110
111 class WebSocketTest : public WebSocketTestBase, public ::testing::Test {
112 public:
113 };
114
115 class WebSocketValidClosingCodeTest : public WebSocketTestBase, public ::testing ::TestWithParam<unsigned short> {
116 public:
117 };
118
119 class WebSocketInvalidClosingCodeTest : public WebSocketTestBase, public ::testi ng::TestWithParam<unsigned short> {
120 public:
121 };
tyoshino (SeeGerritForStatus) 2014/05/26 08:17:51 plase see if placing class declaration, the test t
yhirano 2014/05/26 11:37:51 I don't have a strong preference here. Done.
122
123 TEST_F(WebSocketTest, connectToBadURL)
124 {
125 m_websocket->connect("xxx", Vector<String>(), m_constructionExceptionState);
126 const ExceptionState& exceptionState = m_constructionExceptionState;
127
128 EXPECT_TRUE(exceptionState.hadException());
129 EXPECT_EQ(SyntaxError, exceptionState.code());
130 EXPECT_EQ("The URL 'xxx' is invalid.", exceptionState.message());
131 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
132 }
133
134 TEST_F(WebSocketTest, connectToNonWsURL)
135 {
136 m_websocket->connect("http://example.com/", Vector<String>(), m_construction ExceptionState);
137 const ExceptionState& exceptionState = m_constructionExceptionState;
138
139 EXPECT_TRUE(exceptionState.hadException());
140 EXPECT_EQ(SyntaxError, exceptionState.code());
141 EXPECT_EQ("The URL's scheme must be either 'ws' or 'wss'. 'http' is not allo wed.", exceptionState.message());
142 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
143 }
144
145 TEST_F(WebSocketTest, connectToURLHavingFragmentIdentifier)
146 {
147 m_websocket->connect("ws://example.com/#fragment", Vector<String>(), m_const ructionExceptionState);
148 const ExceptionState& exceptionState = m_constructionExceptionState;
149
150 EXPECT_TRUE(exceptionState.hadException());
151 EXPECT_EQ(SyntaxError, exceptionState.code());
152 EXPECT_EQ("The URL contains a fragment identifier ('fragment'). Fragment ide ntifiers are not allowed in WebSocket URLs.", exceptionState.message());
153 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
154 }
155
156 TEST_F(WebSocketTest, invalidPort)
157 {
158 m_websocket->connect("ws://example.com:7", Vector<String>(), m_constructionE xceptionState);
159 const ExceptionState& exceptionState = m_constructionExceptionState;
160
161 EXPECT_TRUE(exceptionState.hadException());
162 EXPECT_EQ(SecurityError, exceptionState.code());
163 EXPECT_EQ("The port 7 is not allowed.", exceptionState.message());
164 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
165 }
166
167 // FIXME: Add a test for Content Security Policy.
168
169 TEST_F(WebSocketTest, invalidSubprotocols)
170 {
171 Vector<String> subprotocols;
172 subprotocols.append("@subprotocol-|'\"x\x01\x02\x03x");
173
174 {
175 InSequence s;
176 EXPECT_CALL(*m_websocket->channel(), disconnect());
tyoshino (SeeGerritForStatus) 2014/05/26 08:17:51 add an accessor to WebSocketTestBase to get m_webs
yhirano 2014/05/26 11:37:51 Done.
177 }
178
179 m_websocket->connect("ws://example.com/", subprotocols, m_constructionExcept ionState);
180 const ExceptionState& exceptionState = m_constructionExceptionState;
181 EXPECT_TRUE(exceptionState.hadException());
182 EXPECT_EQ(SyntaxError, exceptionState.code());
183 EXPECT_EQ("The subprotocol '@subprotocol-|'\"x\\u0001\\u0002\\u0003x' is inv alid.", exceptionState.message());
184 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
185 }
186
187 TEST_F(WebSocketTest, channelConnectSuccess)
188 {
189 Vector<String> subprotocols;
190 subprotocols.append("aa");
191 subprotocols.append("bb");
192
193 {
194 InSequence s;
195 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/hoge"), String("aa, bb"))).WillOnce(Return(true));
196 }
197
198 m_websocket->connect("ws://example.com/hoge", Vector<String>(subprotocols), m_constructionExceptionState);
199 const ExceptionState& exceptionState = m_constructionExceptionState;
200
201 EXPECT_FALSE(exceptionState.hadException());
202 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
203 EXPECT_EQ(KURL(KURL(), "ws://example.com/hoge"), m_websocket->url());
204 }
205
206 TEST_F(WebSocketTest, channelConnectFail)
207 {
208 Vector<String> subprotocols;
209 subprotocols.append("aa");
210 subprotocols.append("bb");
211
212 {
213 InSequence s;
214 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String("aa, bb"))).WillOnce(Return(false));
215 EXPECT_CALL(*m_websocket->channel(), disconnect());
216 }
217
218 m_websocket->connect("ws://example.com/", Vector<String>(subprotocols), m_co nstructionExceptionState);
219 const ExceptionState& exceptionState = m_constructionExceptionState;
220
221 EXPECT_TRUE(exceptionState.hadException());
222 EXPECT_EQ(SecurityError, exceptionState.code());
223 EXPECT_EQ("An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.", exceptionState.message());
224 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
225 }
226
227 TEST_F(WebSocketTest, isValidSubprotocolString)
228 {
229 EXPECT_TRUE(WebSocket::isValidSubprotocolString("Helloworld!!"));
230 EXPECT_FALSE(WebSocket::isValidSubprotocolString("Hello, world!!"));
231 EXPECT_FALSE(WebSocket::isValidSubprotocolString(String()));
232 EXPECT_FALSE(WebSocket::isValidSubprotocolString(""));
233
234 const char validCharacters[] = "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWX YZ^_`abcdefghijklmnopqrstuvwxyz|~";
235 size_t length = strlen(validCharacters);
236 for (size_t i = 0; i < length; ++i) {
237 String s;
238 s.append(static_cast<UChar>(validCharacters[i]));
239 EXPECT_TRUE(WebSocket::isValidSubprotocolString(s));
240 }
241 for (size_t i = 0; i < 256; ++i) {
242 if (std::find(validCharacters, validCharacters + length, static_cast<cha r>(i)) != validCharacters + length) {
243 continue;
244 }
245 String s;
246 s.append(static_cast<UChar>(i));
247 EXPECT_FALSE(WebSocket::isValidSubprotocolString(s));
248 }
249 }
250
251 TEST_F(WebSocketTest, connectSuccess)
252 {
253 Vector<String> subprotocols;
254 subprotocols.append("aa");
255 subprotocols.append("bb");
256 {
257 InSequence s;
258 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String("aa, bb"))).WillOnce(Return(true));
259 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng("bb")));
260 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g("cc")));
261 }
262 m_websocket->connect("ws://example.com/", subprotocols, m_constructionExcept ionState);
263 const ExceptionState& exceptionState = m_constructionExceptionState;
264 EXPECT_FALSE(exceptionState.hadException());
265 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
266
267 m_websocket->didConnect();
268
269 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
270 EXPECT_EQ("bb", m_websocket->protocol());
271 EXPECT_EQ("cc", m_websocket->extensions());
272 }
273
274 TEST_F(WebSocketTest, didClose)
275 {
276 {
277 InSequence s;
278 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
279 EXPECT_CALL(*m_websocket->channel(), disconnect());
280 }
281 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
282 const ExceptionState& exceptionState = m_constructionExceptionState;
283 EXPECT_FALSE(exceptionState.hadException());
284 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
285
286 m_websocket->didClose(0, WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
287
288 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
289 }
290
291 TEST_P(WebSocketValidClosingCodeTest, test)
292 {
293 {
294 InSequence s;
295 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
296 EXPECT_CALL(*m_websocket->channel(), fail(_, _, _, _));
297 }
298 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
299 const ExceptionState& exceptionState = m_constructionExceptionState;
300 EXPECT_FALSE(exceptionState.hadException());
301 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
302
303 m_websocket->close(GetParam(), "bye", m_constructionExceptionState);
304
305 EXPECT_FALSE(exceptionState.hadException());
306 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
307 }
308
309 TEST_P(WebSocketInvalidClosingCodeTest, test)
310 {
311 {
312 InSequence s;
313 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
314 }
315 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
316 const ExceptionState& exceptionState = m_constructionExceptionState;
317 EXPECT_FALSE(exceptionState.hadException());
318 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
319
320 m_websocket->close(GetParam(), "bye", m_constructionExceptionState);
321
322 EXPECT_TRUE(exceptionState.hadException());
323 EXPECT_EQ(InvalidAccessError, exceptionState.code());
324 EXPECT_EQ(String::format("The code must be either 1000, or between 3000 and 4999. %d is neither.", GetParam()), exceptionState.message());
325 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
326 }
327
328 INSTANTIATE_TEST_CASE_P(WebSocketValidClosingCode, WebSocketValidClosingCodeTest , ::testing::Values(1000, 3000, 3001, 4998, 4999));
329 INSTANTIATE_TEST_CASE_P(WebSocketInvalidClosingCode, WebSocketInvalidClosingCode Test, ::testing::Values(0, 1, 998, 999, 1001, 2999, 5000, 9999, 65535));
330
331 TEST_F(WebSocketTest, maximumReasonSize)
332 {
333 {
334 InSequence s;
335 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
336 EXPECT_CALL(*m_websocket->channel(), fail(_, _, _, _));
337 }
338 String reason;
339 for (size_t i = 0; i < 123; ++i)
340 reason.append("a");
341 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
342 const ExceptionState& exceptionState = m_constructionExceptionState;
343 EXPECT_FALSE(exceptionState.hadException());
344 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
345
346 m_websocket->close(1000, reason, m_constructionExceptionState);
347
348 EXPECT_FALSE(exceptionState.hadException());
349 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
350 }
351
352 TEST_F(WebSocketTest, reasonSizeExceeding)
353 {
354 {
355 InSequence s;
356 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
357 }
358 String reason;
359 for (size_t i = 0; i < 124; ++i)
360 reason.append("a");
361 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
362 const ExceptionState& exceptionState = m_constructionExceptionState;
363 EXPECT_FALSE(exceptionState.hadException());
364 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
365
366 m_websocket->close(1000, reason, m_constructionExceptionState);
367
368 EXPECT_TRUE(exceptionState.hadException());
369 EXPECT_EQ(SyntaxError, exceptionState.code());
370 EXPECT_EQ("The message must not be greater than 123 bytes.", exceptionState. message());
371 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
372 }
373
374 TEST_F(WebSocketTest, closeWhenConnecting)
375 {
376 {
377 InSequence s;
378 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
379 EXPECT_CALL(*m_websocket->channel(), fail(String("WebSocket is closed be fore the connection is established."), WarningMessageLevel, String(), 0));
380 }
381 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
382 const ExceptionState& exceptionState = m_constructionExceptionState;
383 EXPECT_FALSE(exceptionState.hadException());
384 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
385
386 m_websocket->close(1000, "bye", m_constructionExceptionState);
387
388 EXPECT_FALSE(exceptionState.hadException());
389 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
390 }
391
392 TEST_F(WebSocketTest, close)
393 {
394 {
395 InSequence s;
396 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
397 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
398 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
399 EXPECT_CALL(*m_websocket->channel(), close(3005, String("bye")));
400 }
401 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
402 const ExceptionState& exceptionState = m_constructionExceptionState;
403 EXPECT_FALSE(exceptionState.hadException());
404 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
405
406 m_websocket->didConnect();
407 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
408 m_websocket->close(3005, "bye", m_constructionExceptionState);
409
410 EXPECT_FALSE(exceptionState.hadException());
411 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
412 }
413
414 TEST_F(WebSocketTest, closeWithoutReason)
415 {
416 {
417 InSequence s;
418 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
419 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
420 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
421 EXPECT_CALL(*m_websocket->channel(), close(3005, String()));
422 }
423 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
424 const ExceptionState& exceptionState = m_constructionExceptionState;
425 EXPECT_FALSE(exceptionState.hadException());
426 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
427
428 m_websocket->didConnect();
429 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
430 m_websocket->close(3005, m_constructionExceptionState);
431
432 EXPECT_FALSE(exceptionState.hadException());
433 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
434 }
435
436 TEST_F(WebSocketTest, closeWithoutCodeAndReason)
437 {
438 {
439 InSequence s;
440 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
441 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
442 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
443 EXPECT_CALL(*m_websocket->channel(), close(-1, String()));
444 }
445 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
446 const ExceptionState& exceptionState = m_constructionExceptionState;
447 EXPECT_FALSE(exceptionState.hadException());
448 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
449
450 m_websocket->didConnect();
451 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
452 m_websocket->close(m_constructionExceptionState);
453
454 EXPECT_FALSE(exceptionState.hadException());
455 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
456 }
457
458 TEST_F(WebSocketTest, closeWhenClosing)
459 {
460 {
461 InSequence s;
462 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
463 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
464 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
465 EXPECT_CALL(*m_websocket->channel(), close(-1, String()));
466 }
467 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
468 const ExceptionState& exceptionState = m_constructionExceptionState;
469 EXPECT_FALSE(exceptionState.hadException());
470 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
471
472 m_websocket->didConnect();
473 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
474 m_websocket->close(m_constructionExceptionState);
475 EXPECT_FALSE(exceptionState.hadException());
476 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
477
478 m_websocket->close(m_constructionExceptionState);
479
480 EXPECT_FALSE(exceptionState.hadException());
481 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
482 }
483
484 TEST_F(WebSocketTest, closeWhenClosed)
485 {
486 {
487 InSequence s;
488 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
489 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
490 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
491 EXPECT_CALL(*m_websocket->channel(), close(-1, String()));
492 EXPECT_CALL(*m_websocket->channel(), disconnect());
493 }
494 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
495 const ExceptionState& exceptionState = m_constructionExceptionState;
496 EXPECT_FALSE(exceptionState.hadException());
497 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
498
499 m_websocket->didConnect();
500 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
501 m_websocket->close(m_constructionExceptionState);
502 EXPECT_FALSE(exceptionState.hadException());
503 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
504
505 m_websocket->didClose(0, WebSocketChannelClient::ClosingHandshakeComplete, 1 000, String());
506 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
507 m_websocket->close(m_constructionExceptionState);
508
509 EXPECT_FALSE(exceptionState.hadException());
510 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
511 }
512
513 TEST_F(WebSocketTest, sendStringWhenConnecting)
514 {
515 {
516 InSequence s;
517 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
518 }
519 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
520 const ExceptionState& exceptionState = m_constructionExceptionState;
521 EXPECT_FALSE(exceptionState.hadException());
522
523 m_websocket->send("hello", m_constructionExceptionState);
524
525 EXPECT_TRUE(exceptionState.hadException());
526 EXPECT_EQ(InvalidStateError, exceptionState.code());
527 EXPECT_EQ("Still in CONNECTING state.", exceptionState.message());
528 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
529 }
530
531 TEST_F(WebSocketTest, sendStringWhenClosing)
532 {
533 Checkpoint checkpoint;
534 {
535 InSequence s;
536 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
537 EXPECT_CALL(*m_websocket->channel(), fail(_, _, _, _));
538 }
539 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
540 const ExceptionState& exceptionState = m_constructionExceptionState;
541 EXPECT_FALSE(exceptionState.hadException());
542
543 m_websocket->close(m_constructionExceptionState);
544 EXPECT_FALSE(exceptionState.hadException());
545
546 m_websocket->send("hello", m_constructionExceptionState);
547
548 EXPECT_FALSE(exceptionState.hadException());
549 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
550 }
551
552 TEST_F(WebSocketTest, sendStringWhenClosed)
553 {
554 Checkpoint checkpoint;
555 {
556 InSequence s;
557 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
558 EXPECT_CALL(*m_websocket->channel(), disconnect());
559 EXPECT_CALL(checkpoint, Call(1));
560 }
561 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
562 const ExceptionState& exceptionState = m_constructionExceptionState;
563 EXPECT_FALSE(exceptionState.hadException());
564
565 m_websocket->didClose(0, WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
566 checkpoint.Call(1);
567
568 m_websocket->send("hello", m_constructionExceptionState);
569
570 EXPECT_FALSE(exceptionState.hadException());
571 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
572 }
573
574 TEST_F(WebSocketTest, sendStringSuccess)
575 {
576 {
577 InSequence s;
578 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
579 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
580 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
581 EXPECT_CALL(*m_websocket->channel(), send(String("hello"))).WillOnce(Ret urn(WebSocketChannel::SendSuccess));
582 }
583 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
584 const ExceptionState& exceptionState = m_constructionExceptionState;
585 EXPECT_FALSE(exceptionState.hadException());
586
587 m_websocket->didConnect();
588 m_websocket->send("hello", m_constructionExceptionState);
589
590 EXPECT_FALSE(exceptionState.hadException());
591 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
592 }
593
594 TEST_F(WebSocketTest, sendStringFail)
595 {
596 {
597 InSequence s;
598 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
599 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
600 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
601 EXPECT_CALL(*m_websocket->channel(), send(String("hello"))).WillOnce(Ret urn(WebSocketChannel::SendFail));
602 }
603 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
604 const ExceptionState& exceptionState = m_constructionExceptionState;
605 EXPECT_FALSE(exceptionState.hadException());
606
607 m_websocket->didConnect();
608 m_websocket->send("hello", m_constructionExceptionState);
609
610 EXPECT_FALSE(exceptionState.hadException());
611 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
612 }
613
614 TEST_F(WebSocketTest, sendStringInvalidMessage)
615 {
616 {
617 InSequence s;
618 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
619 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
620 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
621 EXPECT_CALL(*m_websocket->channel(), send(String("hello"))).WillOnce(Ret urn(WebSocketChannel::InvalidMessage));
622 }
623 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
624 const ExceptionState& exceptionState = m_constructionExceptionState;
625 EXPECT_FALSE(exceptionState.hadException());
626
627 m_websocket->didConnect();
628 m_websocket->send("hello", m_constructionExceptionState);
629
630 EXPECT_TRUE(exceptionState.hadException());
631 EXPECT_EQ(SyntaxError, exceptionState.code());
632 EXPECT_EQ("The message contains invalid characters.", exceptionState.message ());
633 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
634 }
635
636 TEST_F(WebSocketTest, sendArrayBufferWhenConnecting)
637 {
638 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
639 {
640 InSequence s;
641 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
642 }
643 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
644 const ExceptionState& exceptionState = m_constructionExceptionState;
645 EXPECT_FALSE(exceptionState.hadException());
646
647 m_websocket->send(view->buffer().get(), m_constructionExceptionState);
648
649 EXPECT_TRUE(exceptionState.hadException());
650 EXPECT_EQ(InvalidStateError, exceptionState.code());
651 EXPECT_EQ("Still in CONNECTING state.", exceptionState.message());
652 EXPECT_EQ(WebSocket::CONNECTING, m_websocket->readyState());
653 }
654
655 TEST_F(WebSocketTest, sendArrayBufferWhenClosing)
656 {
657 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
658 {
659 InSequence s;
660 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
661 EXPECT_CALL(*m_websocket->channel(), fail(_, _, _, _));
662 }
663 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
664 const ExceptionState& exceptionState = m_constructionExceptionState;
665 EXPECT_FALSE(exceptionState.hadException());
666
667 m_websocket->close(m_constructionExceptionState);
668 EXPECT_FALSE(exceptionState.hadException());
669
670 m_websocket->send(view->buffer().get(), m_constructionExceptionState);
671
672 EXPECT_FALSE(exceptionState.hadException());
673 EXPECT_EQ(WebSocket::CLOSING, m_websocket->readyState());
674 }
675
676 TEST_F(WebSocketTest, sendArrayBufferWhenClosed)
677 {
678 Checkpoint checkpoint;
679 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
680 {
681 InSequence s;
682 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
683 EXPECT_CALL(*m_websocket->channel(), disconnect());
684 EXPECT_CALL(checkpoint, Call(1));
685 }
686 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
687 const ExceptionState& exceptionState = m_constructionExceptionState;
688 EXPECT_FALSE(exceptionState.hadException());
689
690 m_websocket->didClose(0, WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
691 checkpoint.Call(1);
692
693 m_websocket->send(view->buffer().get(), m_constructionExceptionState);
694
695 EXPECT_FALSE(exceptionState.hadException());
696 EXPECT_EQ(WebSocket::CLOSED, m_websocket->readyState());
697 }
698
699 TEST_F(WebSocketTest, sendArrayBufferSuccess)
700 {
701 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
702 {
703 InSequence s;
704 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
705 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
706 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
707 EXPECT_CALL(*m_websocket->channel(), send(Ref(*view->buffer()), 0, 8)).W illOnce(Return(WebSocketChannel::SendSuccess));
708 }
709 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
710 const ExceptionState& exceptionState = m_constructionExceptionState;
711 EXPECT_FALSE(exceptionState.hadException());
712
713 m_websocket->didConnect();
714 m_websocket->send(view->buffer().get(), m_constructionExceptionState);
715
716 EXPECT_FALSE(exceptionState.hadException());
717 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
718 }
719
720 TEST_F(WebSocketTest, sendArrayBufferFail)
721 {
722 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
723 {
724 InSequence s;
725 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
726 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
727 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
728 EXPECT_CALL(*m_websocket->channel(), send(Ref(*view->buffer()), 0, 8)).W illOnce(Return(WebSocketChannel::SendFail));
729 }
730 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
731 const ExceptionState& exceptionState = m_constructionExceptionState;
732 EXPECT_FALSE(exceptionState.hadException());
733
734 m_websocket->didConnect();
735 m_websocket->send(view->buffer().get(), m_constructionExceptionState);
736
737 EXPECT_FALSE(exceptionState.hadException());
738 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
739 }
740
741 TEST_F(WebSocketTest, sendArrayBufferInvalidMessage)
742 {
743 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
744 {
745 InSequence s;
746 EXPECT_CALL(*m_websocket->channel(), connect(KURL(KURL(), "ws://example. com/"), String())).WillOnce(Return(true));
747 EXPECT_CALL(*m_websocket->channel(), subprotocol()).WillOnce(Return(Stri ng()));
748 EXPECT_CALL(*m_websocket->channel(), extensions()).WillOnce(Return(Strin g()));
749 EXPECT_CALL(*m_websocket->channel(), send(Ref(*view->buffer()), 0, 8)).W illOnce(Return(WebSocketChannel::InvalidMessage));
750 }
751 m_websocket->connect("ws://example.com/", Vector<String>(), m_constructionEx ceptionState);
752 const ExceptionState& exceptionState = m_constructionExceptionState;
753 EXPECT_FALSE(exceptionState.hadException());
754
755 m_websocket->didConnect();
756 m_websocket->send(view->buffer().get(), m_constructionExceptionState);
757
758 EXPECT_TRUE(exceptionState.hadException());
759 EXPECT_EQ(SyntaxError, exceptionState.code());
760 EXPECT_EQ("The message contains invalid characters.", exceptionState.message ());
761 EXPECT_EQ(WebSocket::OPEN, m_websocket->readyState());
762 }
763
764 // FIXME: We should have Blob tests here.
765 // We can't create a Blob because the blob registration cannot be mocked yet.
766
767 // FIXME: We should add tests for bufferedAmount.
768
769 // FIXME: We should add tests for data receiving.
770
771 TEST_F(WebSocketTest, binaryType)
772 {
773 EXPECT_EQ("blob", m_websocket->binaryType());
774
775 m_websocket->setBinaryType("hoge");
776
777 EXPECT_EQ("blob", m_websocket->binaryType());
778
779 m_websocket->setBinaryType("arraybuffer");
780
781 EXPECT_EQ("arraybuffer", m_websocket->binaryType());
782
783 m_websocket->setBinaryType("fuga");
784
785 EXPECT_EQ("arraybuffer", m_websocket->binaryType());
786
787 m_websocket->setBinaryType("blob");
788
789 EXPECT_EQ("blob", m_websocket->binaryType());
790 }
791
792 // FIXME: We should add tests for suspend / resume.
793
794 } // namespace
795
796 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/modules/websockets/WebSocket.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698