219 строки
8.8 KiB
C#
219 строки
8.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Bot.Builder;
|
|
using Microsoft.Bot.Builder.Integration;
|
|
using Microsoft.Bot.Builder.Integration.AspNet.Core;
|
|
using Microsoft.Bot.Builder.Streaming;
|
|
using Microsoft.Bot.Connector.Authentication;
|
|
using Microsoft.Bot.Schema;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Rest.Serialization;
|
|
using Moq;
|
|
using Moq.Protected;
|
|
using Newtonsoft.Json.Linq;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.Bot.Builder.Streaming.Tests
|
|
{
|
|
public class DirectLineAdapterTests
|
|
{
|
|
[Fact]
|
|
public async Task BasicMessageActivity()
|
|
{
|
|
// Arrange
|
|
var headerDictionaryMock = new Mock<IHeaderDictionary>();
|
|
headerDictionaryMock.Setup(h => h[It.Is<string>(v => v == "Authorization")]).Returns<string>(null);
|
|
|
|
var httpRequestMock = new Mock<HttpRequest>();
|
|
httpRequestMock.Setup(r => r.Body).Returns(CreateMessageActivityStream());
|
|
httpRequestMock.Setup(r => r.Headers).Returns(headerDictionaryMock.Object);
|
|
|
|
var httpResponseMock = new Mock<HttpResponse>();
|
|
|
|
var botMock = new Mock<IBot>();
|
|
botMock.Setup(b => b.OnTurnAsync(It.IsAny<TurnContext>(), It.IsAny<CancellationToken>())).Returns(Task.CompletedTask);
|
|
|
|
// Act
|
|
var adapter = new BotFrameworkHttpAdapter();
|
|
await adapter.ProcessAsync(httpRequestMock.Object, httpResponseMock.Object, botMock.Object);
|
|
|
|
// Assert
|
|
botMock.Verify(m => m.OnTurnAsync(It.Is<TurnContext>(tc => true), It.Is<CancellationToken>(ct => true)), Times.Once());
|
|
}
|
|
|
|
// [Fact]
|
|
// public async Task InvokeActivity()
|
|
// {
|
|
// // Arrange
|
|
// var headerDictionaryMock = new Mock<IHeaderDictionary>();
|
|
// headerDictionaryMock.Setup(h => h[It.Is<string>(v => v == "Authorization")]).Returns<string>(null);
|
|
|
|
// var httpRequestMock = new Mock<HttpRequest>();
|
|
// httpRequestMock.Setup(r => r.Body).Returns(CreateInvokeActivityStream());
|
|
// httpRequestMock.Setup(r => r.Headers).Returns(headerDictionaryMock.Object);
|
|
|
|
// var response = new MemoryStream();
|
|
// var httpResponseMock = new Mock<HttpResponse>();
|
|
// httpResponseMock.Setup(r => r.Body).Returns(response);
|
|
|
|
// var bot = new InvokeResponseBot();
|
|
|
|
// // Act
|
|
// var adapter = new DirectLineAdapter();
|
|
// await adapter.ProcessAsync(httpRequestMock.Object, httpResponseMock.Object, bot);
|
|
|
|
// // Assert
|
|
// using (var stream = new MemoryStream(response.GetBuffer()))
|
|
// using (var reader = new StreamReader(stream))
|
|
// {
|
|
// var s = reader.ReadToEnd();
|
|
// var json = JObject.Parse(s);
|
|
// Assert.Equal("im.feeling.really.attacked.right.now", json["quite.honestly"]);
|
|
// }
|
|
// }
|
|
|
|
// [Fact]
|
|
// public async Task MessageActivityWithHttpClient()
|
|
// {
|
|
// // Arrange
|
|
// var headerDictionaryMock = new Mock<IHeaderDictionary>();
|
|
// headerDictionaryMock.Setup(h => h[It.Is<string>(v => v == "Authorization")]).Returns<string>(null);
|
|
|
|
// var httpRequestMock = new Mock<HttpRequest>();
|
|
// httpRequestMock.Setup(r => r.Body).Returns(CreateMessageActivityStream());
|
|
// httpRequestMock.Setup(r => r.Headers).Returns(headerDictionaryMock.Object);
|
|
|
|
// var httpResponseMock = new Mock<HttpResponse>();
|
|
|
|
// var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
|
|
// mockHttpMessageHandler.Protected()
|
|
// .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
|
|
// .Returns((HttpRequestMessage request, CancellationToken cancellationToken) => Task.FromResult(CreateInternalHttpResponse()));
|
|
|
|
// var httpClient = new HttpClient(mockHttpMessageHandler.Object);
|
|
|
|
// var bot = new MessageBot();
|
|
|
|
// // Act
|
|
// var adapter = new DirectLineAdapter(null, null, httpClient, null);
|
|
// await adapter.ProcessAsync(httpRequestMock.Object, httpResponseMock.Object, bot);
|
|
|
|
// // Assert
|
|
// mockHttpMessageHandler.Protected().Verify<Task<HttpResponseMessage>>("SendAsync", Times.Once(), ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>());
|
|
// }
|
|
[Fact]
|
|
public void ConstructorWithConfiguration()
|
|
{
|
|
// Arrange
|
|
var appSettings = new Dictionary<string, string>
|
|
{
|
|
{ "MicrosoftAppId", "appId" },
|
|
{ "MicrosoftAppPassword", "appPassword" },
|
|
{ "ChannelService", "channelService" },
|
|
{ "BotOpenIdMetadata", "botOpenIdMetadata" },
|
|
};
|
|
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(appSettings)
|
|
.Build();
|
|
|
|
// Act
|
|
var adapter = new MyAdapter(configuration);
|
|
|
|
// Assert
|
|
|
|
// Note this is a special case testing a little more than just the public interface.
|
|
var credentialProviderField = typeof(BotFrameworkAdapter).GetField("_credentialProvider", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
|
|
var channelProviderField = typeof(BotFrameworkAdapter).GetField("_channelProvider", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
|
|
|
|
var credentialProvider = (SimpleCredentialProvider)credentialProviderField.GetValue(adapter);
|
|
var channelProvider = (SimpleChannelProvider)channelProviderField.GetValue(adapter);
|
|
|
|
Assert.Equal("appId", credentialProvider.AppId);
|
|
Assert.Equal("appPassword", credentialProvider.Password);
|
|
Assert.Equal("channelService", channelProvider.ChannelService);
|
|
Assert.Equal("botOpenIdMetadata", ChannelValidation.OpenIdMetadataUrl);
|
|
Assert.Equal("botOpenIdMetadata", GovernmentChannelValidation.OpenIdMetadataUrl);
|
|
}
|
|
|
|
private static Stream CreateMessageActivityStream()
|
|
{
|
|
return CreateStream(new Activity
|
|
{
|
|
Type = ActivityTypes.Message,
|
|
Text = "hi",
|
|
ServiceUrl = "http://localhost",
|
|
ChannelId = "ChannelId",
|
|
Conversation = new ConversationAccount { Id = "ConversationId" },
|
|
});
|
|
}
|
|
|
|
private static HttpResponseMessage CreateInternalHttpResponse()
|
|
{
|
|
var response = new HttpResponseMessage(HttpStatusCode.OK);
|
|
response.Content = new StringContent(new JObject { { "id", "SendActivityId" } }.ToString());
|
|
return response;
|
|
}
|
|
|
|
private static Stream CreateInvokeActivityStream()
|
|
{
|
|
return CreateStream(new Activity { Type = ActivityTypes.Invoke, ServiceUrl = "http://localhost" });
|
|
}
|
|
|
|
private static Stream CreateStream(Activity activity)
|
|
{
|
|
string json = SafeJsonConvert.SerializeObject(activity, MessageSerializerSettings.Create());
|
|
var stream = new MemoryStream();
|
|
var textWriter = new StreamWriter(stream);
|
|
textWriter.Write(json);
|
|
textWriter.Flush();
|
|
stream.Seek(0, SeekOrigin.Begin);
|
|
return stream;
|
|
}
|
|
|
|
private class MyAdapter : BotFrameworkHttpAdapter
|
|
{
|
|
public MyAdapter(IConfiguration configuration)
|
|
: base(configuration)
|
|
{
|
|
}
|
|
}
|
|
|
|
private class InvokeResponseBot : IBot
|
|
{
|
|
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
|
|
{
|
|
await turnContext.SendActivityAsync(CreateInvokeResponseActivity());
|
|
}
|
|
|
|
private static Activity CreateInvokeResponseActivity()
|
|
{
|
|
return new Activity
|
|
{
|
|
Type = ActivityTypesEx.InvokeResponse,
|
|
Value = new InvokeResponse
|
|
{
|
|
Status = 200,
|
|
Body = new JObject { { "quite.honestly", "im.feeling.really.attacked.right.now" } },
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
private class MessageBot : IBot
|
|
{
|
|
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
|
|
{
|
|
await turnContext.SendActivityAsync(MessageFactory.Text("rage.rage.against.the.dying.of.the.light"));
|
|
}
|
|
}
|
|
}
|
|
}
|