From ad2ac30ad54e907935b3974342c809c281d741d4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:36:02 +0000 Subject: [PATCH 1/3] Initial plan From 1581fbd9f5bff3c904125828f7d739fbf05389e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:41:23 +0000 Subject: [PATCH 2/3] Add xUnit test project with comprehensive UsersController tests Co-authored-by: frye <98463+frye@users.noreply.github.com> --- .../Controllers/UsersControllerTests.cs | 184 ++++++++++++++++++ .../net-users-api.Tests.csproj | 27 +++ net-users-demo.sln | 70 ++++--- 3 files changed, 259 insertions(+), 22 deletions(-) create mode 100644 net-users-api.Tests/Controllers/UsersControllerTests.cs create mode 100644 net-users-api.Tests/net-users-api.Tests.csproj diff --git a/net-users-api.Tests/Controllers/UsersControllerTests.cs b/net-users-api.Tests/Controllers/UsersControllerTests.cs new file mode 100644 index 0000000..3e43765 --- /dev/null +++ b/net-users-api.Tests/Controllers/UsersControllerTests.cs @@ -0,0 +1,184 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Moq; +using NetUsersApi.Controllers; +using NetUsersApi.Models; + +namespace NetUsersApi.Tests.Controllers; + +public class UsersControllerTests +{ + private readonly Mock> _mockLogger; + private readonly UsersController _controller; + + public UsersControllerTests() + { + _mockLogger = new Mock>(); + _controller = new UsersController(_mockLogger.Object); + } + + [Fact] + public void GetUsers_ReturnsAllUsers() + { + // Arrange + // The controller uses static data, so we can just call it + + // Act + var result = _controller.GetUsers(); + + // Assert + var okResult = Assert.IsType(result.Result); + var users = Assert.IsAssignableFrom>(okResult.Value); + Assert.NotEmpty(users); + } + + [Theory] + [InlineData("1")] + [InlineData("2")] + [InlineData("3")] + public void GetUser_ValidId_ReturnsUser(string id) + { + // Act + var result = _controller.GetUser(id); + + // Assert + var okResult = Assert.IsType(result.Result); + var user = Assert.IsType(okResult.Value); + Assert.Equal(id, user.Id); + } + + [Fact] + public void GetUser_InvalidId_ReturnsNotFound() + { + // Arrange + var invalidId = "999"; + + // Act + var result = _controller.GetUser(invalidId); + + // Assert + var notFoundResult = Assert.IsType(result.Result); + Assert.NotNull(notFoundResult.Value); + } + + [Fact] + public void CreateUser_ValidUser_ReturnsCreatedAtAction() + { + // Arrange + var newUser = new UserProfile + { + Id = "100", + FullName = "Test User", + Emoji = "🧪" + }; + + // Act + var result = _controller.CreateUser(newUser); + + // Assert + var createdResult = Assert.IsType(result.Result); + var returnedUser = Assert.IsType(createdResult.Value); + Assert.Equal(newUser.Id, returnedUser.Id); + Assert.Equal(newUser.FullName, returnedUser.FullName); + Assert.Equal(newUser.Emoji, returnedUser.Emoji); + Assert.Equal(nameof(UsersController.GetUser), createdResult.ActionName); + } + + [Fact] + public void CreateUser_NullUser_ReturnsBadRequest() + { + // Act + var result = _controller.CreateUser(null!); + + // Assert + var badRequestResult = Assert.IsType(result.Result); + Assert.NotNull(badRequestResult.Value); + } + + [Fact] + public void UpdateUser_ValidUser_ReturnsUpdatedUser() + { + // Arrange + var userId = "1"; + var updatedUser = new UserProfile + { + Id = userId, + FullName = "Updated Name", + Emoji = "✨" + }; + + // Act + var result = _controller.UpdateUser(userId, updatedUser); + + // Assert + var okResult = Assert.IsType(result.Result); + var returnedUser = Assert.IsType(okResult.Value); + Assert.Equal(userId, returnedUser.Id); + Assert.Equal(updatedUser.FullName, returnedUser.FullName); + Assert.Equal(updatedUser.Emoji, returnedUser.Emoji); + } + + [Fact] + public void UpdateUser_InvalidId_ReturnsNotFound() + { + // Arrange + var invalidId = "999"; + var updatedUser = new UserProfile + { + Id = invalidId, + FullName = "Updated Name", + Emoji = "✨" + }; + + // Act + var result = _controller.UpdateUser(invalidId, updatedUser); + + // Assert + Assert.IsType(result.Result); + } + + [Fact] + public void UpdateUser_NullUser_ReturnsBadRequest() + { + // Arrange + var userId = "1"; + + // Act + var result = _controller.UpdateUser(userId, null!); + + // Assert + var badRequestResult = Assert.IsType(result.Result); + Assert.NotNull(badRequestResult.Value); + } + + [Fact] + public void UpdateUser_MismatchedId_UpdatesWithCorrectId() + { + // Arrange + var userId = "1"; + var updatedUser = new UserProfile + { + Id = "999", // Different from the route parameter + FullName = "Updated Name", + Emoji = "✨" + }; + + // Act + var result = _controller.UpdateUser(userId, updatedUser); + + // Assert + var okResult = Assert.IsType(result.Result); + var returnedUser = Assert.IsType(okResult.Value); + Assert.Equal(userId, returnedUser.Id); // Should use the route parameter ID + } + + [Fact] + public void DeleteUser_ThrowsNotImplementedException() + { + // Arrange + var userId = "1"; + + // Act & Assert + Assert.Throws(() => _controller.DeleteUser(userId)); + } +} diff --git a/net-users-api.Tests/net-users-api.Tests.csproj b/net-users-api.Tests/net-users-api.Tests.csproj new file mode 100644 index 0000000..d0f0629 --- /dev/null +++ b/net-users-api.Tests/net-users-api.Tests.csproj @@ -0,0 +1,27 @@ + + + + net9.0 + NetUsersApi.Tests + enable + enable + false + + + + + + + + + + + + + + + + + + + diff --git a/net-users-demo.sln b/net-users-demo.sln index e9bb8f5..a8d1496 100644 --- a/net-users-demo.sln +++ b/net-users-demo.sln @@ -1,22 +1,48 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "net-users-api", "net-users-api\net-users-api.csproj", "{F2C0F837-02EA-42E5-BDC0-48C31DD4245D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "net-users-api", "net-users-api\net-users-api.csproj", "{F2C0F837-02EA-42E5-BDC0-48C31DD4245D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "net-users-api.Tests", "net-users-api.Tests\net-users-api.Tests.csproj", "{4F388C16-F623-435E-904F-00E0C80D9F87}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|x64.ActiveCfg = Debug|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|x64.Build.0 = Debug|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|x86.ActiveCfg = Debug|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|x86.Build.0 = Debug|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|Any CPU.Build.0 = Release|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|x64.ActiveCfg = Release|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|x64.Build.0 = Release|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|x86.ActiveCfg = Release|Any CPU + {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|x86.Build.0 = Release|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Debug|x64.ActiveCfg = Debug|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Debug|x64.Build.0 = Debug|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Debug|x86.ActiveCfg = Debug|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Debug|x86.Build.0 = Debug|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Release|Any CPU.Build.0 = Release|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Release|x64.ActiveCfg = Release|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Release|x64.Build.0 = Release|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Release|x86.ActiveCfg = Release|Any CPU + {4F388C16-F623-435E-904F-00E0C80D9F87}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal From 1c7cebcd0371f507f3247fc4cb11669ed38936ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:43:12 +0000 Subject: [PATCH 3/3] Address code review feedback: improve null handling in tests Co-authored-by: frye <98463+frye@users.noreply.github.com> --- net-users-api.Tests/Controllers/UsersControllerTests.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net-users-api.Tests/Controllers/UsersControllerTests.cs b/net-users-api.Tests/Controllers/UsersControllerTests.cs index 3e43765..d0dc7a5 100644 --- a/net-users-api.Tests/Controllers/UsersControllerTests.cs +++ b/net-users-api.Tests/Controllers/UsersControllerTests.cs @@ -87,8 +87,11 @@ public void CreateUser_ValidUser_ReturnsCreatedAtAction() [Fact] public void CreateUser_NullUser_ReturnsBadRequest() { + // Arrange + UserProfile? nullUser = null; + // Act - var result = _controller.CreateUser(null!); + var result = _controller.CreateUser(nullUser!); // Assert var badRequestResult = Assert.IsType(result.Result); @@ -142,9 +145,10 @@ public void UpdateUser_NullUser_ReturnsBadRequest() { // Arrange var userId = "1"; + UserProfile? nullUser = null; // Act - var result = _controller.UpdateUser(userId, null!); + var result = _controller.UpdateUser(userId, nullUser!); // Assert var badRequestResult = Assert.IsType(result.Result);