using Api.SeaHavenIndustries.Controllers; using Api.SeaHavenIndustries.DTOs; using Api.SeaHavenIndustries.Helper.ViewModel; using Data.SeaHavenIndustries; using FluentAssertions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Moq; using SeaHaven.Services.DTOs; using SeaHaven.Services.Interfaces; using Xunit; namespace Api.SeaHavenIndustries.Tests; public class SettingsControllerTests { private static SettingsController NewController(Mock service) => new(service.Object, Mock.Of>()); [Fact] public async Task GetCategoryList_ReturnsPaginationEnvelopeWithServiceItems() { var service = new Mock(); service.Setup(s => s.GetCategoryListAsync(1, 10, It.IsAny())) .ReturnsAsync((new List { new() { Id = 1, Name = "A" } }, 1)); var result = await NewController(service).GetCategoryList(1, 10, CancellationToken.None); var ok = result.Should().BeOfType().Subject; var envelope = ok.Value.Should().BeOfType().Subject; envelope.TotalCount.Should().Be(1); envelope.TotalPages.Should().Be(1); } [Fact] public async Task GetTemplates_ReturnsTypedServiceDtosInEnvelope() { var service = new Mock(); service.Setup(s => s.GetTemplatesAsync(1, 10, It.IsAny())) .ReturnsAsync((new List { new() { Id = 1, WorkerOrderTitle = "T" } }, 1)); var result = await NewController(service).GetTemplates(1, 10, CancellationToken.None); var ok = result.Should().BeOfType().Subject; var envelope = ok.Value.Should().BeOfType().Subject; envelope.TotalCount.Should().Be(1); } [Fact] public async Task AddCategory_WhenServiceSucceeds_ReturnsSaved() { var service = new Mock(); var result = await NewController(service).AddCategory(new Category_DTO { Name = "X" }, CancellationToken.None); var ok = result.Should().BeOfType().Subject; var response = ok.Value.Should().BeOfType().Subject; response.Status.Should().Be("200"); response.Message.Should().Be("Successfully Saved Data"); service.Verify(s => s.AddCategoryAsync("X", It.IsAny()), Times.Once); } [Fact] public async Task EditCategory_WhenMissing_ReturnsBadRequest() { var service = new Mock(); service.Setup(s => s.UpdateCategoryAsync(9, "X", It.IsAny())) .ReturnsAsync(false); var result = await NewController(service).EditCategory(new EditCategory_DTO { Id = 9, Name = "X" }, CancellationToken.None); var bad = result.Should().BeOfType().Subject; bad.Value.Should().BeOfType().Subject.Message.Should().Be("Category not found"); } [Fact] public async Task DeleteCategory_WhenMissing_ReturnsIdNotMatched() { var service = new Mock(); service.Setup(s => s.DeleteCategoryAsync(9, It.IsAny())) .ReturnsAsync(false); var result = await NewController(service).DeleteCategory(9, CancellationToken.None); var bad = result.Should().BeOfType().Subject; bad.Value.Should().BeOfType().Subject.Message.Should().Be("ID not matched!"); } [Fact] public async Task GetUsers_MapsServiceUsersToUserRoleViewModel() { var service = new Mock(); service.Setup(s => s.GetUsersAsync("", 1, 10, It.IsAny())) .ReturnsAsync((new List { new() { Id = "u1", UserName = "Sara", Email = "s@x.com", RoleName = "User", Status = "Active", Date = "2026-01-01" } }, 1)); var result = await NewController(service).GetUsers("", 1, 10, CancellationToken.None); var ok = result.Should().BeOfType().Subject; var envelope = ok.Value.Should().BeOfType().Subject; object data = envelope.Data!; var rows = ((System.Collections.IEnumerable)data).Cast().ToList(); rows.Should().ContainSingle(u => u.UserName == "Sara" && u.RoleName == "User" && u.Email == "s@x.com"); } [Fact] public async Task GetRoles_MapsServiceRolesToRolesDto() { var service = new Mock(); service.Setup(s => s.GetRolesAsync(It.IsAny())) .ReturnsAsync(new List { new() { Name = "Admin", Description = "Full Access" } }); var result = await NewController(service).GetRoles(CancellationToken.None); var ok = result.Should().BeOfType().Subject; var roles = ((System.Collections.IEnumerable)ok.Value!).Cast().ToList(); roles.Should().ContainSingle(r => r.Name == "Admin" && r.Description == "Full Access"); } }