Phase 06 complete: - Namespace renamed in 62 .cs files (namespace + using directives) - AssemblyName + RootNamespace updated in csproj files - FanucProgramManager.csproj → NcProgramManager.csproj - FanucProgramManager.sln → NcProgramManager.sln - FanucProgramManager.Tests/ → NcProgramManager.Tests/ - FANUCMachine.cs deleted (dead code, zero references) Fanuc-prefixed class names kept (FanucMachine, FanucProgram, IFanucMachine) — manufacturer identifiers, not project names. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
161 lines
5.7 KiB
C#
161 lines
5.7 KiB
C#
using System;
|
|
using NUnit.Framework;
|
|
using Moq;
|
|
using NcProgramManager.Cnc;
|
|
using NcProgramManager.Cnc.Models;
|
|
using NcProgramManager.Cnc.Siemens;
|
|
|
|
namespace NcProgramManager.Tests.Unit
|
|
{
|
|
[TestFixture]
|
|
public class SiemensMachineTests
|
|
{
|
|
private SiemensConnectionConfig _config;
|
|
private Mock<ISiemensFtpClient> _ftpMock;
|
|
private Mock<INcProgramValidator> _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<ISiemensFtpClient>(MockBehavior.Strict);
|
|
// Always-ok validator so existing write tests are not affected by validation rules
|
|
_validatorMock = new Mock<INcProgramValidator>();
|
|
_validatorMock.Setup(v => v.Validate(It.IsAny<string>(), It.IsAny<string>()))
|
|
.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<string>(), "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<string>(), "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<string>(), It.IsAny<string>()), 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<string>(), It.IsAny<string>()), 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);
|
|
}
|
|
}
|
|
}
|