using System; using NUnit.Framework; using Moq; using FanucProgramManager.Cnc; using FanucProgramManager.Cnc.Models; using FanucProgramManager.Cnc.Siemens; namespace FanucProgramManager.Tests.Unit { [TestFixture] public class SiemensMachineTests { private SiemensConnectionConfig _config; private Mock _ftpMock; private Mock _validatorMock; private SiemensMachine _machine; [SetUp] public void SetUp() { _config = new SiemensConnectionConfig { Name = "TestSiemens", IpAddress = "192.168.1.2", Port = 21, ProgramDirectory = "/_N_MPF_DIR/" }; _ftpMock = new Mock(MockBehavior.Strict); // Always-ok validator so existing write tests are not affected by validation rules _validatorMock = new Mock(); _validatorMock.Setup(v => v.Validate(It.IsAny(), It.IsAny())) .Returns(ValidationResult.Ok()); _machine = new SiemensMachine(_config, _ftpMock.Object, _validatorMock.Object); } [TearDown] public void TearDown() { _machine?.Dispose(); } // ConnectAsync [Test] public void ConnectAsync_PingTrue_StateConnectedAndResultOk() { _ftpMock.Setup(f => f.Ping()).Returns(true); var result = _machine.ConnectAsync().GetAwaiter().GetResult(); Assert.That(result.Success, Is.True); Assert.That(result.Value, Is.True); Assert.That(_machine.State, Is.EqualTo(ConnectionState.Connected)); } [Test] public void ConnectAsync_PingFalse_StateFaultedAndResultFail() { _ftpMock.Setup(f => f.Ping()).Returns(false); var result = _machine.ConnectAsync().GetAwaiter().GetResult(); Assert.That(result.Success, Is.False); Assert.That(_machine.State, Is.EqualTo(ConnectionState.Faulted)); } // ReadProgramAsync [Test] public void ReadProgramAsync_FullPath_CallsDownloadFileWithPath() { _ftpMock.Setup(f => f.Ping()).Returns(true); _ftpMock.Setup(f => f.DownloadFile("/_N_MPF_DIR/O1234.MPF")).Returns("PROGRAM_CONTENT"); _machine.ConnectAsync().GetAwaiter().GetResult(); var result = _machine.ReadProgramAsync("/_N_MPF_DIR/O1234.MPF").GetAwaiter().GetResult(); Assert.That(result.Success, Is.True); Assert.That(result.Value, Is.EqualTo("PROGRAM_CONTENT")); _ftpMock.Verify(f => f.DownloadFile("/_N_MPF_DIR/O1234.MPF"), Times.Once); } [Test] public void ReadProgramAsync_ShortName_ResolvesWithDirectoryAndMpfExtension() { _ftpMock.Setup(f => f.Ping()).Returns(true); _ftpMock.Setup(f => f.DownloadFile("/_N_MPF_DIR/O1234.MPF")).Returns("DATA"); _machine.ConnectAsync().GetAwaiter().GetResult(); _machine.ReadProgramAsync("O1234").GetAwaiter().GetResult(); _ftpMock.Verify(f => f.DownloadFile("/_N_MPF_DIR/O1234.MPF"), Times.Once); } // WriteProgramAsync [Test] public void WriteProgramAsync_ValidContent_CallsUploadFile() { _ftpMock.Setup(f => f.Ping()).Returns(true); _ftpMock.Setup(f => f.UploadFile(It.IsAny(), "CONTENT")); _machine.ConnectAsync().GetAwaiter().GetResult(); var prog = new CncProgram { Name = "O1234", Content = "CONTENT" }; var result = _machine.WriteProgramAsync("/_N_MPF_DIR/", prog).GetAwaiter().GetResult(); Assert.That(result.Success, Is.True); _ftpMock.Verify(f => f.UploadFile(It.IsAny(), "CONTENT"), Times.Once); } [Test] public void WriteProgramAsync_EmptyContent_FailsWithoutCallingUploadFile() { _ftpMock.Setup(f => f.Ping()).Returns(true); _machine.ConnectAsync().GetAwaiter().GetResult(); var prog = new CncProgram { Name = "O1234", Content = "" }; var result = _machine.WriteProgramAsync("/_N_MPF_DIR/", prog).GetAwaiter().GetResult(); Assert.That(result.Success, Is.False); _ftpMock.Verify(f => f.UploadFile(It.IsAny(), It.IsAny()), Times.Never); } [Test] public void WriteProgramAsync_NullProgram_FailsWithoutCallingUploadFile() { _ftpMock.Setup(f => f.Ping()).Returns(true); _machine.ConnectAsync().GetAwaiter().GetResult(); var result = _machine.WriteProgramAsync("/_N_MPF_DIR/", null).GetAwaiter().GetResult(); Assert.That(result.Success, Is.False); _ftpMock.Verify(f => f.UploadFile(It.IsAny(), It.IsAny()), Times.Never); } // DeleteProgramAsync [Test] public void DeleteProgramAsync_ValidPath_CallsDeleteFile() { _ftpMock.Setup(f => f.Ping()).Returns(true); _ftpMock.Setup(f => f.DeleteFile("/_N_MPF_DIR/O1234.MPF")); _machine.ConnectAsync().GetAwaiter().GetResult(); var result = _machine.DeleteProgramAsync("/_N_MPF_DIR/O1234.MPF").GetAwaiter().GetResult(); Assert.That(result.Success, Is.True); _ftpMock.Verify(f => f.DeleteFile("/_N_MPF_DIR/O1234.MPF"), Times.Once); } // ReadActiveProgramAsync [Test] public void ReadActiveProgramAsync_ReturnsFailNotSupported() { var result = _machine.ReadActiveProgramAsync().GetAwaiter().GetResult(); Assert.That(result.Success, Is.False); } } }