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

Side by Side Diff: Source/modules/websockets/WebSocketTest.cpp

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

Powered by Google App Engine
This is Rietveld 408576698