Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion libraries/Microsoft.Bot.Builder/BotFrameworkAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,8 @@ public virtual async Task CreateConversationAsync(string channelId, string servi
eventActivity.ChannelId = channelId;
eventActivity.ServiceUrl = serviceUrl;
eventActivity.Id = result.ActivityId ?? Guid.NewGuid().ToString("n");
eventActivity.Conversation = new ConversationAccount(id: result.Id);
eventActivity.Conversation = new ConversationAccount(id: result.Id, tenantId: conversationParameters.TenantId);
eventActivity.ChannelData = conversationParameters.ChannelData;
eventActivity.Recipient = conversationParameters.Bot;

using (TurnContext context = new TurnContext(this, (Activity)eventActivity))
Expand Down
98 changes: 50 additions & 48 deletions tests/Microsoft.Bot.Builder.Tests/BotFrameworkAdapterTests.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.using System.Security.Claims;

using System;
using System.Net.Http;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Logging;
using Microsoft.Rest.TransientFaultHandling;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Moq.Protected;
using Newtonsoft.Json.Linq;

namespace Microsoft.Bot.Builder.Tests
Expand Down Expand Up @@ -43,30 +43,53 @@ public async Task TenantIdShouldNotBeSetInConversationIfNotTeams()
[TestMethod]
public async Task CreateConversastionOverloadProperlySetsTenantId()
{
var mockClaims = new Mock<ClaimsIdentity>();
// Arrange
const string ActivityIdName = "ActivityId";
const string ActivityIdValue = "SendActivityId";
const string ConversationIdName = "Id";
const string ConversationIdValue = "NewConversationId";
const string TenantIdValue = "theTenantId";
const string EventActivityName = "CreateConversation";

Func<Task<HttpResponseMessage>> createResponseMessage = async () =>
{
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new StringContent(new JObject { { ActivityIdName, ActivityIdValue }, { ConversationIdName, ConversationIdValue } }.ToString());
return response;
};

var mockCredentialProvider = new Mock<ICredentialProvider>();
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.Returns((HttpRequestMessage request, CancellationToken cancellationToken) => createResponseMessage());

var sut = new MockAdapter(mockCredentialProvider.Object);
var httpClient = new HttpClient(mockHttpMessageHandler.Object);

var adapter = new BotFrameworkAdapter(mockCredentialProvider.Object, customHttpClient: httpClient);

var activity = new Activity("test")
{
ChannelId = Channels.Msteams,
ServiceUrl = "https://fake.service.url",
ChannelData = new JObject
{
["tenant"] = new JObject
{ ["id"] = TenantIdValue },
},
Conversation = new ConversationAccount
{ TenantId = TenantIdValue },
};

var activity = await ProcessActivity(Channels.Msteams, "theTenantId", null);
var parameters = new ConversationParameters()
{
Activity = new Activity()
{
ChannelData = activity.ChannelData,
},
};
var reference = new ConversationReference()
{
ActivityId = activity.Id,
Bot = activity.Recipient,
ChannelId = activity.ChannelId,
Conversation = activity.Conversation,
ServiceUrl = activity.ServiceUrl,
User = activity.From,
};

var credentials = new MicrosoftAppCredentials(string.Empty, string.Empty);
var reference = activity.GetConversationReference();
var credentials = new MicrosoftAppCredentials(string.Empty, string.Empty, httpClient);

Activity newActivity = null;

Expand All @@ -76,8 +99,15 @@ Task UpdateParameters(ITurnContext turnContext, CancellationToken cancellationTo
return Task.CompletedTask;
}

await sut.CreateConversationAsync(activity.ChannelId, activity.ServiceUrl, credentials, parameters, UpdateParameters, reference, new CancellationToken());
Assert.AreEqual("theTenantId", newActivity.ChannelData.GetType().GetProperty("TenantId").GetValue(newActivity.ChannelData, null));
// Act
await adapter.CreateConversationAsync(activity.ChannelId, activity.ServiceUrl, credentials, parameters, UpdateParameters, reference, new CancellationToken());

// Assert - all values set correctly
Assert.AreEqual(TenantIdValue, JObject.FromObject(newActivity.ChannelData)["tenant"]["tenantId"]);
Assert.AreEqual(ActivityIdValue, newActivity.Id);
Assert.AreEqual(ConversationIdValue, newActivity.Conversation.Id);
Assert.AreEqual(TenantIdValue, newActivity.Conversation.TenantId);
Assert.AreEqual(EventActivityName, newActivity.Name);
}

private static async Task<IActivity> ProcessActivity(string channelId, string channelDataTenantId, string conversationTenantId)
Expand All @@ -96,10 +126,10 @@ await sut.ProcessActivityAsync(
ChannelData = new JObject
{
["tenant"] = new JObject
{ ["id"] = channelDataTenantId },
{ ["id"] = channelDataTenantId },
},
Conversation = new ConversationAccount
{ TenantId = conversationTenantId },
{ TenantId = conversationTenantId },
},
(context, token) =>
{
Expand All @@ -109,33 +139,5 @@ await sut.ProcessActivityAsync(
CancellationToken.None);
return activity;
}

private class MockAdapter : BotFrameworkAdapter
{
private const string BotIdentityKey = "BotIdentity";

public MockAdapter(
ICredentialProvider credentialProvider,
IChannelProvider channelProvider = null,
RetryPolicy connectorClientRetryPolicy = null,
HttpClient customHttpClient = null,
IMiddleware middleware = null,
ILogger logger = null)
: base(credentialProvider, channelProvider, connectorClientRetryPolicy, customHttpClient, middleware, logger)
{
}

public async override Task CreateConversationAsync(string channelId, string serviceUrl, MicrosoftAppCredentials credentials, ConversationParameters conversationParameters, BotCallbackHandler callback, CancellationToken cancellationToken)
{
var activity = conversationParameters.Activity;
activity.ChannelData = new
{
conversationParameters.TenantId,
};
await RunPipelineAsync(new TurnContext(this, conversationParameters.Activity), callback, cancellationToken).ConfigureAwait(false);

return;
}
}
}
}