public void CreateMessageBoxFailsWithNoMessageBus(MB002MessageBoxAnalyzer analyzer, ILogger logger, AzureIntegrationServicesModel model, MigrationContext context, Exception e)
        {
            "Given an analyzer"
            .x(() => analyzer.Should().BeNull());

            "And a model"
            .x(() => model = new AzureIntegrationServicesModel());

            "And a context"
            .x(() => context = TestHelper.BuildContext());

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "And an analyzer"
            .x(() => analyzer = new MB002MessageBoxAnalyzer(model, context, logger));

            "When analyzing"
            .x(async() => e = await Record.ExceptionAsync(async() => await analyzer.AnalyzeAsync(CancellationToken.None).ConfigureAwait(false)).ConfigureAwait(false));

            "Then there should be no exception"
            .x(() => e.Should().BeNull());

            "And and the context contains an error"
            .x(() =>
            {
                context.Errors.Should().NotBeNullOrEmpty();
                context.Errors.Should().HaveCount(1);
                context.Errors[0].Message.Should().NotBeNullOrEmpty();
                context.Errors[0].Message.Should().Contain("MessageBus:SystemApplication");
            });
        }
        public void ConstructWithNullContext(MB002MessageBoxAnalyzer analyzer, ILogger logger, IApplicationModel model, MigrationContext context, Exception e)
        {
            "Given an analyzer"
            .x(() => analyzer.Should().BeNull());

            "And a model"
            .x(() => model = new AzureIntegrationServicesModel());

            "And null context"
            .x(() => context.Should().BeNull());

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "When constructing with a null context"
            .x(() => e = Record.Exception(() => new MB002MessageBoxAnalyzer(model, context, logger)));

            "Then the constructor should throw an exception"
            .x(() => e.Should().NotBeNull().And.Subject.Should().BeOfType <ArgumentNullException>().Which.ParamName.Should().Be("context"));
        }
        public void ConstructWithSuccess(MB002MessageBoxAnalyzer analyzer, ILogger logger, IApplicationModel model, MigrationContext context, Exception e)
        {
            "Given an analyzer"
            .x(() => analyzer.Should().BeNull());

            "And a model"
            .x(() => model = new AzureIntegrationServicesModel());

            "And a context"
            .x(() => context = TestHelper.BuildContext());

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "When constructing"
            .x(() => e = Record.Exception(() => new MB002MessageBoxAnalyzer(model, context, logger)));

            "Then the constructor should NOT throw an exception"
            .x(() => e.Should().BeNull());
        }
        public void CreateMessageBoxWithSuccess(MB002MessageBoxAnalyzer analyzer, ILogger logger, AzureIntegrationServicesModel model, MigrationContext context, Exception e)
        {
            var messageBusKey        = "MessageBus";
            var systemApplicationKey = "SystemApplication";

            "Given an analyzer"
            .x(() => analyzer.Should().BeNull());

            "And a model with a message bus and system application"
            .x(() =>
            {
                model = new AzureIntegrationServicesModel();

                model.MigrationTarget.MessageBus = new ApplicationModel.Target.MessageBus
                {
                    Name = "messageBusName",
                    Key  = messageBusKey
                };

                model.MigrationTarget.MessageBus.Applications.Add(
                    new ApplicationModel.Target.Application
                {
                    Name = "systemApplicationName",
                    Key  = $"{messageBusKey}:{systemApplicationKey}"
                });
            });

            "And a context"
            .x(() => context = TestHelper.BuildContext());

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "And an analyzer"
            .x(() => analyzer = new MB002MessageBoxAnalyzer(model, context, logger));

            "When analyzing"
            .x(async() => e = await Record.ExceptionAsync(async() => await analyzer.AnalyzeAsync(CancellationToken.None).ConfigureAwait(false)).ConfigureAwait(false));

            "Then there should be no exception"
            .x(() => e.Should().BeNull());

            "And the message box will have been created"
            .x(() =>
            {
                model.Should().NotBeNull();
                model.MigrationTarget.Should().NotBeNull();
                model.MigrationTarget.MessageBus.Should().NotBeNull();
                model.MigrationTarget.MessageBus.Applications.Should().NotBeNullOrEmpty();
                model.MigrationTarget.MessageBus.Applications.Should().HaveCount(1);
                model.MigrationTarget.MessageBus.Applications[0].Channels.Should().NotBeNullOrEmpty();
                model.MigrationTarget.MessageBus.Applications[0].Channels.Should().HaveCount(4);

                var channel = model.MigrationTarget.MessageBus.Applications[0].Channels[0];

                channel.Should().BeOfType(typeof(TopicChannel));

                var topicChannel = (TopicChannel)channel;

                topicChannel.Key.Should().Be($"{messageBusKey}:{systemApplicationKey}:MessageBox");
                topicChannel.ResourceMapKey.Should().Be("messageBox");
                topicChannel.Description.Should().NotBeNullOrEmpty();
                topicChannel.Name.Should().Be("Message Box");
                topicChannel.Rating.Should().Be(ApplicationModel.Report.ConversionRating.FullConversion);

                channel = model.MigrationTarget.MessageBus.Applications[0].Channels[1];

                channel.Should().BeOfType(typeof(TopicChannel));

                var topicResponseChannel = (TopicChannel)channel;

                topicResponseChannel.Key.Should().Be($"{messageBusKey}:{systemApplicationKey}:{ModelConstants.MessageBoxResponseLeafKey}");
                topicResponseChannel.ResourceMapKey.Should().Be("messageBoxResponse");
                topicResponseChannel.Description.Should().NotBeNullOrEmpty();
                topicResponseChannel.Name.Should().Be("Message Box Response");
                topicResponseChannel.Rating.Should().Be(ApplicationModel.Report.ConversionRating.FullConversion);
                topicResponseChannel.ChannelType.Should().Be(ChannelType.PublishSubscribe);

                channel = model.MigrationTarget.MessageBus.Applications[0].Channels[2];

                channel.Should().BeOfType(typeof(TopicChannel));

                var suspendTopicChannel = (TopicChannel)channel;

                suspendTopicChannel.Key.Should().Be($"{messageBusKey}:{systemApplicationKey}:{ModelConstants.SuspendQueueLeafKey}");
                suspendTopicChannel.ResourceMapKey.Should().Be("suspendQueue");
                suspendTopicChannel.Description.Should().NotBeNullOrEmpty();
                suspendTopicChannel.Name.Should().Be("Suspend Queue");
                suspendTopicChannel.Rating.Should().Be(ApplicationModel.Report.ConversionRating.FullConversion);
                suspendTopicChannel.ChannelType.Should().Be(ChannelType.InvalidMessage);

                channel = model.MigrationTarget.MessageBus.Applications[0].Channels[3];

                channel.Should().BeOfType(typeof(CorrelatingQueueChannel));

                var interchangeQueueChannel = (CorrelatingQueueChannel)channel;

                interchangeQueueChannel.Key.Should().Be($"{messageBusKey}:{systemApplicationKey}:{ModelConstants.InterchangeQueueLeafKey}");
                interchangeQueueChannel.ResourceMapKey.Should().BeNullOrEmpty();
                interchangeQueueChannel.Description.Should().NotBeNullOrEmpty();
                interchangeQueueChannel.Name.Should().Be("Interchange Queue");
                interchangeQueueChannel.Rating.Should().Be(ApplicationModel.Report.ConversionRating.NoAutomaticConversion);
            });
        }