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

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

Powered by Google App Engine
This is Rietveld 408576698