Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
/k:"rrusson_DarkClippy" \
/o:"rrusson" \
/d:sonar.host.url="https://sonarcloud.io" \
/d:sonar.token="${{ SONAR_TOKEN }}" \
/d:sonar.token="${SONAR_TOKEN}" \
/d:sonar.cs.opencover.reportsPaths="**/TestResults/**/coverage.opencover.xml"

- name: Restore
Expand Down
80 changes: 80 additions & 0 deletions ClippyWeb.Tests/ChatClientFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using Microsoft.Extensions.Caching.Memory;

using SemanticKernelHelper;

using SharedInterfaces;

namespace ClippyWeb.Tests
{
[TestClass]
public class ChatClientFactoryTests
{
private const string TestApiUrl = "http://localhost:11434/v1";
private const string TestModel = "test-model";
private const string TestApiKey = "test-api-key";
private IMemoryCache _cache = null!;

[TestInitialize]
public void TestInitialize()
{
_cache = new MemoryCache(new MemoryCacheOptions());
}

[TestCleanup]
public void TestCleanup()
{
_cache?.Dispose();
}

[TestMethod]
public void IfSessionKeyIsProvidedThenClientIsReturned()
{
var factory = new ChatClientFactory(TestApiUrl, TestModel, TestApiKey, _cache);

var client = factory.GetOrCreateClient("test-session");

Assert.IsNotNull(client);
}

[TestMethod]
public void IfSameSessionKeyIsUsedThenSameClientIsReturned()
{
var factory = new ChatClientFactory(TestApiUrl, TestModel, TestApiKey, _cache);

var client1 = factory.GetOrCreateClient("test-session");
var client2 = factory.GetOrCreateClient("test-session");

Assert.AreSame(client1, client2);
}

[TestMethod]
public void IfDifferentSessionKeysAreUsedThenDifferentClientsAreReturned()
{
var factory = new ChatClientFactory(TestApiUrl, TestModel, TestApiKey, _cache);

var client1 = factory.GetOrCreateClient("session-1");
var client2 = factory.GetOrCreateClient("session-2");

Assert.AreNotSame(client1, client2);
}

[TestMethod]
public void IfMultipleSessionsAreConcurrentThenFactoryIsThreadSafe()
{
var factory = new ChatClientFactory(TestApiUrl, TestModel, TestApiKey, _cache);
var clients = new List<IChatClient>();
var lockObj = new object();

Parallel.For(0, 10, i =>
{
var client = factory.GetOrCreateClient($"session-{i % 3}");
lock (lockObj)
{
clients.Add(client);
}
});

Assert.AreEqual(10, clients.Count);
}
}
}
6 changes: 1 addition & 5 deletions ClippyWeb.Tests/ClippyWeb.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,8 @@

<ItemGroup>
<ProjectReference Include="..\ClippyWeb\ClippyWeb.csproj" />
<ProjectReference Include="..\SemanticKernelHelper\SemanticKernelHelper.csproj" />
<ProjectReference Include="..\SharedInterfaces\SharedInterfaces.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Util\" />
<Folder Include="Pages\" />
</ItemGroup>

</Project>
13 changes: 9 additions & 4 deletions ClippyWeb.Tests/Controllers/ChatControllerTests.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.Net;
using System.Net.Sockets;

using ClippyWeb.Controllers;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using System.Net;
using System.Net.Sockets;

using ClippyWeb.Controllers;
using SharedInterfaces;

namespace ClippyWeb.Tests.Controllers
Expand All @@ -17,6 +19,7 @@ namespace ClippyWeb.Tests.Controllers
public class ChatControllerTests
{
private Mock<IChatClient> _mockChatClient = null!;
private Mock<IChatClientFactory> _mockChatClientFactory = null!;
private IMemoryCache _memoryCache = null!;
private Mock<IConfiguration> _mockConfiguration = null!;
private ChatController _sut = null!;
Expand All @@ -25,10 +28,12 @@ public class ChatControllerTests
public void TestInitialize()
{
_mockChatClient = new Mock<IChatClient>();
_mockChatClientFactory = new Mock<IChatClientFactory>();
_mockChatClientFactory.Setup(f => f.GetOrCreateClient(It.IsAny<string>())).Returns(_mockChatClient.Object);
_memoryCache = new MemoryCache(new MemoryCacheOptions());
_mockConfiguration = new Mock<IConfiguration>();

_sut = new ChatController(_mockChatClient.Object, _memoryCache, _mockConfiguration.Object);
_sut = new ChatController(_mockChatClientFactory.Object, _memoryCache, _mockConfiguration.Object);
SetupHttpContext();
}

Expand Down
1 change: 1 addition & 0 deletions ClippyWeb.Tests/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
global using Microsoft.VisualStudio.TestTools.UnitTesting;

global using Moq;
9 changes: 4 additions & 5 deletions ClippyWeb.Tests/Pages/ErrorModelTests.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;

using System.Diagnostics;

using ClippyWeb.Pages;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;

namespace ClippyWeb.Tests.Pages
{
/// <summary>
Expand Down
94 changes: 94 additions & 0 deletions ClippyWeb.Tests/SemanticKernelClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using SemanticKernelHelper;

namespace ClippyWeb.Tests
{
[TestClass]
public class SemanticKernelClientTests
{
private const string TestApiUrl = "http://localhost:11434/v1";
private const string TestModel = "test-model";
private const string TestApiKey = "test-api-key";

[TestMethod]
public void IfApiKeyIsProvidedThenClientIsCreated()
{
var client = new SemanticKernelClient(TestApiUrl, TestModel, TestApiKey);

Assert.IsNotNull(client);
}

[TestMethod]
public void IfApiKeyIsNullThenClientIsCreatedWithEmptyKey()
{
var client = new SemanticKernelClient(TestApiUrl, TestModel, null);

Assert.IsNotNull(client);
}

[TestMethod]
public void IfApiKeyIsNotProvidedThenClientIsCreatedWithEmptyKey()
{
var client = new SemanticKernelClient(TestApiUrl, TestModel);

Assert.IsNotNull(client);
}
Comment thread
rrusson marked this conversation as resolved.

[TestMethod]
public async Task IfEmptyMessageThenReturnsDefaultResponse()
{
var client = new SemanticKernelClient(TestApiUrl, TestModel, TestApiKey);

var response = await client.GetChatResponseAsync("");

Assert.AreEqual("You say something?", response);
}

[TestMethod]
public async Task IfWhitespaceMessageThenReturnsDefaultResponse()
{
var client = new SemanticKernelClient(TestApiUrl, TestModel, TestApiKey);

var response = await client.GetChatResponseAsync(" ");

Assert.AreEqual("You say something?", response);
}

[TestMethod]
public async Task IfNullMessageThenReturnsDefaultResponse()
{
var client = new SemanticKernelClient(TestApiUrl, TestModel, TestApiKey);

var response = await client.GetChatResponseAsync(null!);

Assert.AreEqual("You say something?", response);
}

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void IfApiUrlIsNullThenThrowsArgumentNullException()
{
_ = new SemanticKernelClient(null!, TestModel, TestApiKey);
}

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void IfModelIsNullThenThrowsArgumentNullException()
{
_ = new SemanticKernelClient(TestApiUrl, null!, TestApiKey);
}

[TestMethod]
[ExpectedException(typeof(UriFormatException))]
public void IfApiUrlIsInvalidThenThrowsUriFormatException()
{
_ = new SemanticKernelClient("not-a-valid-url", TestModel, TestApiKey);
}

[TestMethod]
[ExpectedException(typeof(UriFormatException))]
public void IfApiUrlIsNotHttpOrHttpsThenThrowsUriFormatException()
{
_ = new SemanticKernelClient("ftp://localhost:11434", TestModel, TestApiKey);
}
}
}
Comment thread
rrusson marked this conversation as resolved.
3 changes: 0 additions & 3 deletions ClippyWeb.Tests/Util/ConnectionValidatorTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System.Net;
using System.Net.Sockets;

using ClippyWeb.Util;

using Microsoft.Extensions.Configuration;
Expand Down
23 changes: 23 additions & 0 deletions ClippyWeb.Tests/Util/TcpClientFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace ClippyWeb.Util.UnitTests
{
/// <summary>
/// Unit tests for the <see cref="ClippyWeb.Util.TcpClientFactory"/> class.
/// </summary>
[TestClass]
public class TcpClientFactoryTests
{
/// <summary>
/// Tests that the Dispose method calls Dispose(bool) with true parameter.
/// </summary>
[TestMethod]
public void CreateWorks()
{
// Act
var result = new TcpClientFactory().Create();

// Assert
Assert.IsNotNull(result);
Assert.IsInstanceOfType(result, typeof(TcpClientWrapper));
}
}
}
Loading
Loading