public async Task ShowsUnsupportedCitiesWarning(string jsonFile, string expectedMessage)
        {
            // Load the LUIS result json and create a mock recognizer that returns the expected result.
            var luisResultJson     = GetEmbeddedTestData($"{GetType().Namespace}.TestData.{jsonFile}");
            var mockLuisResult     = JsonConvert.DeserializeObject <FlightBooking>(luisResultJson);
            var mockLuisRecognizer = SimpleMockFactory.CreateMockLuisRecognizer <FlightBookingRecognizer, FlightBooking>(
                mockLuisResult,
                new Mock <IConfiguration>().Object);

            mockLuisRecognizer.Setup(x => x.IsConfigured).Returns(true);

            var sut        = new MainDialog(mockLuisRecognizer.Object, _mockBookingDialog, _mockLogger.Object);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: new[] { new XUnitDialogTestLogger(Output) });

            // Execute the test case
            Output.WriteLine($"Test Case: {mockLuisResult.Text}");
            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            var weekLaterDate = DateTime.Now.AddDays(7).ToString("MMMM d, yyyy");

            Assert.Equal($"What can I help you with today?\nSay something like \"Book a flight from Paris to Berlin on {weekLaterDate}\"", reply.Text);

            reply = await testClient.SendActivityAsync <IMessageActivity>(mockLuisResult.Text);

            Assert.Equal(expectedMessage, reply.Text);
        }
        public async Task TaskSelector(string utterance, string intent, string invokedDialogResponse)
        {
            var mockLuisRecognizer = SimpleMockFactory.CreateMockLuisRecognizer <IRecognizer, FlightBooking>(
                new FlightBooking
            {
                Intents = new Dictionary <FlightBooking.Intent, IntentScore>
                {
                    { Enum.Parse <FlightBooking.Intent>(intent), new IntentScore()
                      {
                          Score = 1
                      } },
                },
                Entities = new FlightBooking._Entities(),
            });

            var sut        = new MainDialog(_mockLogger.Object, mockLuisRecognizer.Object, _mockBookingDialog);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: new[] { new XUnitOutputMiddleware(Output) });

            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            Assert.Equal("What can I help you with today?", reply.Text);

            reply = await testClient.SendActivityAsync <IMessageActivity>(utterance);

            Assert.Equal(invokedDialogResponse, reply.Text);

            reply = testClient.GetNextReply <IMessageActivity>();
            Assert.Equal("What else can I do for you?", reply.Text);
        }
        public async Task WholeEnchilada()
        {
            var mockFlightBookingService = new Mock <IFlightBookingService>();

            mockFlightBookingService.Setup(x => x.BookFlight(It.IsAny <BookingDetails>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(true));
            var mockBookingDialog = SimpleMockFactory.CreateMockDialog <BookingDialog>(null, mockFlightBookingService.Object).Object;
            var mockLogger        = new Mock <ILogger <MainDialog> >();
            var sut = new MainDialog(mockLogger.Object, null, mockBookingDialog);

            var testFlow = BuildTestFlow(sut);

            await testFlow.Send("hi")
            .AssertReply("What can I help you with today?")
            .Send("hi")
            .AssertReply("Where would you like to travel to?")
            .Send("Bahamas")
            .AssertReply("Where are you traveling from?")
            .Send("New York")
            .AssertReply("When would you like to travel?")
            .Send("tomorrow at 5 PM")
            .AssertReply(activity =>
            {
                // TODO: I had to add the Yes No for the channelId = test, the emulator displays suggested actions instead.
                var message = (IMessageActivity)activity;
                Assert.Equal(
                    "Please confirm, I have you traveling to: Bahamas from: New York on: 2019-04-18T17 (1) Yes or (2) No",
                    message.Text);
            })
            .Send("Yes")
            .AssertReply("I have you booked to Bahamas from New York on tomorrow 5PM")
            .StartTestAsync();
        }
示例#4
0
        public async Task SavesTurnStateUsingMockWithVirtualSaveChangesAsync()
        {
            // Note: this test requires that SaveChangesAsync is made virtual in order to be able to create a mock.
            var memoryStorage         = new MemoryStorage();
            var mockConversationState = new Mock <ConversationState>(memoryStorage)
            {
                CallBase = true,
            };

            var mockUserState = new Mock <UserState>(memoryStorage)
            {
                CallBase = true,
            };

            var mockRootDialog = SimpleMockFactory.CreateMockDialog <Dialog>(null, "mockRootDialog");
            var mockLogger     = new Mock <ILogger <DialogBot <Dialog> > >();

            // Act
            var sut         = new DialogBot <Dialog>(mockConversationState.Object, mockUserState.Object, mockRootDialog.Object, mockLogger.Object);
            var testAdapter = new TestAdapter();
            var testFlow    = new TestFlow(testAdapter, sut);
            await testFlow.Send("Hi").StartTestAsync();

            // Assert that SaveChangesAsync was called
            mockConversationState.Verify(x => x.SaveChangesAsync(It.IsAny <TurnContext>(), It.IsAny <bool>(), It.IsAny <CancellationToken>()), Times.Once);
            mockUserState.Verify(x => x.SaveChangesAsync(It.IsAny <TurnContext>(), It.IsAny <bool>(), It.IsAny <CancellationToken>()), Times.Once);
        }
示例#5
0
        public async Task ShowsFirstMessageAndCallsAzureDialogDirectly()
        {
            // Arrange
            var feedbackOptions     = new FeedbackOptions();
            var mockTemplateManager = SimpleMockFactory.CreateMockTemplateManager("mock template message");

            var mockDialog = new Mock <AzureDialog>(Configuration, _telemetryClient, mockTemplateManager.Object);

            mockDialog.Setup(x => x.BeginDialogAsync(It.IsAny <DialogContext>(), It.IsAny <object>(), It.IsAny <CancellationToken>()))
            .Returns(async(DialogContext dialogContext, object options, CancellationToken cancellationToken) =>
            {
                dialogContext.Dialogs.Add(new TextPrompt("MockDialog"));
                return(await dialogContext.PromptAsync("MockDialog",
                                                       new PromptOptions()
                {
                    Prompt = MessageFactory.Text($"{nameof(AzureDialog)} mock invoked")
                }, cancellationToken));
            });
            var fileSearchDialog = new Mock <FileSearchDialog>(_telemetryClient, Configuration);

            var mainDialog = new MainDialog(_telemetryClient, feedbackOptions, _mockLogger.Object, mockTemplateManager.Object, _userState, mockDialog.Object, fileSearchDialog.Object);
            var testClient = new DialogTestClient(Channels.Test, mainDialog, middlewares: new[] { new XUnitDialogTestLogger(Output) });

            // Act/Assert
            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            Assert.Equal("mock template message", reply.Text);

            reply = await testClient.SendActivityAsync <IMessageActivity>("next");

            Assert.Equal($"{nameof(AzureDialog)} mock invoked", reply.Text);
        }
示例#6
0
        public async Task LogsInformationToILogger()
        {
            // Arrange
            var memoryStorage     = new MemoryStorage();
            var conversationState = new ConversationState(memoryStorage);
            var userState         = new UserState(memoryStorage);

            var mockRootDialog = SimpleMockFactory.CreateMockDialog <Dialog>(null, "mockRootDialog");
            var mockLogger     = new Mock <ILogger <DialogBot <Dialog> > >();

            mockLogger.Setup(x =>
                             x.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <object>(), null, It.IsAny <Func <object, Exception, string> >()));

            // Run the bot
            var sut         = new DialogBot <Dialog>(conversationState, userState, mockRootDialog.Object, mockLogger.Object);
            var testAdapter = new TestAdapter();
            var testFlow    = new TestFlow(testAdapter, sut);
            await testFlow.Send("Hi").StartTestAsync();

            // Assert that log was changed with the expected parameters
            mockLogger.Verify(
                x => x.Log(
                    LogLevel.Information,
                    It.IsAny <EventId>(),
                    It.Is <object>(o => o.ToString() == "Running dialog with Message Activity."),
                    null,
                    It.IsAny <Func <object, Exception, string> >()),
                Times.Once);
        }
示例#7
0
        public async Task ShowsMessageIfLuisNotConfiguredAndCallsBookDialogDirectly()
        {
            // Arrange
            var mockRecognizer = SimpleMockFactory.CreateMockLuisRecognizer <FlightBookingRecognizer>(null, constructorParams: new Mock <IConfiguration>().Object);

            mockRecognizer.Setup(x => x.IsConfigured).Returns(false);

            // Create a specialized mock for BookingDialog that displays a dummy TextPrompt.
            // The dummy prompt is used to prevent the MainDialog waterfall from moving to the next step
            // and assert that the dialog was called.
            var mockDialog = new Mock <BookingDialog>();

            mockDialog
            .Setup(x => x.BeginDialogAsync(It.IsAny <DialogContext>(), It.IsAny <object>(), It.IsAny <CancellationToken>()))
            .Returns(async(DialogContext dialogContext, object options, CancellationToken cancellationToken) =>
            {
                dialogContext.Dialogs.Add(new TextPrompt("MockDialog"));
                return(await dialogContext.PromptAsync("MockDialog", new PromptOptions()
                {
                    Prompt = MessageFactory.Text($"{nameof(BookingDialog)} mock invoked")
                }, cancellationToken));
            });

            var sut        = new MainDialog(mockRecognizer.Object, mockDialog.Object, _mockLogger.Object);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: new[] { new XUnitDialogTestLogger(Output) });

            // Act/Assert
            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            Assert.Equal("NOTE: LUIS is not configured. To enable all capabilities, add 'LuisAppId', 'LuisAPIKey' and 'LuisAPIHostName' to the appsettings.json file.", reply.Text);

            reply = testClient.GetNextReply <IMessageActivity>();
            Assert.Equal("BookingDialog mock invoked", reply.Text);
        }
示例#8
0
        public async Task DialogFlowUseCases(TestDataObject testData)
        {
            // Arrange
            var bookingTestData          = testData.GetObject <BookingDialogTestCase>();
            var mockFlightBookingService = new Mock <IFlightBookingService>();

            mockFlightBookingService
            .Setup(x => x.BookFlight(It.IsAny <BookingDetails>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(bookingTestData.FlightBookingServiceResult));

            var mockGetBookingDetailsDialog = SimpleMockFactory.CreateMockDialog <GetBookingDetailsDialog>(bookingTestData.GetBookingDetailsDialogResult).Object;

            var sut        = new BookingDialog(mockGetBookingDetailsDialog, mockFlightBookingService.Object);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: _middlewares);

            // Act/Assert
            Output.WriteLine($"Test Case: {bookingTestData.Name}");
            for (var i = 0; i < bookingTestData.UtterancesAndReplies.GetLength(0); i++)
            {
                var utterance = bookingTestData.UtterancesAndReplies[i, 0];

                // Send the activity and receive the first reply or just pull the next
                // activity from the queue if there's nothing to send
                var reply = !string.IsNullOrEmpty(utterance)
                    ? await testClient.SendActivityAsync <IMessageActivity>(utterance)
                    : testClient.GetNextReply <IMessageActivity>();

                Assert.Equal(bookingTestData.UtterancesAndReplies[i, 1], reply.Text);
            }

            Assert.Equal(bookingTestData.ExpectedDialogResult.Status, testClient.DialogTurnResult.Status);
        }
示例#9
0
        public async Task ReturnsWelcomeCardOnConversationUpdate()
        {
            // Arrange
            var mockRootDialog = SimpleMockFactory.CreateMockDialog <Dialog>(null, "mockRootDialog");

            // TODO: do we need state here?
            var memoryStorage = new MemoryStorage();
            var sut           = new DialogAndWelcomeBot <Dialog>(new ConversationState(memoryStorage), new UserState(memoryStorage), mockRootDialog.Object, null);
            var conversationUpdateActivity = new Activity
            {
                Type         = ActivityTypes.ConversationUpdate,
                MembersAdded = new List <ChannelAccount>
                {
                    new ChannelAccount {
                        Id = "theUser"
                    },
                },
                Recipient = new ChannelAccount {
                    Id = "theBot"
                },
            };
            var testAdapter = new TestAdapter(Channels.Test);

            // Act
            // Note: it is kind of obscure that we need to use OnTurnAsync to trigger OnMembersAdded so we get the card
            await testAdapter.ProcessActivityAsync(conversationUpdateActivity, sut.OnTurnAsync, CancellationToken.None);

            var reply = testAdapter.GetNextReply();

            // Assert
            var m = (IMessageActivity)reply;

            Assert.Equal(1, m.Attachments.Count);
            Assert.Equal("application/vnd.microsoft.card.adaptive", m.Attachments.FirstOrDefault()?.ContentType);
        }
示例#10
0
        public async Task ShowsAnswerFromQnAMaker()
        {
            var mockTemplateManager = SimpleMockFactory.CreateMockTemplateManager("mock template message");
            var azureDialog         = new AzureDialog(_configurationLazy.Value, _telemetryClient, mockTemplateManager.Object);
            var testClient          = new DialogTestClient(Channels.Test, azureDialog, middlewares: new[] { new XUnitDialogTestLogger(Output) });

            var reply = await testClient.SendActivityAsync <IMessageActivity>("azure database for mysql");

            Assert.NotNull(reply);
        }
        public async Task ShowsPromptIfLuisIsConfigured()
        {
            // Arrange
            var sut        = new MainDialog(_mockLogger.Object, SimpleMockFactory.CreateMockLuisRecognizer <IRecognizer>(null).Object, _mockBookingDialog);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: new[] { new XUnitOutputMiddleware(Output) });

            // Act/Assert
            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            Assert.Equal("What can I help you with today?", reply.Text);
        }
        public MainDialogTests(ITestOutputHelper output)
            : base(output)
        {
            _mockLogger = new Mock <ILogger <MainDialog> >();

            var mockFlightBookingService = new Mock <IFlightBookingService>();

            mockFlightBookingService
            .Setup(x => x.BookFlight(It.IsAny <BookingDetails>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(true));
            _mockBookingDialog = SimpleMockFactory.CreateMockDialog <BookingDialog>(null, new Mock <GetBookingDetailsDialog>().Object, mockFlightBookingService.Object).Object;
        }
示例#13
0
        public MainDialogTests(ITestOutputHelper output)
            : base(output)
        {
            _mockLogger = new Mock <ILogger <MainDialog> >();
            var expectedBookingDialogResult = new BookingDetails()
            {
                Destination = "Seattle",
                Origin      = "New York",
                TravelDate  = $"{DateTime.UtcNow.AddDays(1):yyyy-MM-dd}"
            };

            _mockBookingDialog = SimpleMockFactory.CreateMockDialog <BookingDialog>(expectedBookingDialogResult).Object;
        }
示例#14
0
        public async Task ShowsPromptIfLuisIsConfigured()
        {
            // Arrange
            var mockRecognizer = SimpleMockFactory.CreateMockLuisRecognizer <FlightBookingRecognizer>(null, constructorParams: new Mock <IConfiguration>().Object);

            mockRecognizer.Setup(x => x.IsConfigured).Returns(true);
            var sut        = new MainDialog(mockRecognizer.Object, _mockBookingDialog, _mockLogger.Object);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: new[] { new XUnitDialogTestLogger(Output) });

            // Act/Assert
            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            Assert.Equal("What can I help you with today?", reply.Text);
        }
示例#15
0
        public async Task ShowsPromptIfLuisIsConfigured()
        {
            // Arrange
            var mockRecognizer = SimpleMockFactory.CreateMockLuisRecognizer <FlightBookingRecognizer>(null, constructorParams: new Mock <IConfiguration>().Object);

            mockRecognizer.Setup(x => x.IsConfigured).Returns(true);
            var sut        = new MainDialog(mockRecognizer.Object, _mockBookingDialog, _mockLogger.Object);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: new[] { new XUnitDialogTestLogger(Output) });

            // Act/Assert
            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            var weekLaterDate = DateTime.Now.AddDays(7).ToString("MMMM d, yyyy");

            Assert.Equal($"What can I help you with today?\nSay something like \"Book a flight from Paris to Berlin on {weekLaterDate}\"", reply.Text);
        }
示例#16
0
        public async Task TaskSelector(string utterance, string intent, string invokedDialogResponse, string taskConfirmationMessage)
        {
            // Create a mock recognizer that returns the expected intent.
            var mockLuisRecognizer = SimpleMockFactory.CreateMockLuisRecognizer <FlightBookingRecognizer, FlightBooking>(
                new FlightBooking
            {
                Intents = new Dictionary <FlightBooking.Intent, IntentScore>
                {
                    { Enum.Parse <FlightBooking.Intent>(intent), new IntentScore()
                      {
                          Score = 1
                      } },
                },
                Entities = new FlightBooking._Entities(),
            },
                new Mock <IConfiguration>().Object);

            mockLuisRecognizer.Setup(x => x.IsConfigured).Returns(true);
            var sut        = new MainDialog(mockLuisRecognizer.Object, _mockBookingDialog, _mockLogger.Object);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: new[] { new XUnitDialogTestLogger(Output) });

            // Execute the test case
            Output.WriteLine($"Test Case: {intent}");
            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            var weekLaterDate = DateTime.Now.AddDays(7).ToString("MMMM d, yyyy");

            Assert.Equal($"What can I help you with today?\nSay something like \"Book a flight from Paris to Berlin on {weekLaterDate}\"", reply.Text);

            reply = await testClient.SendActivityAsync <IMessageActivity>(utterance);

            Assert.Equal(invokedDialogResponse, reply.Text);

            // The Booking dialog displays an additional confirmation message, assert that it is what we expect.
            if (!string.IsNullOrEmpty(taskConfirmationMessage))
            {
                reply = testClient.GetNextReply <IMessageActivity>();
                Assert.StartsWith(taskConfirmationMessage, reply.Text);
            }

            // Validate that the MainDialog starts over once the task is completed.
            reply = testClient.GetNextReply <IMessageActivity>();
            Assert.Equal("What else can I do for you?", reply.Text);
        }
        public async Task TaskSelector(string utterance, string intent, string invokedDialogResponse, string taskConfirmationMessage)
        {
            // Create a mock recognizer that returns the expected intent.
            var mockLuisRecognizer = SimpleMockFactory.CreateMockLuisRecognizer <FlightBookingRecognizer, FlightBooking>(
                new FlightBooking
            {
                Intents = new Dictionary <FlightBooking.Intent, IntentScore>
                {
                    { Enum.Parse <FlightBooking.Intent>(intent), new IntentScore()
                      {
                          Score = 1
                      } },
                },
                Entities = new FlightBooking._Entities(),
            },
                new Mock <IConfiguration>().Object);

            mockLuisRecognizer.Setup(x => x.IsConfigured).Returns(true);
            var sut        = new MainDialog(mockLuisRecognizer.Object, _mockBookingDialog, _mockLogger.Object);
            var testClient = new DialogTestClient(Channels.Test, sut, middlewares: new[] { new XUnitDialogTestLogger(Output) });

            // Execute the test case
            Output.WriteLine($"Test Case: {intent}");
            var reply = await testClient.SendActivityAsync <IMessageActivity>("hi");

            Assert.Equal("Are you experiencing any of the following: severe difficulty breathing, chest pain, very hard time waking up, confusion, lost consciousness?", reply.Text);



            reply = await testClient.SendActivityAsync <IMessageActivity>(utterance);

            Assert.Equal("Please call 911 or go directly to your nearest emergency department.", reply.Text);



            // Validate that the MainDialog starts over once the task is completed.
            reply = testClient.GetNextReply <IMessageActivity>();
            //Assert.Equal("What else can I do for you?", reply.Text);
        }
        public async Task ReturnsWelcomeCardOnConversationUpdate()
        {
            // Arrange
            var mockRootDialog = SimpleMockFactory.CreateMockDialog <Dialog>(null, "mockRootDialog");
            var memoryStorage  = new MemoryStorage();
            var sut            = new DialogAndWelcomeBot <Dialog>(new ConversationState(memoryStorage), new UserState(memoryStorage), mockRootDialog.Object, null);

            // Create conversationUpdate activity
            var conversationUpdateActivity = new Activity
            {
                Type         = ActivityTypes.ConversationUpdate,
                MembersAdded = new List <ChannelAccount>
                {
                    new ChannelAccount {
                        Id = "theUser"
                    },
                },
                Recipient = new ChannelAccount {
                    Id = "theBot"
                },
            };
            var testAdapter = new TestAdapter(Channels.Test);

            // Act
            // Send the conversation update activity to the bot.
            await testAdapter.ProcessActivityAsync(conversationUpdateActivity, sut.OnTurnAsync, CancellationToken.None);

            // Assert we got the welcome card
            var reply = (IMessageActivity)testAdapter.GetNextReply();

            Assert.Equal(1, reply.Attachments.Count);
            Assert.Equal("application/vnd.microsoft.card.adaptive", reply.Attachments.FirstOrDefault()?.ContentType);

            // Assert that we started the main dialog.
            reply = (IMessageActivity)testAdapter.GetNextReply();
            Assert.Equal("Dialog mock invoked", reply.Text);
        }