public async Task when_subscribing_new_topics_then_subscriptions_are_created_and_ack_is_sent() { var configuration = new MqttConfiguration { MaximumQualityOfService = MqttQualityOfService.AtLeastOnce }; var topicEvaluator = new Mock <IMqttTopicEvaluator> (); var sessionRepository = new Mock <IRepository <ClientSession> > (); var packetIdProvider = Mock.Of <IPacketIdProvider> (); var retainedMessageRepository = Mock.Of <IRepository <RetainedMessage> > (); var senderFlow = Mock.Of <IPublishSenderFlow> (); var clientId = Guid.NewGuid().ToString(); var session = new ClientSession(clientId, clean: false); topicEvaluator.Setup(e => e.IsValidTopicFilter(It.IsAny <string> ())).Returns(true); sessionRepository.Setup(r => r.Read(It.IsAny <string> ())).Returns(session); var fooQoS = MqttQualityOfService.AtLeastOnce; var fooTopic = "test/foo/1"; var fooSubscription = new Subscription(fooTopic, fooQoS); var barQoS = MqttQualityOfService.AtMostOnce; var barTopic = "test/bar/1"; var barSubscription = new Subscription(barTopic, barQoS); var packetId = (ushort)new Random().Next(0, ushort.MaxValue); var subscribe = new Subscribe(packetId, fooSubscription, barSubscription); var channel = new Mock <IMqttChannel <IPacket> > (); var response = default(IPacket); channel.Setup(c => c.SendAsync(It.IsAny <IPacket> ())) .Callback <IPacket> (p => response = p) .Returns(Task.Delay(0)); var connectionProvider = new Mock <IConnectionProvider> (); connectionProvider .Setup(p => p.GetConnection(It.Is <string> (c => c == clientId))) .Returns(channel.Object); var flow = new ServerSubscribeFlow(topicEvaluator.Object, sessionRepository.Object, retainedMessageRepository, packetIdProvider, senderFlow, configuration); await flow.ExecuteAsync(clientId, subscribe, channel.Object) .ConfigureAwait(continueOnCapturedContext: false); sessionRepository.Verify(r => r.Update(It.Is <ClientSession> (s => s.Id == clientId && s.Subscriptions.Count == 2 && s.Subscriptions.All(x => x.TopicFilter == fooTopic || x.TopicFilter == barTopic)))); Assert.NotNull(response); var subscribeAck = response as SubscribeAck; Assert.NotNull(subscribeAck); Assert.Equal(packetId, subscribeAck.PacketId); Assert.Equal(2, subscribeAck.ReturnCodes.Count()); Assert.Contains(subscribeAck.ReturnCodes, c => c == SubscribeReturnCode.MaximumQoS0); Assert.Contains(subscribeAck.ReturnCodes, c => c == SubscribeReturnCode.MaximumQoS1); }
public async Task when_subscribing_topic_with_retain_message_then_retained_is_sent() { var configuration = new MqttConfiguration { MaximumQualityOfService = MqttQualityOfService.AtLeastOnce }; var topicEvaluator = new Mock <IMqttTopicEvaluator> (); var sessionRepository = new Mock <IRepository <ClientSession> > (); var packetIdProvider = Mock.Of <IPacketIdProvider> (); var retainedMessageRepository = new Mock <IRepository <RetainedMessage> > (); var senderFlow = new Mock <IPublishSenderFlow> (); var clientId = Guid.NewGuid().ToString(); var session = new ClientSession(clientId, clean: false); sessionRepository.Setup(r => r.Read(It.IsAny <string> ())).Returns(session); var fooQoS = MqttQualityOfService.AtLeastOnce; var fooTopic = "test/foo/#"; var fooSubscription = new Subscription(fooTopic, fooQoS); var retainedTopic = "test/foo/bar"; var retainedQoS = MqttQualityOfService.ExactlyOnce; var retainedPayload = Encoding.UTF8.GetBytes("Retained Message Test"); var retainedMessages = new List <RetainedMessage> { new RetainedMessage(retainedTopic, retainedQoS, retainedPayload) }; topicEvaluator.Setup(e => e.IsValidTopicFilter(It.IsAny <string> ())).Returns(true); topicEvaluator.Setup(e => e.Matches(It.IsAny <string> (), It.IsAny <string> ())).Returns(true); retainedMessageRepository.Setup(r => r.ReadAll()).Returns(retainedMessages.AsQueryable()); var packetId = (ushort)new Random().Next(0, ushort.MaxValue); var subscribe = new Subscribe(packetId, fooSubscription); var channel = new Mock <IMqttChannel <IPacket> > (); var connectionProvider = new Mock <IConnectionProvider> (); connectionProvider .Setup(p => p.GetConnection(It.Is <string> (c => c == clientId))) .Returns(channel.Object); var flow = new ServerSubscribeFlow(topicEvaluator.Object, sessionRepository.Object, retainedMessageRepository.Object, packetIdProvider, senderFlow.Object, configuration); await flow.ExecuteAsync(clientId, subscribe, channel.Object) .ConfigureAwait(continueOnCapturedContext: false); senderFlow.Verify(f => f.SendPublishAsync(It.Is <string>(s => s == clientId), It.Is <Publish> (p => p.Topic == retainedTopic && p.QualityOfService == fooQoS && p.Payload.ToList().SequenceEqual(retainedPayload) && p.PacketId.HasValue && p.Retain), It.Is <IMqttChannel <IPacket> >(c => c == channel.Object), It.Is <PendingMessageStatus>(x => x == PendingMessageStatus.PendingToSend))); }
public async Task when_subscribing_invalid_topic_then_failure_is_sent_in_ack() { var configuration = new MqttConfiguration { MaximumQualityOfService = MqttQualityOfService.AtLeastOnce }; var topicEvaluator = new Mock <IMqttTopicEvaluator> (); var sessionRepository = new Mock <IRepository <ClientSession> > (); var packetIdProvider = Mock.Of <IPacketIdProvider> (); var retainedMessageRepository = Mock.Of <IRepository <RetainedMessage> > (); var senderFlow = Mock.Of <IPublishSenderFlow> (); var clientId = Guid.NewGuid().ToString(); var session = new ClientSession { ClientId = clientId, Clean = false }; topicEvaluator.Setup(e => e.IsValidTopicFilter(It.IsAny <string> ())).Returns(false); sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ())).Returns(session); var fooQoS = MqttQualityOfService.AtLeastOnce; var fooTopic = "test/foo/1"; var fooSubscription = new Subscription(fooTopic, fooQoS); var packetId = (ushort)new Random().Next(0, ushort.MaxValue); var subscribe = new Subscribe(packetId, fooSubscription); var channel = new Mock <IMqttChannel <IPacket> > (); var response = default(IPacket); channel.Setup(c => c.SendAsync(It.IsAny <IPacket> ())) .Callback <IPacket> (p => response = p) .Returns(Task.Delay(0)); var connectionProvider = new Mock <IConnectionProvider> (); connectionProvider .Setup(p => p.GetConnection(It.Is <string> (c => c == clientId))) .Returns(channel.Object); var flow = new ServerSubscribeFlow(topicEvaluator.Object, sessionRepository.Object, retainedMessageRepository, packetIdProvider, senderFlow, configuration); await flow.ExecuteAsync(clientId, subscribe, channel.Object) .ConfigureAwait(continueOnCapturedContext: false); Assert.NotNull(response); var subscribeAck = response as SubscribeAck; Assert.NotNull(subscribeAck); Assert.Equal(packetId, subscribeAck.PacketId); Assert.Equal(1, subscribeAck.ReturnCodes.Count()); Assert.Equal(SubscribeReturnCode.Failure, subscribeAck.ReturnCodes.First()); }
public async Task when_subscribing_invalid_topic_then_failure_is_sent_in_ack() { MqttConfiguration configuration = new MqttConfiguration { MaximumQualityOfService = MqttQualityOfService.AtLeastOnce }; Mock <IMqttTopicEvaluator> topicEvaluator = new Mock <IMqttTopicEvaluator>(); Mock <IRepository <ClientSession> > sessionRepository = new Mock <IRepository <ClientSession> >(); IPacketIdProvider packetIdProvider = Mock.Of <IPacketIdProvider>(); IRepository <RetainedMessage> retainedMessageRepository = Mock.Of <IRepository <RetainedMessage> >(); IPublishSenderFlow senderFlow = Mock.Of <IPublishSenderFlow>(); string clientId = Guid.NewGuid().ToString(); ClientSession session = new ClientSession(clientId, clean: false); topicEvaluator.Setup(e => e.IsValidTopicFilter(It.IsAny <string>())).Returns(false); sessionRepository.Setup(r => r.Read(It.IsAny <string>())).Returns(session); MqttQualityOfService fooQoS = MqttQualityOfService.AtLeastOnce; string fooTopic = "test/foo/1"; Subscription fooSubscription = new Subscription(fooTopic, fooQoS); ushort packetId = (ushort)new Random().Next(0, ushort.MaxValue); Subscribe subscribe = new Subscribe(packetId, fooSubscription); Mock <IMqttChannel <IPacket> > channel = new Mock <IMqttChannel <IPacket> >(); IPacket response = default; channel.Setup(c => c.SendAsync(It.IsAny <IPacket>())) .Callback <IPacket>(p => response = p) .Returns(Task.Delay(0)); Mock <IConnectionProvider> connectionProvider = new Mock <IConnectionProvider>(); connectionProvider .Setup(p => p.GetConnection(It.Is <string>(c => c == clientId))) .Returns(channel.Object); ServerSubscribeFlow flow = new ServerSubscribeFlow(topicEvaluator.Object, sessionRepository.Object, retainedMessageRepository, packetIdProvider, senderFlow, configuration); await flow.ExecuteAsync(clientId, subscribe, channel.Object); Assert.NotNull(response); SubscribeAck subscribeAck = response as SubscribeAck; Assert.NotNull(subscribeAck); packetId.Should().Be(subscribeAck.PacketId); 1.Should().Be(subscribeAck.ReturnCodes.Count()); SubscribeReturnCode.Failure.Should().Be(subscribeAck.ReturnCodes.First()); }
public void when_getting_explicit_server_flow_from_type_then_succeeds() { IMqttAuthenticationProvider authenticationProvider = Mock.Of <IMqttAuthenticationProvider>(p => p.Authenticate(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>()) == true); ServerProtocolFlowProvider flowProvider = new ServerProtocolFlowProvider(authenticationProvider, Mock.Of <IConnectionProvider>(), Mock.Of <IMqttTopicEvaluator>(), Mock.Of <IRepositoryProvider>(), Mock.Of <IPacketIdProvider>(), Mock.Of <ISubject <MqttUndeliveredMessage> >(), new MqttConfiguration()); ServerConnectFlow connectFlow = flowProvider.GetFlow <ServerConnectFlow>(); PublishSenderFlow senderFlow = flowProvider.GetFlow <PublishSenderFlow>(); ServerPublishReceiverFlow receiverFlow = flowProvider.GetFlow <ServerPublishReceiverFlow>(); ServerSubscribeFlow subscribeFlow = flowProvider.GetFlow <ServerSubscribeFlow>(); ServerUnsubscribeFlow unsubscribeFlow = flowProvider.GetFlow <ServerUnsubscribeFlow>(); DisconnectFlow disconnectFlow = flowProvider.GetFlow <DisconnectFlow>(); Assert.NotNull(connectFlow); Assert.NotNull(senderFlow); Assert.NotNull(receiverFlow); Assert.NotNull(subscribeFlow); Assert.NotNull(unsubscribeFlow); Assert.NotNull(disconnectFlow); }