public async Task TestAdapter_ExceptionTypesOnAssertReply()
        {
            string      uniqueExceptionId = Guid.NewGuid().ToString();
            TestAdapter adapter           = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName));

            try
            {
                await new TestFlow(adapter, async(context, cancellationToken) =>
                {
                    await context.SendActivityAsync(context.Activity.CreateReply("one"));
                })
                .Send("foo")
                .AssertReply(
                    (activity) => throw new Exception(uniqueExceptionId), "should throw")
                .StartTestAsync();

                Assert.Fail("An Exception should have been thrown");
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex.Message == uniqueExceptionId, "Incorrect Exception Text");
            }
        }
        public async Task Middlware_ThrowException()
        {
            string uniqueId = Guid.NewGuid().ToString();

            TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                                  .Use(new CatchExceptionMiddleware());

            async Task EchoWithException(ITurnContext ctx, CancellationToken cancellationToken)
            {
                string toEcho = "ECHO:" + ctx.Activity.AsMessageActivity().Text;
                await ctx.SendActivityAsync(ctx.Activity.CreateReply(toEcho));

                throw new Exception(uniqueId);
            }

            await new TestFlow(adapter, EchoWithException)
            .Send("test")
            .AssertReply("BEFORE")
            .AssertReply("ECHO:test")
            .AssertReply("CAUGHT:" + uniqueId)
            .AssertReply("AFTER")
            .StartTestAsync();
        }
        public async Task TemplateManager_DataDefined()
        {
            TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                                  .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false)));

            var templateManager = new TemplateManager()
            {
                Renderers =
                {
                    new DictionaryRenderer(templates1),
                    new DictionaryRenderer(templates2)
                }
            };

            await new TestFlow(adapter, async(context, cancellationToken) =>
            {
                var templateId = context.Activity.AsMessageActivity().Text.Trim();
                await templateManager.ReplyWith(context, templateId, new { name = "joe" });
            })
            .Send("stringTemplate").AssertReply("default: joe")
            .Send("activityTemplate").AssertReply("(Activity)default: joe")
            .StartTestAsync();
        }
示例#4
0
        public async Task SettingsMemoryScopeTest()
        {
            var configuration = new ConfigurationBuilder().AddInMemoryCollection(new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("test", "yoyo")
            }).Build();
            var storage = new MemoryStorage();
            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .UseStorage(storage)
                          .Use(new RegisterClassMiddleware <Extensions.Configuration.IConfiguration>(configuration))
                          .UseState(new UserState(storage), new ConversationState(storage))
                          .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger()));

            DialogManager dm = new DialogManager(new SettingsScopeTestDialog());

            await new TestFlow((TestAdapter)adapter, async(turnContext, cancellationToken) =>
            {
                await dm.OnTurnAsync(turnContext);
            })
            .Send("settings.test")
            .AssertReply("yoyo")
            .StartTestAsync();
        }
示例#5
0
        public async Task ShowTyping_TestMiddleware_1_Second_Interval()
        {
            TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation("ShowTyping_TestMiddleware_1_Second_Interval"))
                                  .Use(new MockBotIdentityMiddleware(FlowTestCase.RootBot))
                                  .Use(new ShowTypingMiddleware(100, 1000));

            await new TestFlow(adapter, async(context, cancellationToken) =>
            {
                await Task.Delay(TimeSpan.FromMilliseconds(2800));

                // note the ShowTypingMiddleware should not cause the Responded flag to be set
                Assert.False(context.Responded);

                await context.SendActivityAsync("Message sent after delay");
                await Task.CompletedTask;
            })
            .Send("foo")
            .AssertReply(ValidateTypingActivity, "check typing activity")
            .AssertReply(ValidateTypingActivity, "check typing activity")
            .AssertReply(ValidateTypingActivity, "check typing activity")
            .AssertReply("Message sent after delay")
            .StartTestAsync();
        }
示例#6
0
        public async Task LogDeleteActivities()
        {
            if (CheckEmulator())
            {
                var         conversation = TestAdapter.CreateConversation(Guid.NewGuid().ToString("n"));
                TestAdapter adapter      = new TestAdapter(conversation)
                                           .Use(new TranscriptLoggerMiddleware(TranscriptStore));
                string activityId = null;
                await new TestFlow(adapter, async(context, cancellationToken) =>
                {
                    if (context.Activity.Text == "deleteIt")
                    {
                        await context.DeleteActivityAsync(activityId);
                    }
                    else
                    {
                        var activity = context.Activity.CreateReply("response");
                        var response = await context.SendActivityAsync(activity);
                        activityId   = response.Id;
                    }
                })
                .Send("foo")
                .AssertReply("response")
                .Send("deleteIt")
                .StartTestAsync();

                await Task.Delay(1000);

                var pagedResult = await TranscriptStore.GetTranscriptActivitiesAsync(conversation.ChannelId, conversation.Conversation.Id);

                Assert.AreEqual(3, pagedResult.Items.Length);
                Assert.AreEqual("foo", pagedResult.Items[0].AsMessageActivity().Text);
                Assert.IsNotNull(pagedResult.Items[1].AsMessageDeleteActivity());
                Assert.AreEqual(ActivityTypes.MessageDelete, pagedResult.Items[1].Type);
                Assert.AreEqual("deleteIt", pagedResult.Items[2].AsMessageActivity().Text);
            }
        }
示例#7
0
        public async Task ValidateImBack(string inputText, string expectedText)
        {
            var adapter = new TestAdapter(TestAdapter.CreateConversation("ValidateImBack"));

            async Task ReplyWithImBack(ITurnContext ctx, CancellationToken cancellationToken)
            {
                if (ctx.Activity.AsMessageActivity().Text == "test")
                {
                    var activity = MessageFactory.SuggestedActions(
                        new CardAction[]
                    {
                        new CardAction(type: "imBack", text: "red", title: "redTitle"),
                    },
                        inputText);

                    await ctx.SendActivityAsync((Activity)activity);
                }
            }

            void ValidateImBack(IActivity activity)
            {
                Assert.True(activity.Type == ActivityTypes.Message);

                var messageActivity = activity.AsMessageActivity();

                Assert.True(messageActivity.Text == expectedText);
                Assert.True(messageActivity.SuggestedActions.Actions.Count == 1, "Incorrect Count");
                Assert.True(messageActivity.SuggestedActions.Actions[0].Type == ActionTypes.ImBack, "Incorrect Action Type");
                Assert.True(messageActivity.SuggestedActions.Actions[0].Text == "red", "incorrect text");
                Assert.True(messageActivity.SuggestedActions.Actions[0].Title == "redTitle", "incorrect text");
            }

            await new TestFlow(adapter, ReplyWithImBack)
            .Send("test")
            .AssertReply(ValidateImBack, "ImBack Did not validate")
            .StartTestAsync();
        }
示例#8
0
        private TestFlow CreateFlow(AdaptiveDialog dialog, bool sendTrace = false)
        {
            TypeFactory.Configuration = new ConfigurationBuilder().Build();
            var resourceExplorer = new ResourceExplorer();
            var storage          = new MemoryStorage();
            var convoState       = new ConversationState(storage);
            var userState        = new UserState(storage);
            var adapter          = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName), sendTrace);

            adapter
            .UseStorage(storage)
            .UseState(userState, convoState)
            .UseResourceExplorer(resourceExplorer)
            .UseLanguageGeneration(resourceExplorer)
            .UseAdaptiveDialogs()
            .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger()));

            DialogManager dm = new DialogManager(dialog);

            return(new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
            }));
        }
        public async Task TestEntityRecognize()
        {
            var mockResult = new Result
            {
                Score = 0.9,
                Label = new Label {
                    Name = "mockLabel"
                }
            };

            var mockScore = new List <Result> {
                mockResult
            };
            var mockResolver = new MockResolver(mockScore);
            var recognizer   = new OrchestratorAdaptiveRecognizer(string.Empty, string.Empty, mockResolver)
            {
                ModelPath    = new StringExpression("fakePath"),
                SnapshotPath = new StringExpression("fakePath")
            };

            recognizer.EntityRecognizers.Add(new NumberEntityRecognizer());

            var adapter  = new TestAdapter(TestAdapter.CreateConversation("ds"));
            var activity = MessageFactory.Text("12");
            var context  = new TurnContext(adapter, activity);

            var dc     = new DialogContext(new DialogSet(), context, new DialogState());
            var result = await recognizer.RecognizeAsync(dc, activity, default);

            Assert.NotNull(result.Entities);
            Assert.Equal(new JValue("12"), result.Entities["number"][0]);
            var resolution = result.Entities["$instance"]["number"][0]["resolution"];

            Assert.Equal(new JValue("integer"), resolution["subtype"]);
            Assert.Equal(new JValue("12"), resolution["value"]);
        }
        public async Task OnTurnError_Test()
        {
            TestAdapter adapter = new TestAdapter(TestAdapter.CreateConversation("OnTurnError_Test"));

            adapter.OnTurnError = async(context, exception) =>
            {
                if (exception is NotImplementedException)
                {
                    await context.SendActivityAsync(context.Activity.CreateReply(exception.Message));
                }
                else
                {
                    await context.SendActivityAsync("Unexpected exception");
                }
            };

            await new TestFlow(adapter, (context, cancellationToken) =>
            {
                if (context.Activity.AsMessageActivity().Text == "foo")
                {
                    context.SendActivityAsync(context.Activity.AsMessageActivity().Text);
                }

                if (context.Activity.AsMessageActivity().Text == "NotImplementedException")
                {
                    throw new NotImplementedException("Test");
                }

                return(Task.CompletedTask);
            })
            .Send("foo")
            .AssertReply("foo", "passthrough")
            .Send("NotImplementedException")
            .AssertReply("Test")
            .StartTestAsync();
        }
        private TestFlow CreateFlow(string locale)
        {
            var convoState = new ConversationState(new MemoryStorage());
            var userState  = new UserState(new MemoryStorage());
            var dialog     = new AdaptiveDialog();

            dialog.Triggers.AddRange(new List <OnCondition>()
            {
                new OnUnknownIntent(actions:
                                    new List <Dialog>()
                {
                    new SendActivity()
                    {
                        Activity = new ActivityTemplate("{settings.ApplicationInsights.InstrumentationKey}")
                    },
                }),
            });

            var resourceExplorer = new ResourceExplorer();

            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(new RegisterClassMiddleware <ResourceExplorer>(resourceExplorer))
                          .Use(new RegisterClassMiddleware <IStorage>(new MemoryStorage()))
                          .UseAdaptiveDialogs()
                          .UseLanguageGeneration(resourceExplorer)
                          .Use(new RegisterClassMiddleware <IConfiguration>(this.Configuration))
                          .Use(new AutoSaveStateMiddleware(convoState, userState))
                          .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger()));

            DialogManager dm = new DialogManager(dialog);

            return(new TestFlow((TestAdapter)adapter, async(turnContext, cancellationToken) =>
            {
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
            }));
        }
        public async Task TextPromptValidatorWithMessageShouldNotSendRetryPrompt()
        {
            var convoState  = new ConversationState(new MemoryStorage());
            var dialogState = convoState.CreateProperty <DialogState>("dialogState");

            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(new AutoSaveStateMiddleware(convoState))
                          .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false)));

            var dialogs = new DialogSet(dialogState);

            PromptValidator <string> validator = async(promptContext, cancellationToken) =>
            {
                var value = promptContext.Recognized.Value;
                if (value.Length <= 3)
                {
                    await promptContext.Context.SendActivityAsync(MessageFactory.Text("The text should be greater than 3 chars."), cancellationToken);

                    return(false);
                }
                else
                {
                    return(true);
                }
            };
            var textPrompt = new TextPrompt("TextPrompt", validator);

            dialogs.Add(textPrompt);

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);

                var results = await dc.ContinueDialogAsync(cancellationToken);
                if (results.Status == DialogTurnStatus.Empty)
                {
                    var options = new PromptOptions
                    {
                        Prompt = new Activity {
                            Type = ActivityTypes.Message, Text = "Enter some text."
                        },
                        RetryPrompt = new Activity {
                            Type = ActivityTypes.Message, Text = "Make sure the text is greater than three characters."
                        },
                    };
                    await dc.PromptAsync("TextPrompt", options);
                }
                else if (results.Status == DialogTurnStatus.Complete)
                {
                    var textResult = (string)results.Result;
                    await turnContext.SendActivityAsync(MessageFactory.Text($"Bot received the text '{textResult}'."), cancellationToken);
                }
            })
            .Send("hello")
            .AssertReply("Enter some text.")
            .Send("hi")
            .AssertReply("The text should be greater than 3 chars.")
            .Send("hello")
            .AssertReply("Bot received the text 'hello'.")
            .StartTestAsync();
        }
示例#13
0
        /// <summary>
        /// Creates a TestFlow instance with state data to recreate and assert the different test case.
        /// </summary>
        private TestFlow CreateTestFlow(Dialog dialog, FlowTestCase testCase, string locale = null)
        {
            var conversationId = Guid.NewGuid().ToString();
            var storage        = new MemoryStorage();
            var convoState     = new ConversationState(storage);
            var userState      = new UserState(storage);

            var adapter = new TestAdapter(TestAdapter.CreateConversation(conversationId));

            adapter
            .UseStorage(storage)
            .UseBotState(userState, convoState)
            .Use(new AutoSaveStateMiddleware(userState, convoState))
            .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false)));

            if (!string.IsNullOrEmpty(locale))
            {
                adapter.Locale = locale;
            }

            return(new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                if (testCase != FlowTestCase.RootBotOnly)
                {
                    // Create a skill ClaimsIdentity and put it in TurnState so SkillValidation.IsSkillClaim() returns true.
                    var claimsIdentity = new ClaimsIdentity();
                    claimsIdentity.AddClaim(new Claim(AuthenticationConstants.VersionClaim, "2.0"));
                    claimsIdentity.AddClaim(new Claim(AuthenticationConstants.AudienceClaim, _skillBotId));
                    claimsIdentity.AddClaim(new Claim(AuthenticationConstants.AuthorizedParty, _parentBotId));
                    turnContext.TurnState.Add(BotAdapter.BotIdentityKey, claimsIdentity);

                    if (testCase == FlowTestCase.RootBotConsumingSkill)
                    {
                        // Simulate the SkillConversationReference with a channel OAuthScope stored in TurnState.
                        // This emulates a response coming to a root bot through SkillHandler.
                        turnContext.TurnState.Add(SkillHandler.SkillConversationReferenceKey, new SkillConversationReference {
                            OAuthScope = AuthenticationConstants.ToChannelFromBotOAuthScope
                        });
                    }

                    if (testCase == FlowTestCase.MiddleSkill)
                    {
                        // Simulate the SkillConversationReference with a parent Bot ID stored in TurnState.
                        // This emulates a response coming to a skill from another skill through SkillHandler.
                        turnContext.TurnState.Add(SkillHandler.SkillConversationReferenceKey, new SkillConversationReference {
                            OAuthScope = _parentBotId
                        });
                    }
                }

                // Interceptor to capture the EoC activity if it was sent so we can assert it in the tests.
                turnContext.OnSendActivities(async(tc, activities, next) =>
                {
                    _eocSent = activities.FirstOrDefault(activity => activity.Type == ActivityTypes.EndOfConversation);
                    return await next().ConfigureAwait(false);
                });

                // Invoke RunAsync on the dialog.
                await dialog.RunAsync(turnContext, convoState.CreateProperty <DialogState>("DialogState"), cancellationToken);
            }));
        }
示例#14
0
 private TurnContext GetTurnContext(string text, string locale = "en-us")
 {
     return(new TurnContext(new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName)), new Schema.Activity(type: Schema.ActivityTypes.Message, text: text, locale: locale)));
 }
示例#15
0
        public void Constructor()
        {
            var c = new TurnContext(new TestAdapter(TestAdapter.CreateConversation("Constructor")), new Activity());

            Assert.NotNull(c);
        }
        private static async Task EnsureToLogActivitiesWithIdsTest(ITranscriptStore transcriptStore)
        {
            var conversation = TestAdapter.CreateConversation(Guid.NewGuid().ToString("n"));
            var adapter      = new AllowNullIdTestAdapter(conversation)
                               .Use(new TranscriptLoggerMiddleware(transcriptStore));

            await new TestFlow(adapter, async(context, cancellationToken) =>
            {
                var activityWithId = new Activity
                {
                    Id        = "TestActivityWithId",
                    Text      = "I am an activity with an Id.",
                    Type      = ActivityTypes.Message,
                    RelatesTo = context.Activity.RelatesTo
                };
                var activityWithNullId = new Activity
                {
                    Id        = null,
                    Text      = "My Id is null.",
                    Type      = ActivityTypes.Message,
                    RelatesTo = context.Activity.RelatesTo
                };
                var activityWithEmptyId = new Activity
                {
                    Id        = string.Empty,
                    Text      = "My Id is empty.",
                    Type      = ActivityTypes.Message,
                    RelatesTo = context.Activity.RelatesTo
                };

                await context.SendActivityAsync(activityWithId);
                await context.SendActivityAsync(activityWithId);

                await context.SendActivityAsync(activityWithNullId);

                await context.SendActivityAsync(activityWithEmptyId);
            })
            .Send("inbound message to TestFlow")
            .AssertReply("I am an activity with an Id.")
            .Send("2nd inbound message to TestFlow")
            .AssertReply((activity) => Assert.Equal("TestActivityWithId", activity.Id))
            .Send("3rd inbound message to TestFlow")
            .AssertReply("My Id is null.")
            .Send("4rd inbound message to TestFlow")
            .AssertReply("My Id is empty.")
            .StartTestAsync();

            await Task.Delay(100);

            var pagedResult = await transcriptStore.GetTranscriptActivitiesAsync(conversation.ChannelId, conversation.Conversation.Id);

            Assert.Equal(20, pagedResult.Items.Length);
            Assert.Equal("inbound message to TestFlow", pagedResult.Items[0].AsMessageActivity().Text);
            Assert.NotNull(pagedResult.Items[1].AsMessageActivity());
            Assert.Equal("I am an activity with an Id.", pagedResult.Items[1].AsMessageActivity().Text);
            Assert.Equal("My Id is empty.", pagedResult.Items[4].AsMessageActivity().Text);
            Assert.Equal("2nd inbound message to TestFlow", pagedResult.Items[5].AsMessageActivity().Text);
            Assert.Equal("TestActivityWithId", pagedResult.Items[6].Id);
            Assert.Equal("3rd inbound message to TestFlow", pagedResult.Items[10].AsMessageActivity().Text);
            Assert.Equal("My Id is null.", pagedResult.Items[13].AsMessageActivity().Text);
            Assert.Contains("g_", pagedResult.Items[13].AsMessageActivity().Id);
            foreach (var activity in pagedResult.Items)
            {
                Assert.True(activity.Timestamp > default(DateTimeOffset));
            }
        }
        public async Task ConfirmPromptChoiceOptionsMultipleAttempts()
        {
            var convoState  = new ConversationState(new MemoryStorage());
            var dialogState = convoState.CreateProperty <DialogState>("dialogState");

            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(new AutoSaveStateMiddleware(convoState))
                          .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger()));

            var dialogs = new DialogSet(dialogState);
            var prompt  = new ConfirmPrompt("ConfirmPrompt", defaultLocale: Culture.English);

            // Set options
            prompt.ChoiceOptions = new Choices.ChoiceFactoryOptions {
                IncludeNumbers = true
            };
            prompt.Style = Choices.ListStyle.Inline;
            dialogs.Add(prompt);

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);

                var results = await dc.ContinueDialogAsync(cancellationToken);
                if (results.Status == DialogTurnStatus.Empty)
                {
                    var options = new PromptOptions
                    {
                        Prompt = new Activity
                        {
                            Type = ActivityTypes.Message,
                            Text = "Please confirm.",
                        },
                        RetryPrompt = new Activity
                        {
                            Type = ActivityTypes.Message,
                            Text = "Please confirm, say 'yes' or 'no' or something like that.",
                        },
                    };
                    await dc.PromptAsync("ConfirmPrompt", options, cancellationToken);
                }
                else if (results.Status == DialogTurnStatus.Complete)
                {
                    if ((bool)results.Result)
                    {
                        await turnContext.SendActivityAsync(MessageFactory.Text("Confirmed."), cancellationToken);
                    }
                    else
                    {
                        await turnContext.SendActivityAsync(MessageFactory.Text("Not confirmed."), cancellationToken);
                    }
                }
            })
            .Send("hello")
            .AssertReply("Please confirm. (1) Yes or (2) No")
            .Send("lala")
            .AssertReply("Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No")
            .Send("what")
            .AssertReply("Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No")
            .Send("2")
            .AssertReply("Not confirmed.")
            .StartTestAsync();
        }
示例#18
0
        private TestFlow CreateFlow(ITriggerSelector selector)
        {
            TypeFactory.Configuration = new ConfigurationBuilder().Build();
            var storage          = new MemoryStorage();
            var convoState       = new ConversationState(storage);
            var userState        = new UserState(storage);
            var resourceExplorer = new ResourceExplorer();
            var adapter          = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName));

            adapter
            .UseStorage(storage)
            .UseState(userState, convoState)
            .UseResourceExplorer(resourceExplorer)
            .UseAdaptiveDialogs()
            .UseLanguageGeneration(resourceExplorer)
            .Use(new TranscriptLoggerMiddleware(new FileTranscriptLogger()));

            var dialog = new AdaptiveDialog()
            {
                Selector = selector
            };

            dialog.Recognizer = new RegexRecognizer
            {
                Intents = new List <IntentPattern>()
                {
                    new IntentPattern("a", "a"),
                    new IntentPattern("b", "b"),
                    new IntentPattern("trigger", "trigger"),
                }
            };
            dialog.Triggers.AddRange(new List <OnCondition>()
            {
                new OnIntent("a", actions: new List <Dialog> {
                    new SetProperty {
                        Property = "user.a", Value = "1"
                    }
                }),
                new OnIntent("b", actions: new List <Dialog> {
                    new SetProperty {
                        Property = "user.b", Value = "1"
                    }
                }),
                new OnIntent("trigger", constraint: "user.a == 1", actions: new List <Dialog> {
                    new SendActivity("ruleA1")
                }),
                new OnIntent("trigger", constraint: "user.a == 1", actions: new List <Dialog> {
                    new SendActivity("ruleA2")
                }),
                new OnIntent("trigger", constraint: "user.b == 1 || user.c == 1", actions: new List <Dialog> {
                    new SendActivity("ruleBorC")
                }),
                new OnIntent("trigger", constraint: "user.a == 1 && user.b == 1", actions: new List <Dialog> {
                    new SendActivity("ruleAandB")
                }),
                new OnIntent("trigger", constraint: "user.a == 1 && user.c == 1", actions: new List <Dialog> {
                    new SendActivity("ruleAandC")
                }),
                new OnIntent("trigger", constraint: string.Empty, actions: new List <Dialog> {
                    new SendActivity("default")
                })
            });
            dialog.AutoEndDialog = false;

            DialogManager dm = new DialogManager(dialog);

            return(new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                await dm.OnTurnAsync(turnContext, cancellationToken: cancellationToken).ConfigureAwait(false);
            }));
        }
        public async Task CallDialogInParentComponent()
        {
            var convoState  = new ConversationState(new MemoryStorage());
            var dialogState = convoState.CreateProperty <DialogState>("dialogState");

            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(new AutoSaveStateMiddleware(convoState))
                          .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false)));

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                var state   = await dialogState.GetAsync(turnContext, () => new DialogState());
                var dialogs = new DialogSet(dialogState);

                var childComponent = new ComponentDialog("childComponent");
                var childStep      = new WaterfallStep[]
                {
                    async(step, token) =>
                    {
                        await step.Context.SendActivityAsync("Child started.");
                        return(await step.BeginDialogAsync("parentDialog", "test"));
                    },
                    async(step, token) =>
                    {
                        await step.Context.SendActivityAsync($"Child finished. Value: {step.Result}");
                        return(await step.EndDialogAsync());
                    }
                };
                childComponent.AddDialog(new WaterfallDialog("childDialog", childStep));

                var parentComponent = new ComponentDialog("parentComponent");
                parentComponent.AddDialog(childComponent);
                var parentStep = new WaterfallStep[]
                {
                    async(step, token) =>
                    {
                        await step.Context.SendActivityAsync("Parent called.");
                        return(await step.EndDialogAsync(step.Options));
                    }
                };
                parentComponent.AddDialog(new WaterfallDialog("parentDialog", parentStep));

                dialogs.Add(parentComponent);

                var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);

                var results = await dc.ContinueDialogAsync(cancellationToken);
                if (results.Status == DialogTurnStatus.Empty)
                {
                    await dc.BeginDialogAsync("parentComponent", null, cancellationToken);
                }
                else if (results.Status == DialogTurnStatus.Complete)
                {
                    var value = (int)results.Result;
                    await turnContext.SendActivityAsync(MessageFactory.Text($"Bot received the number '{value}'."), cancellationToken);
                }
            })
            .Send("Hi")
            .AssertReply("Child started.")
            .AssertReply("Parent called.")
            .AssertReply("Child finished. Value: test")
            .StartTestAsync();
        }
        public async Task EnsureCancelDialogCalled()
        {
            var convoState = new ConversationState(new MemoryStorage());

            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(new AutoSaveStateMiddleware(convoState));

            var dialogState      = convoState.CreateProperty <DialogState>("dialogState");
            var dialogs          = new DialogSet(dialogState);
            var telemetryClient  = new Mock <IBotTelemetryClient>();
            var saved_properties = new Dictionary <string, IDictionary <string, string> >();
            var counter          = 0;

            // Set up the client to save all logged property names and associated properties (in "saved_properties").
            telemetryClient.Setup(c => c.TrackEvent(It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <IDictionary <string, double> >()))
            .Callback <string, IDictionary <string, string>, IDictionary <string, double> >((name, properties, metrics) => saved_properties.Add($"{name}_{counter++}", properties))
            .Verifiable();

            var steps = new WaterfallStep[]
            {
                async(step, cancellationToken) =>
                {
                    await step.Context.SendActivityAsync("step1");

                    return(Dialog.EndOfTurn);
                },
                async(step, cancellationToken) =>
                {
                    await step.Context.SendActivityAsync("step2");

                    return(Dialog.EndOfTurn);
                },
                async(step, cancellationToken) =>
                {
                    await step.CancelAllDialogsAsync();

                    return(Dialog.EndOfTurn);
                },
            };
            var waterfallDialog = new MyWaterfallDialog("test", steps);

            dialogs.Add(waterfallDialog);
            dialogs.TelemetryClient = telemetryClient.Object;

            await new TestFlow(adapter, async(turnContext, cancellationToken) =>
            {
                var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);
                await dc.ContinueDialogAsync(cancellationToken);
                if (!turnContext.Responded)
                {
                    await dc.BeginDialogAsync("test", null, cancellationToken);
                }
            })
            .Send("hello")
            .AssertReply("step1")
            .Send("hello")
            .AssertReply("step2")
            .Send("hello")
            .AssertReply("step1")
            .StartTestAsync();
            telemetryClient.Verify(m => m.TrackEvent(It.IsAny <string>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <IDictionary <string, double> >()), Times.Exactly(7));

            // Verify:
            // Event name is "WaterfallCancel"
            // Event occurs on the 4th event logged
            // Event contains DialogId
            // Event DialogId is set correctly.
            Assert.IsTrue(saved_properties["WaterfallStart_0"].ContainsKey("DialogId"));
            Assert.IsTrue(saved_properties["WaterfallStart_0"].ContainsKey("InstanceId"));
            Assert.IsTrue(saved_properties["WaterfallCancel_4"].ContainsKey("DialogId"));
            Assert.IsTrue(saved_properties["WaterfallCancel_4"]["DialogId"] == "test");
            Assert.IsTrue(saved_properties["WaterfallCancel_4"].ContainsKey("StepName"));
            Assert.IsTrue(saved_properties["WaterfallCancel_4"].ContainsKey("InstanceId"));

            // Event contains "StepName"
            // Event naming on lambda's is "StepXofY"
            Assert.IsTrue(saved_properties["WaterfallCancel_4"]["StepName"] == "Step3of3");
            Assert.IsTrue(waterfallDialog.CancelDialogCalled);
            Assert.IsFalse(waterfallDialog.EndDialogCalled);
        }
        public async Task TextPromptWithNaughtyStrings()
        {
            var convoState  = new ConversationState(new MemoryStorage());
            var dialogState = convoState.CreateProperty <DialogState>("dialogState");

            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(new AutoSaveStateMiddleware(convoState))
                          .Use(new TranscriptLoggerMiddleware(new TraceTranscriptLogger(traceActivity: false)));

            var dialogs = new DialogSet(dialogState);

            var textPrompt = new TextPrompt("TextPrompt");

            dialogs.Add(textPrompt);

            var filePath = Path.Combine(new string[] { "..", "..", "..", "Resources", "naughtyStrings.txt" });

            using var sr = new StreamReader(filePath);
            var naughtyString = string.Empty;

            do
            {
                naughtyString = GetNextNaughtyString(sr);
                try
                {
                    await new TestFlow(adapter, async(turnContext, cancellationToken) =>
                    {
                        var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);

                        var results = await dc.ContinueDialogAsync(cancellationToken);
                        if (results.Status == DialogTurnStatus.Empty)
                        {
                            var options = new PromptOptions {
                                Prompt = new Activity {
                                    Type = ActivityTypes.Message, Text = "Enter some text."
                                }
                            };
                            await dc.PromptAsync("TextPrompt", options, cancellationToken);
                        }
                        else if (results.Status == DialogTurnStatus.Complete)
                        {
                            var textResult = (string)results.Result;
                            await turnContext.SendActivityAsync(MessageFactory.Text(textResult), cancellationToken);
                        }
                    })
                    .Send("hello")
                    .AssertReply("Enter some text.")
                    .Send(naughtyString)
                    .AssertReply(naughtyString)
                    .StartTestAsync();
                }
                catch (Exception e)
                {
                    // If the input message is empty after a .Trim() operation, character the comparison will fail because the reply message will be a
                    // Message Activity with null as Text, this is expected behavior
                    var messageIsBlank = e.Message.Equals(" :\nExpected: \nReceived:", StringComparison.CurrentCultureIgnoreCase) && naughtyString.Equals(" ", StringComparison.CurrentCultureIgnoreCase);
                    var messageIsEmpty = e.Message.Equals(":\nExpected:\nReceived:", StringComparison.CurrentCultureIgnoreCase) && naughtyString.IsNullOrEmpty();
                    if (!(messageIsBlank || messageIsEmpty))
                    {
                        throw;
                    }
                }
            }while (!string.IsNullOrEmpty(naughtyString));
        }
示例#22
0
        public void ConstructorNullActivity()
        {
            var a = new TestAdapter(TestAdapter.CreateConversation("ConstructorNullActivity"));

            Assert.Throws <ArgumentNullException>(() => new TurnContext(a, null));
        }
示例#23
0
        public async Task WaterfallCosmos()
        {
            if (CheckEmulator())
            {
                var convoState = new ConversationState(_storage);

                var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                              .Use(new AutoSaveStateMiddleware(convoState));

                var dialogState = convoState.CreateProperty <DialogState>("dialogState");
                var dialogs     = new DialogSet(dialogState);

                dialogs.Add(new TextPrompt(nameof(TextPrompt), async(promptContext, cancellationToken) =>
                {
                    var result = promptContext.Recognized.Value;
                    if (result.Length > 3)
                    {
                        var succeededMessage = MessageFactory.Text($"You got it at the {promptContext.AttemptCount}th try!");
                        await promptContext.Context.SendActivityAsync(succeededMessage, cancellationToken);
                        return(true);
                    }

                    var reply = MessageFactory.Text($"Please send a name that is longer than 3 characters. {promptContext.AttemptCount}");
                    await promptContext.Context.SendActivityAsync(reply, cancellationToken);

                    return(false);
                }));

                var steps = new WaterfallStep[]
                {
                    async(stepContext, ct) =>
                    {
                        Assert.AreEqual(stepContext.ActiveDialog.State["stepIndex"].GetType(), typeof(int));
                        await stepContext.Context.SendActivityAsync("step1");

                        return(Dialog.EndOfTurn);
                    },
                    async(stepContext, ct) =>
                    {
                        Assert.AreEqual(stepContext.ActiveDialog.State["stepIndex"].GetType(), typeof(int));
                        return(await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Please type your name.") }, ct));
                    },
                    async(stepContext, ct) =>
                    {
                        Assert.AreEqual(stepContext.ActiveDialog.State["stepIndex"].GetType(), typeof(int));
                        await stepContext.Context.SendActivityAsync("step3");

                        return(Dialog.EndOfTurn);
                    },
                };

                dialogs.Add(new WaterfallDialog(nameof(WaterfallDialog), steps));

                await new TestFlow(adapter, async(turnContext, cancellationToken) =>
                {
                    var dc = await dialogs.CreateContextAsync(turnContext);

                    await dc.ContinueDialogAsync();
                    if (!turnContext.Responded)
                    {
                        await dc.BeginDialogAsync(nameof(WaterfallDialog));
                    }
                })
                .Send("hello")
                .AssertReply("step1")
                .Send("hello")
                .AssertReply("Please type your name.")
                .Send("hi")
                .AssertReply("Please send a name that is longer than 3 characters. 1")
                .Send("hi")
                .AssertReply("Please send a name that is longer than 3 characters. 2")
                .Send("hi")
                .AssertReply("Please send a name that is longer than 3 characters. 3")
                .Send("Kyle")
                .AssertReply("You got it at the 4th try!")
                .AssertReply("step3")
                .StartTestAsync();
            }
        }
示例#24
0
        public void RespondedIsFalse()
        {
            var c = new TurnContext(new TestAdapter(TestAdapter.CreateConversation("RespondedIsFalse")), new Activity());

            Assert.False(c.Responded);
        }
示例#25
0
        public async Task AutoSaveStateMiddleware_Chain()
        {
            var storage = new MemoryStorage();

            // setup userstate
            var userState    = new UserState(storage);
            var userProperty = userState.CreateProperty <int>("userCount");

            // setup convState
            var convState    = new ConversationState(storage);
            var convProperty = convState.CreateProperty <int>("convCount");
            var bss          = new AutoSaveStateMiddleware()
                               .Add(userState)
                               .Add(convState);
            var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName))
                          .Use(bss);

            const int          USER_INITITAL_COUNT        = 100;
            const int          CONVERSATION_INITIAL_COUNT = 10;
            BotCallbackHandler botLogic = async(context, cancellationToken) =>
            {
                // get userCount and convCount from botStateSet
                var userCount = await userProperty.GetAsync(context, () => USER_INITITAL_COUNT).ConfigureAwait(false);

                var convCount = await convProperty.GetAsync(context, () => CONVERSATION_INITIAL_COUNT).ConfigureAwait(false);

                if (context.Activity.Type == ActivityTypes.Message)
                {
                    if (context.Activity.Text == "get userCount")
                    {
                        await context.SendActivityAsync(context.Activity.CreateReply($"{userCount}"));
                    }
                    else if (context.Activity.Text == "get convCount")
                    {
                        await context.SendActivityAsync(context.Activity.CreateReply($"{convCount}"));
                    }
                }

                // increment userCount and set property using accessor.  To be saved later by AutoSaveStateMiddleware
                userCount++;
                await userProperty.SetAsync(context, userCount);

                // increment convCount and set property using accessor.  To be saved later by AutoSaveStateMiddleware
                convCount++;
                await convProperty.SetAsync(context, convCount);
            };

            await new TestFlow(adapter, botLogic)
            .Send("test1")
            .Send("get userCount")
            .AssertReply((USER_INITITAL_COUNT + 1).ToString())
            .Send("get userCount")
            .AssertReply((USER_INITITAL_COUNT + 2).ToString())
            .Send("get convCount")
            .AssertReply((CONVERSATION_INITIAL_COUNT + 3).ToString())
            .StartTestAsync();

            // new adapter on new conversation
            var bss2 = new AutoSaveStateMiddleware()
                       .Add(userState)
                       .Add(convState);

            adapter = new TestAdapter(new ConversationReference
            {
                ChannelId    = "test",
                ServiceUrl   = "https://test.com",
                User         = new ChannelAccount("user1", "User1"),
                Bot          = new ChannelAccount("bot", "Bot"),
                Conversation = new ConversationAccount(false, "convo2", "Conversation2"),
            })
                      .Use(bss2);

            await new TestFlow(adapter, botLogic)
            .Send("get userCount")
            .AssertReply((USER_INITITAL_COUNT + 4).ToString(), "user count should continue on new conversation")
            .Send("get convCount")
            .AssertReply((CONVERSATION_INITIAL_COUNT + 1).ToString(), "conversationCount for conversation2 should be reset")
            .StartTestAsync();
        }