microsoft/teams.net

Public

mirrored from https://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feature/user-agent-header

Branches

Tags

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

Clone

HTTPS

Download ZIP

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

234lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System.Text;
5using Microsoft.AspNetCore.Http;
6using Microsoft.Teams.Bot.Core.Schema;
7using Microsoft.Extensions.Configuration;
8using Microsoft.Extensions.Logging.Abstractions;
9using Moq;
10
11namespace Microsoft.Teams.Bot.Core.UnitTests;
12
13public class MiddlewareTests
14{
15 [Fact]
16 public async Task BotApplication_Use_AddsMiddlewareToChain()
17 {
18 ConversationClient conversationClient = CreateMockConversationClient();
19 UserTokenClient userTokenClient = CreateMockUserTokenClient();
20 Mock<IConfiguration> mockConfig = new();
21 NullLogger<BotApplication> logger = NullLogger<BotApplication>.Instance;
22 BotApplication botApp = new(conversationClient, userTokenClient, mockConfig.Object, logger);
23
24 Mock<ITurnMiddleWare> mockMiddleware = new();
25
26 ITurnMiddleWare result = botApp.Use(mockMiddleware.Object);
27
28 Assert.NotNull(result);
29 }
30
31
32 [Fact]
33 public async Task Middleware_ExecutesInOrder()
34 {
35 ConversationClient conversationClient = CreateMockConversationClient();
36 UserTokenClient userTokenClient = CreateMockUserTokenClient();
37 Mock<IConfiguration> mockConfig = new();
38 NullLogger<BotApplication> logger = NullLogger<BotApplication>.Instance;
39 BotApplication botApp = new(conversationClient, userTokenClient, mockConfig.Object, logger);
40
41 List<int> executionOrder = [];
42
43 Mock<ITurnMiddleWare> mockMiddleware1 = new();
44 mockMiddleware1
45 .Setup(m => m.OnTurnAsync(It.IsAny<BotApplication>(), It.IsAny<CoreActivity>(), It.IsAny<NextTurn>(), It.IsAny<CancellationToken>()))
46 .Callback<BotApplication, CoreActivity, NextTurn, CancellationToken>(async (app, act, next, ct) =>
47 {
48 executionOrder.Add(1);
49 await next(ct);
50 })
51 .Returns(Task.CompletedTask);
52
53 Mock<ITurnMiddleWare> mockMiddleware2 = new();
54 mockMiddleware2
55 .Setup(m => m.OnTurnAsync(It.IsAny<BotApplication>(), It.IsAny<CoreActivity>(), It.IsAny<NextTurn>(), It.IsAny<CancellationToken>()))
56 .Callback<BotApplication, CoreActivity, NextTurn, CancellationToken>(async (app, act, next, ct) =>
57 {
58 executionOrder.Add(2);
59 await next(ct);
60 })
61 .Returns(Task.CompletedTask);
62
63 botApp.Use(mockMiddleware1.Object);
64 botApp.Use(mockMiddleware2.Object);
65
66 CoreActivity activity = new()
67 {
68 Type = ActivityType.Message,
69 Id = "act123"
70 };
71 activity.Recipient.Properties["appId"] = "test-app-id";
72
73 DefaultHttpContext httpContext = CreateHttpContextWithActivity(activity);
74
75 botApp.OnActivity = (act, ct) =>
76 {
77 executionOrder.Add(3);
78 return Task.CompletedTask;
79 };
80
81 await botApp.ProcessAsync(httpContext);
82 int[] expected = [1, 2, 3];
83 Assert.Equal(expected, executionOrder);
84 }
85
86 [Fact]
87 public async Task Middleware_CanShortCircuit()
88 {
89 ConversationClient conversationClient = CreateMockConversationClient();
90 UserTokenClient userTokenClient = CreateMockUserTokenClient();
91 Mock<IConfiguration> mockConfig = new();
92 NullLogger<BotApplication> logger = NullLogger<BotApplication>.Instance;
93 BotApplication botApp = new(conversationClient, userTokenClient, mockConfig.Object, logger);
94
95 bool secondMiddlewareCalled = false;
96 bool onActivityCalled = false;
97
98 Mock<ITurnMiddleWare> mockMiddleware1 = new();
99 mockMiddleware1
100 .Setup(m => m.OnTurnAsync(It.IsAny<BotApplication>(), It.IsAny<CoreActivity>(), It.IsAny<NextTurn>(), It.IsAny<CancellationToken>()))
101 .Returns(Task.CompletedTask); // Don't call next
102
103 Mock<ITurnMiddleWare> mockMiddleware2 = new();
104 mockMiddleware2
105 .Setup(m => m.OnTurnAsync(It.IsAny<BotApplication>(), It.IsAny<CoreActivity>(), It.IsAny<NextTurn>(), It.IsAny<CancellationToken>()))
106 .Callback(() => secondMiddlewareCalled = true)
107 .Returns(Task.CompletedTask);
108
109 botApp.Use(mockMiddleware1.Object);
110 botApp.Use(mockMiddleware2.Object);
111
112 CoreActivity activity = new()
113 {
114 Type = ActivityType.Message,
115 Id = "act123"
116 };
117 activity.Recipient.Properties["appId"] = "test-app-id";
118
119 DefaultHttpContext httpContext = CreateHttpContextWithActivity(activity);
120
121 botApp.OnActivity = (act, ct) =>
122 {
123 onActivityCalled = true;
124 return Task.CompletedTask;
125 };
126
127 await botApp.ProcessAsync(httpContext);
128
129 Assert.False(secondMiddlewareCalled);
130 Assert.False(onActivityCalled);
131 }
132
133 [Fact]
134 public async Task Middleware_ReceivesCancellationToken()
135 {
136 ConversationClient conversationClient = CreateMockConversationClient();
137 UserTokenClient userTokenClient = CreateMockUserTokenClient();
138 Mock<IConfiguration> mockConfig = new();
139 NullLogger<BotApplication> logger = NullLogger<BotApplication>.Instance;
140 BotApplication botApp = new(conversationClient, userTokenClient, mockConfig.Object, logger);
141
142 CancellationToken receivedToken = default;
143
144 Mock<ITurnMiddleWare> mockMiddleware = new();
145 mockMiddleware
146 .Setup(m => m.OnTurnAsync(It.IsAny<BotApplication>(), It.IsAny<CoreActivity>(), It.IsAny<NextTurn>(), It.IsAny<CancellationToken>()))
147 .Callback<BotApplication, CoreActivity, NextTurn, CancellationToken>(async (app, act, next, ct) =>
148 {
149 receivedToken = ct;
150 await next(ct);
151 })
152 .Returns(Task.CompletedTask);
153
154 botApp.Use(mockMiddleware.Object);
155
156 CoreActivity activity = new()
157 {
158 Type = ActivityType.Message,
159 Id = "act123"
160 };
161 activity.Recipient.Properties["appId"] = "test-app-id";
162
163 DefaultHttpContext httpContext = CreateHttpContextWithActivity(activity);
164
165 CancellationTokenSource cts = new();
166
167 await botApp.ProcessAsync(httpContext, cts.Token);
168
169 Assert.Equal(cts.Token, receivedToken);
170 }
171
172 [Fact]
173 public async Task Middleware_ReceivesActivity()
174 {
175 ConversationClient conversationClient = CreateMockConversationClient();
176
177 Mock<IConfiguration> mockConfig = new();
178 UserTokenClient userTokenClient = CreateMockUserTokenClient();
179 NullLogger<BotApplication> logger = NullLogger<BotApplication>.Instance;
180 BotApplication botApp = new(conversationClient, userTokenClient, mockConfig.Object, logger);
181
182 CoreActivity? receivedActivity = null;
183
184 Mock<ITurnMiddleWare> mockMiddleware = new();
185 mockMiddleware
186 .Setup(m => m.OnTurnAsync(It.IsAny<BotApplication>(), It.IsAny<CoreActivity>(), It.IsAny<NextTurn>(), It.IsAny<CancellationToken>()))
187 .Callback<BotApplication, CoreActivity, NextTurn, CancellationToken>(async (app, act, next, ct) =>
188 {
189 receivedActivity = act;
190 await next(ct);
191 })
192 .Returns(Task.CompletedTask);
193
194 botApp.Use(mockMiddleware.Object);
195
196 CoreActivity activity = new()
197 {
198 Type = ActivityType.Message,
199 Id = "act123"
200 };
201 activity.Recipient.Properties["appId"] = "test-app-id";
202
203 DefaultHttpContext httpContext = CreateHttpContextWithActivity(activity);
204
205 await botApp.ProcessAsync(httpContext);
206
207 Assert.NotNull(receivedActivity);
208 Assert.Equal(ActivityType.Message, receivedActivity.Type);
209 }
210
211 private static ConversationClient CreateMockConversationClient()
212 {
213 Mock<HttpClient> mockHttpClient = new();
214 return new ConversationClient(mockHttpClient.Object);
215 }
216
217 private static UserTokenClient CreateMockUserTokenClient()
218 {
219 Mock<HttpClient> mockHttpClient = new();
220 Mock<IConfiguration> mockConfig = new();
221 NullLogger<UserTokenClient> logger = NullLogger<UserTokenClient>.Instance;
222 return new UserTokenClient(mockHttpClient.Object, mockConfig.Object, logger);
223 }
224
225 private static DefaultHttpContext CreateHttpContextWithActivity(CoreActivity activity)
226 {
227 DefaultHttpContext httpContext = new();
228 string activityJson = activity.ToJson();
229 byte[] bodyBytes = Encoding.UTF8.GetBytes(activityJson);
230 httpContext.Request.Body = new MemoryStream(bodyBytes);
231 httpContext.Request.ContentType = "application/json";
232 return httpContext;
233 }
234}
235