diff --git a/net-users-api.Tests/Controllers/UsersControllerTests.cs b/net-users-api.Tests/Controllers/UsersControllerTests.cs new file mode 100644 index 0000000..d0dc7a5 --- /dev/null +++ b/net-users-api.Tests/Controllers/UsersControllerTests.cs @@ -0,0 +1,188 @@ +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() + { + // Arrange + UserProfile? nullUser = null; + + // Act + var result = _controller.CreateUser(nullUser!); + + // 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"; + UserProfile? nullUser = null; + + // Act + var result = _controller.UpdateUser(userId, nullUser!); + + // 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