using Moq; using PersonalToolBox.Models; using PersonalToolBox.Services; using PersonalToolBox.ViewModels; namespace PersonalToolBox.Tests.ViewModels; public class CategoryEditViewModelTests { private readonly Mock _dataServiceMock = new(); private readonly Mock _logServiceMock = new(); private readonly AppConfig _config; public CategoryEditViewModelTests() { _config = new AppConfig(); _dataServiceMock.Setup(d => d.Config).Returns(_config); } [Fact] public void Constructor_AddMode_SetsTitle() { var vm = new CategoryEditViewModel(_dataServiceMock.Object, _logServiceMock.Object); Assert.Equal("添加分类", vm.WindowTitle); Assert.Empty(vm.Name); } [Fact] public void Constructor_EditMode_SetsTitleAndName() { var cat = new Category { Name = "开发工具" }; var vm = new CategoryEditViewModel(_dataServiceMock.Object, _logServiceMock.Object, cat); Assert.Equal("编辑分类", vm.WindowTitle); Assert.Equal("开发工具", vm.Name); } [Fact] public void Save_EmptyName_LogsWarning() { var vm = new CategoryEditViewModel(_dataServiceMock.Object, _logServiceMock.Object); vm.SaveCommand.Execute(null); _logServiceMock.Verify(x => x.Warning(It.Is(s => s.Contains("名称不能为空"))), Times.Once); } [Fact] public void Save_AddMode_AddsCategoryAndCloses() { var vm = new CategoryEditViewModel(_dataServiceMock.Object, _logServiceMock.Object) { Name = "新分类" }; bool? closeResult = null; vm.CloseAction = (r) => closeResult = r; vm.SaveCommand.Execute(null); Assert.True(vm.Saved); Assert.True(closeResult); Assert.Single(_config.Categories); Assert.Equal("新分类", _config.Categories[0].Name); _dataServiceMock.Verify(x => x.Save(), Times.Once); } [Fact] public void Save_EditMode_UpdatesCategoryAndCloses() { var cat = new Category { Name = "旧名称" }; var vm = new CategoryEditViewModel(_dataServiceMock.Object, _logServiceMock.Object, cat) { Name = "新名称" }; bool? closeResult = null; vm.CloseAction = (r) => closeResult = r; vm.SaveCommand.Execute(null); Assert.True(vm.Saved); Assert.True(closeResult); Assert.Equal("新名称", cat.Name); _dataServiceMock.Verify(x => x.Save(), Times.Once); } [Fact] public void Cancel_ClosesWithoutSaving() { var vm = new CategoryEditViewModel(_dataServiceMock.Object, _logServiceMock.Object); bool? closeResult = null; vm.CloseAction = (r) => closeResult = r; vm.CancelCommand.Execute(null); Assert.False(vm.Saved); Assert.False(closeResult); _dataServiceMock.Verify(x => x.Save(), Times.Never); } }