Skip to content

Commit 0227436

Browse files
Add additional tests for all client methods
Co-authored-by: christiannagel <1908285+christiannagel@users.noreply.github.com>
1 parent 31773d4 commit 0227436

1 file changed

Lines changed: 275 additions & 2 deletions

File tree

src/clients/Codebreaker.GameAPIs.Client.Tests/GamesClientTests.cs

Lines changed: 275 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
using Codebreaker.GameAPIs.Client.Models;
22
using System.Diagnostics;
3+
using System.Text;
34

45
namespace Codebreaker.GameAPIs.Client.Tests;
56

67
public class GamesClientTests
78
{
9+
private readonly ITestOutputHelper? _testOutputHelper;
10+
11+
public GamesClientTests(ITestOutputHelper? testOutputHelper = null)
12+
{
13+
_testOutputHelper = testOutputHelper;
14+
}
15+
816
[Fact]
917
public async Task StartGameAsync_Should_ReturnResults()
1018
{
@@ -94,6 +102,146 @@ public async Task GetGamesAsync_Should_ReturnResults()
94102
Assert.Equal(2, games.Count());
95103
}
96104

105+
[Fact]
106+
public async Task SetMoveAsync_Should_ReturnResults()
107+
{
108+
// Arrange
109+
(var httpClient, var handlerMock) = GetHttpClientReturningSetMoveSkeleton();
110+
111+
GamesClient gamesClient = new(httpClient, NullLogger<GamesClient>.Instance);
112+
113+
// Act
114+
var gameId = Guid.Parse("91f3c729-5e6e-459a-b656-2d77f3f45dd9");
115+
var (Results, Ended, IsVictory) = await gamesClient.SetMoveAsync(
116+
gameId,
117+
"test",
118+
GameType.Game6x4,
119+
1,
120+
new[] { "Red", "Green", "Blue", "Yellow" });
121+
122+
// Assert
123+
Assert.Equal(2, Results.Length);
124+
Assert.Equal("White", Results[0]);
125+
Assert.Equal("White", Results[1]);
126+
Assert.False(Ended);
127+
Assert.False(IsVictory);
128+
129+
handlerMock.Protected().Verify(
130+
"SendAsync",
131+
Times.Once(),
132+
ItExpr.IsAny<HttpRequestMessage>(),
133+
ItExpr.IsAny<CancellationToken>());
134+
}
135+
136+
[Fact]
137+
public async Task GetGameAsync_Should_ReturnResults()
138+
{
139+
// Arrange
140+
(var httpClient, var handlerMock) = GetHttpClientReturningGameSkeleton();
141+
142+
GamesClient gamesClient = new(httpClient, NullLogger<GamesClient>.Instance);
143+
144+
// Act
145+
var gameId = Guid.Parse("91f3c729-5e6e-459a-b656-2d77f3f45dd9");
146+
var game = await gamesClient.GetGameAsync(gameId);
147+
148+
// Assert
149+
Assert.NotNull(game);
150+
Assert.Equal(gameId, game.Id);
151+
Assert.Equal("Game6x4", game.GameType.ToString());
152+
Assert.Equal("test", game.PlayerName);
153+
Assert.Equal(1, game.LastMoveNumber);
154+
Assert.Equal(4, game.NumberCodes);
155+
Assert.Equal(12, game.MaxMoves);
156+
Assert.False(game.IsVictory);
157+
158+
handlerMock.Protected().Verify(
159+
"SendAsync",
160+
Times.Once(),
161+
ItExpr.IsAny<HttpRequestMessage>(),
162+
ItExpr.IsAny<CancellationToken>());
163+
}
164+
165+
[Fact]
166+
public async Task CancelGameAsync_Should_CallApi()
167+
{
168+
// Arrange
169+
(var httpClient, var handlerMock) = GetHttpClientForCancelGame();
170+
171+
GamesClient gamesClient = new(httpClient, NullLogger<GamesClient>.Instance);
172+
173+
// Act
174+
var gameId = Guid.Parse("91f3c729-5e6e-459a-b656-2d77f3f45dd9");
175+
await gamesClient.CancelGameAsync(gameId, "test", GameType.Game6x4);
176+
177+
// Assert
178+
handlerMock.Protected().Verify(
179+
"SendAsync",
180+
Times.Once(),
181+
ItExpr.IsAny<HttpRequestMessage>(),
182+
ItExpr.IsAny<CancellationToken>());
183+
}
184+
185+
[Fact]
186+
public async Task CancelGameAsync_Should_TrackActivity()
187+
{
188+
// Arrange
189+
(var httpClient, var handlerMock) = GetHttpClientForCancelGame();
190+
bool startActivityReceived = false;
191+
bool stopActivityReceived = false;
192+
193+
using ActivityListener listener = new()
194+
{
195+
ShouldListenTo = _ => true,
196+
ActivityStarted = activity =>
197+
{
198+
if (activity.OperationName == "CancelGameAsync")
199+
{
200+
startActivityReceived = true;
201+
Assert.Equal(ActivityKind.Client, activity.Kind);
202+
}
203+
},
204+
ActivityStopped = activity =>
205+
{
206+
if (activity.OperationName == "CancelGameAsync")
207+
{
208+
stopActivityReceived = true;
209+
ActivityEvent? gameCanceledEvent = activity.Events.FirstOrDefault(e => e.Name == "GameCanceled");
210+
211+
// Check if the event exists
212+
if (gameCanceledEvent != null)
213+
{
214+
// Check if there are any tags
215+
var tags = gameCanceledEvent.Value.Tags;
216+
foreach (var tag in tags)
217+
{
218+
if (tag.Key == "gameId")
219+
{
220+
// We found the gameId tag
221+
Assert.NotNull(tag.Value);
222+
}
223+
}
224+
}
225+
226+
Assert.Equal(ActivityKind.Client, activity.Kind);
227+
}
228+
},
229+
Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllData
230+
};
231+
232+
ActivitySource.AddActivityListener(listener);
233+
234+
GamesClient gamesClient = new(httpClient, NullLogger<GamesClient>.Instance);
235+
236+
// Act
237+
var gameId = Guid.Parse("91f3c729-5e6e-459a-b656-2d77f3f45dd9");
238+
await gamesClient.CancelGameAsync(gameId, "test", GameType.Game6x4);
239+
240+
// Assert
241+
Assert.True(startActivityReceived);
242+
Assert.True(stopActivityReceived);
243+
}
244+
97245
private static (HttpClient Client, Mock<HttpMessageHandler> Handler) GetHttpClientReturningACreatedGameSkeleton()
98246
{
99247
Mock<IConfiguration> configMock = new();
@@ -127,7 +275,7 @@ private static (HttpClient Client, Mock<HttpMessageHandler> Handler) GetHttpClie
127275
.ReturnsAsync(new HttpResponseMessage
128276
{
129277
StatusCode = HttpStatusCode.OK,
130-
Content = new StringContent(returnMessage)
278+
Content = new StringContent(returnMessage, Encoding.UTF8, "application/json")
131279
}).Verifiable();
132280

133281
return (new(handlerMock.Object)
@@ -289,7 +437,132 @@ private static (HttpClient Client, Mock<HttpMessageHandler> Handler) GetHttpClie
289437
.ReturnsAsync(new HttpResponseMessage
290438
{
291439
StatusCode = HttpStatusCode.OK,
292-
Content = new StringContent(returnMessage)
440+
Content = new StringContent(returnMessage, Encoding.UTF8, "application/json")
441+
}).Verifiable();
442+
443+
return (new(handlerMock.Object)
444+
{
445+
BaseAddress = new Uri(configMock.Object["GameAPIs"] ?? throw new InvalidOperationException())
446+
}, handlerMock);
447+
}
448+
449+
private static (HttpClient Client, Mock<HttpMessageHandler> Handler) GetHttpClientReturningSetMoveSkeleton()
450+
{
451+
Mock<IConfiguration> configMock = new();
452+
configMock.Setup(x => x[It.IsAny<string>()]).Returns("http://localhost:5000");
453+
454+
Mock<HttpMessageHandler> handlerMock = new(MockBehavior.Strict);
455+
string returnMessage = """
456+
{
457+
"id": "91f3c729-5e6e-459a-b656-2d77f3f45dd9",
458+
"gameType": "Game6x4",
459+
"moveNumber": 1,
460+
"ended": false,
461+
"isVictory": false,
462+
"results": ["White", "White"]
463+
}
464+
""";
465+
handlerMock.Protected()
466+
.Setup<Task<HttpResponseMessage>>(
467+
"SendAsync",
468+
ItExpr.IsAny<HttpRequestMessage>(),
469+
ItExpr.IsAny<CancellationToken>())
470+
.ReturnsAsync(new HttpResponseMessage
471+
{
472+
StatusCode = HttpStatusCode.OK,
473+
Content = new StringContent(returnMessage, Encoding.UTF8, "application/json")
474+
}).Verifiable();
475+
476+
return (new(handlerMock.Object)
477+
{
478+
BaseAddress = new Uri(configMock.Object["GameAPIs"] ?? throw new InvalidOperationException())
479+
}, handlerMock);
480+
}
481+
482+
private static (HttpClient Client, Mock<HttpMessageHandler> Handler) GetHttpClientReturningGameSkeleton()
483+
{
484+
Mock<IConfiguration> configMock = new();
485+
configMock.Setup(x => x[It.IsAny<string>()]).Returns("http://localhost:5000");
486+
487+
Mock<HttpMessageHandler> handlerMock = new(MockBehavior.Strict);
488+
string returnMessage = """
489+
{
490+
"id": "91f3c729-5e6e-459a-b656-2d77f3f45dd9",
491+
"gameType": "Game6x4",
492+
"playerName": "test",
493+
"playerIsAuthenticated": false,
494+
"startTime": "2024-02-14T18:14:49.4420411Z",
495+
"endTime": null,
496+
"duration": null,
497+
"lastMoveNumber": 1,
498+
"numberCodes": 4,
499+
"maxMoves": 12,
500+
"isVictory": false,
501+
"fieldValues": {
502+
"colors": [
503+
"Red",
504+
"Green",
505+
"Blue",
506+
"Yellow",
507+
"Purple",
508+
"Orange"
509+
]
510+
},
511+
"codes": [
512+
"Yellow",
513+
"Yellow",
514+
"Green",
515+
"Green"
516+
],
517+
"moves": [
518+
{
519+
"id": "963baba8-44b8-45e5-81f3-193959ae5bf6",
520+
"moveNumber": 1,
521+
"guessPegs": [
522+
"Red",
523+
"Green",
524+
"Blue",
525+
"Yellow"
526+
],
527+
"keyPegs": [
528+
"White",
529+
"White"
530+
]
531+
}
532+
]
533+
}
534+
""";
535+
handlerMock.Protected()
536+
.Setup<Task<HttpResponseMessage>>(
537+
"SendAsync",
538+
ItExpr.IsAny<HttpRequestMessage>(),
539+
ItExpr.IsAny<CancellationToken>())
540+
.ReturnsAsync(new HttpResponseMessage
541+
{
542+
StatusCode = HttpStatusCode.OK,
543+
Content = new StringContent(returnMessage, Encoding.UTF8, "application/json")
544+
}).Verifiable();
545+
546+
return (new(handlerMock.Object)
547+
{
548+
BaseAddress = new Uri(configMock.Object["GameAPIs"] ?? throw new InvalidOperationException())
549+
}, handlerMock);
550+
}
551+
552+
private static (HttpClient Client, Mock<HttpMessageHandler> Handler) GetHttpClientForCancelGame()
553+
{
554+
Mock<IConfiguration> configMock = new();
555+
configMock.Setup(x => x[It.IsAny<string>()]).Returns("http://localhost:5000");
556+
557+
Mock<HttpMessageHandler> handlerMock = new(MockBehavior.Strict);
558+
handlerMock.Protected()
559+
.Setup<Task<HttpResponseMessage>>(
560+
"SendAsync",
561+
ItExpr.IsAny<HttpRequestMessage>(),
562+
ItExpr.IsAny<CancellationToken>())
563+
.ReturnsAsync(new HttpResponseMessage
564+
{
565+
StatusCode = HttpStatusCode.OK
293566
}).Verifiable();
294567

295568
return (new(handlerMock.Object)

0 commit comments

Comments
 (0)