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.
6 #include "modules/websockets/DOMWebSocket.h"
8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/V8Binding.h"
10 #include "core/dom/DOMTypedArray.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/OwnPtr.h"
17 #include "wtf/Vector.h"
18 #include "wtf/testing/WTFTestHelpers.h"
19 #include "wtf/text/WTFString.h"
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
25 using testing::AnyNumber;
26 using testing::InSequence;
28 using testing::Return;
34 typedef testing::StrictMock<testing::MockFunction<void(int)> > Checkpoint; // NOLINT
36 class MockWebSocketChannel : public WebSocketChannel {
38 static MockWebSocketChannel* create()
40 return new testing::StrictMock<MockWebSocketChannel>();
43 virtual ~MockWebSocketChannel()
47 MOCK_METHOD2(connect, bool(const KURL&, const String&));
48 MOCK_METHOD1(send, void(const String&));
49 MOCK_METHOD3(send, void(const ArrayBuffer&, unsigned, unsigned));
50 MOCK_METHOD1(send, void(PassRefPtr<BlobDataHandle>));
51 MOCK_METHOD1(send, void(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());
59 MockWebSocketChannel()
64 class DOMWebSocketWithMockChannel final : public DOMWebSocket {
66 static DOMWebSocketWithMockChannel* create(ExecutionContext* context)
68 DOMWebSocketWithMockChannel* websocket = new DOMWebSocketWithMockChannel(context);
69 websocket->suspendIfNeeded();
73 MockWebSocketChannel* channel() { return m_channel.get(); }
75 virtual WebSocketChannel* createChannel(ExecutionContext*, WebSocketChannelClient*) override
77 ASSERT(!m_hasCreatedChannel);
78 m_hasCreatedChannel = true;
79 return m_channel.get();
82 virtual void trace(Visitor* visitor) override
84 visitor->trace(m_channel);
85 DOMWebSocket::trace(visitor);
89 DOMWebSocketWithMockChannel(ExecutionContext* context)
90 : DOMWebSocket(context)
91 , m_channel(MockWebSocketChannel::create())
92 , m_hasCreatedChannel(false) { }
94 Member<MockWebSocketChannel> m_channel;
95 bool m_hasCreatedChannel;
98 class DOMWebSocketTestBase {
100 DOMWebSocketTestBase()
101 : m_pageHolder(DummyPageHolder::create())
102 , m_websocket(DOMWebSocketWithMockChannel::create(&m_pageHolder->document()))
103 , m_executionScope(v8::Isolate::GetCurrent())
104 , m_exceptionState(ExceptionState::ConstructionContext, "property", "interface", m_executionScope.scriptState()->context()->Global(), m_executionScope.isolate())
108 virtual ~DOMWebSocketTestBase()
112 // These statements are needed to clear WebSocket::m_channel to
113 // avoid ASSERTION failure on ~DOMWebSocket.
114 ASSERT(m_websocket->channel());
115 ::testing::Mock::VerifyAndClear(m_websocket->channel());
116 EXPECT_CALL(channel(), disconnect()).Times(AnyNumber());
118 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
121 MockWebSocketChannel& channel() { return *m_websocket->channel(); }
123 OwnPtr<DummyPageHolder> m_pageHolder;
124 Persistent<DOMWebSocketWithMockChannel> m_websocket;
125 V8TestingScope m_executionScope;
126 ExceptionState m_exceptionState;
129 class DOMWebSocketTest : public DOMWebSocketTestBase, public ::testing::Test {
133 TEST_F(DOMWebSocketTest, connectToBadURL)
135 m_websocket->connect("xxx", Vector<String>(), m_exceptionState);
138 EXPECT_TRUE(m_exceptionState.hadException());
139 EXPECT_EQ(SyntaxError, m_exceptionState.code());
140 EXPECT_EQ("The URL 'xxx' is invalid.", m_exceptionState.message());
141 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
144 TEST_F(DOMWebSocketTest, connectToNonWsURL)
146 m_websocket->connect("http://example.com/", Vector<String>(), m_exceptionState);
149 EXPECT_TRUE(m_exceptionState.hadException());
150 EXPECT_EQ(SyntaxError, m_exceptionState.code());
151 EXPECT_EQ("The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.", m_exceptionState.message());
152 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
155 TEST_F(DOMWebSocketTest, connectToURLHavingFragmentIdentifier)
157 m_websocket->connect("ws://example.com/#fragment", Vector<String>(), m_exceptionState);
160 EXPECT_TRUE(m_exceptionState.hadException());
161 EXPECT_EQ(SyntaxError, m_exceptionState.code());
162 EXPECT_EQ("The URL contains a fragment identifier ('fragment'). Fragment identifiers are not allowed in WebSocket URLs.", m_exceptionState.message());
163 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
166 TEST_F(DOMWebSocketTest, invalidPort)
168 m_websocket->connect("ws://example.com:7", Vector<String>(), m_exceptionState);
171 EXPECT_TRUE(m_exceptionState.hadException());
172 EXPECT_EQ(SecurityError, m_exceptionState.code());
173 EXPECT_EQ("The port 7 is not allowed.", m_exceptionState.message());
174 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
177 // FIXME: Add a test for Content Security Policy.
179 TEST_F(DOMWebSocketTest, invalidSubprotocols)
181 Vector<String> subprotocols;
182 subprotocols.append("@subprotocol-|'\"x\x01\x02\x03x");
184 m_websocket->connect("ws://example.com/", subprotocols, m_exceptionState);
186 EXPECT_TRUE(m_exceptionState.hadException());
187 EXPECT_EQ(SyntaxError, m_exceptionState.code());
188 EXPECT_EQ("The subprotocol '@subprotocol-|'\"x\\u0001\\u0002\\u0003x' is invalid.", m_exceptionState.message());
189 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
192 TEST_F(DOMWebSocketTest, channelConnectSuccess)
194 Vector<String> subprotocols;
195 subprotocols.append("aa");
196 subprotocols.append("bb");
200 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/hoge"), String("aa, bb"))).WillOnce(Return(true));
203 m_websocket->connect("ws://example.com/hoge", Vector<String>(subprotocols), m_exceptionState);
206 EXPECT_FALSE(m_exceptionState.hadException());
207 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
208 EXPECT_EQ(KURL(KURL(), "ws://example.com/hoge"), m_websocket->url());
211 TEST_F(DOMWebSocketTest, channelConnectFail)
213 Vector<String> subprotocols;
214 subprotocols.append("aa");
215 subprotocols.append("bb");
219 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String("aa, bb"))).WillOnce(Return(false));
220 EXPECT_CALL(channel(), disconnect());
223 m_websocket->connect("ws://example.com/", Vector<String>(subprotocols), m_exceptionState);
226 EXPECT_TRUE(m_exceptionState.hadException());
227 EXPECT_EQ(SecurityError, m_exceptionState.code());
228 EXPECT_EQ("An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.", m_exceptionState.message());
229 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
232 TEST_F(DOMWebSocketTest, isValidSubprotocolString)
234 EXPECT_TRUE(DOMWebSocket::isValidSubprotocolString("Helloworld!!"));
235 EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString("Hello, world!!"));
236 EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(String()));
237 EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(""));
239 const char validCharacters[] = "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~";
240 size_t length = strlen(validCharacters);
241 for (size_t i = 0; i < length; ++i) {
243 s.append(static_cast<UChar>(validCharacters[i]));
244 EXPECT_TRUE(DOMWebSocket::isValidSubprotocolString(s));
246 for (size_t i = 0; i < 256; ++i) {
247 if (std::find(validCharacters, validCharacters + length, static_cast<char>(i)) != validCharacters + length) {
251 s.append(static_cast<UChar>(i));
252 EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(s));
256 TEST_F(DOMWebSocketTest, connectSuccess)
258 Vector<String> subprotocols;
259 subprotocols.append("aa");
260 subprotocols.append("bb");
263 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String("aa, bb"))).WillOnce(Return(true));
265 m_websocket->connect("ws://example.com/", subprotocols, m_exceptionState);
267 EXPECT_FALSE(m_exceptionState.hadException());
268 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
270 m_websocket->didConnect("bb", "cc");
272 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
273 EXPECT_EQ("bb", m_websocket->protocol());
274 EXPECT_EQ("cc", m_websocket->extensions());
277 TEST_F(DOMWebSocketTest, didClose)
281 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
282 EXPECT_CALL(channel(), disconnect());
284 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
286 EXPECT_FALSE(m_exceptionState.hadException());
287 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
289 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
291 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
294 TEST_F(DOMWebSocketTest, maximumReasonSize)
298 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
299 EXPECT_CALL(channel(), fail(_, _, _, _));
302 for (size_t i = 0; i < 123; ++i)
304 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
306 EXPECT_FALSE(m_exceptionState.hadException());
307 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
309 m_websocket->close(1000, reason, m_exceptionState);
311 EXPECT_FALSE(m_exceptionState.hadException());
312 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
315 TEST_F(DOMWebSocketTest, reasonSizeExceeding)
319 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
322 for (size_t i = 0; i < 124; ++i)
324 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
326 EXPECT_FALSE(m_exceptionState.hadException());
327 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
329 m_websocket->close(1000, reason, m_exceptionState);
331 EXPECT_TRUE(m_exceptionState.hadException());
332 EXPECT_EQ(SyntaxError, m_exceptionState.code());
333 EXPECT_EQ("The message must not be greater than 123 bytes.", m_exceptionState.message());
334 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
337 TEST_F(DOMWebSocketTest, closeWhenConnecting)
341 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
342 EXPECT_CALL(channel(), fail(String("WebSocket is closed before the connection is established."), WarningMessageLevel, String(), 0));
344 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
346 EXPECT_FALSE(m_exceptionState.hadException());
347 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
349 m_websocket->close(1000, "bye", m_exceptionState);
351 EXPECT_FALSE(m_exceptionState.hadException());
352 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
355 TEST_F(DOMWebSocketTest, close)
359 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
360 EXPECT_CALL(channel(), close(3005, String("bye")));
362 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
364 EXPECT_FALSE(m_exceptionState.hadException());
365 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
367 m_websocket->didConnect("", "");
368 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
369 m_websocket->close(3005, "bye", m_exceptionState);
371 EXPECT_FALSE(m_exceptionState.hadException());
372 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
375 TEST_F(DOMWebSocketTest, closeWithoutReason)
379 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
380 EXPECT_CALL(channel(), close(3005, String()));
382 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
384 EXPECT_FALSE(m_exceptionState.hadException());
385 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
387 m_websocket->didConnect("", "");
388 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
389 m_websocket->close(3005, m_exceptionState);
391 EXPECT_FALSE(m_exceptionState.hadException());
392 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
395 TEST_F(DOMWebSocketTest, closeWithoutCodeAndReason)
399 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
400 EXPECT_CALL(channel(), close(-1, String()));
402 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
404 EXPECT_FALSE(m_exceptionState.hadException());
405 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
407 m_websocket->didConnect("", "");
408 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
409 m_websocket->close(m_exceptionState);
411 EXPECT_FALSE(m_exceptionState.hadException());
412 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
415 TEST_F(DOMWebSocketTest, closeWhenClosing)
419 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
420 EXPECT_CALL(channel(), close(-1, String()));
422 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
424 EXPECT_FALSE(m_exceptionState.hadException());
425 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
427 m_websocket->didConnect("", "");
428 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
429 m_websocket->close(m_exceptionState);
430 EXPECT_FALSE(m_exceptionState.hadException());
431 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
433 m_websocket->close(m_exceptionState);
435 EXPECT_FALSE(m_exceptionState.hadException());
436 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
439 TEST_F(DOMWebSocketTest, closeWhenClosed)
443 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
444 EXPECT_CALL(channel(), close(-1, String()));
445 EXPECT_CALL(channel(), disconnect());
447 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
449 EXPECT_FALSE(m_exceptionState.hadException());
450 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
452 m_websocket->didConnect("", "");
453 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
454 m_websocket->close(m_exceptionState);
455 EXPECT_FALSE(m_exceptionState.hadException());
456 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
458 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeComplete, 1000, String());
459 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
460 m_websocket->close(m_exceptionState);
462 EXPECT_FALSE(m_exceptionState.hadException());
463 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
466 TEST_F(DOMWebSocketTest, sendStringWhenConnecting)
470 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
472 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
474 EXPECT_FALSE(m_exceptionState.hadException());
476 m_websocket->send("hello", m_exceptionState);
478 EXPECT_TRUE(m_exceptionState.hadException());
479 EXPECT_EQ(InvalidStateError, m_exceptionState.code());
480 EXPECT_EQ("Still in CONNECTING state.", m_exceptionState.message());
481 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
484 TEST_F(DOMWebSocketTest, sendStringWhenClosing)
486 Checkpoint checkpoint;
489 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
490 EXPECT_CALL(channel(), fail(_, _, _, _));
492 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
494 EXPECT_FALSE(m_exceptionState.hadException());
496 m_websocket->close(m_exceptionState);
497 EXPECT_FALSE(m_exceptionState.hadException());
499 m_websocket->send("hello", m_exceptionState);
501 EXPECT_FALSE(m_exceptionState.hadException());
502 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
505 TEST_F(DOMWebSocketTest, sendStringWhenClosed)
507 Checkpoint checkpoint;
510 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
511 EXPECT_CALL(channel(), disconnect());
512 EXPECT_CALL(checkpoint, Call(1));
514 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
516 EXPECT_FALSE(m_exceptionState.hadException());
518 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
521 m_websocket->send("hello", m_exceptionState);
523 EXPECT_FALSE(m_exceptionState.hadException());
524 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
527 TEST_F(DOMWebSocketTest, sendStringSuccess)
531 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
532 EXPECT_CALL(channel(), send(String("hello")));
534 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
536 EXPECT_FALSE(m_exceptionState.hadException());
538 m_websocket->didConnect("", "");
539 m_websocket->send("hello", m_exceptionState);
541 EXPECT_FALSE(m_exceptionState.hadException());
542 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
545 TEST_F(DOMWebSocketTest, sendArrayBufferWhenConnecting)
547 RefPtr<DOMArrayBufferView> view = DOMUint8Array::create(8);
550 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
552 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
554 EXPECT_FALSE(m_exceptionState.hadException());
556 m_websocket->send(view->buffer().get(), m_exceptionState);
558 EXPECT_TRUE(m_exceptionState.hadException());
559 EXPECT_EQ(InvalidStateError, m_exceptionState.code());
560 EXPECT_EQ("Still in CONNECTING state.", m_exceptionState.message());
561 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
564 TEST_F(DOMWebSocketTest, sendArrayBufferWhenClosing)
566 RefPtr<DOMArrayBufferView> view = DOMUint8Array::create(8);
569 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
570 EXPECT_CALL(channel(), fail(_, _, _, _));
572 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
574 EXPECT_FALSE(m_exceptionState.hadException());
576 m_websocket->close(m_exceptionState);
577 EXPECT_FALSE(m_exceptionState.hadException());
579 m_websocket->send(view->buffer().get(), m_exceptionState);
581 EXPECT_FALSE(m_exceptionState.hadException());
582 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
585 TEST_F(DOMWebSocketTest, sendArrayBufferWhenClosed)
587 Checkpoint checkpoint;
588 RefPtr<DOMArrayBufferView> view = DOMUint8Array::create(8);
591 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
592 EXPECT_CALL(channel(), disconnect());
593 EXPECT_CALL(checkpoint, Call(1));
595 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
597 EXPECT_FALSE(m_exceptionState.hadException());
599 m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
602 m_websocket->send(view->buffer().get(), m_exceptionState);
604 EXPECT_FALSE(m_exceptionState.hadException());
605 EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
608 TEST_F(DOMWebSocketTest, sendArrayBufferSuccess)
610 RefPtr<DOMArrayBufferView> view = DOMUint8Array::create(8);
613 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
614 EXPECT_CALL(channel(), send(Ref(*view->view()->buffer()), 0, 8));
616 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
618 EXPECT_FALSE(m_exceptionState.hadException());
620 m_websocket->didConnect("", "");
621 m_websocket->send(view->buffer().get(), m_exceptionState);
623 EXPECT_FALSE(m_exceptionState.hadException());
624 EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
627 // FIXME: We should have Blob tests here.
628 // We can't create a Blob because the blob registration cannot be mocked yet.
630 // FIXME: We should add tests for bufferedAmount.
632 // FIXME: We should add tests for data receiving.
634 TEST_F(DOMWebSocketTest, binaryType)
636 EXPECT_EQ("blob", m_websocket->binaryType());
638 m_websocket->setBinaryType("hoge");
640 EXPECT_EQ("blob", m_websocket->binaryType());
642 m_websocket->setBinaryType("arraybuffer");
644 EXPECT_EQ("arraybuffer", m_websocket->binaryType());
646 m_websocket->setBinaryType("fuga");
648 EXPECT_EQ("arraybuffer", m_websocket->binaryType());
650 m_websocket->setBinaryType("blob");
652 EXPECT_EQ("blob", m_websocket->binaryType());
655 // FIXME: We should add tests for suspend / resume.
657 class DOMWebSocketValidClosingTest : public DOMWebSocketTestBase, public ::testing::TestWithParam<unsigned short> {
661 TEST_P(DOMWebSocketValidClosingTest, test)
665 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
666 EXPECT_CALL(channel(), fail(_, _, _, _));
668 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
670 EXPECT_FALSE(m_exceptionState.hadException());
671 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
673 m_websocket->close(GetParam(), "bye", m_exceptionState);
675 EXPECT_FALSE(m_exceptionState.hadException());
676 EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
679 INSTANTIATE_TEST_CASE_P(DOMWebSocketValidClosing, DOMWebSocketValidClosingTest, ::testing::Values(1000, 3000, 3001, 4998, 4999));
681 class DOMWebSocketInvalidClosingCodeTest : public DOMWebSocketTestBase, public ::testing::TestWithParam<unsigned short> {
685 TEST_P(DOMWebSocketInvalidClosingCodeTest, test)
689 EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
691 m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
693 EXPECT_FALSE(m_exceptionState.hadException());
694 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
696 m_websocket->close(GetParam(), "bye", m_exceptionState);
698 EXPECT_TRUE(m_exceptionState.hadException());
699 EXPECT_EQ(InvalidAccessError, m_exceptionState.code());
700 EXPECT_EQ(String::format("The code must be either 1000, or between 3000 and 4999. %d is neither.", GetParam()), m_exceptionState.message());
701 EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
704 INSTANTIATE_TEST_CASE_P(DOMWebSocketInvalidClosingCode, DOMWebSocketInvalidClosingCodeTest, ::testing::Values(0, 1, 998, 999, 1001, 2999, 5000, 9999, 65535));