PageRenderTime 96ms CodeModel.GetById 47ms app.highlight 24ms RepoModel.GetById 21ms app.codeStats 0ms

/tests/Microsoft.AspNet.SignalR.Tests/Server/Hubs/HubFacts.cs

https://github.com/mip1983/SignalR
C# | 941 lines | 714 code | 220 blank | 7 comment | 13 complexity | 05e5bf7a2e561272b3f5fae98d8b5c73 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Threading;
  5using System.Threading.Tasks;
  6using Newtonsoft.Json.Linq;
  7using Moq;
  8using Microsoft.AspNet.SignalR.Client.Hubs;
  9using Microsoft.AspNet.SignalR.Hosting.Memory;
 10using Microsoft.AspNet.SignalR.Hubs;
 11using Microsoft.AspNet.SignalR.Tests.Infrastructure;
 12using Xunit;
 13
 14namespace Microsoft.AspNet.SignalR.Tests
 15{
 16    public class HubFacts : IDisposable
 17    {
 18        [Fact]
 19        public void ReadingState()
 20        {
 21            var host = new MemoryHost();
 22            host.MapHubs();
 23            var connection = new Client.Hubs.HubConnection("http://foo/");
 24
 25            var hub = connection.CreateHubProxy("demo");
 26
 27            hub["name"] = "test";
 28
 29            connection.Start(host).Wait();
 30
 31            var result = hub.Invoke<string>("ReadStateValue").Result;
 32
 33            Assert.Equal("test", result);
 34
 35            connection.Stop();
 36        }
 37
 38        [Fact]
 39        public void SettingState()
 40        {
 41            var host = new MemoryHost();
 42            host.MapHubs();
 43            var connection = new Client.Hubs.HubConnection("http://foo/");
 44
 45            var hub = connection.CreateHubProxy("demo");
 46            connection.Start(host).Wait();
 47
 48            var result = hub.Invoke<string>("SetStateValue", "test").Result;
 49
 50            Assert.Equal("test", result);
 51            Assert.Equal("test", hub["Company"]);
 52
 53            connection.Stop();
 54        }
 55
 56        [Fact]
 57        public void GetValueFromServer()
 58        {
 59            var host = new MemoryHost();
 60            host.MapHubs();
 61            var connection = new Client.Hubs.HubConnection("http://foo/");
 62
 63            var hub = connection.CreateHubProxy("demo");
 64
 65            connection.Start(host).Wait();
 66
 67            var result = hub.Invoke<int>("GetValue").Result;
 68
 69            Assert.Equal(10, result);
 70            connection.Stop();
 71        }
 72
 73        [Fact]
 74        public void TaskWithException()
 75        {
 76            var host = new MemoryHost();
 77            host.MapHubs();
 78            var connection = new Client.Hubs.HubConnection("http://foo/");
 79
 80            var hub = connection.CreateHubProxy("demo");
 81
 82            connection.Start(host).Wait();
 83
 84            var ex = Assert.Throws<AggregateException>(() => hub.Invoke("TaskWithException").Wait());
 85
 86            Assert.IsType<InvalidOperationException>(ex.GetBaseException());
 87            Assert.Contains("System.Exception", ex.GetBaseException().Message);
 88            connection.Stop();
 89        }
 90
 91        [Fact]
 92        public void GenericTaskWithException()
 93        {
 94            var host = new MemoryHost();
 95            host.MapHubs();
 96            var connection = new Client.Hubs.HubConnection("http://foo/");
 97
 98            var hub = connection.CreateHubProxy("demo");
 99
100            connection.Start(host).Wait();
101
102            var ex = Assert.Throws<AggregateException>(() => hub.Invoke("GenericTaskWithException").Wait());
103
104            Assert.IsType<InvalidOperationException>(ex.GetBaseException());
105            Assert.Contains("System.Exception", ex.GetBaseException().Message);
106            connection.Stop();
107        }
108
109        [Fact]
110        public void GenericTaskWithContinueWith()
111        {
112            var host = new MemoryHost();
113            host.MapHubs();
114            var connection = new Client.Hubs.HubConnection("http://foo/");
115
116            var hub = connection.CreateHubProxy("demo");
117
118            connection.Start(host).Wait();
119
120            int result = hub.Invoke<int>("GenericTaskWithContinueWith").Result;
121
122            Assert.Equal(4, result);
123            connection.Stop();
124        }
125
126        [Fact]
127        public void Overloads()
128        {
129            var host = new MemoryHost();
130            host.MapHubs();
131            var connection = new Client.Hubs.HubConnection("http://foo/");
132
133            var hub = connection.CreateHubProxy("demo");
134
135            connection.Start(host).Wait();
136
137            hub.Invoke("Overload").Wait();
138            int n = hub.Invoke<int>("Overload", 1).Result;
139
140            Assert.Equal(1, n);
141            connection.Stop();
142        }
143
144        [Fact]
145        public void UnsupportedOverloads()
146        {
147            var host = new MemoryHost();
148            host.MapHubs();
149            var connection = new Client.Hubs.HubConnection("http://foo/");
150
151            var hub = connection.CreateHubProxy("demo");
152
153            connection.Start(host).Wait();
154
155            var ex = Assert.Throws<InvalidOperationException>(() => hub.Invoke("UnsupportedOverload", 13177).Wait());
156
157            Assert.Equal("'UnsupportedOverload' method could not be resolved.", ex.GetBaseException().Message);
158            connection.Stop();
159        }
160
161        [Fact]
162        public void ChangeHubUrl()
163        {
164            var host = new MemoryHost();
165            host.MapHubs("/foo");
166            var connection = new Client.Hubs.HubConnection("http://site/foo", useDefaultUrl: false);
167
168            var hub = connection.CreateHubProxy("demo");
169
170            var wh = new ManualResetEvent(false);
171
172            hub.On("signal", id =>
173            {
174                Assert.NotNull(id);
175                wh.Set();
176            });
177
178            connection.Start(host).Wait();
179
180            hub.Invoke("DynamicTask").Wait();
181
182            Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5)));
183            connection.Stop();
184        }
185
186        [Fact]
187        public void GuidTest()
188        {
189            var host = new MemoryHost();
190            host.MapHubs();
191            var connection = new Client.Hubs.HubConnection("http://site/");
192
193            var hub = connection.CreateHubProxy("demo");
194
195            var wh = new ManualResetEvent(false);
196
197            hub.On<Guid>("TestGuid", id =>
198            {
199                Assert.NotNull(id);
200                wh.Set();
201            });
202
203            connection.Start(host).Wait();
204
205            hub.Invoke("TestGuid").Wait();
206
207            Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5)));
208            connection.Stop();
209        }
210
211        [Fact]
212        public void HubHasConnectionEvents()
213        {
214            var type = typeof(Hub);
215            // Hub has the disconnect method
216            Assert.True(type.GetMethod("OnDisconnected") != null);
217
218            // Hub has the connect method
219            Assert.True(type.GetMethod("OnConnected") != null);
220
221            // Hub has the reconnect method
222            Assert.True(type.GetMethod("OnReconnected") != null);
223        }
224
225        [Fact]
226        public void ComplexPersonState()
227        {
228            var host = new MemoryHost();
229            host.MapHubs();
230            var connection = new Client.Hubs.HubConnection("http://site/");
231
232            var hub = connection.CreateHubProxy("demo");
233
234            var wh = new ManualResetEvent(false);
235
236            connection.Start(host).Wait();
237
238            var person = new SignalR.Samples.Hubs.DemoHub.DemoHub.Person
239            {
240                Address = new SignalR.Samples.Hubs.DemoHub.DemoHub.Address
241                {
242                    Street = "Redmond",
243                    Zip = "98052"
244                },
245                Age = 25,
246                Name = "David"
247            };
248
249            var person1 = hub.Invoke<SignalR.Samples.Hubs.DemoHub.DemoHub.Person>("ComplexType", person).Result;
250            var person2 = hub.GetValue<SignalR.Samples.Hubs.DemoHub.DemoHub.Person>("person");
251            JObject obj = ((dynamic)hub).person;
252            var person3 = obj.ToObject<SignalR.Samples.Hubs.DemoHub.DemoHub.Person>();
253
254            Assert.NotNull(person1);
255            Assert.NotNull(person2);
256            Assert.NotNull(person3);
257            Assert.Equal("David", person1.Name);
258            Assert.Equal("David", person2.Name);
259            Assert.Equal("David", person3.Name);
260            Assert.Equal(25, person1.Age);
261            Assert.Equal(25, person2.Age);
262            Assert.Equal(25, person3.Age);
263            Assert.Equal("Redmond", person1.Address.Street);
264            Assert.Equal("Redmond", person2.Address.Street);
265            Assert.Equal("Redmond", person3.Address.Street);
266            Assert.Equal("98052", person1.Address.Zip);
267            Assert.Equal("98052", person2.Address.Zip);
268            Assert.Equal("98052", person3.Address.Zip);
269
270            connection.Stop();
271        }
272
273        [Fact]
274        public void DynamicInvokeTest()
275        {
276            var host = new MemoryHost();
277            host.MapHubs();
278            var connection = new Client.Hubs.HubConnection("http://site/");
279            string callback = @"!!!|\CallMeBack,,,!!!";
280
281            var hub = connection.CreateHubProxy("demo");
282
283            var wh = new ManualResetEvent(false);
284
285            hub.On(callback, () => wh.Set());
286
287            connection.Start(host).Wait();
288
289            hub.Invoke("DynamicInvoke", callback).Wait();
290
291            Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5)));
292            connection.Stop();
293        }
294
295        [Fact]
296        public void CreateProxyAfterConnectionStartsThrows()
297        {
298            var host = new MemoryHost();
299            host.MapHubs();
300            var connection = new Client.Hubs.HubConnection("http://site/");
301
302            try
303            {
304                connection.Start(host).Wait();
305                Assert.Throws<InvalidOperationException>(() => connection.CreateHubProxy("demo"));
306            }
307            finally
308            {
309                connection.Stop();
310            }
311        }
312
313        [Fact]
314        public void AddingToMultipleGroups()
315        {
316            var host = new MemoryHost();
317            host.MapHubs();
318            int max = 10;
319
320            var countDown = new CountDownRange<int>(Enumerable.Range(0, max));
321            var connection = new Client.Hubs.HubConnection("http://foo");
322            var proxy = connection.CreateHubProxy("MultGroupHub");
323
324            proxy.On<User>("onRoomJoin", user =>
325            {
326                Assert.True(countDown.Mark(user.Index));
327            });
328
329            connection.Start(host).Wait();
330
331            for (int i = 0; i < max; i++)
332            {
333                var user = new User { Index = i, Name = "tester", Room = "test" + i };
334                proxy.Invoke("login", user).Wait();
335                proxy.Invoke("joinRoom", user).Wait();
336            }
337
338            Assert.True(countDown.Wait(TimeSpan.FromSeconds(30)), "Didn't receive " + max + " messages. Got " + (max - countDown.Count) + " missed " + String.Join(",", countDown.Left.Select(i => i.ToString())));
339
340            connection.Stop();
341        }
342
343        [Fact]
344        public void HubGroupsDontRejoinByDefault()
345        {
346            var host = new MemoryHost();
347            host.Configuration.KeepAlive = null;
348            host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(1);
349            host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(1);
350            host.MapHubs();
351            int max = 10;
352
353            var countDown = new CountDownRange<int>(Enumerable.Range(0, max));
354            var countDownAfterReconnect = new CountDownRange<int>(Enumerable.Range(max, max));
355            var connection = new Client.Hubs.HubConnection("http://foo");
356            var proxy = connection.CreateHubProxy("MultGroupHub");
357
358            proxy.On<User>("onRoomJoin", u =>
359            {
360                if (u.Index < max)
361                {
362                    Assert.True(countDown.Mark(u.Index));
363                }
364                else
365                {
366                    Assert.True(countDownAfterReconnect.Mark(u.Index));
367                }
368            });
369
370            connection.Start(host).Wait();
371
372            var user = new User { Name = "tester" };
373            proxy.Invoke("login", user).Wait();
374
375            for (int i = 0; i < max; i++)
376            {
377                user.Index = i;
378                proxy.Invoke("joinRoom", user).Wait();
379            }
380
381            // Force Reconnect
382            Thread.Sleep(TimeSpan.FromSeconds(3));
383
384            for (int i = max; i < 2 * max; i++)
385            {
386                user.Index = i;
387                proxy.Invoke("joinRoom", user).Wait();
388            }
389
390            Assert.True(countDown.Wait(TimeSpan.FromSeconds(30)), "Didn't receive " + max + " messages. Got " + (max - countDown.Count) + " missed " + String.Join(",", countDown.Left.Select(i => i.ToString())));
391            Assert.True(!countDownAfterReconnect.Wait(TimeSpan.FromSeconds(30)) && countDownAfterReconnect.Count == max);
392
393            connection.Stop();
394        }
395
396        [Fact]
397        public void HubGroupsRejoinWhenAutoRejoiningGroupsEnabled()
398        {
399            var host = new MemoryHost();
400            host.HubPipeline.EnableAutoRejoiningGroups();
401            host.Configuration.KeepAlive = null;
402            host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(1);
403            host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(1);
404            host.MapHubs();
405            int max = 10;
406
407            var countDown = new CountDownRange<int>(Enumerable.Range(0, max));
408            var countDownAfterReconnect = new CountDownRange<int>(Enumerable.Range(max, max));
409            var connection = new Client.Hubs.HubConnection("http://foo");
410            var proxy = connection.CreateHubProxy("MultGroupHub");
411
412            proxy.On<User>("onRoomJoin", u =>
413            {
414                if (u.Index < max)
415                {
416                    Assert.True(countDown.Mark(u.Index));
417                }
418                else
419                {
420                    Assert.True(countDownAfterReconnect.Mark(u.Index));
421                }
422            });
423
424            connection.Start(host).Wait();
425
426            var user = new User { Name = "tester" };
427            proxy.Invoke("login", user).Wait();
428
429            for (int i = 0; i < max; i++)
430            {
431                user.Index = i;
432                proxy.Invoke("joinRoom", user).Wait();
433            }
434
435            // Force Reconnect
436            Thread.Sleep(TimeSpan.FromSeconds(3));
437
438            for (int i = max; i < 2 * max; i++)
439            {
440                user.Index = i;
441                proxy.Invoke("joinRoom", user).Wait();
442            }
443
444            Assert.True(countDown.Wait(TimeSpan.FromSeconds(30)), "Didn't receive " + max + " messages. Got " + (max - countDown.Count) + " missed " + String.Join(",", countDown.Left.Select(i => i.ToString())));
445            Assert.True(countDownAfterReconnect.Wait(TimeSpan.FromSeconds(30)), "Didn't receive " + max + " messages. Got " + (max - countDownAfterReconnect.Count) + " missed " + String.Join(",", countDownAfterReconnect.Left.Select(i => i.ToString())));
446
447            connection.Stop();
448        }
449
450        [Fact]
451        public void RejoiningGroupsOnlyReceivesGroupsBelongingToHub()
452        {
453            var logRejoiningGroups = new LogRejoiningGroupsModule();
454            var host = new MemoryHost();
455            host.HubPipeline.AddModule(logRejoiningGroups);
456
457            host.Configuration.KeepAlive = null;
458            host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(1);
459            host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(1);
460            host.MapHubs();
461
462            var connection = new Client.Hubs.HubConnection("http://foo");
463            var proxy = connection.CreateHubProxy("MultGroupHub");
464            var proxy2 = connection.CreateHubProxy("MultGroupHub2");
465
466            connection.Start(host).Wait();
467
468            var user = new User { Name = "tester" };
469            proxy.Invoke("login", user).Wait();
470            proxy2.Invoke("login", user).Wait();
471
472            // Force Reconnect
473            Thread.Sleep(TimeSpan.FromSeconds(3));
474
475            proxy.Invoke("joinRoom", user).Wait();
476            proxy2.Invoke("joinRoom", user).Wait();
477
478            Thread.Sleep(TimeSpan.FromSeconds(3));
479
480            Assert.True(logRejoiningGroups.GroupsRejoined["MultGroupHub"].Contains("foo"));
481            Assert.True(logRejoiningGroups.GroupsRejoined["MultGroupHub"].Contains("tester"));
482            Assert.False(logRejoiningGroups.GroupsRejoined["MultGroupHub"].Contains("foo2"));
483            Assert.False(logRejoiningGroups.GroupsRejoined["MultGroupHub"].Contains("tester2"));
484            Assert.True(logRejoiningGroups.GroupsRejoined["MultGroupHub2"].Contains("foo2"));
485            Assert.True(logRejoiningGroups.GroupsRejoined["MultGroupHub2"].Contains("tester2"));
486            Assert.False(logRejoiningGroups.GroupsRejoined["MultGroupHub2"].Contains("foo"));
487            Assert.False(logRejoiningGroups.GroupsRejoined["MultGroupHub2"].Contains("tester"));
488
489            connection.Stop();
490        }
491
492        [Fact]
493        public void CustomQueryStringRaw()
494        {
495            var host = new MemoryHost();
496            host.MapHubs();
497            var connection = new Client.Hubs.HubConnection("http://foo/", "a=b");
498
499            var hub = connection.CreateHubProxy("CustomQueryHub");
500
501            connection.Start(host).Wait();
502
503            var result = hub.Invoke<string>("GetQueryString", "a").Result;
504
505            Assert.Equal("b", result);
506
507            connection.Stop();
508        }
509
510        [Fact]
511        public void CustomQueryString()
512        {
513            var host = new MemoryHost();
514            host.MapHubs();
515            var qs = new Dictionary<string, string>();
516            qs["a"] = "b";
517            var connection = new Client.Hubs.HubConnection("http://foo/", qs);
518
519            var hub = connection.CreateHubProxy("CustomQueryHub");
520
521            connection.Start(host).Wait();
522
523            var result = hub.Invoke<string>("GetQueryString", "a").Result;
524
525            Assert.Equal("b", result);
526
527            connection.Stop();
528        }
529
530        [Fact]
531        public void ReturningNullFromConnectAndDisconnectAccepted()
532        {
533            var mockHub = new Mock<SomeHub>() { CallBase = true };
534            mockHub.Setup(h => h.OnConnected()).Returns<Task>(null).Verifiable();
535            mockHub.Setup(h => h.OnDisconnected()).Returns<Task>(null).Verifiable();
536
537            var host = new MemoryHost();
538            host.HubPipeline.EnableAutoRejoiningGroups();
539            host.Configuration.KeepAlive = null;
540            host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(1);
541            host.DependencyResolver.Register(typeof(SomeHub), () => mockHub.Object);
542            host.MapHubs();
543            var connection = new Client.Hubs.HubConnection("http://foo");
544
545            var hub = connection.CreateHubProxy("SomeHub");
546            connection.Start(host).Wait();
547
548            connection.Stop();
549            Thread.Sleep(TimeSpan.FromSeconds(3));
550
551            mockHub.Verify();
552        }
553
554        [Fact]
555        public void ReturningNullFromReconnectAccepted()
556        {
557            var mockHub = new Mock<SomeHub>() { CallBase = true };
558            mockHub.Setup(h => h.OnReconnected()).Returns<Task>(null).Verifiable();
559
560            var host = new MemoryHost();
561            host.HubPipeline.EnableAutoRejoiningGroups();
562            host.Configuration.KeepAlive = null;
563            host.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(1);
564            host.Configuration.HeartBeatInterval = TimeSpan.FromSeconds(1);
565            host.DependencyResolver.Register(typeof(SomeHub), () => mockHub.Object);
566            host.MapHubs();
567            var connection = new Client.Hubs.HubConnection("http://foo");
568
569            var hub = connection.CreateHubProxy("SomeHub");
570            connection.Start(host).Wait();
571
572            // Force Reconnect
573            Thread.Sleep(TimeSpan.FromSeconds(3));
574
575            hub.Invoke("AllFoo").Wait();
576
577            Thread.Sleep(TimeSpan.FromSeconds(3));
578
579            connection.Stop();
580
581            mockHub.Verify();
582        }
583
584        [Fact]
585        public void UsingHubAfterManualCreationThrows()
586        {
587            var hub = new SomeHub();
588            Assert.Throws<InvalidOperationException>(() => hub.AllFoo());
589            Assert.Throws<InvalidOperationException>(() => hub.OneFoo());
590        }
591
592        [Fact]
593        public void CreatedHubsGetDisposed()
594        {
595            var mockDemoHubs = new List<Mock<SignalR.Samples.Hubs.DemoHub.DemoHub>>();
596
597            var host = new MemoryHost();
598            host.DependencyResolver.Register(typeof(SignalR.Samples.Hubs.DemoHub.DemoHub), () =>
599            {
600                var mockDemoHub = new Mock<SignalR.Samples.Hubs.DemoHub.DemoHub>() { CallBase = true };
601                mockDemoHubs.Add(mockDemoHub);
602                return mockDemoHub.Object;
603            });
604            host.MapHubs();
605            var connection = new Client.Hubs.HubConnection("http://foo/");
606
607            var hub = connection.CreateHubProxy("demo");
608
609            connection.Start(host).Wait();
610
611            var result = hub.Invoke<string>("ReadStateValue").Result;
612
613            foreach (var mockDemoHub in mockDemoHubs)
614            {
615                mockDemoHub.Verify(d => d.Dispose(), Times.Once());
616            }
617
618            connection.Stop();
619        }
620
621        [Fact]
622        public void SendToAllButCaller()
623        {
624            var host = new MemoryHost();
625            host.MapHubs();
626            var connection1 = new Client.Hubs.HubConnection("http://foo/");
627            var connection2 = new Client.Hubs.HubConnection("http://foo/");
628
629            var wh1 = new ManualResetEventSlim(initialState: false);
630            var wh2 = new ManualResetEventSlim(initialState: false);
631
632            var hub1 = connection1.CreateHubProxy("SendToSome");
633            var hub2 = connection2.CreateHubProxy("SendToSome");
634
635            connection1.Start(host).Wait();
636            connection2.Start(host).Wait();
637
638            hub1.On("send", wh1.Set);
639            hub2.On("send", wh2.Set);
640
641            hub1.Invoke("SendToAllButCaller").Wait();
642
643            Assert.False(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(10)));
644            Assert.True(wh2.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
645
646            connection1.Stop();
647            connection2.Stop();
648        }
649
650        [Fact]
651        public void SendToAllButCallerInGroup()
652        {
653            var host = new MemoryHost();
654            host.MapHubs();
655            var connection1 = new Client.Hubs.HubConnection("http://foo/");
656            var connection2 = new Client.Hubs.HubConnection("http://foo/");
657
658            var wh1 = new ManualResetEventSlim(initialState: false);
659            var wh2 = new ManualResetEventSlim(initialState: false);
660
661            var hub1 = connection1.CreateHubProxy("SendToSome");
662            var hub2 = connection2.CreateHubProxy("SendToSome");
663
664            connection1.Start(host).Wait();
665            connection2.Start(host).Wait();
666
667            hub1.On("send", wh1.Set);
668            hub2.On("send", wh2.Set);
669
670            hub1.Invoke("JoinGroup", "group").Wait();
671            hub2.Invoke("JoinGroup", "group").Wait();
672
673            hub1.Invoke("AllInGroupButCaller", "group").Wait();
674
675            Assert.False(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(10)));
676            Assert.True(wh2.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
677
678            connection1.Stop();
679            connection2.Stop();
680        }
681
682        [Fact]
683        public void SendToAll()
684        {
685            var host = new MemoryHost();
686            host.MapHubs();
687            var connection1 = new Client.Hubs.HubConnection("http://foo/");
688            var connection2 = new Client.Hubs.HubConnection("http://foo/");
689
690            var wh1 = new ManualResetEventSlim(initialState: false);
691            var wh2 = new ManualResetEventSlim(initialState: false);
692
693            var hub1 = connection1.CreateHubProxy("SendToSome");
694            var hub2 = connection2.CreateHubProxy("SendToSome");
695
696            connection1.Start(host).Wait();
697            connection2.Start(host).Wait();
698
699            hub1.On("send", wh1.Set);
700            hub2.On("send", wh2.Set);
701
702            hub1.Invoke("SendToAll").Wait();
703
704            Assert.True(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
705            Assert.True(wh2.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
706
707            connection1.Stop();
708            connection2.Stop();
709        }
710
711        [Fact]
712        public void SendToSelf()
713        {
714            var host = new MemoryHost();
715            host.MapHubs();
716            var connection1 = new Client.Hubs.HubConnection("http://foo/");
717            var connection2 = new Client.Hubs.HubConnection("http://foo/");
718
719            var wh1 = new ManualResetEventSlim(initialState: false);
720            var wh2 = new ManualResetEventSlim(initialState: false);
721
722            var hub1 = connection1.CreateHubProxy("SendToSome");
723            var hub2 = connection2.CreateHubProxy("SendToSome");
724
725            connection1.Start(host).Wait();
726            connection2.Start(host).Wait();
727
728            hub1.On("send", wh1.Set);
729            hub2.On("send", wh2.Set);
730
731            hub1.Invoke("SendToSelf").Wait();
732
733            Assert.True(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
734            Assert.False(wh2.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
735
736            connection1.Stop();
737            connection2.Stop();
738        }
739
740        [Fact]
741        public void SendToGroupFromOutsideOfHub()
742        {
743            var host = new MemoryHost();
744            host.MapHubs();
745            var connection1 = new Client.Hubs.HubConnection("http://foo/");
746            var hubContext = host.ConnectionManager.GetHubContext("SendToSome");
747
748            var wh1 = new ManualResetEventSlim(initialState: false);
749
750            var hub1 = connection1.CreateHubProxy("SendToSome");
751
752            connection1.Start(host).Wait();
753
754            hub1.On("send", wh1.Set);
755
756            hubContext.Groups.Add(connection1.ConnectionId, "Foo").Wait();
757            hubContext.Clients.Group("Foo").send();
758
759            Assert.True(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
760
761            connection1.Stop();
762        }
763
764        [Fact]
765        public void SendToSpecificClientFromOutsideOfHub()
766        {
767            var host = new MemoryHost();
768            host.MapHubs();
769            var connection1 = new Client.Hubs.HubConnection("http://foo/");
770            var hubContext = host.ConnectionManager.GetHubContext("SendToSome");
771
772            var wh1 = new ManualResetEventSlim(initialState: false);
773
774            var hub1 = connection1.CreateHubProxy("SendToSome");
775
776            connection1.Start(host).Wait();
777
778            hub1.On("send", wh1.Set);
779
780            hubContext.Clients.Client(connection1.ConnectionId).send();
781
782            Assert.True(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
783
784            connection1.Stop();
785        }
786
787        [Fact]
788        public void SendToAllFromOutsideOfHub()
789        {
790            var host = new MemoryHost();
791            host.MapHubs();
792            var connection1 = new Client.Hubs.HubConnection("http://foo/");
793            var connection2 = new Client.Hubs.HubConnection("http://foo/");
794            var hubContext = host.ConnectionManager.GetHubContext("SendToSome");
795
796            var wh1 = new ManualResetEventSlim(initialState: false);
797            var wh2 = new ManualResetEventSlim(initialState: false);
798
799            var hub1 = connection1.CreateHubProxy("SendToSome");
800            var hub2 = connection2.CreateHubProxy("SendToSome");
801
802            connection1.Start(host).Wait();
803            connection2.Start(host).Wait();
804
805            hub1.On("send", wh1.Set);
806            hub2.On("send", wh2.Set);
807
808            hubContext.Clients.All.send();
809
810            Assert.True(wh1.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
811            Assert.True(wh2.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)));
812
813            connection1.Stop();
814            connection2.Stop();
815        }
816
817        public class SendToSome : Hub
818        {
819            public Task SendToAllButCaller()
820            {
821                return Clients.Others.send();
822            }
823
824            public Task SendToAll()
825            {
826                return Clients.All.send();
827            }
828
829            public Task JoinGroup(string group)
830            {
831                return Groups.Add(Context.ConnectionId, group);
832            }
833
834            public Task AllInGroupButCaller(string group)
835            {
836                return Clients.OthersInGroup(group).send();
837            }
838
839            public Task SendToSelf()
840            {
841                return Clients.Client(Context.ConnectionId).send();
842            }
843        }
844
845        public class SomeHub : Hub
846        {
847            public void AllFoo()
848            {
849                Clients.All.foo();
850            }
851
852            public void OneFoo()
853            {
854                Clients.Caller.foo();
855            }
856        }
857
858        public class CustomQueryHub : Hub
859        {
860            public string GetQueryString(string key)
861            {
862                return Context.QueryString[key];
863            }
864        }
865
866        public class MultGroupHub : Hub
867        {
868            public virtual Task Login(User user)
869            {
870                return Task.Factory.StartNew(
871                    () =>
872                    {
873                        Groups.Remove(Context.ConnectionId, "foo").Wait();
874                        Groups.Add(Context.ConnectionId, "foo").Wait();
875
876                        Groups.Remove(Context.ConnectionId, user.Name).Wait();
877                        Groups.Add(Context.ConnectionId, user.Name).Wait();
878                    });
879            }
880
881            public Task JoinRoom(User user)
882            {
883                return Task.Factory.StartNew(
884                    () =>
885                    {
886                        Clients.Group(user.Name).onRoomJoin(user).Wait();
887                    });
888            }
889        }
890
891        public class MultGroupHub2 : MultGroupHub
892        {
893            public override Task Login(User user)
894            {
895                return Task.Factory.StartNew(
896                    () =>
897                    {
898                        Groups.Remove(Context.ConnectionId, "foo2").Wait();
899                        Groups.Add(Context.ConnectionId, "foo2").Wait();
900
901                        Groups.Remove(Context.ConnectionId, user.Name + "2").Wait();
902                        Groups.Add(Context.ConnectionId, user.Name + "2").Wait();
903                    });
904            }
905        }
906
907        public class LogRejoiningGroupsModule : HubPipelineModule
908        {
909            public Dictionary<string, List<string>> GroupsRejoined = new Dictionary<string,List<string>>();
910
911            public override Func<HubDescriptor, IRequest, IEnumerable<string>, IEnumerable<string>> BuildRejoiningGroups(Func<HubDescriptor, IRequest, IEnumerable<string>, IEnumerable<string>> rejoiningGroups)
912            {
913                return (hubDescriptor, request, groups) =>
914                {
915                    if (!GroupsRejoined.ContainsKey(hubDescriptor.Name))
916                    {
917                        GroupsRejoined[hubDescriptor.Name] = new List<string>(groups);
918                    }
919                    else
920                    {
921                        GroupsRejoined[hubDescriptor.Name].AddRange(groups);
922                    }
923                    return groups;
924                };
925            }
926        }
927
928        public class User
929        {
930            public int Index { get; set; }
931            public string Name { get; set; }
932            public string Room { get; set; }
933        }
934
935        public void Dispose()
936        {
937            GC.Collect();
938            GC.WaitForPendingFinalizers();
939        }
940    }
941}