1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6#include "modules/websockets/WebSocketChannel.h"
7
8#include "core/dom/Document.h"
9#include "core/fileapi/Blob.h"
10#include "core/frame/ConsoleTypes.h"
11#include "core/testing/DummyPageHolder.h"
12#include "modules/websockets/NewWebSocketChannelImpl.h"
13#include "modules/websockets/WebSocketChannelClient.h"
14#include "platform/heap/Handle.h"
15#include "platform/weborigin/KURL.h"
16#include "public/platform/WebSerializedOrigin.h"
17#include "public/platform/WebSocketHandle.h"
18#include "public/platform/WebSocketHandleClient.h"
19#include "public/platform/WebString.h"
20#include "public/platform/WebURL.h"
21#include "public/platform/WebVector.h"
22#include "wtf/ArrayBuffer.h"
23#include "wtf/OwnPtr.h"
24#include "wtf/Vector.h"
25#include "wtf/text/WTFString.h"
26
27#include <gmock/gmock.h>
28#include <gtest/gtest.h>
29
30using testing::_;
31using testing::InSequence;
32using testing::PrintToString;
33using testing::AnyNumber;
34
35
36namespace blink {
37
38namespace {
39
40typedef testing::StrictMock< testing::MockFunction<void(int)> > Checkpoint;
41
42class MockWebSocketChannelClient : public GarbageCollectedFinalized<MockWebSocketChannelClient>, public WebSocketChannelClient {
43    USING_GARBAGE_COLLECTED_MIXIN(MockWebSocketChannelClient);
44public:
45    static MockWebSocketChannelClient* create()
46    {
47        return new testing::StrictMock<MockWebSocketChannelClient>();
48    }
49
50    MockWebSocketChannelClient() { }
51
52    virtual ~MockWebSocketChannelClient() { }
53
54    MOCK_METHOD2(didConnect, void(const String&, const String&));
55    MOCK_METHOD1(didReceiveMessage, void(const String&));
56    virtual void didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData) OVERRIDE
57    {
58        didReceiveBinaryDataMock(*binaryData);
59    }
60    MOCK_METHOD1(didReceiveBinaryDataMock, void(const Vector<char>&));
61    MOCK_METHOD0(didReceiveMessageError, void());
62    MOCK_METHOD1(didConsumeBufferedAmount, void(unsigned long));
63    MOCK_METHOD0(didStartClosingHandshake, void());
64    MOCK_METHOD3(didClose, void(ClosingHandshakeCompletionStatus, unsigned short, const String&));
65
66    virtual void trace(Visitor* visitor) OVERRIDE
67    {
68        WebSocketChannelClient::trace(visitor);
69    }
70
71};
72
73class MockWebSocketHandle : public WebSocketHandle {
74public:
75    static MockWebSocketHandle* create()
76    {
77        return new testing::StrictMock<MockWebSocketHandle>();
78    }
79
80    MockWebSocketHandle() { }
81
82    virtual ~MockWebSocketHandle() { }
83
84    MOCK_METHOD4(connect, void(const WebURL&, const WebVector<WebString>&, const WebSerializedOrigin&, WebSocketHandleClient*));
85    MOCK_METHOD4(send, void(bool, WebSocketHandle::MessageType, const char*, size_t));
86    MOCK_METHOD1(flowControl, void(int64_t));
87    MOCK_METHOD2(close, void(unsigned short, const WebString&));
88};
89
90class NewWebSocketChannelImplTest : public ::testing::Test {
91public:
92    NewWebSocketChannelImplTest()
93        : m_pageHolder(DummyPageHolder::create())
94        , m_channelClient(MockWebSocketChannelClient::create())
95        , m_handle(MockWebSocketHandle::create())
96        , m_channel(NewWebSocketChannelImpl::create(&m_pageHolder->document(), m_channelClient.get(), String(), 0, handle()))
97        , m_sumOfConsumedBufferedAmount(0)
98    {
99        ON_CALL(*channelClient(), didConsumeBufferedAmount(_)).WillByDefault(Invoke(this, &NewWebSocketChannelImplTest::didConsumeBufferedAmount));
100    }
101
102    ~NewWebSocketChannelImplTest()
103    {
104        channel()->disconnect();
105        m_channelClient.clear();
106        m_channel.clear();
107        Heap::collectAllGarbage();
108    }
109
110    MockWebSocketChannelClient* channelClient()
111    {
112        return m_channelClient.get();
113    }
114
115    WebSocketChannel* channel()
116    {
117        return static_cast<WebSocketChannel*>(m_channel.get());
118    }
119
120    WebSocketHandleClient* handleClient()
121    {
122        return static_cast<WebSocketHandleClient*>(m_channel.get());
123    }
124
125    MockWebSocketHandle* handle()
126    {
127        return m_handle;
128    }
129
130    void didConsumeBufferedAmount(unsigned long a)
131    {
132        m_sumOfConsumedBufferedAmount += a;
133    }
134
135    void connect()
136    {
137        {
138            InSequence s;
139            EXPECT_CALL(*handle(), connect(WebURL(KURL(KURL(), "ws://localhost/")), _, _, handleClient()));
140            EXPECT_CALL(*handle(), flowControl(65536));
141            EXPECT_CALL(*channelClient(), didConnect(String("a"), String("b")));
142        }
143        EXPECT_TRUE(channel()->connect(KURL(KURL(), "ws://localhost/"), "x"));
144        handleClient()->didConnect(handle(), false, WebString("a"), WebString("b"));
145        ::testing::Mock::VerifyAndClearExpectations(this);
146    }
147
148    OwnPtr<DummyPageHolder> m_pageHolder;
149    Persistent<MockWebSocketChannelClient> m_channelClient;
150    MockWebSocketHandle* m_handle;
151    Persistent<NewWebSocketChannelImpl> m_channel;
152    unsigned long m_sumOfConsumedBufferedAmount;
153};
154
155MATCHER_P2(MemEq, p, len,
156    std::string("pointing to memory")
157    + (negation ? " not" : "")
158    + " equal to \""
159    + std::string(p, len) + "\" (length=" + PrintToString(len) + ")"
160)
161{
162    return memcmp(arg, p, len) == 0;
163}
164
165TEST_F(NewWebSocketChannelImplTest, connectSuccess)
166{
167    Checkpoint checkpoint;
168    {
169        InSequence s;
170        EXPECT_CALL(*handle(), connect(WebURL(KURL(KURL(), "ws://localhost/")), _, _, handleClient()));
171        EXPECT_CALL(*handle(), flowControl(65536));
172        EXPECT_CALL(checkpoint, Call(1));
173        EXPECT_CALL(*channelClient(), didConnect(String("a"), String("b")));
174    }
175
176    EXPECT_TRUE(channel()->connect(KURL(KURL(), "ws://localhost/"), "x"));
177    checkpoint.Call(1);
178    handleClient()->didConnect(handle(), false, WebString("a"), WebString("b"));
179}
180
181TEST_F(NewWebSocketChannelImplTest, sendText)
182{
183    connect();
184    {
185        InSequence s;
186        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeText, MemEq("foo", 3), 3));
187        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeText, MemEq("bar", 3), 3));
188        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeText, MemEq("baz", 3), 3));
189    }
190
191    handleClient()->didReceiveFlowControl(handle(), 16);
192    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
193
194    channel()->send("foo");
195    channel()->send("bar");
196    channel()->send("baz");
197
198    EXPECT_EQ(9ul, m_sumOfConsumedBufferedAmount);
199}
200
201TEST_F(NewWebSocketChannelImplTest, sendTextContinuation)
202{
203    connect();
204    Checkpoint checkpoint;
205    {
206        InSequence s;
207        EXPECT_CALL(*handle(), send(false, WebSocketHandle::MessageTypeText, MemEq("0123456789abcdef", 16), 16));
208        EXPECT_CALL(checkpoint, Call(1));
209        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeContinuation, MemEq("g", 1), 1));
210        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeText, MemEq("hijk", 4), 4));
211        EXPECT_CALL(*handle(), send(false, WebSocketHandle::MessageTypeText, MemEq("lmnopqrstuv", 11), 11));
212        EXPECT_CALL(checkpoint, Call(2));
213        EXPECT_CALL(*handle(), send(false, WebSocketHandle::MessageTypeContinuation, MemEq("wxyzABCDEFGHIJKL", 16), 16));
214        EXPECT_CALL(checkpoint, Call(3));
215        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeContinuation, MemEq("MNOPQRSTUVWXYZ", 14), 14));
216    }
217
218    handleClient()->didReceiveFlowControl(handle(), 16);
219    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
220
221    channel()->send("0123456789abcdefg");
222    channel()->send("hijk");
223    channel()->send("lmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
224    checkpoint.Call(1);
225    handleClient()->didReceiveFlowControl(handle(), 16);
226    checkpoint.Call(2);
227    handleClient()->didReceiveFlowControl(handle(), 16);
228    checkpoint.Call(3);
229    handleClient()->didReceiveFlowControl(handle(), 16);
230
231    EXPECT_EQ(62ul, m_sumOfConsumedBufferedAmount);
232}
233
234TEST_F(NewWebSocketChannelImplTest, sendTextNonLatin1)
235{
236    connect();
237    {
238        InSequence s;
239        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeText, MemEq("\xe7\x8b\x90\xe0\xa4\x94", 6), 6));
240    }
241
242    handleClient()->didReceiveFlowControl(handle(), 16);
243    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
244
245    UChar nonLatin1String[] = {
246        0x72d0,
247        0x0914,
248        0x0000
249    };
250    channel()->send(nonLatin1String);
251
252    EXPECT_EQ(6ul, m_sumOfConsumedBufferedAmount);
253}
254
255TEST_F(NewWebSocketChannelImplTest, sendTextNonLatin1Continuation)
256{
257    connect();
258    Checkpoint checkpoint;
259    {
260        InSequence s;
261        EXPECT_CALL(*handle(), send(false, WebSocketHandle::MessageTypeText, MemEq("\xe7\x8b\x90\xe0\xa4\x94\xe7\x8b\x90\xe0\xa4\x94\xe7\x8b\x90\xe0", 16), 16));
262        EXPECT_CALL(checkpoint, Call(1));
263        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeContinuation, MemEq("\xa4\x94", 2), 2));
264    }
265
266    handleClient()->didReceiveFlowControl(handle(), 16);
267    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
268
269    UChar nonLatin1String[] = {
270        0x72d0,
271        0x0914,
272        0x72d0,
273        0x0914,
274        0x72d0,
275        0x0914,
276        0x0000
277    };
278    channel()->send(nonLatin1String);
279    checkpoint.Call(1);
280    handleClient()->didReceiveFlowControl(handle(), 16);
281
282    EXPECT_EQ(18ul, m_sumOfConsumedBufferedAmount);
283}
284
285TEST_F(NewWebSocketChannelImplTest, sendBinaryInVector)
286{
287    connect();
288    {
289        InSequence s;
290        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("foo", 3), 3));
291    }
292
293    handleClient()->didReceiveFlowControl(handle(), 16);
294    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
295
296    Vector<char> fooVector;
297    fooVector.append("foo", 3);
298    channel()->send(adoptPtr(new Vector<char>(fooVector)));
299
300    EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount);
301}
302
303TEST_F(NewWebSocketChannelImplTest, sendBinaryInVectorWithNullBytes)
304{
305    connect();
306    {
307        InSequence s;
308        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("\0ar", 3), 3));
309        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("b\0z", 3), 3));
310        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("qu\0", 3), 3));
311        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("\0\0\0", 3), 3));
312    }
313
314    handleClient()->didReceiveFlowControl(handle(), 16);
315    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
316
317    {
318        Vector<char> v;
319        v.append("\0ar", 3);
320        channel()->send(adoptPtr(new Vector<char>(v)));
321    }
322    {
323        Vector<char> v;
324        v.append("b\0z", 3);
325        channel()->send(adoptPtr(new Vector<char>(v)));
326    }
327    {
328        Vector<char> v;
329        v.append("qu\0", 3);
330        channel()->send(adoptPtr(new Vector<char>(v)));
331    }
332    {
333        Vector<char> v;
334        v.append("\0\0\0", 3);
335        channel()->send(adoptPtr(new Vector<char>(v)));
336    }
337
338    EXPECT_EQ(12ul, m_sumOfConsumedBufferedAmount);
339}
340
341TEST_F(NewWebSocketChannelImplTest, sendBinaryInVectorNonLatin1UTF8)
342{
343    connect();
344    EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("\xe7\x8b\x90", 3), 3));
345
346    handleClient()->didReceiveFlowControl(handle(), 16);
347    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
348
349    Vector<char> v;
350    v.append("\xe7\x8b\x90", 3);
351    channel()->send(adoptPtr(new Vector<char>(v)));
352
353    EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount);
354}
355
356TEST_F(NewWebSocketChannelImplTest, sendBinaryInVectorNonUTF8)
357{
358    connect();
359    EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("\x80\xff\xe7", 3), 3));
360
361    handleClient()->didReceiveFlowControl(handle(), 16);
362    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
363
364    Vector<char> v;
365    v.append("\x80\xff\xe7", 3);
366    channel()->send(adoptPtr(new Vector<char>(v)));
367
368    EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount);
369}
370
371TEST_F(NewWebSocketChannelImplTest, sendBinaryInVectorNonLatin1UTF8Continuation)
372{
373    connect();
374    Checkpoint checkpoint;
375    {
376        InSequence s;
377        EXPECT_CALL(*handle(), send(false, WebSocketHandle::MessageTypeBinary, MemEq("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7", 16), 16));
378        EXPECT_CALL(checkpoint, Call(1));
379        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeContinuation, MemEq("\x8b\x90", 2), 2));
380    }
381
382    handleClient()->didReceiveFlowControl(handle(), 16);
383    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
384
385    Vector<char> v;
386    v.append("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90", 18);
387    channel()->send(adoptPtr(new Vector<char>(v)));
388    checkpoint.Call(1);
389
390    handleClient()->didReceiveFlowControl(handle(), 16);
391
392    EXPECT_EQ(18ul, m_sumOfConsumedBufferedAmount);
393}
394
395TEST_F(NewWebSocketChannelImplTest, sendBinaryInArrayBuffer)
396{
397    connect();
398    {
399        InSequence s;
400        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("foo", 3), 3));
401    }
402
403    handleClient()->didReceiveFlowControl(handle(), 16);
404    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
405
406    RefPtr<ArrayBuffer> fooBuffer = ArrayBuffer::create("foo", 3);
407    channel()->send(*fooBuffer, 0, 3);
408
409    EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount);
410}
411
412TEST_F(NewWebSocketChannelImplTest, sendBinaryInArrayBufferPartial)
413{
414    connect();
415    {
416        InSequence s;
417        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("foo", 3), 3));
418        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("bar", 3), 3));
419        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("baz", 3), 3));
420        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("a", 1), 1));
421    }
422
423    handleClient()->didReceiveFlowControl(handle(), 16);
424    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
425
426    RefPtr<ArrayBuffer> foobarBuffer = ArrayBuffer::create("foobar", 6);
427    RefPtr<ArrayBuffer> qbazuxBuffer = ArrayBuffer::create("qbazux", 6);
428    channel()->send(*foobarBuffer, 0, 3);
429    channel()->send(*foobarBuffer, 3, 3);
430    channel()->send(*qbazuxBuffer, 1, 3);
431    channel()->send(*qbazuxBuffer, 2, 1);
432
433    EXPECT_EQ(10ul, m_sumOfConsumedBufferedAmount);
434}
435
436TEST_F(NewWebSocketChannelImplTest, sendBinaryInArrayBufferWithNullBytes)
437{
438    connect();
439    {
440        InSequence s;
441        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("\0ar", 3), 3));
442        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("b\0z", 3), 3));
443        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("qu\0", 3), 3));
444        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("\0\0\0", 3), 3));
445    }
446
447    handleClient()->didReceiveFlowControl(handle(), 16);
448    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
449
450    {
451        RefPtr<ArrayBuffer> b = ArrayBuffer::create("\0ar", 3);
452        channel()->send(*b, 0, 3);
453    }
454    {
455        RefPtr<ArrayBuffer> b = ArrayBuffer::create("b\0z", 3);
456        channel()->send(*b, 0, 3);
457    }
458    {
459        RefPtr<ArrayBuffer> b = ArrayBuffer::create("qu\0", 3);
460        channel()->send(*b, 0, 3);
461    }
462    {
463        RefPtr<ArrayBuffer> b = ArrayBuffer::create("\0\0\0", 3);
464        channel()->send(*b, 0, 3);
465    }
466
467    EXPECT_EQ(12ul, m_sumOfConsumedBufferedAmount);
468}
469
470TEST_F(NewWebSocketChannelImplTest, sendBinaryInArrayBufferNonLatin1UTF8)
471{
472    connect();
473    EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("\xe7\x8b\x90", 3), 3));
474
475    handleClient()->didReceiveFlowControl(handle(), 16);
476    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
477
478    RefPtr<ArrayBuffer> b = ArrayBuffer::create("\xe7\x8b\x90", 3);
479    channel()->send(*b, 0, 3);
480
481    EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount);
482}
483
484TEST_F(NewWebSocketChannelImplTest, sendBinaryInArrayBufferNonUTF8)
485{
486    connect();
487    EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeBinary, MemEq("\x80\xff\xe7", 3), 3));
488
489    handleClient()->didReceiveFlowControl(handle(), 16);
490    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
491
492    RefPtr<ArrayBuffer> b = ArrayBuffer::create("\x80\xff\xe7", 3);
493    channel()->send(*b, 0, 3);
494
495    EXPECT_EQ(3ul, m_sumOfConsumedBufferedAmount);
496}
497
498TEST_F(NewWebSocketChannelImplTest, sendBinaryInArrayBufferNonLatin1UTF8Continuation)
499{
500    connect();
501    Checkpoint checkpoint;
502    {
503        InSequence s;
504        EXPECT_CALL(*handle(), send(false, WebSocketHandle::MessageTypeBinary, MemEq("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7", 16), 16));
505        EXPECT_CALL(checkpoint, Call(1));
506        EXPECT_CALL(*handle(), send(true, WebSocketHandle::MessageTypeContinuation, MemEq("\x8b\x90", 2), 2));
507    }
508
509    handleClient()->didReceiveFlowControl(handle(), 16);
510    EXPECT_CALL(*channelClient(), didConsumeBufferedAmount(_)).Times(AnyNumber());
511
512    RefPtr<ArrayBuffer> b = ArrayBuffer::create("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90", 18);
513    channel()->send(*b, 0, 18);
514    checkpoint.Call(1);
515
516    handleClient()->didReceiveFlowControl(handle(), 16);
517
518    EXPECT_EQ(18ul, m_sumOfConsumedBufferedAmount);
519}
520
521// FIXME: Add tests for WebSocketChannel::send(PassRefPtr<BlobDataHandle>)
522
523TEST_F(NewWebSocketChannelImplTest, receiveText)
524{
525    connect();
526    {
527        InSequence s;
528        EXPECT_CALL(*channelClient(), didReceiveMessage(String("FOO")));
529        EXPECT_CALL(*channelClient(), didReceiveMessage(String("BAR")));
530    }
531
532    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeText, "FOOX", 3);
533    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeText, "BARX", 3);
534}
535
536TEST_F(NewWebSocketChannelImplTest, receiveTextContinuation)
537{
538    connect();
539    EXPECT_CALL(*channelClient(), didReceiveMessage(String("BAZ")));
540
541    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeText, "BX", 1);
542    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeContinuation, "AX", 1);
543    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeContinuation, "ZX", 1);
544}
545
546TEST_F(NewWebSocketChannelImplTest, receiveTextNonLatin1)
547{
548    connect();
549    UChar nonLatin1String[] = {
550        0x72d0,
551        0x0914,
552        0x0000
553    };
554    EXPECT_CALL(*channelClient(), didReceiveMessage(String(nonLatin1String)));
555
556    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeText, "\xe7\x8b\x90\xe0\xa4\x94", 6);
557}
558
559TEST_F(NewWebSocketChannelImplTest, receiveTextNonLatin1Continuation)
560{
561    connect();
562    UChar nonLatin1String[] = {
563        0x72d0,
564        0x0914,
565        0x0000
566    };
567    EXPECT_CALL(*channelClient(), didReceiveMessage(String(nonLatin1String)));
568
569    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeText, "\xe7\x8b", 2);
570    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeContinuation, "\x90\xe0", 2);
571    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeContinuation, "\xa4", 1);
572    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeContinuation, "\x94", 1);
573}
574
575TEST_F(NewWebSocketChannelImplTest, receiveBinary)
576{
577    connect();
578    Vector<char> fooVector;
579    fooVector.append("FOO", 3);
580    EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(fooVector));
581
582    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeBinary, "FOOx", 3);
583}
584
585TEST_F(NewWebSocketChannelImplTest, receiveBinaryContinuation)
586{
587    connect();
588    Vector<char> bazVector;
589    bazVector.append("BAZ", 3);
590    EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(bazVector));
591
592    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeBinary, "Bx", 1);
593    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeContinuation, "Ax", 1);
594    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeContinuation, "Zx", 1);
595}
596
597TEST_F(NewWebSocketChannelImplTest, receiveBinaryWithNullBytes)
598{
599    connect();
600    {
601        InSequence s;
602        {
603            Vector<char> v;
604            v.append("\0AR", 3);
605            EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(v));
606        }
607        {
608            Vector<char> v;
609            v.append("B\0Z", 3);
610            EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(v));
611        }
612        {
613            Vector<char> v;
614            v.append("QU\0", 3);
615            EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(v));
616        }
617        {
618            Vector<char> v;
619            v.append("\0\0\0", 3);
620            EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(v));
621        }
622    }
623
624    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeBinary, "\0AR", 3);
625    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeBinary, "B\0Z", 3);
626    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeBinary, "QU\0", 3);
627    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeBinary, "\0\0\0", 3);
628}
629
630TEST_F(NewWebSocketChannelImplTest, receiveBinaryNonLatin1UTF8)
631{
632    connect();
633    Vector<char> v;
634    v.append("\xe7\x8b\x90\xe0\xa4\x94", 6);
635    EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(v));
636
637    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeBinary, "\xe7\x8b\x90\xe0\xa4\x94", 6);
638}
639
640TEST_F(NewWebSocketChannelImplTest, receiveBinaryNonLatin1UTF8Continuation)
641{
642    connect();
643    Vector<char> v;
644    v.append("\xe7\x8b\x90\xe0\xa4\x94", 6);
645    EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(v));
646
647    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeBinary, "\xe7\x8b", 2);
648    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeContinuation, "\x90\xe0", 2);
649    handleClient()->didReceiveData(handle(), false, WebSocketHandle::MessageTypeContinuation, "\xa4", 1);
650    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeContinuation, "\x94", 1);
651}
652
653TEST_F(NewWebSocketChannelImplTest, receiveBinaryNonUTF8)
654{
655    connect();
656    Vector<char> v;
657    v.append("\x80\xff", 2);
658    EXPECT_CALL(*channelClient(), didReceiveBinaryDataMock(v));
659
660    handleClient()->didReceiveData(handle(), true, WebSocketHandle::MessageTypeBinary, "\x80\xff", 2);
661}
662
663TEST_F(NewWebSocketChannelImplTest, closeFromBrowser)
664{
665    connect();
666    Checkpoint checkpoint;
667    {
668        InSequence s;
669
670        EXPECT_CALL(*channelClient(), didStartClosingHandshake());
671        EXPECT_CALL(checkpoint, Call(1));
672
673        EXPECT_CALL(*handle(), close(WebSocketChannel::CloseEventCodeNormalClosure, WebString("close reason")));
674        EXPECT_CALL(checkpoint, Call(2));
675
676        EXPECT_CALL(*channelClient(), didClose(WebSocketChannelClient::ClosingHandshakeComplete, WebSocketChannel::CloseEventCodeNormalClosure, String("close reason")));
677        EXPECT_CALL(checkpoint, Call(3));
678    }
679
680    handleClient()->didStartClosingHandshake(handle());
681    checkpoint.Call(1);
682
683    channel()->close(WebSocketChannel::CloseEventCodeNormalClosure, String("close reason"));
684    checkpoint.Call(2);
685
686    handleClient()->didClose(handle(), true, WebSocketChannel::CloseEventCodeNormalClosure, String("close reason"));
687    checkpoint.Call(3);
688
689    channel()->disconnect();
690}
691
692TEST_F(NewWebSocketChannelImplTest, closeFromWebSocket)
693{
694    connect();
695    Checkpoint checkpoint;
696    {
697        InSequence s;
698
699        EXPECT_CALL(*handle(), close(WebSocketChannel::CloseEventCodeNormalClosure, WebString("close reason")));
700        EXPECT_CALL(checkpoint, Call(1));
701
702        EXPECT_CALL(*channelClient(), didClose(WebSocketChannelClient::ClosingHandshakeComplete, WebSocketChannel::CloseEventCodeNormalClosure, String("close reason")));
703        EXPECT_CALL(checkpoint, Call(2));
704    }
705
706    channel()->close(WebSocketChannel::CloseEventCodeNormalClosure, String("close reason"));
707    checkpoint.Call(1);
708
709    handleClient()->didClose(handle(), true, WebSocketChannel::CloseEventCodeNormalClosure, String("close reason"));
710    checkpoint.Call(2);
711
712    channel()->disconnect();
713}
714
715TEST_F(NewWebSocketChannelImplTest, failFromBrowser)
716{
717    connect();
718    {
719        InSequence s;
720
721        EXPECT_CALL(*channelClient(), didReceiveMessageError());
722        EXPECT_CALL(*channelClient(), didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, WebSocketChannel::CloseEventCodeAbnormalClosure, String()));
723    }
724
725    handleClient()->didFail(handle(), "fail message");
726}
727
728TEST_F(NewWebSocketChannelImplTest, failFromWebSocket)
729{
730    connect();
731    {
732        InSequence s;
733
734        EXPECT_CALL(*channelClient(), didReceiveMessageError());
735        EXPECT_CALL(*channelClient(), didClose(WebSocketChannelClient::ClosingHandshakeIncomplete, WebSocketChannel::CloseEventCodeAbnormalClosure, String()));
736    }
737
738    channel()->fail("fail message from WebSocket", ErrorMessageLevel, "sourceURL", 1234);
739}
740
741} // namespace
742
743} // namespace blink
744