microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
samples/migration-bot

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/test/Microsoft.Teams.Bot.Core.UnitTests/BotApplicationTests.cs

229lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System.Net;
5using System.Text;
6using Microsoft.AspNetCore.Http;
7using Microsoft.Extensions.Configuration;
8using Microsoft.Extensions.Logging.Abstractions;
9using Microsoft.Teams.Bot.Core.Hosting;
10using Microsoft.Teams.Bot.Core.Schema;
11using Moq;
12using Moq.Protected;
13
14namespace Microsoft.Teams.Bot.Core.UnitTests;
15
16public class BotApplicationTests
17{
18 [Fact]
19 public void Constructor_InitializesProperties()
20 {
21 ConversationClient conversationClient = CreateMockConversationClient();
22 UserTokenClient userTokenClient = CreateMockUserTokenClient();
23 NullLogger<BotApplication> logger = NullLogger<BotApplication>.Instance;
24
25 BotApplication botApp = new(conversationClient, userTokenClient, logger, CreateOptions("test-app-id"));
26 Assert.NotNull(botApp);
27 Assert.NotNull(botApp.ConversationClient);
28 Assert.NotNull(botApp.UserTokenClient);
29 Assert.NotNull(botApp.UserTokenClient);
30 }
31
32
33
34 [Fact]
35 public async Task ProcessAsync_WithNullHttpContext_ThrowsArgumentNullException()
36 {
37 BotApplication botApp = CreateBotApplication();
38
39 await Assert.ThrowsAsync<ArgumentNullException>(() =>
40 botApp.ProcessAsync(null!));
41 }
42
43 [Fact]
44 public async Task ProcessAsync_WithValidActivity_ProcessesSuccessfully()
45 {
46 BotApplication botApp = CreateBotApplication();
47
48 CoreActivity activity = new()
49 {
50 Type = ActivityType.Message,
51 Id = "act123"
52 };
53 activity.Properties["text"] = "Test message";
54
55 if (activity.Recipient is not null)
56 {
57 activity.Recipient.Properties["appId"] = "test-app-id";
58 }
59
60 DefaultHttpContext httpContext = CreateHttpContextWithActivity(activity);
61
62 bool onActivityCalled = false;
63 botApp.OnActivity = (act, ct) =>
64 {
65 onActivityCalled = true;
66 return Task.CompletedTask;
67 };
68
69 await botApp.ProcessAsync(httpContext);
70
71 Assert.True(onActivityCalled);
72 }
73
74 [Fact]
75 public async Task ProcessAsync_WithMiddleware_ExecutesMiddleware()
76 {
77 BotApplication botApp = CreateBotApplication();
78
79 CoreActivity activity = new()
80 {
81 Type = ActivityType.Message,
82 Id = "act123"
83 };
84 if (activity.Recipient is not null)
85 {
86 activity.Recipient.Properties["appId"] = "test-app-id";
87 }
88
89 DefaultHttpContext httpContext = CreateHttpContextWithActivity(activity);
90
91 bool middlewareCalled = false;
92 Mock<ITurnMiddleware> mockMiddleware = new();
93 mockMiddleware
94 .Setup(m => m.OnTurnAsync(It.IsAny<BotApplication>(), It.IsAny<CoreActivity>(), It.IsAny<NextTurn>(), It.IsAny<CancellationToken>()))
95 .Callback<BotApplication, CoreActivity, NextTurn, CancellationToken>(async (app, act, next, ct) =>
96 {
97 middlewareCalled = true;
98 await next(ct);
99 })
100 .Returns(Task.CompletedTask);
101
102 botApp.UseMiddleware(mockMiddleware.Object);
103
104 bool onActivityCalled = false;
105 botApp.OnActivity = (act, ct) =>
106 {
107 onActivityCalled = true;
108 return Task.CompletedTask;
109 };
110
111 await botApp.ProcessAsync(httpContext);
112
113 Assert.True(middlewareCalled);
114 Assert.True(onActivityCalled);
115 }
116
117 [Fact]
118 public async Task ProcessAsync_WithException_ThrowsBotHandlerException()
119 {
120 BotApplication botApp = CreateBotApplication();
121
122 CoreActivity activity = new()
123 {
124 Type = ActivityType.Message,
125 Id = "act123"
126 };
127
128 if (activity.Recipient is not null)
129 {
130 activity.Recipient.Properties["appId"] = "test-app-id";
131 }
132
133 DefaultHttpContext httpContext = CreateHttpContextWithActivity(activity);
134
135 botApp.OnActivity = (act, ct) => throw new InvalidOperationException("Test exception");
136
137 BotHandlerException exception = await Assert.ThrowsAsync<BotHandlerException>(() =>
138 botApp.ProcessAsync(httpContext));
139
140 Assert.Equal("Error processing activity", exception.Message);
141 Assert.IsType<InvalidOperationException>(exception.InnerException);
142 }
143
144 [Fact]
145 public void Use_AddsMiddlewareToChain()
146 {
147 BotApplication botApp = CreateBotApplication();
148
149 Mock<ITurnMiddleware> mockMiddleware = new();
150
151 ITurnMiddleware result = botApp.UseMiddleware(mockMiddleware.Object);
152
153 Assert.NotNull(result);
154 }
155
156 [Fact]
157 public async Task SendActivityAsync_WithValidActivity_SendsSuccessfully()
158 {
159 Mock<HttpMessageHandler> mockHttpMessageHandler = new();
160 mockHttpMessageHandler
161 .Protected()
162 .Setup<Task<HttpResponseMessage>>(
163 "SendAsync",
164 ItExpr.IsAny<HttpRequestMessage>(),
165 ItExpr.IsAny<CancellationToken>())
166 .ReturnsAsync(new HttpResponseMessage
167 {
168 StatusCode = HttpStatusCode.OK,
169 Content = new StringContent("{\"id\":\"activity123\"}")
170 });
171
172 HttpClient httpClient = new(mockHttpMessageHandler.Object);
173 ConversationClient conversationClient = new(httpClient);
174 UserTokenClient userTokenClient = CreateMockUserTokenClient();
175 NullLogger<BotApplication> logger = NullLogger<BotApplication>.Instance;
176 BotApplication botApp = new(conversationClient, userTokenClient, logger);
177
178 CoreActivity activity = new()
179 {
180 Type = ActivityType.Message,
181 Conversation = new Conversation { Id = "conv123" },
182 ServiceUrl = new Uri("https://test.service.url/")
183 };
184
185 SendActivityResponse? result = await botApp.SendActivityAsync(activity);
186
187 Assert.NotNull(result);
188 Assert.Contains("activity123", result.Id);
189 }
190
191 [Fact]
192 public async Task SendActivityAsync_WithNullActivity_ThrowsArgumentNullException()
193 {
194 BotApplication botApp = CreateBotApplication();
195
196 await Assert.ThrowsAsync<ArgumentNullException>(() =>
197 botApp.SendActivityAsync(null!));
198 }
199
200 private static BotApplicationOptions CreateOptions(string appId) =>
201 new() { AppId = appId };
202
203 private static BotApplication CreateBotApplication() =>
204 new(CreateMockConversationClient(), CreateMockUserTokenClient(), NullLogger<BotApplication>.Instance);
205
206 private static ConversationClient CreateMockConversationClient()
207 {
208 Mock<HttpClient> mockHttpClient = new();
209 return new ConversationClient(mockHttpClient.Object);
210 }
211
212 private static UserTokenClient CreateMockUserTokenClient()
213 {
214 Mock<HttpClient> mockHttpClient = new();
215 NullLogger<UserTokenClient> logger = NullLogger<UserTokenClient>.Instance;
216 Mock<IConfiguration> mockConfiguration = new();
217 return new UserTokenClient(mockHttpClient.Object, mockConfiguration.Object, logger);
218 }
219
220 private static DefaultHttpContext CreateHttpContextWithActivity(CoreActivity activity)
221 {
222 DefaultHttpContext httpContext = new();
223 string activityJson = activity.ToJson();
224 byte[] bodyBytes = Encoding.UTF8.GetBytes(activityJson);
225 httpContext.Request.Body = new MemoryStream(bodyBytes);
226 httpContext.Request.ContentType = "application/json";
227 return httpContext;
228 }
229}
230