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

Side by Side Diff: third_party/WebKit/Source/core/page/EventSourceTest.cpp

Issue 1642563002: Introduce EventSourceParser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@event-source-retry-fix
Patch Set: Created 4 years, 10 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
OLDNEW
(Empty)
1 // Copyright 2016 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 "core/page/EventSource.h"
6
7 #include "bindings/core/v8/ExceptionState.h"
8 #include "bindings/core/v8/ScriptState.h"
9 #include "bindings/core/v8/ScriptValue.h"
10 #include "bindings/core/v8/SerializedScriptValue.h"
11 #include "bindings/core/v8/V8Binding.h"
12 #include "core/dom/ExecutionContext.h"
13 #include "core/dom/MessagePort.h"
14 #include "core/events/Event.h"
15 #include "core/events/EventListener.h"
16 #include "core/events/MessageEvent.h"
17 #include "core/page/EventSourceInit.h"
18 #include "core/testing/DummyPageHolder.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 #include <string.h>
22 #include <v8.h>
23
24 namespace blink {
25
26 namespace {
27
28 String dataAsString(ScriptState* scriptState, MessageEvent* event)
29 {
30 ScriptState::Scope scope(scriptState);
31 v8::Isolate* isolate = scriptState->isolate();
32 ASSERT(MessageEvent::DataTypeSerializedScriptValue == event->dataType());
33 if (!event->dataAsSerializedScriptValue())
34 return String();
35 MessagePortArray ports = event->ports();
36 NonThrowableExceptionState es;
37 return toUSVString(isolate, event->dataAsSerializedScriptValue()->deserializ e(isolate, &ports), es);
38 }
39
40 class FakeEventListener : public EventListener {
41 public:
42 static PassRefPtrWillBeRawPtr<FakeEventListener> create()
43 {
44 return adoptRefWillBeNoop(new FakeEventListener());
45 }
46 bool operator==(const EventListener& x) const override { return &x == this; }
47 const WillBeHeapVector<RefPtrWillBeMember<Event>>& events() { return m_event s; }
48 void handleEvent(ExecutionContext* executionContext, Event* event)
49 {
50 m_events.append(event);
51 }
52 DEFINE_INLINE_TRACE()
53 {
54 visitor->trace(m_events);
55 EventListener::trace(visitor);
56 }
57
58 protected:
59 FakeEventListener() : EventListener(EventListener::CPPEventListenerType) {}
60 WillBeHeapVector<RefPtrWillBeMember<Event>> m_events;
61 };
62
63 class EventSourceTest : public ::testing::Test {
64 protected:
65 EventSourceTest()
66 : m_page(DummyPageHolder::create())
67 , m_source(EventSource::create(&document(), "https://localhost/", EventS ourceInit(), m_exceptionState))
68 {
69 source()->setStateForTest(EventSource::OPEN);
70 source()->setRequestInFlightForTest(true);
71 }
72 ~EventSourceTest() override
73 {
74 source()->setRequestInFlightForTest(false);
75 source()->close();
76
77 // We need this because there is
78 // listener -> event -> source -> listener
79 // reference cycle on non-oilpan build.
80 m_source->removeAllEventListeners();
81 m_source = nullptr;
82 }
83
84 void enqueue(const char* data) { client()->didReceiveData(data, strlen(data) ); }
85 void enqueueOneByOne(const char* data)
86 {
87 const char*p = data;
88 while (*p != '\0')
89 client()->didReceiveData(p++, 1);
90 }
91
92 Document& document() { return m_page->document(); }
93 ScriptState* scriptState() { return ScriptState::forMainWorld(document().fra me()); }
94 EventSource* source() { return m_source; }
95 ThreadableLoaderClient* client() { return m_source->asThreadableLoaderClient ForTest(); }
96
97 private:
98 OwnPtr<DummyPageHolder> m_page;
99 NonThrowableExceptionState m_exceptionState;
100 Persistent<EventSource> m_source;
101 };
102
103 TEST_F(EventSourceTest, EmptyMessageEventShouldNotBeDispatched)
104 {
105 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
106
107 source()->addEventListener("message", listener);
108 enqueue("\n");
109
110 EXPECT_EQ(0u, listener->events().size());
111 }
112
113 TEST_F(EventSourceTest, DispatchSimpleMessageEvent)
114 {
115 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
116
117 source()->addEventListener("message", listener);
118 enqueue("data:hello\n\n");
119
120 ASSERT_EQ(1u, listener->events().size());
121 ASSERT_EQ("message", listener->events()[0]->type());
122 RefPtrWillBeRawPtr<MessageEvent> event = static_cast<MessageEvent*>(listener ->events()[0].get());
123 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event->dataType());
124 EXPECT_EQ("hello", dataAsString(scriptState(), event.get()));
125 EXPECT_EQ(String(), event->lastEventId());
126 }
127
128 TEST_F(EventSourceTest, DispatchMessageEventWithLastEventId)
129 {
130 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
131
132 source()->addEventListener("message", listener);
133 enqueue("id:99\ndata:hello\n\n");
134
135 ASSERT_EQ(1u, listener->events().size());
136 ASSERT_EQ("message", listener->events()[0]->type());
137 RefPtrWillBeRawPtr<MessageEvent> event = static_cast<MessageEvent*>(listener ->events()[0].get());
138 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event->dataType());
139 EXPECT_EQ("hello", dataAsString(scriptState(), event.get()));
140 EXPECT_EQ("99", event->lastEventId());
141 }
142
143 TEST_F(EventSourceTest, DispatchMessageEventWithCustomEventType)
144 {
145 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
146
147 source()->addEventListener("foo", listener);
148 enqueue("event:foo\ndata:hello\n\n");
149
150 ASSERT_EQ(1u, listener->events().size());
151 ASSERT_EQ("foo", listener->events()[0]->type());
152 RefPtrWillBeRawPtr<MessageEvent> event = static_cast<MessageEvent*>(listener ->events()[0].get());
153 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event->dataType());
154 EXPECT_EQ("hello", dataAsString(scriptState(), event.get()));
155 }
156
157 TEST_F(EventSourceTest, RetryTakesEffectEvenWhenNotDispatching)
158 {
159 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
160
161 source()->addEventListener("message", listener);
162 ASSERT_NE(999u, EventSource::defaultReconnectDelay);
163
164 EXPECT_EQ(EventSource::defaultReconnectDelay, source()->reconnectDelayForTes t());
165 enqueue("retry:999\n");
166 EXPECT_EQ(999u, source()->reconnectDelayForTest());
167 EXPECT_EQ(0u, listener->events().size());
168 }
169
170 TEST_F(EventSourceTest, EventTypeShouldBeReset)
171 {
172 RefPtrWillBeRawPtr<FakeEventListener> fooListener = FakeEventListener::creat e();
173 RefPtrWillBeRawPtr<FakeEventListener> messageListener = FakeEventListener::c reate();
174
175 source()->addEventListener("foo", fooListener);
176 source()->addEventListener("message", messageListener);
177 enqueue("event:foo\ndata:hello\n\ndata:bye\n\n");
178
179 ASSERT_EQ(1u, fooListener->events().size());
180 ASSERT_EQ("foo", fooListener->events()[0]->type());
181 RefPtrWillBeRawPtr<MessageEvent> fooEvent = static_cast<MessageEvent*>(fooLi stener->events()[0].get());
182 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, fooEvent->dataType()) ;
183 EXPECT_EQ("hello", dataAsString(scriptState(), fooEvent.get()));
184
185 ASSERT_EQ(1u, messageListener->events().size());
186 ASSERT_EQ("message", messageListener->events()[0]->type());
187 RefPtrWillBeRawPtr<MessageEvent> messageEvent = static_cast<MessageEvent*>(m essageListener->events()[0].get());
188 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, messageEvent->dataTyp e());
189 EXPECT_EQ("bye", dataAsString(scriptState(), messageEvent.get()));
190 }
191
192 TEST_F(EventSourceTest, DataShouldBeReset)
193 {
194 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
195
196 source()->addEventListener("message", listener);
197 enqueue("data:hello\n\n\n");
198
199 ASSERT_EQ(1u, listener->events().size());
200 ASSERT_EQ("message", listener->events()[0]->type());
201 RefPtrWillBeRawPtr<MessageEvent> event = static_cast<MessageEvent*>(listener ->events()[0].get());
202 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event->dataType());
203 EXPECT_EQ("hello", dataAsString(scriptState(), event.get()));
204 }
205
206 TEST_F(EventSourceTest, LastEventIdShouldNotBeReset)
207 {
208 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
209
210 source()->addEventListener("message", listener);
211 enqueue("id:99\ndata:hello\n\ndata:bye\n\n");
212
213 ASSERT_EQ(2u, listener->events().size());
214
215 ASSERT_EQ("message", listener->events()[0]->type());
216 RefPtrWillBeRawPtr<MessageEvent> event0 = static_cast<MessageEvent*>(listene r->events()[0].get());
217 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event0->dataType());
218 EXPECT_EQ("hello", dataAsString(scriptState(), event0.get()));
219 EXPECT_EQ("99", event0->lastEventId());
220
221 ASSERT_EQ("message", listener->events()[1]->type());
222 RefPtrWillBeRawPtr<MessageEvent> event1 = static_cast<MessageEvent*>(listene r->events()[1].get());
223 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event1->dataType());
224 EXPECT_EQ("bye", dataAsString(scriptState(), event1.get()));
225 EXPECT_EQ("99", event1->lastEventId());
226 }
227
228 TEST_F(EventSourceTest, VariousNewLinesShouldBeAllowed)
229 {
230 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
231
232 source()->addEventListener("message", listener);
233 enqueueOneByOne("data:hello\r\n\rdata:bye\r\r");
234
235 ASSERT_EQ(2u, listener->events().size());
236
237 ASSERT_EQ("message", listener->events()[0]->type());
238 RefPtrWillBeRawPtr<MessageEvent> event0 = static_cast<MessageEvent*>(listene r->events()[0].get());
239 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event0->dataType());
240 EXPECT_EQ("hello", dataAsString(scriptState(), event0.get()));
241
242 ASSERT_EQ("message", listener->events()[1]->type());
243 RefPtrWillBeRawPtr<MessageEvent> event1 = static_cast<MessageEvent*>(listene r->events()[1].get());
244 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event1->dataType());
245 EXPECT_EQ("bye", dataAsString(scriptState(), event1.get()));
246 }
247
248 TEST_F(EventSourceTest, RetryWithEmptyValueShouldRestoreDefaultValue)
249 {
250 // TODO(yhirano): This is unspecified in the spec. We need to update
251 // the implementation or the spec.
252 EXPECT_EQ(EventSource::defaultReconnectDelay, source()->reconnectDelayForTes t());
253 enqueue("retry: 12\n");
254 EXPECT_NE(EventSource::defaultReconnectDelay, source()->reconnectDelayForTes t());
255 enqueue("retry\n");
256 EXPECT_EQ(EventSource::defaultReconnectDelay, source()->reconnectDelayForTes t());
257 }
258
259 TEST_F(EventSourceTest, NonDigitRetryShouldBeIgnored)
260 {
261 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
262
263 source()->addEventListener("message", listener);
264
265 EXPECT_EQ(EventSource::defaultReconnectDelay, source()->reconnectDelayForTes t());
266 enqueue("retry:123\n");
267 EXPECT_NE(EventSource::defaultReconnectDelay, source()->reconnectDelayForTes t());
268 EXPECT_EQ(123u, source()->reconnectDelayForTest());
269
270 enqueue("retry:a0\n");
271 EXPECT_EQ(123u, source()->reconnectDelayForTest());
272 enqueue("retry:xi\n");
273 EXPECT_EQ(123u, source()->reconnectDelayForTest());
274
275 enqueue("retry:2a\n");
276 EXPECT_EQ(123u, source()->reconnectDelayForTest());
277
278 enqueue("retry:09a\n");
279 EXPECT_EQ(123u, source()->reconnectDelayForTest());
280
281 enqueue("retry:1\b\n");
282 EXPECT_EQ(123u, source()->reconnectDelayForTest());
283
284 enqueue("retry: 1234\n");
285 EXPECT_EQ(123u, source()->reconnectDelayForTest());
286
287 enqueue("retry:456 \n");
288 EXPECT_EQ(123u, source()->reconnectDelayForTest());
289
290 EXPECT_EQ(0u, listener->events().size());
291 }
292
293 TEST_F(EventSourceTest, UnrecognizedFieldShouldBeIgnored)
294 {
295 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
296
297 source()->addEventListener("message", listener);
298 enqueue("data:hello\nhoge:fuga\npiyo\n\n");
299
300 ASSERT_EQ(1u, listener->events().size());
301 ASSERT_EQ("message", listener->events()[0]->type());
302 RefPtrWillBeRawPtr<MessageEvent> event = static_cast<MessageEvent*>(listener ->events()[0].get());
303 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event->dataType());
304 EXPECT_EQ("hello", dataAsString(scriptState(), event.get()));
305 }
306
307 TEST_F(EventSourceTest, CommentShouldBeIgnored)
308 {
309 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
310
311 source()->addEventListener("message", listener);
312 enqueue("data:hello\n:event:a\n\n");
313
314 ASSERT_EQ(1u, listener->events().size());
315
316 ASSERT_EQ("message", listener->events()[0]->type());
317 RefPtrWillBeRawPtr<MessageEvent> event0 = static_cast<MessageEvent*>(listene r->events()[0].get());
318 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event0->dataType());
319 EXPECT_EQ("hello", dataAsString(scriptState(), event0.get()));
320 }
321
322 TEST_F(EventSourceTest, BOMShouldBeIgnored)
323 {
324 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
325
326 source()->addEventListener("message", listener);
327 enqueue("\xef\xbb\xbf" "data:hello\n\n");
328
329 ASSERT_EQ(1u, listener->events().size());
330
331 ASSERT_EQ("message", listener->events()[0]->type());
332 RefPtrWillBeRawPtr<MessageEvent> event0 = static_cast<MessageEvent*>(listene r->events()[0].get());
333 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event0->dataType());
334 EXPECT_EQ("hello", dataAsString(scriptState(), event0.get()));
335 }
336
337 TEST_F(EventSourceTest, ColonlessLineShouldBeTreatedAsNameOnlyField)
338 {
339 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
340
341 source()->addEventListener("message", listener);
342 enqueue("data:hello\nevent:a\nevent\n\n");
343
344 ASSERT_EQ(1u, listener->events().size());
345
346 ASSERT_EQ("message", listener->events()[0]->type());
347 RefPtrWillBeRawPtr<MessageEvent> event0 = static_cast<MessageEvent*>(listene r->events()[0].get());
348 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event0->dataType());
349 EXPECT_EQ("hello", dataAsString(scriptState(), event0.get()));
350 }
351
352 TEST_F(EventSourceTest, AtMostOneLeadingSpaceCanBeSkipped)
353 {
354 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
355
356 source()->addEventListener(" type ", listener);
357 enqueue("data: hello \nevent: type \n\n");
358
359 ASSERT_EQ(1u, listener->events().size());
360 ASSERT_EQ(" type ", listener->events()[0]->type());
361 RefPtrWillBeRawPtr<MessageEvent> event = static_cast<MessageEvent*>(listener ->events()[0].get());
362 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event->dataType());
363 EXPECT_EQ(" hello ", dataAsString(scriptState(), event.get()));
364 }
365
366 TEST_F(EventSourceTest, DataShouldAccumulate)
367 {
368 RefPtrWillBeRawPtr<FakeEventListener> listener = FakeEventListener::create() ;
369
370 source()->addEventListener("message", listener);
371 enqueue("data:hello\ndata: world\ndata\n\n");
372
373 ASSERT_EQ(1u, listener->events().size());
374 ASSERT_EQ("message", listener->events()[0]->type());
375 RefPtrWillBeRawPtr<MessageEvent> event = static_cast<MessageEvent*>(listener ->events()[0].get());
376 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event->dataType());
377 EXPECT_EQ("hello\nworld\n", dataAsString(scriptState(), event.get()));
378 }
379
380 TEST_F(EventSourceTest, EventShouldNotAccumulate)
381 {
382 RefPtrWillBeRawPtr<FakeEventListener> aListener = FakeEventListener::create( );
383 RefPtrWillBeRawPtr<FakeEventListener> bListener = FakeEventListener::create( );
384
385 source()->addEventListener("a", aListener);
386 source()->addEventListener("b", bListener);
387 enqueue("data:hello\nevent:a\nevent:b\n\n");
388
389 ASSERT_EQ(0u, aListener->events().size());
390 ASSERT_EQ(1u, bListener->events().size());
391 ASSERT_EQ("b", bListener->events()[0]->type());
392 RefPtrWillBeRawPtr<MessageEvent> event = static_cast<MessageEvent*>(bListene r->events()[0].get());
393 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, event->dataType());
394 EXPECT_EQ("hello", dataAsString(scriptState(), event.get()));
395 }
396
397 TEST_F(EventSourceTest, FeedDataOneByOne)
398 {
399 RefPtrWillBeRawPtr<FakeEventListener> aListener = FakeEventListener::create( );
400 RefPtrWillBeRawPtr<FakeEventListener> bListener = FakeEventListener::create( );
401 RefPtrWillBeRawPtr<FakeEventListener> messageListener = FakeEventListener::c reate();
402
403 source()->addEventListener("a", aListener);
404 source()->addEventListener("b", bListener);
405 source()->addEventListener("message", messageListener);
406 enqueueOneByOne("data:hello\r\ndata:world\revent:a\revent:b\nid:4\n\nid:8\nd ata:bye\r\n\r");
407
408 ASSERT_EQ(0u, aListener->events().size());
409
410 ASSERT_EQ(1u, bListener->events().size());
411 ASSERT_EQ("b", bListener->events()[0]->type());
412 RefPtrWillBeRawPtr<MessageEvent> bEvent = static_cast<MessageEvent*>(bListen er->events()[0].get());
413 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, bEvent->dataType());
414 EXPECT_EQ("hello\nworld", dataAsString(scriptState(), bEvent.get()));
415 EXPECT_EQ("4", bEvent->lastEventId());
416
417 ASSERT_EQ(1u, messageListener->events().size());
418 ASSERT_EQ("message", messageListener->events()[0]->type());
419 RefPtrWillBeRawPtr<MessageEvent> messageEvent = static_cast<MessageEvent*>(m essageListener->events()[0].get());
420 ASSERT_EQ(MessageEvent::DataTypeSerializedScriptValue, messageEvent->dataTyp e());
421 EXPECT_EQ("bye", dataAsString(scriptState(), messageEvent.get()));
422 EXPECT_EQ("8", messageEvent->lastEventId());
423 }
424
425 } // namespace
426
427 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698