1f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// found in the LICENSE file.
4f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
5f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "config.h"
6f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
7197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "modules/websockets/DOMWebSocket.h"
8f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
9197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
10197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8Binding.h"
117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/dom/Document.h"
12f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "core/dom/ExceptionCode.h"
13f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "core/fileapi/Blob.h"
14f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "core/frame/ConsoleTypes.h"
15f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "core/testing/DummyPageHolder.h"
16f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "wtf/ArrayBuffer.h"
17f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "wtf/OwnPtr.h"
18f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "wtf/Uint8Array.h"
19f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "wtf/Vector.h"
20f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "wtf/testing/WTFTestHelpers.h"
21f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "wtf/text/WTFString.h"
22f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include <gmock/gmock.h>
23f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include <gtest/gtest.h>
24f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include <v8.h>
25f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
26f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)using testing::_;
27f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)using testing::AnyNumber;
28f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)using testing::InSequence;
29f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)using testing::Ref;
30f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)using testing::Return;
31f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
33f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
34f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)namespace {
35f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
36f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)typedef testing::StrictMock<testing::MockFunction<void(int)> > Checkpoint;  // NOLINT
37f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
38f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)class MockWebSocketChannel : public WebSocketChannel {
39f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)public:
40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static MockWebSocketChannel* create()
41f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return adoptRefCountedGarbageCollected(new testing::StrictMock<MockWebSocketChannel>());
43f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
44f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
45f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    virtual ~MockWebSocketChannel()
46f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
47f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
48f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
49f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MOCK_METHOD2(connect, bool(const KURL&, const String&));
50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    MOCK_METHOD1(send, void(const String&));
51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    MOCK_METHOD3(send, void(const ArrayBuffer&, unsigned, unsigned));
52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    MOCK_METHOD1(send, void(PassRefPtr<BlobDataHandle>));
53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    MOCK_METHOD1(send, void(PassOwnPtr<Vector<char> >));
54f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MOCK_CONST_METHOD0(bufferedAmount, unsigned long());
55f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MOCK_METHOD2(close, void(int, const String&));
56f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MOCK_METHOD4(fail, void(const String&, MessageLevel, const String&, unsigned));
57f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MOCK_METHOD0(disconnect, void());
58f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MOCK_METHOD0(suspend, void());
59f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MOCK_METHOD0(resume, void());
60f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
61f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MockWebSocketChannel()
62f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
63f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
64f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)};
65f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
66197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass DOMWebSocketWithMockChannel FINAL : public DOMWebSocket {
67f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)public:
68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static DOMWebSocketWithMockChannel* create(ExecutionContext* context)
69f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
70c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        DOMWebSocketWithMockChannel* websocket = adoptRefCountedGarbageCollectedWillBeNoop(new DOMWebSocketWithMockChannel(context));
71f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        websocket->suspendIfNeeded();
72c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return websocket;
73f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
74f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
75f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MockWebSocketChannel* channel() { return m_channel.get(); }
76f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
77c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual WebSocketChannel* createChannel(ExecutionContext*, WebSocketChannelClient*) OVERRIDE
78f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
79f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ASSERT(!m_hasCreatedChannel);
80f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_hasCreatedChannel = true;
81f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        return m_channel.get();
82f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
83f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
84f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    virtual void trace(Visitor* visitor) OVERRIDE
85f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
86f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        visitor->trace(m_channel);
87197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DOMWebSocket::trace(visitor);
88f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
89f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
90f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)private:
91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DOMWebSocketWithMockChannel(ExecutionContext* context)
92197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        : DOMWebSocket(context)
93f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        , m_channel(MockWebSocketChannel::create())
94f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        , m_hasCreatedChannel(false) { }
95f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Member<MockWebSocketChannel> m_channel;
97f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    bool m_hasCreatedChannel;
98f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)};
99f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
100197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass DOMWebSocketTestBase {
101f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)public:
102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DOMWebSocketTestBase()
103f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        : m_pageHolder(DummyPageHolder::create())
104197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        , m_websocket(DOMWebSocketWithMockChannel::create(&m_pageHolder->document()))
105f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        , m_executionScope(v8::Isolate::GetCurrent())
106f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        , m_exceptionState(ExceptionState::ConstructionContext, "property", "interface", m_executionScope.scriptState()->context()->Global(), m_executionScope.isolate())
107f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
108f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
109f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
110197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual ~DOMWebSocketTestBase()
111f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
112f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (!m_websocket)
113f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            return;
114f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        // These statements are needed to clear WebSocket::m_channel to
115f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        // avoid ASSERTION failure on ~WebSocket.
116f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ASSERT(m_websocket->channel());
117f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        ::testing::Mock::VerifyAndClear(m_websocket->channel());
118f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), disconnect()).Times(AnyNumber());
119f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
12076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
121f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_websocket.clear();
122f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        Heap::collectAllGarbage();
123f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
124f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
125f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    MockWebSocketChannel& channel() { return *m_websocket->channel(); }
126f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
127f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    OwnPtr<DummyPageHolder> m_pageHolder;
128c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Persistent<DOMWebSocketWithMockChannel> m_websocket;
129f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    V8TestingScope m_executionScope;
130f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ExceptionState m_exceptionState;
131f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)};
132f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
133197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass DOMWebSocketTest : public DOMWebSocketTestBase, public ::testing::Test {
134f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)public:
135f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)};
136f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
137197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, connectToBadURL)
138f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
139f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("xxx", Vector<String>(), m_exceptionState);
140f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
141f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
142f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
143f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(SyntaxError, m_exceptionState.code());
144f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("The URL 'xxx' is invalid.", m_exceptionState.message());
145197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
146f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
147f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
148197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, connectToNonWsURL)
149f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
150f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("http://example.com/", Vector<String>(), m_exceptionState);
151f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
152f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
153f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
154f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(SyntaxError, m_exceptionState.code());
155f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.", m_exceptionState.message());
156197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
157f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
158f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
159197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, connectToURLHavingFragmentIdentifier)
160f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
161f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/#fragment", Vector<String>(), m_exceptionState);
162f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
163f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
164f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
165f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(SyntaxError, m_exceptionState.code());
166f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("The URL contains a fragment identifier ('fragment'). Fragment identifiers are not allowed in WebSocket URLs.", m_exceptionState.message());
167197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
168f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
169f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
170197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, invalidPort)
171f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
172f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com:7", Vector<String>(), m_exceptionState);
173f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
174f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
175f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
176f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(SecurityError, m_exceptionState.code());
177f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("The port 7 is not allowed.", m_exceptionState.message());
178197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
179f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
180f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
181f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// FIXME: Add a test for Content Security Policy.
182f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
183197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, invalidSubprotocols)
184f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
185f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    Vector<String> subprotocols;
186f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    subprotocols.append("@subprotocol-|'\"x\x01\x02\x03x");
187f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
188f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
189f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
190f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), disconnect());
191f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
192f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
193f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", subprotocols, m_exceptionState);
194f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
195f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
196f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(SyntaxError, m_exceptionState.code());
197f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("The subprotocol '@subprotocol-|'\"x\\u0001\\u0002\\u0003x' is invalid.", m_exceptionState.message());
198197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
199f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
200f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
201197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, channelConnectSuccess)
202f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
203f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    Vector<String> subprotocols;
204f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    subprotocols.append("aa");
205f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    subprotocols.append("bb");
206f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
207f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
208f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
209f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/hoge"), String("aa, bb"))).WillOnce(Return(true));
210f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
211f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
212f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/hoge", Vector<String>(subprotocols), m_exceptionState);
213f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
214f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
215f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
216197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
217f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(KURL(KURL(), "ws://example.com/hoge"), m_websocket->url());
218f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
219f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
220197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, channelConnectFail)
221f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
222f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    Vector<String> subprotocols;
223f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    subprotocols.append("aa");
224f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    subprotocols.append("bb");
225f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
226f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
227f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
228f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String("aa, bb"))).WillOnce(Return(false));
229f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), disconnect());
230f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
231f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
232f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(subprotocols), m_exceptionState);
233f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
234f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
235f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
236f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(SecurityError, m_exceptionState.code());
237f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.", m_exceptionState.message());
238197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
239f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
240f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
241197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, isValidSubprotocolString)
242f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
243197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_TRUE(DOMWebSocket::isValidSubprotocolString("Helloworld!!"));
244197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString("Hello, world!!"));
245197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(String()));
246197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(""));
247f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
248f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    const char validCharacters[] = "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~";
249f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    size_t length = strlen(validCharacters);
250f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (size_t i = 0; i < length; ++i) {
251f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        String s;
252f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        s.append(static_cast<UChar>(validCharacters[i]));
253197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        EXPECT_TRUE(DOMWebSocket::isValidSubprotocolString(s));
254f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
255f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (size_t i = 0; i < 256; ++i) {
256f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (std::find(validCharacters, validCharacters + length, static_cast<char>(i)) != validCharacters + length) {
257f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            continue;
258f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        }
259f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        String s;
260f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        s.append(static_cast<UChar>(i));
261197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        EXPECT_FALSE(DOMWebSocket::isValidSubprotocolString(s));
262f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
263f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
264f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
265197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, connectSuccess)
266f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
267f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    Vector<String> subprotocols;
268f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    subprotocols.append("aa");
269f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    subprotocols.append("bb");
270f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
271f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
272f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String("aa, bb"))).WillOnce(Return(true));
273f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
274f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", subprotocols, m_exceptionState);
275f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
276f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
277197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
278f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
2795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_websocket->didConnect("bb", "cc");
280f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
281197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
282f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("bb", m_websocket->protocol());
283f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("cc", m_websocket->extensions());
284f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
285f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
286197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, didClose)
287f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
288f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
289f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
290f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
291f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), disconnect());
292f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
293f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
294f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
295f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
296197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
297f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
29876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
299f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
300197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
301f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
302f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
303197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, maximumReasonSize)
304f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
305f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
306f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
307f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
308f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), fail(_, _, _, _));
309f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
310f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    String reason;
311f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (size_t i = 0; i < 123; ++i)
312f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        reason.append("a");
313f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
314f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
315f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
316197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
317f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
318f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(1000, reason, m_exceptionState);
319f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
320f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
321197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
322f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
323f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
324197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, reasonSizeExceeding)
325f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
326f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
327f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
328f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
329f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
330f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    String reason;
331f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (size_t i = 0; i < 124; ++i)
332f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        reason.append("a");
333f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
334f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
335f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
336197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
337f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
338f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(1000, reason, m_exceptionState);
339f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
340f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
341f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(SyntaxError, m_exceptionState.code());
342f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("The message must not be greater than 123 bytes.", m_exceptionState.message());
343197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
344f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
345f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
346197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, closeWhenConnecting)
347f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
348f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
349f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
350f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
351f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), fail(String("WebSocket is closed before the connection is established."), WarningMessageLevel, String(), 0));
352f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
353f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
354f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
355f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
356197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
357f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
358f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(1000, "bye", m_exceptionState);
359f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
360f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
361197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
362f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
363f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
364197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, close)
365f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
366f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
367f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
368f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
369f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), close(3005, String("bye")));
370f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
371f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
372f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
373f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
374197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
375f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
3765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_websocket->didConnect("", "");
377197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
378f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(3005, "bye", m_exceptionState);
379f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
380f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
381197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
382f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
383f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
384197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, closeWithoutReason)
385f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
386f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
387f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
388f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
389f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), close(3005, String()));
390f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
391f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
392f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
393f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
394197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
395f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
3965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_websocket->didConnect("", "");
397197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
398f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(3005, m_exceptionState);
399f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
400f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
401197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
402f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
403f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
404197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, closeWithoutCodeAndReason)
405f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
406f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
407f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
408f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
409f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), close(-1, String()));
410f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
411f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
412f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
413f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
414197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
415f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
4165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_websocket->didConnect("", "");
417197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
418f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(m_exceptionState);
419f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
420f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
421197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
422f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
423f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
424197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, closeWhenClosing)
425f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
426f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
427f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
428f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
429f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), close(-1, String()));
430f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
431f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
432f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
433f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
434197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
435f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
4365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_websocket->didConnect("", "");
437197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
438f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(m_exceptionState);
439f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
440197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
441f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
442f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(m_exceptionState);
443f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
444f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
445197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
446f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
447f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
448197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, closeWhenClosed)
449f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
450f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
451f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
452f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
453f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), close(-1, String()));
454f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), disconnect());
455f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
456f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
457f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
458f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
459197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
460f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
4615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_websocket->didConnect("", "");
462197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
463f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(m_exceptionState);
464f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
465197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
466f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
46776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeComplete, 1000, String());
468197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
469f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(m_exceptionState);
470f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
471f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
472197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
473f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
474f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
475197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, sendStringWhenConnecting)
476f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
477f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
478f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
479f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
480f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
481f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
482f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
483f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
484f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
485f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->send("hello", m_exceptionState);
486f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
487f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
488f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(InvalidStateError, m_exceptionState.code());
489f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("Still in CONNECTING state.", m_exceptionState.message());
490197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
491f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
492f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
493197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, sendStringWhenClosing)
494f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
495f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    Checkpoint checkpoint;
496f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
497f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
498f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
499f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), fail(_, _, _, _));
500f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
501f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
502f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
503f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
504f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
505f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(m_exceptionState);
506f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
507f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
508f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->send("hello", m_exceptionState);
509f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
510f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
511197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
512f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
513f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
514197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, sendStringWhenClosed)
515f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
516f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    Checkpoint checkpoint;
517f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
518f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
519f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
520f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), disconnect());
521f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(checkpoint, Call(1));
522f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
523f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
524f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
525f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
526f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
52776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
528f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    checkpoint.Call(1);
529f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
530f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->send("hello", m_exceptionState);
531f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
532f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
533197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
534f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
535f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
536197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, sendStringSuccess)
537f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
538f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
539f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
540f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
541c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_CALL(channel(), send(String("hello")));
542f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
543f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
544f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
545f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
546f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
5475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_websocket->didConnect("", "");
548f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->send("hello", m_exceptionState);
549f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
550f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
551197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
552f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
553f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
554197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, sendArrayBufferWhenConnecting)
555f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
556f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtr<ArrayBufferView> view = Uint8Array::create(8);
557f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
558f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
559f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
560f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
561f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
562f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
563f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
564f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
565f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->send(view->buffer().get(), m_exceptionState);
566f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
567f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
568f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(InvalidStateError, m_exceptionState.code());
569f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("Still in CONNECTING state.", m_exceptionState.message());
570197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
571f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
572f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
573197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, sendArrayBufferWhenClosing)
574f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
575f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtr<ArrayBufferView> view = Uint8Array::create(8);
576f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
577f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
578f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
579f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), fail(_, _, _, _));
580f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
581f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
582f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
583f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
584f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
585f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(m_exceptionState);
586f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
587f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
588f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->send(view->buffer().get(), m_exceptionState);
589f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
590f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
591197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
592f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
593f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
594197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, sendArrayBufferWhenClosed)
595f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
596f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    Checkpoint checkpoint;
597f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtr<ArrayBufferView> view = Uint8Array::create(8);
598f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
599f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
600f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
601f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), disconnect());
602f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(checkpoint, Call(1));
603f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
604f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
605f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
606f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
607f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
60876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    m_websocket->didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, 1006, "");
609f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    checkpoint.Call(1);
610f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
611f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->send(view->buffer().get(), m_exceptionState);
612f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
613f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
614197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSED, m_websocket->readyState());
615f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
616f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
617197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, sendArrayBufferSuccess)
618f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
619f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtr<ArrayBufferView> view = Uint8Array::create(8);
620f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
621f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
622f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
623c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_CALL(channel(), send(Ref(*view->buffer()), 0, 8));
624f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
625f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
626f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
627f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
628f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
6295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_websocket->didConnect("", "");
630f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->send(view->buffer().get(), m_exceptionState);
631f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
632f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
633197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::OPEN, m_websocket->readyState());
634f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
635f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
636f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// FIXME: We should have Blob tests here.
637f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// We can't create a Blob because the blob registration cannot be mocked yet.
638f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
639f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// FIXME: We should add tests for bufferedAmount.
640f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
641f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// FIXME: We should add tests for data receiving.
642f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
643197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_F(DOMWebSocketTest, binaryType)
644f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
645f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("blob", m_websocket->binaryType());
646f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
647f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->setBinaryType("hoge");
648f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
649f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("blob", m_websocket->binaryType());
650f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
651f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->setBinaryType("arraybuffer");
652f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
653f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("arraybuffer", m_websocket->binaryType());
654f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
655f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->setBinaryType("fuga");
656f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
657f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("arraybuffer", m_websocket->binaryType());
658f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
659f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->setBinaryType("blob");
660f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
661f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ("blob", m_websocket->binaryType());
662f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
663f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
664f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// FIXME: We should add tests for suspend / resume.
665f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
666197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass DOMWebSocketValidClosingTest : public DOMWebSocketTestBase, public ::testing::TestWithParam<unsigned short> {
667f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)public:
668f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)};
669f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
670197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_P(DOMWebSocketValidClosingTest, test)
671f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
672f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
673f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
674f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
675f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), fail(_, _, _, _));
676f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
677f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
678f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
679f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
680197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
681f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
682f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(GetParam(), "bye", m_exceptionState);
683f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
684f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
685197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CLOSING, m_websocket->readyState());
686f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
687f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
688197021e6b966cfb06891637935ef33fff06433d1Ben MurdochINSTANTIATE_TEST_CASE_P(DOMWebSocketValidClosing, DOMWebSocketValidClosingTest, ::testing::Values(1000, 3000, 3001, 4998, 4999));
689f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
690197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass DOMWebSocketInvalidClosingCodeTest : public DOMWebSocketTestBase, public ::testing::TestWithParam<unsigned short> {
691f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)public:
692f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)};
693f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
694197021e6b966cfb06891637935ef33fff06433d1Ben MurdochTEST_P(DOMWebSocketInvalidClosingCodeTest, test)
695f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
696f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    {
697f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        InSequence s;
698f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        EXPECT_CALL(channel(), connect(KURL(KURL(), "ws://example.com/"), String())).WillOnce(Return(true));
699f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
700f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->connect("ws://example.com/", Vector<String>(), m_exceptionState);
701f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
702f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(m_exceptionState.hadException());
703197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
704f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
705f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_websocket->close(GetParam(), "bye", m_exceptionState);
706f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
707f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(m_exceptionState.hadException());
708f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(InvalidAccessError, m_exceptionState.code());
709f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(String::format("The code must be either 1000, or between 3000 and 4999. %d is neither.", GetParam()), m_exceptionState.message());
710197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(DOMWebSocket::CONNECTING, m_websocket->readyState());
711f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
712f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
713197021e6b966cfb06891637935ef33fff06433d1Ben MurdochINSTANTIATE_TEST_CASE_P(DOMWebSocketInvalidClosingCode, DOMWebSocketInvalidClosingCodeTest, ::testing::Values(0, 1, 998, 999, 1001, 2999, 5000, 9999, 65535));
714f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
715f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)} // namespace
716f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
717c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
718