Merge pull request #2953 from microsoft/gary/adapters-ga-work

Adapter updates ahead of GA
This commit is contained in:
Gary Pretty 2019-11-14 19:27:02 +00:00 коммит произвёл GitHub
Родитель 4a4cc55cab 3087e2f4c5
Коммит 93129b16c9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 225 добавлений и 139 удалений

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
@ -13,6 +14,8 @@ using Microsoft.Bot.Builder.Adapters.Facebook.FacebookEvents;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Adapters.Facebook
@ -22,6 +25,7 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
private const string HubModeSubscribe = "subscribe";
private readonly FacebookClientWrapper _facebookClient;
private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="FacebookAdapter"/> class using configuration settings.
@ -33,8 +37,9 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
/// AppSecret: The secret used to validate incoming webhooks.
/// AccessToken: An access token for the bot.
/// </remarks>
public FacebookAdapter(IConfiguration configuration)
: this(new FacebookClientWrapper(new FacebookAdapterOptions(configuration["FacebookVerifyToken"], configuration["FacebookAppSecret"], configuration["FacebookAccessToken"])))
/// <param name="logger">The ILogger implementation this adapter should use.</param>
public FacebookAdapter(IConfiguration configuration, ILogger logger = null)
: this(new FacebookClientWrapper(new FacebookAdapterOptions(configuration["FacebookVerifyToken"], configuration["FacebookAppSecret"], configuration["FacebookAccessToken"])), logger)
{
}
@ -43,9 +48,11 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
/// Creates a Facebook adapter.
/// </summary>
/// <param name="facebookClient">A Facebook API interface.</param>
public FacebookAdapter(FacebookClientWrapper facebookClient)
/// <param name="logger">The ILogger implementation this adapter should use.</param>
public FacebookAdapter(FacebookClientWrapper facebookClient, ILogger logger = null)
{
_facebookClient = facebookClient ?? throw new ArgumentNullException(nameof(facebookClient));
_logger = logger ?? NullLogger.Instance;
}
/// <summary>
@ -63,25 +70,24 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
{
if (activity.Type != ActivityTypes.Message)
{
throw new Exception("Only Activities of type Message are supported for sending.");
_logger.LogTrace($"Unsupported Activity Type: '{activity.Type}'. Only Activities of type 'Message' are supported.");
}
var message = FacebookHelper.ActivityToFacebook(activity);
if (message.Message.Attachment != null)
else
{
message.Message.Attachments = null;
message.Message.Text = null;
var message = FacebookHelper.ActivityToFacebook(activity);
if (message.Message.Attachment != null)
{
message.Message.Text = null;
}
var res = await _facebookClient.SendMessageAsync("/me/messages", message, null, cancellationToken)
.ConfigureAwait(false);
var response = new ResourceResponse() { Id = res, };
responses.Add(response);
}
var res = await _facebookClient.SendMessageAsync("/me/messages", message, null, cancellationToken).ConfigureAwait(false);
var response = new ResourceResponse()
{
Id = res,
};
responses.Add(response);
}
return responses.ToArray();
@ -145,7 +151,7 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
/// <param name="bot">A bot logic function.</param>
/// <param name="cancellationToken">A cancellation token for the task.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task ProcessAsync(HttpRequest request, HttpResponse response, IBot bot, CancellationToken cancellationToken)
public async Task ProcessAsync(HttpRequest request, HttpResponse response, IBot bot, CancellationToken cancellationToken = default)
{
if (request.Query["hub.mode"] == HubModeSubscribe)
{
@ -174,7 +180,7 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
{
var payload = new List<FacebookMessage>();
payload = entry.Changes ?? entry.Messaging;
payload = entry.Changes.Any() ? entry.Changes : entry.Messaging;
foreach (var message in payload)
{
@ -187,7 +193,7 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
}
// Handle standby messages (this bot is not the active receiver)
if (entry.Standby != null)
if (!entry.Standby.Any())
{
payload = entry.Standby;

Просмотреть файл

@ -20,21 +20,36 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook.FacebookEvents
public long Time { get; set; }
/// <summary>
/// Gets or sets the messaging list.
/// Gets the messaging list.
/// </summary>
/// <value>List containing one messaging object. Note that even though this is an enumerable, it will only contain one object.</value>
public List<FacebookMessage> Messaging { get; set; }
public List<FacebookMessage> Messaging { get; } = new List<FacebookMessage>();
/// <summary>
/// Gets or sets the changes list.
/// Gets the changes list.
/// </summary>
/// <value>List containing the list of changes.</value>
public List<FacebookMessage> Changes { get; set; }
public List<FacebookMessage> Changes { get; } = new List<FacebookMessage>();
/// <summary>
/// Gets or sets the standby messages list.
/// Gets the standby messages list.
/// </summary>
/// <value>List containing the messages sent while in standby mode.</value>
public List<FacebookMessage> Standby { get; set; }
public List<FacebookMessage> Standby { get; } = new List<FacebookMessage>();
public bool ShouldSerializeMessaging()
{
return Messaging.Count > 0;
}
public bool ShouldSerializeStandby()
{
return Messaging.Count > 0;
}
public bool ShouldSerializeChanges()
{
return Messaging.Count > 0;
}
}
}

Просмотреть файл

@ -11,6 +11,11 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook.FacebookEvents
[JsonProperty(PropertyName = "object")]
public string ResponseObject { get; set; }
public List<FacebookEntry> Entry { get; set; }
public List<FacebookEntry> Entry { get; } = new List<FacebookEntry>();
public bool ShouldSerializeEntry()
{
return Entry.Count > 0;
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
@ -38,7 +39,7 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
facebookMessage = activity.GetChannelData<FacebookMessage>();
// make sure the quick reply has a type
if (activity.GetChannelData<FacebookMessage>().Message.QuickReplies != null)
if (activity.GetChannelData<FacebookMessage>().Message.QuickReplies.Any())
{
foreach (var reply in facebookMessage.Message.QuickReplies)
{

Просмотреть файл

@ -24,11 +24,11 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
public string StickerId { get; set; }
/// <summary>
/// Gets or sets a list of attachments.
/// Gets a list of attachments.
/// </summary>
/// <value>Attachments.</value>
[JsonProperty(PropertyName = "attachments")]
public List<FacebookAttachment> Attachments { get; set; }
public List<FacebookAttachment> Attachments { get; } = new List<FacebookAttachment>();
/// <summary>
/// Gets or sets the attachment.
@ -45,12 +45,11 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
public string Metadata { get; set; }
/// <summary>
/// Gets or sets the quick replies.
/// Gets the quick replies.
/// </summary>
/// <value>The quick replies array.</value>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "it needs to be set in ActivityToFacebook method")]
[JsonProperty(PropertyName = "quick_replies")]
public List<FacebookQuickReply> QuickReplies { get; set; } = new List<FacebookQuickReply>();
public List<FacebookQuickReply> QuickReplies { get; } = new List<FacebookQuickReply>();
[JsonProperty(PropertyName = "is_echo")]
public bool IsEcho { get; set; }
@ -64,5 +63,10 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook
{
return IsEcho;
}
public bool ShouldSerializeAttachments()
{
return Attachments.Count > 0;
}
}
}

Просмотреть файл

@ -17,6 +17,8 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU' ">
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Microsoft.Bot.Builder.Adapters.Facebook.xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -13,10 +13,14 @@
<PackageId>Microsoft.Bot.Builder.Adapters.Slack</PackageId>
<Description>Library for connecting bots with Slack.</Description>
<Summary>This library implements C# classes for the Slack adapter.</Summary>
<!-- The SlackAPI package isn't signed, so supress the warning. There seems to not be a way to supress this for ONLY SlackAPI. -->
<NoWarn>$(NoWarn),CS8002</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Microsoft.Bot.Builder.Adapters.Slack.xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -12,12 +12,15 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.Bot.Builder.Adapters.Slack
{
public class SlackAdapter : BotAdapter, IBotFrameworkHttpAdapter
{
private readonly SlackClientWrapper _slackClient;
private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="SlackAdapter"/> class using configuration settings.
@ -29,8 +32,9 @@ namespace Microsoft.Bot.Builder.Adapters.Slack
/// SlackBotToken: A token for a bot to work on a single workspace.
/// SlackClientSigningSecret: The token used to validate that incoming webhooks are originated from Slack.
/// </remarks>
public SlackAdapter(IConfiguration configuration)
: this(new SlackClientWrapper(new SlackAdapterOptions(configuration["SlackVerificationToken"], configuration["SlackBotToken"], configuration["SlackClientSigningSecret"])))
/// <param name="logger">The ILogger implementation this adapter should use.</param>
public SlackAdapter(IConfiguration configuration, ILogger logger = null)
: this(new SlackClientWrapper(new SlackAdapterOptions(configuration["SlackVerificationToken"], configuration["SlackBotToken"], configuration["SlackClientSigningSecret"])), logger)
{
}
@ -39,9 +43,11 @@ namespace Microsoft.Bot.Builder.Adapters.Slack
/// Creates a Slack adapter.
/// </summary>
/// <param name="slackClient">An initialized instance of the SlackClientWrapper class to connect to.</param>
public SlackAdapter(SlackClientWrapper slackClient)
/// <param name="logger">The ILogger implementation this adapter should use.</param>
public SlackAdapter(SlackClientWrapper slackClient, ILogger logger = null)
{
_slackClient = slackClient ?? throw new ArgumentNullException(nameof(slackClient));
_logger = logger ?? NullLogger.Instance;
}
/// <summary>
@ -69,25 +75,25 @@ namespace Microsoft.Bot.Builder.Adapters.Slack
{
if (activity.Type != ActivityTypes.Message)
{
throw new ArgumentException("Unsupported Activity Type. Only Activities of type Message are supported.", nameof(activities));
_logger.LogTrace($"Unsupported Activity Type: '{activity.Type}'. Only Activities of type 'Message' are supported.");
}
var message = SlackHelper.ActivityToSlack(activity);
var slackResponse = await _slackClient.PostMessageAsync(message, cancellationToken).ConfigureAwait(false);
if (slackResponse != null && slackResponse.Ok)
else
{
var resourceResponse = new ActivityResourceResponse()
var message = SlackHelper.ActivityToSlack(activity);
var slackResponse = await _slackClient.PostMessageAsync(message, cancellationToken)
.ConfigureAwait(false);
if (slackResponse != null && slackResponse.Ok)
{
Id = slackResponse.Ts,
ActivityId = slackResponse.Ts,
Conversation = new ConversationAccount()
var resourceResponse = new ActivityResourceResponse()
{
Id = slackResponse.Channel,
},
};
responses.Add(resourceResponse);
Id = slackResponse.Ts,
ActivityId = slackResponse.Ts,
Conversation = new ConversationAccount() { Id = slackResponse.Channel, },
};
responses.Add(resourceResponse);
}
}
}

Просмотреть файл

@ -23,6 +23,8 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU' ">
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Microsoft.Bot.Builder.Adapters.Twilio.xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -13,6 +13,8 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.Bot.Builder.Adapters.Twilio
{
@ -22,6 +24,7 @@ namespace Microsoft.Bot.Builder.Adapters.Twilio
public class TwilioAdapter : BotAdapter, IBotFrameworkHttpAdapter
{
private readonly TwilioClientWrapper _twilioClient;
private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="TwilioAdapter"/> class using configuration settings.
@ -34,8 +37,9 @@ namespace Microsoft.Bot.Builder.Adapters.Twilio
/// TwilioAuthToken: The authentication token for the account.
/// TwilioValidationUrl: The validation URL for incoming requests.
/// </remarks>
public TwilioAdapter(IConfiguration configuration)
: this(new TwilioClientWrapper(new TwilioAdapterOptions(configuration["TwilioNumber"], configuration["TwilioAccountSid"], configuration["TwilioAuthToken"], new Uri(configuration["TwilioValidationUrl"]))))
/// <param name="logger">The ILogger implementation this adapter should use.</param>
public TwilioAdapter(IConfiguration configuration, ILogger logger)
: this(new TwilioClientWrapper(new TwilioAdapterOptions(configuration["TwilioNumber"], configuration["TwilioAccountSid"], configuration["TwilioAuthToken"], new Uri(configuration["TwilioValidationUrl"]))), logger)
{
}
@ -43,9 +47,11 @@ namespace Microsoft.Bot.Builder.Adapters.Twilio
/// Initializes a new instance of the <see cref="TwilioAdapter"/> class.
/// </summary>
/// <param name="twilioClient">The Twilio client to connect to.</param>
public TwilioAdapter(TwilioClientWrapper twilioClient)
/// <param name="logger">The ILogger implementation this adapter should use.</param>
public TwilioAdapter(TwilioClientWrapper twilioClient, ILogger logger = null)
{
_twilioClient = twilioClient ?? throw new ArgumentNullException(nameof(twilioClient));
_logger = logger ?? NullLogger.Instance;
}
/// <summary>
@ -67,19 +73,18 @@ namespace Microsoft.Bot.Builder.Adapters.Twilio
{
if (activity.Type != ActivityTypes.Message)
{
throw new ArgumentException("Unsupported Activity Type. Only Activities of type Message are supported.", nameof(activities));
_logger.LogTrace($"Unsupported Activity Type: '{activity.Type}'. Only Activities of type 'Message' are supported.");
}
var messageOptions = TwilioHelper.ActivityToTwilio(activity, _twilioClient.Options.TwilioNumber);
var res = await _twilioClient.SendMessage(messageOptions).ConfigureAwait(false);
var response = new ResourceResponse()
else
{
Id = res,
};
var messageOptions = TwilioHelper.ActivityToTwilio(activity, _twilioClient.Options.TwilioNumber);
responses.Add(response);
var res = await _twilioClient.SendMessage(messageOptions).ConfigureAwait(false);
var response = new ResourceResponse() { Id = res, };
responses.Add(response);
}
}
return responses.ToArray();
@ -96,7 +101,7 @@ namespace Microsoft.Bot.Builder.Adapters.Twilio
/// <returns>A task that represents the work queued to execute.</returns>
/// <exception cref="ArgumentNullException"><paramref name="httpRequest"/>,
/// <paramref name="httpResponse"/>, or <paramref name="bot"/> is <c>null</c>.</exception>
public async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot, CancellationToken cancellationToken = default)
public async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpResponse, IBot bot, CancellationToken cancellationToken)
{
if (httpRequest == null)
{

Просмотреть файл

@ -13,10 +13,14 @@
<PackageId>Microsoft.Bot.Builder.Adapters.Webex</PackageId>
<Description>Library for connecting bots with Webex Teams API.</Description>
<Summary>This library implements C# classes for the Webex Adapter</Summary>
<!-- The Thrzn41.WebexTeams package isn't signed, so supress the warning. There seems to not be a way to supress this for ONLY Thrzn41.WebexTeams. -->
<NoWarn>$(NoWarn),CS8002</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU' ">
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Microsoft.Bot.Builder.Adapters.Webex.xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -10,6 +10,8 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using Thrzn41.WebexTeams.Version1;
@ -18,6 +20,7 @@ namespace Microsoft.Bot.Builder.Adapters.Webex
public class WebexAdapter : BotAdapter, IBotFrameworkHttpAdapter
{
private readonly WebexClientWrapper _webexClient;
private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="WebexAdapter"/> class using configuration settings.
@ -30,8 +33,9 @@ namespace Microsoft.Bot.Builder.Adapters.Webex
/// WebexSecret: The secret used to validate incoming webhooks.
/// WebexWebhookName: A name for the webhook subscription.
/// </remarks>
public WebexAdapter(IConfiguration configuration)
: this(new WebexClientWrapper(new WebexAdapterOptions(configuration["WebexAccessToken"], new Uri(configuration["WebexPublicAddress"]), configuration["WebexSecret"], configuration["WebexWebhookName"])))
/// <param name="logger">The ILogger implementation this adapter should use.</param>
public WebexAdapter(IConfiguration configuration, ILogger logger)
: this(new WebexClientWrapper(new WebexAdapterOptions(configuration["WebexAccessToken"], new Uri(configuration["WebexPublicAddress"]), configuration["WebexSecret"], configuration["WebexWebhookName"])), logger)
{
}
@ -40,9 +44,11 @@ namespace Microsoft.Bot.Builder.Adapters.Webex
/// Creates a Webex adapter.
/// </summary>
/// <param name="webexClient">A Webex API interface.</param>
public WebexAdapter(WebexClientWrapper webexClient)
/// <param name="logger">The ILogger implementation this adapter should use.</param>
public WebexAdapter(WebexClientWrapper webexClient, ILogger logger = null)
{
_webexClient = webexClient ?? throw new ArgumentNullException(nameof(webexClient));
_logger = logger ?? NullLogger.Instance;
}
/// <summary>
@ -59,55 +65,59 @@ namespace Microsoft.Bot.Builder.Adapters.Webex
{
if (activity.Type != ActivityTypes.Message)
{
throw new ArgumentException("Unsupported Activity Type. Only Activities of type Message are supported.", nameof(activities));
}
// transform activity into the webex message format
string personIdOrEmail;
if (activity.GetChannelData<WebhookEventData>()?.MessageData.PersonEmail != null)
{
personIdOrEmail = activity.GetChannelData<WebhookEventData>()?.MessageData.PersonEmail;
_logger.LogTrace($"Unsupported Activity Type: '{activity.Type}'. Only Activities of type 'Message' are supported.");
}
else
{
if (activity.Recipient?.Id != null)
// transform activity into the webex message format
string personIdOrEmail;
if (activity.GetChannelData<WebhookEventData>()?.MessageData.PersonEmail != null)
{
personIdOrEmail = activity.Recipient.Id;
personIdOrEmail = activity.GetChannelData<WebhookEventData>()?.MessageData.PersonEmail;
}
else
{
throw new Exception("No Person or Email to send the message");
}
}
string responseId;
if (activity.Attachments != null && activity.Attachments.Count > 0)
{
if (activity.Attachments[0].ContentType == "application/vnd.microsoft.card.adaptive")
{
responseId = await _webexClient.CreateMessageWithAttachmentsAsync(personIdOrEmail, activity.Text, activity.Attachments, cancellationToken).ConfigureAwait(false);
}
else
{
var files = new List<Uri>();
foreach (var attachment in activity.Attachments)
if (activity.Recipient?.Id != null)
{
var file = new Uri(attachment.ContentUrl);
files.Add(file);
personIdOrEmail = activity.Recipient.Id;
}
else
{
throw new Exception("No Person or Email to send the message");
}
responseId = await _webexClient.CreateMessageAsync(personIdOrEmail, activity.Text, files.Count > 0 ? files : null, cancellationToken).ConfigureAwait(false);
}
}
else
{
responseId = await _webexClient.CreateMessageAsync(personIdOrEmail, activity.Text, cancellationToken: cancellationToken).ConfigureAwait(false);
}
responses.Add(new ResourceResponse(responseId));
string responseId;
if (activity.Attachments != null && activity.Attachments.Count > 0)
{
if (activity.Attachments[0].ContentType == "application/vnd.microsoft.card.adaptive")
{
responseId = await _webexClient.CreateMessageWithAttachmentsAsync(personIdOrEmail, activity.Text, activity.Attachments, cancellationToken).ConfigureAwait(false);
}
else
{
var files = new List<Uri>();
foreach (var attachment in activity.Attachments)
{
var file = new Uri(attachment.ContentUrl);
files.Add(file);
}
responseId = await _webexClient.CreateMessageAsync(personIdOrEmail, activity.Text, files.Count > 0 ? files : null, cancellationToken).ConfigureAwait(false);
}
}
else
{
responseId = await _webexClient
.CreateMessageAsync(personIdOrEmail, activity.Text, cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
responses.Add(new ResourceResponse(responseId));
}
}
return responses.ToArray();

Просмотреть файл

@ -226,22 +226,35 @@ namespace Microsoft.Bot.Builder.Adapters.Facebook.Tests
}
[Fact]
public async void SendActivitiesAsyncShouldFailWithActivityTypeNotMessage()
public async void SendActivitiesAsyncShouldSucceedAndNoActivityReturnedWithActivityTypeNotMessage()
{
var facebookAdapter = new FacebookAdapter(new Mock<FacebookClientWrapper>(_testOptions).Object);
const string testResponse = "Test Response";
var facebookClientWrapper = new Mock<FacebookClientWrapper>(_testOptions);
var facebookAdapter = new FacebookAdapter(facebookClientWrapper.Object);
var attachments = new List<Attachment>();
var activity = new Activity
{
Type = ActivityTypes.Event,
Type = ActivityTypes.Trace,
Text = "Test text",
Conversation = new ConversationAccount()
{
Id = "Test id",
},
ChannelData = new FacebookMessage("recipientId", new Message(), "messagingtype"),
Attachments = attachments,
};
Activity[] activities = { activity };
ResourceResponse[] responses = null;
attachments.Add(new Attachment("text/html", "http://contoso.com"));
facebookClientWrapper.Setup(api => api.SendMessageAsync(It.IsAny<string>(), It.IsAny<FacebookMessage>(), It.IsAny<HttpMethod>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(testResponse));
using (var turnContext = new TurnContext(facebookAdapter, activity))
{
await Assert.ThrowsAsync<Exception>(async () =>
{
await facebookAdapter.SendActivitiesAsync(turnContext, activities, default);
});
responses = await facebookAdapter.SendActivitiesAsync(turnContext, activities, default);
}
Assert.True(responses.Length == 0);
}
[Fact]

Просмотреть файл

@ -2,6 +2,8 @@
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<!-- The SlackAPI package isn't signed, so supress the warning. There seems to not be a way to supress this for ONLY SlackAPI. -->
<NoWarn>$(NoWarn),CS8002</NoWarn>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -10,6 +10,8 @@
<DelaySign>true</DelaySign>
<AssemblyOriginatorKeyFile>..\..\..\build\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
<DefineConstants>SIGNASSEMBLY</DefineConstants>
<!-- The SlackAPI package isn't signed, so supress the warning. There seems to not be a way to supress this for ONLY SlackAPI. -->
<NoWarn>$(NoWarn),CS8002</NoWarn>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -51,21 +51,22 @@ namespace Microsoft.Bot.Builder.Adapters.Twilio.Tests
}
[Fact]
public async void SendActivitiesAsyncShouldFailWithActivityTypeNotMessage()
public async void SendActivitiesAsyncShouldSucceedAndNoActivityReturnedWithActivityTypeNotMessage()
{
var twilioAdapter = new TwilioAdapter(new Mock<TwilioClientWrapper>(_testOptions).Object);
var activity = new Mock<Activity>().SetupAllProperties();
activity.Object.Type = ActivityTypes.Trace;
activity.Object.Attachments = new List<Attachment> { new Attachment(contentUrl: "http://example.com") };
activity.Object.Conversation = new ConversationAccount(id: "MockId");
activity.Object.Text = "Trace content";
var activity = new Activity()
{
Type = ActivityTypes.Event,
};
const string resourceIdentifier = "Mocked Resource Identifier";
var twilioApi = new Mock<TwilioClientWrapper>(_testOptions);
twilioApi.Setup(x => x.SendMessage(It.IsAny<CreateMessageOptions>())).Returns(Task.FromResult(resourceIdentifier));
Activity[] activities = { activity };
var twilioAdapter = new TwilioAdapter(twilioApi.Object);
var resourceResponses = await twilioAdapter.SendActivitiesAsync(null, new Activity[] { activity.Object }, default).ConfigureAwait(false);
await Assert.ThrowsAsync<ArgumentException>(async () =>
{
await twilioAdapter.SendActivitiesAsync(new TurnContext(twilioAdapter, activity), activities, default);
});
Assert.True(resourceResponses.Length == 0);
}
[Fact]

Просмотреть файл

@ -2,8 +2,9 @@
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
<!-- The Thrzn41.WebexTeams package isn't signed, so supress the warning. There seems to not be a way to supress this for ONLY Thrzn41.WebexTeams. -->
<NoWarn>$(NoWarn),CS8002</NoWarn>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -322,22 +323,24 @@ namespace Microsoft.Bot.Builder.Adapters.Webex.Tests
}
[Fact]
public async void SendActivitiesAsyncShouldFailWithActivityTypeNotMessage()
public async void SendActivitiesAsyncShouldSucceedAndNoActivityReturnedWithActivityTypeNotMessage()
{
var webexAdapter = new WebexAdapter(new Mock<WebexClientWrapper>(_testOptions).Object);
var activity = new Activity
{
Type = ActivityTypes.Event,
};
const string expectedResponseId = "Mocked Response Id";
var webexApi = new Mock<WebexClientWrapper>(_testOptions);
webexApi.Setup(x => x.CreateMessageWithAttachmentsAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IList<Attachment>>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(expectedResponseId));
Activity[] activities = { activity };
var webexAdapter = new WebexAdapter(webexApi.Object);
var turnContext = new TurnContext(webexAdapter, activity);
var activity = new Mock<Activity>().SetupAllProperties();
activity.Object.Type = ActivityTypes.Trace;
activity.Object.Recipient = new ChannelAccount(id: "MockId");
activity.Object.Text = "Trace content";
await Assert.ThrowsAsync<ArgumentException>(async () =>
{
await webexAdapter.SendActivitiesAsync(turnContext, activities, default);
});
var turnContext = new TurnContext(webexAdapter, activity.Object);
var resourceResponse = await webexAdapter.SendActivitiesAsync(turnContext, new Activity[] { activity.Object }, default).ConfigureAwait(false);
Assert.True(resourceResponse.Length == 0);
}
[Fact]