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.
7 #include "modules/websockets/DOMWebSocket.h"
9 #include "bindings/core/v8/ExceptionState.h"
10 #include "bindings/core/v8/V8Binding.h"
11 #include "core/dom/Document.h"
12 #include "core/dom/ExceptionCode.h"
13 #include "core/fileapi/Blob.h"
14 #include "core/frame/ConsoleTypes.h"
15 #include "core/testing/DummyPageHolder.h"
16 #include "wtf/ArrayBuffer.h"
17 #include "wtf/OwnPtr.h"
18 #include "wtf/Uint8Array.h"
19 #include "wtf/Vector.h"
20 #include "wtf/testing/WTFTestHelpers.h"
21 #include "wtf/text/WTFString.h"
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
27 using testing::AnyNumber;
28 using testing::InSequence;
30 using testing::Return;
36 typedef testing::StrictMock<testing::MockFunction<void(int)> > Checkpoint; // NOLINT
38 class MockWebSocketChannel : public WebSocketChannel {
40 static MockWebSocketChannel* create()
42 return adoptRefCountedGarbageCollected(new testing::StrictMock<MockWebSocketChannel>());
45 virtual ~MockWebSocketChannel()
49 MOCK_METHOD2(connect, bool(const KURL&, const String&));
50 MOCK_METHOD1(send, void(const String&));
51 MOCK_METHOD3(send, void(const ArrayBuffer&, unsigned, unsigned));
52 MOCK_METHOD1(send, void(PassRefPtr<BlobDataHandle>));
53 MOCK_METHOD1(send, void(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());
61 MockWebSocketChannel()
66 class DOMWebSocketWithMockChannel FINAL : public DOMWebSocket {
68 static DOMWebSocketWithMockChannel* create(ExecutionContext* context)
70 DOMWebSocketWithMockChannel* websocket = adoptRefCountedGarbageCollectedWillBeNoop(new DOMWebSocketWithMockChannel(context));
71 websocket->suspendIfNeeded();
75 MockWebSocketChannel* channel() { return m_channel.get(); }
77 virtual WebSocketChannel* createChannel(ExecutionContext*, WebSocketChannelClient*) OVERRIDE
79 ASSERT(!m_hasCreatedChannel);
80 m_hasCreatedChannel = true;
81 return m_channel.get();
84 virtual void trace(Visitor* visitor) OVERRIDE
86 visitor->trace(m_channel);
87 DOMWebSocket::trace(visitor);
91 DOMWebSocketWithMockChannel(ExecutionContext* context)
92 : DOMWebSocket(context)
93 , m_channel(MockWebSocketChannel::create())
94 , m_hasCreatedChannel(false) { }
96 Member<MockWebSocketChannel> m_channel;
97 bool m_hasCreatedChannel;
100 class DOMWebSocketTestBase {
102 DOMWebSocketTestBase()
103 : m_pageHolder(DummyPageHolder::create())
104 , m_websocket(DOMWebSocketWithMockChannel::create(&m_pageHolder->document()))
105 , m_executionScope(v8::Isolate::GetCurrent())
106 , m_exceptionState(ExceptionState::ConstructionContext, "property", "interface", m_executionScope.scriptState()->context()->Global(), m_executionScope.isolate())
110 virtual ~DOMWebSocketTestBase()
114 // These statements are needed to clear WebSocket::m_channel to
115 // avoid ASSERTION failure on ~WebSocket.
116 ASSERT(m_websocket->channel());
117 ::testing::Mock::VerifyAndClear(m_websocket->channel());
118 EXPECT_CALL(channel(), disconnect()).Times(AnyNumber());
120 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
122 Heap::collectAllGarbage();
125 MockWebSocketChannel& channel() { return *m_websocket->channel(); }
127 OwnPtr<DummyPageHolder> m_pageHolder;
128 Persistent<DOMWebSocketWithMockChannel> m_websocket;
129 V8TestingScope m_executionScope;
130 ExceptionState m_exceptionState;
133 class DOMWebSocketTest : public DOMWebSocketTestBase, public ::testing::Test {
137 TEST_F(DOMWebSocketTest, connectToBadURL)
139 m_websocket->connect("xxx", Vector<String>(), m_exceptionState);
142 EXPECT_TRUE(m_exceptionState.hadException());
143 EXPECT_EQ(SyntaxError, m_exceptionState.code());
144 EXPECT_EQ("The URL 'xxx' is invalid.", m_exceptionState.message());
145 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
148 TEST_F(DOMWebSocketTest, connectToNonWsURL)
150 m_websocket->connect("http://example.com/", Vector<String>(), m_exceptionState);
153 EXPECT_TRUE(m_exceptionState.hadException());
154 EXPECT_EQ(SyntaxError, m_exceptionState.code());
155 EXPECT_EQ("The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.", m_exceptionState.message());
156 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
159 TEST_F(DOMWebSocketTest, connectToURLHavingFragmentIdentifier)
161 m_websocket->connect("ws://example.com/#fragment", Vector<String>(), m_exceptionState);
164 EXPECT_TRUE(m_exceptionState.hadException());
165 EXPECT_EQ(SyntaxError, m_exceptionState.code());
166 EXPECT_EQ("The URL contains a fragment identifier ('fragment'). Fragment identifiers are not allowed in WebSocket URLs.", m_exceptionState.message());
167 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
170 TEST_F(DOMWebSocketTest, invalidPort)
172 m_websocket->connect("ws://example.com:7", Vector<String>(), m_exceptionState);
175 EXPECT_TRUE(m_exceptionState.hadException());
176 EXPECT_EQ(SecurityError, m_exceptionState.code());
177 EXPECT_EQ("The port 7 is not allowed.", m_exceptionState.message());
178 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
181 // FIXME: Add a test for Content Security Policy.
183 TEST_F(DOMWebSocketTest, invalidSubprotocols)
185 Vector<String> subprotocols;
186 subprotocols.append("@subprotocol-|'\"x\x01\x02\x03x");
190 EXPECT_CALL(channel(), disconnect());
193 m_websocket->connect("ws://example.com/", subprotocols, m_exceptionState);
195 EXPECT_TRUE(m_exceptionState.hadException());
196 EXPECT_EQ(SyntaxError, m_exceptionState.code());
197 EXPECT_EQ("The subprotocol '@subprotocol-|'\"x\\u0001\\u0002\\u0003x' is invalid.", m_exceptionState.message());
198 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
201 TEST_F(DOMWebSocketTest, channelConnectSuccess)
203 Vector<String> subprotocols;
204 subprotocols.append("aa");
205 subprotocols.append("bb");
209 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/hoge"), String("aa, bb"))).WillOnce(Return(true));
212 m_websocket->connect("ws://example.com/hoge", Vector<String>(subprotocols), m_exceptionState);
215 EXPECT_FALSE(m_exceptionState.hadException());
216 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
217 EXPECT_EQ(KURL(KURL(), "ws://example.com/hoge"), m_websocket->url());
220 TEST_F(DOMWebSocketTest, channelConnectFail)
222 Vector<String> subprotocols;
223 subprotocols.append("aa");
224 subprotocols.append("bb");
228 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String("aa, bb"))).WillOnce(Return(false));
229 EXPECT_CALL(channel(), disconnect());
232 m_websocket->connect("ws://example.com/", Vector<String>(subprotocols), m_exceptionState);
235 EXPECT_TRUE(m_exceptionState.hadException());
236 EXPECT_EQ(SecurityError, m_exceptionState.code());
237 EXPECT_EQ("An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.", m_exceptionState.message());
238 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
241 TEST_F(DOMWebSocketTest, isValidSubprotocolString)
243 EXPECT_TRUE(DOMWebSocket::isValidSubprotocolString("Helloworld!!"));
244 EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString("Hello, world!!"));
245 EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(String()));
246 EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(""));
248 const char validCharacters[] = "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~";
249 size_t length = strlen(validCharacters);
250 for (size_t i = 0; i < length; ++i) {
252 s.append(static_cast<UChar>(validCharacters[i]));
253 EXPECT_TRUE(DOMWebSocket::isValidSubprotocolString(s));
255 for (size_t i = 0; i < 256; ++i) {
256 if (std::find(validCharacters, validCharacters + length, static_cast<char>(i)) != validCharacters + length) {
260 s.append(static_cast<UChar>(i));
261 EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(s));
265 TEST_F(DOMWebSocketTest, connectSuccess)
267 Vector<String> subprotocols;
268 subprotocols.append("aa");
269 subprotocols.append("bb");
272 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String("aa, bb"))).WillOnce(Return(true));
274 m_websocket->connect("ws://example.com/", subprotocols, m_exceptionState);
276 EXPECT_FALSE(m_exceptionState.hadException());
277 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
279 m_websocket->didConnect("bb", "cc");
281 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
282 EXPECT_EQ("bb", m_websocket->protocol());
283 EXPECT_EQ("cc", m_websocket->extensions());
286 TEST_F(DOMWebSocketTest, didClose)
290 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
291 EXPECT_CALL(channel(), disconnect());
293 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
295 EXPECT_FALSE(m_exceptionState.hadException());
296 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
298 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
300 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
303 TEST_F(DOMWebSocketTest, maximumReasonSize)
307 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
308 EXPECT_CALL(channel(), fail(_, _, _, _));
311 for (size_t i = 0; i < 123; ++i)
313 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
315 EXPECT_FALSE(m_exceptionState.hadException());
316 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
318 m_websocket->close(1000, reason, m_exceptionState);
320 EXPECT_FALSE(m_exceptionState.hadException());
321 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
324 TEST_F(DOMWebSocketTest, reasonSizeExceeding)
328 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
331 for (size_t i = 0; i < 124; ++i)
333 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
335 EXPECT_FALSE(m_exceptionState.hadException());
336 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
338 m_websocket->close(1000, reason, m_exceptionState);
340 EXPECT_TRUE(m_exceptionState.hadException());
341 EXPECT_EQ(SyntaxError, m_exceptionState.code());
342 EXPECT_EQ("The message must not be greater than 123 bytes.", m_exceptionState.message());
343 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
346 TEST_F(DOMWebSocketTest, closeWhenConnecting)
350 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
351 EXPECT_CALL(channel(), fail(String("WebSocket is closed before the connection is established."), WarningMessageLevel, String(), 0));
353 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
355 EXPECT_FALSE(m_exceptionState.hadException());
356 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
358 m_websocket->close(1000, "bye", m_exceptionState);
360 EXPECT_FALSE(m_exceptionState.hadException());
361 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
364 TEST_F(DOMWebSocketTest, close)
368 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
369 EXPECT_CALL(channel(), close(3005, String("bye")));
371 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
373 EXPECT_FALSE(m_exceptionState.hadException());
374 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
376 m_websocket->didConnect("", "");
377 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
378 m_websocket->close(3005, "bye", m_exceptionState);
380 EXPECT_FALSE(m_exceptionState.hadException());
381 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
384 TEST_F(DOMWebSocketTest, closeWithoutReason)
388 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
389 EXPECT_CALL(channel(), close(3005, String()));
391 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
393 EXPECT_FALSE(m_exceptionState.hadException());
394 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
396 m_websocket->didConnect("", "");
397 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
398 m_websocket->close(3005, m_exceptionState);
400 EXPECT_FALSE(m_exceptionState.hadException());
401 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
404 TEST_F(DOMWebSocketTest, closeWithoutCodeAndReason)
408 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
409 EXPECT_CALL(channel(), close(-1, String()));
411 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
413 EXPECT_FALSE(m_exceptionState.hadException());
414 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
416 m_websocket->didConnect("", "");
417 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
418 m_websocket->close(m_exceptionState);
420 EXPECT_FALSE(m_exceptionState.hadException());
421 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
424 TEST_F(DOMWebSocketTest, closeWhenClosing)
428 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
429 EXPECT_CALL(channel(), close(-1, String()));
431 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
433 EXPECT_FALSE(m_exceptionState.hadException());
434 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
436 m_websocket->didConnect("", "");
437 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
438 m_websocket->close(m_exceptionState);
439 EXPECT_FALSE(m_exceptionState.hadException());
440 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
442 m_websocket->close(m_exceptionState);
444 EXPECT_FALSE(m_exceptionState.hadException());
445 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
448 TEST_F(DOMWebSocketTest, closeWhenClosed)
452 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
453 EXPECT_CALL(channel(), close(-1, String()));
454 EXPECT_CALL(channel(), disconnect());
456 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
458 EXPECT_FALSE(m_exceptionState.hadException());
459 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
461 m_websocket->didConnect("", "");
462 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
463 m_websocket->close(m_exceptionState);
464 EXPECT_FALSE(m_exceptionState.hadException());
465 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
467 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeComplete, 1000, String());
468 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
469 m_websocket->close(m_exceptionState);
471 EXPECT_FALSE(m_exceptionState.hadException());
472 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
475 TEST_F(DOMWebSocketTest, sendStringWhenConnecting)
479 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
481 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
483 EXPECT_FALSE(m_exceptionState.hadException());
485 m_websocket->send("hello", m_exceptionState);
487 EXPECT_TRUE(m_exceptionState.hadException());
488 EXPECT_EQ(InvalidStateError, m_exceptionState.code());
489 EXPECT_EQ("Still in CONNECTING state.", m_exceptionState.message());
490 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
493 TEST_F(DOMWebSocketTest, sendStringWhenClosing)
495 Checkpoint checkpoint;
498 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
499 EXPECT_CALL(channel(), fail(_, _, _, _));
501 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
503 EXPECT_FALSE(m_exceptionState.hadException());
505 m_websocket->close(m_exceptionState);
506 EXPECT_FALSE(m_exceptionState.hadException());
508 m_websocket->send("hello", m_exceptionState);
510 EXPECT_FALSE(m_exceptionState.hadException());
511 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
514 TEST_F(DOMWebSocketTest, sendStringWhenClosed)
516 Checkpoint checkpoint;
519 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
520 EXPECT_CALL(channel(), disconnect());
521 EXPECT_CALL(checkpoint, Call(1));
523 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
525 EXPECT_FALSE(m_exceptionState.hadException());
527 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
530 m_websocket->send("hello", m_exceptionState);
532 EXPECT_FALSE(m_exceptionState.hadException());
533 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
536 TEST_F(DOMWebSocketTest, sendStringSuccess)
540 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
541 EXPECT_CALL(channel(), send(String("hello")));
543 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
545 EXPECT_FALSE(m_exceptionState.hadException());
547 m_websocket->didConnect("", "");
548 m_websocket->send("hello", m_exceptionState);
550 EXPECT_FALSE(m_exceptionState.hadException());
551 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
554 TEST_F(DOMWebSocketTest, sendArrayBufferWhenConnecting)
556 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
559 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
561 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
563 EXPECT_FALSE(m_exceptionState.hadException());
565 m_websocket->send(view->buffer().get(), m_exceptionState);
567 EXPECT_TRUE(m_exceptionState.hadException());
568 EXPECT_EQ(InvalidStateError, m_exceptionState.code());
569 EXPECT_EQ("Still in CONNECTING state.", m_exceptionState.message());
570 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
573 TEST_F(DOMWebSocketTest, sendArrayBufferWhenClosing)
575 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
578 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
579 EXPECT_CALL(channel(), fail(_, _, _, _));
581 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
583 EXPECT_FALSE(m_exceptionState.hadException());
585 m_websocket->close(m_exceptionState);
586 EXPECT_FALSE(m_exceptionState.hadException());
588 m_websocket->send(view->buffer().get(), m_exceptionState);
590 EXPECT_FALSE(m_exceptionState.hadException());
591 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
594 TEST_F(DOMWebSocketTest, sendArrayBufferWhenClosed)
596 Checkpoint checkpoint;
597 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
600 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
601 EXPECT_CALL(channel(), disconnect());
602 EXPECT_CALL(checkpoint, Call(1));
604 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
606 EXPECT_FALSE(m_exceptionState.hadException());
608 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
611 m_websocket->send(view->buffer().get(), m_exceptionState);
613 EXPECT_FALSE(m_exceptionState.hadException());
614 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
617 TEST_F(DOMWebSocketTest, sendArrayBufferSuccess)
619 RefPtr<ArrayBufferView> view = Uint8Array::create(8);
622 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
623 EXPECT_CALL(channel(), send(Ref(*view->buffer()), 0, 8));
625 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
627 EXPECT_FALSE(m_exceptionState.hadException());
629 m_websocket->didConnect("", "");
630 m_websocket->send(view->buffer().get(), m_exceptionState);
632 EXPECT_FALSE(m_exceptionState.hadException());
633 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
636 // FIXME: We should have Blob tests here.
637 // We can't create a Blob because the blob registration cannot be mocked yet.
639 // FIXME: We should add tests for bufferedAmount.
641 // FIXME: We should add tests for data receiving.
643 TEST_F(DOMWebSocketTest, binaryType)
645 EXPECT_EQ("blob", m_websocket->binaryType());
647 m_websocket->setBinaryType("hoge");
649 EXPECT_EQ("blob", m_websocket->binaryType());
651 m_websocket->setBinaryType("arraybuffer");
653 EXPECT_EQ("arraybuffer", m_websocket->binaryType());
655 m_websocket->setBinaryType("fuga");
657 EXPECT_EQ("arraybuffer", m_websocket->binaryType());
659 m_websocket->setBinaryType("blob");
661 EXPECT_EQ("blob", m_websocket->binaryType());
664 // FIXME: We should add tests for suspend / resume.
666 class DOMWebSocketValidClosingTest : public DOMWebSocketTestBase, public ::testing::TestWithParam<unsigned short> {
670 TEST_P(DOMWebSocketValidClosingTest, test)
674 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
675 EXPECT_CALL(channel(), fail(_, _, _, _));
677 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
679 EXPECT_FALSE(m_exceptionState.hadException());
680 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
682 m_websocket->close(GetParam(), "bye", m_exceptionState);
684 EXPECT_FALSE(m_exceptionState.hadException());
685 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
688 INSTANTIATE_TEST_CASE_P(DOMWebSocketValidClosing, DOMWebSocketValidClosingTest, ::testing::Values(1000, 3000, 3001, 4998, 4999));
690 class DOMWebSocketInvalidClosingCodeTest : public DOMWebSocketTestBase, public ::testing::TestWithParam<unsigned short> {
694 TEST_P(DOMWebSocketInvalidClosingCodeTest, test)
698 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
700 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
702 EXPECT_FALSE(m_exceptionState.hadException());
703 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
705 m_websocket->close(GetParam(), "bye", m_exceptionState);
707 EXPECT_TRUE(m_exceptionState.hadException());
708 EXPECT_EQ(InvalidAccessError, m_exceptionState.code());
709 EXPECT_EQ(String::format("The code must be either 1000, or between 3000 and 4999. %d is neither.", GetParam()), m_exceptionState.message());
710 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
713 INSTANTIATE_TEST_CASE_P(DOMWebSocketInvalidClosingCode, DOMWebSocketInvalidClosingCodeTest, ::testing::Values(0, 1, 998, 999, 1001, 2999, 5000, 9999, 65535));