public async Task TestHubDeleted()
        {
            var notifier        = new TestNotifier();
            var notifierFactory = new TestNotifierFactory(notifier);

            var sink1       = new TestSink <IMessage>();
            var sink2       = new TestSink <IMessage>();
            var sinkFactory = new Mock <ISinkFactory <IMessage> >();

            sinkFactory.Setup(s => s.CreateAsync("hub1")).ReturnsAsync(sink1);
            sinkFactory.Setup(s => s.CreateAsync("hub2")).ReturnsAsync(sink2);
            var client = new FrontendRoutingService(sinkFactory.Object, notifierFactory);

            await client.RouteAsync("hub1", Message1);

            await client.RouteAsync("hub2", Message2);

            await client.RouteAsync("hub2", Message4);

            await client.RouteAsync("hub1", Message3);

            Assert.False(sink1.IsClosed);
            Assert.False(sink2.IsClosed);

            await notifier.Delete("nohub");

            await notifier.Delete("hub2");

            sinkFactory.Setup(s => s.CreateAsync("hub2")).Throws(new InvalidOperationException());

            await client.RouteAsync("hub1", Message1);

            await Assert.ThrowsAsync <InvalidOperationException>(() => client.RouteAsync("hub2", Message2));

            await Assert.ThrowsAsync <InvalidOperationException>(() => client.RouteAsync("hub2", Message4));

            await client.RouteAsync("hub1", Message3);

            Assert.False(sink1.IsClosed);
            Assert.True(sink2.IsClosed);

            await client.CloseAsync(CancellationToken.None);

            Assert.True(sink1.IsClosed);
            Assert.True(sink2.IsClosed);

            Assert.Equal(new List <IMessage> {
                Message1, Message3, Message1, Message3
            }, sink1.Processed);
            Assert.Equal(new List <IMessage> {
                Message2, Message4
            }, sink2.Processed);
        }
        public async Task TestChangingHub()
        {
            var notifier        = new TestNotifier();
            var notifierFactory = new TestNotifierFactory(notifier);
            var underlying      = new Mock <IRoutingService>();
            var store           = new Mock <IRouteStore>();

            store.Setup(s => s.GetRouterConfigAsync("hub1", It.IsAny <CancellationToken>())).ReturnsAsync(new RouterConfig(AllEndpoints, new[] { Route1 }, Option.None <Route>()));
            store.Setup(s => s.GetRouterConfigAsync("hub2", It.IsAny <CancellationToken>())).ReturnsAsync(new RouterConfig(AllEndpoints, new[] { Route2 }, Option.None <Route>()));

            var client = new FilteringRoutingService(underlying.Object, store.Object, notifierFactory);
            await client.RouteAsync("hub1", new[] { Message1, Message2, Message3 });

            await client.RouteAsync("hub2", new[] { Message1, Message2, Message3 });

            underlying.Verify(s => s.RouteAsync("hub1", new[] { Message1 }), Times.Once);
            underlying.Verify(s => s.RouteAsync("hub2", new[] { Message2 }), Times.Once);

            // change hub1
            underlying.ResetCalls();
            store.Setup(s => s.GetRouterConfigAsync("hub1", It.IsAny <CancellationToken>())).ReturnsAsync(new RouterConfig(AllEndpoints, new[] { Route2 }, Option.None <Route>()));
            await notifier.Change("hub1");

            await client.RouteAsync("hub1", new[] { Message1, Message2, Message3 });

            await client.RouteAsync("hub2", new[] { Message1, Message2, Message3 });

            underlying.Verify(s => s.RouteAsync("hub1", new[] { Message2 }), Times.Once);
            underlying.Verify(s => s.RouteAsync("hub2", new[] { Message2 }), Times.Once);

            // change hub2
            underlying.ResetCalls();
            store.Setup(s => s.GetRouterConfigAsync("hub2", It.IsAny <CancellationToken>())).ReturnsAsync(new RouterConfig(AllEndpoints, new[] { Route3 }, Option.None <Route>()));
            await notifier.Change("hub2");

            await client.RouteAsync("hub1", new[] { Message1, Message2, Message3 });

            await client.RouteAsync("hub2", new[] { Message1, Message2, Message3 });

            underlying.Verify(s => s.RouteAsync("hub1", new[] { Message2 }), Times.Once);
            underlying.Verify(s => s.RouteAsync("hub2", new[] { Message3 }), Times.Once);
        }