using Explorer.Application; using Explorer.Contracts; using Explorer.Domain; using Explorer.Hosting.Ipc; using Microsoft.Extensions.Logging.Abstractions; namespace Explorer.Hosting.Tests; public class WorkbenchPipeTests { [Fact] public void Handle_forwards_indexing_and_transfer_calls() { var indexing = new FakeIndexing(); var transfers = new FakeTransfers(); var server = new WorkbenchPipeServer( new WorkbenchHost(indexing, transfers), new WorkbenchIpcOptions { PipeName = "ew-test" }, NullLogger.Instance); var ping = server.Handle(new IpcEnvelope { V = WorkbenchIpc.ProtocolVersion, Op = "Ping" }); Assert.True(ping.Ok); var scan = server.Handle(new IpcEnvelope { V = WorkbenchIpc.ProtocolVersion, Op = "Indexing.EnqueueFullScan", N = 42 }); Assert.True(scan.Ok); Assert.Equal(42, indexing.FullScanId); var pause = server.Handle(new IpcEnvelope { V = WorkbenchIpc.ProtocolVersion, Op = "Transfers.PauseAll" }); Assert.True(pause.Ok); Assert.True(transfers.PausedAll); var paused = server.Handle(new IpcEnvelope { V = WorkbenchIpc.ProtocolVersion, Op = "Transfers.IsPaused" }); Assert.True(paused.Paused); } [Fact] public void Handle_rejects_other_protocol_versions() { var server = new WorkbenchPipeServer( new WorkbenchHost(new FakeIndexing(), new FakeTransfers()), new WorkbenchIpcOptions(), NullLogger.Instance); var reply = server.Handle(new IpcEnvelope { V = 99, Op = "Ping" }); Assert.False(reply.Ok); Assert.Contains("99", reply.Error); } private sealed class FakeIndexing : IIndexingHost { public long FullScanId { get; private set; } public event EventHandler? ProgressChanged = delegate { }; public void EnqueueFullScan(long sourceId) => FullScanId = sourceId; public void EnqueueFolderScan(long sourceId, string pathRel) { } public void EnqueueReconcile(long sourceId, string pathRel) { } public void Cancel(long sourceId) { } } private sealed class FakeTransfers : ITransferHost { public bool PausedAll { get; private set; } public event EventHandler? Changed = delegate { }; public event EventHandler? JobFinished = delegate { }; public bool IsPaused => PausedAll; public IReadOnlyList Snapshot() => []; public void PauseAll() => PausedAll = true; public void ResumeAll() => PausedAll = false; public void Pause(long jobId) { } public void Resume(long jobId) { } public void Retry(long jobId) { } public void Cancel(long jobId) { } public void Dismiss(long jobId) { } public void ClearFinished() { } public bool MoveUp(long jobId) => false; public bool MoveDown(long jobId) => false; } }