Add queued FFmpeg conversion and finish splitting the window from the host.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -395,6 +395,48 @@ public class TransferQueueTests
|
||||
await ctx.Queue.StopAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Convert_fails_when_ffmpeg_is_missing()
|
||||
{
|
||||
await using var ctx = await Harness.CreateAsync();
|
||||
var ops = new FileOperationService(ctx.Queue, ctx.Shell, new DiskEnum());
|
||||
await ctx.Queue.StartAsync(CancellationToken.None);
|
||||
await ops.ConvertAsync(ctx.File("a.txt"), Path.Combine(ctx.Dest, "a.mp4"), ConversionKind.VideoToMp4);
|
||||
await WaitUntil(() => ctx.Queue.Snapshot().Any(j =>
|
||||
j.Op == TransferOp.Convert && j.Status == TransferStatus.Failed));
|
||||
var job = ctx.Queue.Snapshot().Single(j => j.Op == TransferOp.Convert);
|
||||
Assert.Contains("FFmpeg", job.Error, StringComparison.OrdinalIgnoreCase);
|
||||
await ctx.Queue.StopAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Fake_convert_writes_output()
|
||||
{
|
||||
var fake = new FakeConversionExecutor();
|
||||
await using var ctx = await Harness.CreateAsync(conversion: fake);
|
||||
var ops = new FileOperationService(ctx.Queue, ctx.Shell, new DiskEnum());
|
||||
await ctx.Queue.StartAsync(CancellationToken.None);
|
||||
var dest = Path.Combine(ctx.Dest, "a.mp4");
|
||||
await ops.ConvertAsync(ctx.File("a.txt"), dest, ConversionKind.VideoToMp4);
|
||||
await WaitUntil(() => ctx.Queue.Snapshot().Any(j =>
|
||||
j.Op == TransferOp.Convert && j.Status == TransferStatus.Done));
|
||||
Assert.True(File.Exists(dest));
|
||||
await ctx.Queue.StopAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Convert_refuses_online_only_cloud_files()
|
||||
{
|
||||
await using var ctx = await Harness.CreateAsync(hydration: new AlwaysHydrate(), conversion: new FakeConversionExecutor());
|
||||
var ops = new FileOperationService(ctx.Queue, ctx.Shell, new DiskEnum());
|
||||
await ctx.Queue.StartAsync(CancellationToken.None);
|
||||
await ops.ConvertAsync(ctx.File("a.txt"), Path.Combine(ctx.Dest, "a.mp4"), ConversionKind.VideoToMp4);
|
||||
await WaitUntil(() => ctx.Queue.Snapshot().Any(j =>
|
||||
j.Op == TransferOp.Convert && j.Status == TransferStatus.Failed));
|
||||
Assert.Equal(FileOperationErrors.CloudHydration, ctx.Queue.Snapshot().Single().Error);
|
||||
await ctx.Queue.StopAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Empty_recycle_bin_goes_through_the_queue()
|
||||
{
|
||||
@@ -438,7 +480,8 @@ public class TransferQueueTests
|
||||
|
||||
public static async Task<Harness> CreateAsync(
|
||||
IArchiveExecutor? archives = null,
|
||||
IHydrationGuard? hydration = null)
|
||||
IHydrationGuard? hydration = null,
|
||||
IMediaConversionProvider? conversion = null)
|
||||
{
|
||||
var root = Path.Combine(Path.GetTempPath(), "ew-xfer", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(root);
|
||||
@@ -452,7 +495,7 @@ public class TransferQueueTests
|
||||
var shell = new GateShell();
|
||||
var volumes = new ControlledVolumes();
|
||||
var queue = new TransferQueue(
|
||||
new NativeFileOperationExecutor(shell, new DiskEnum(), archives, hydration),
|
||||
new NativeFileOperationExecutor(shell, new DiskEnum(), archives, hydration, conversion),
|
||||
store,
|
||||
volumes,
|
||||
NullLogger<TransferQueue>.Instance);
|
||||
@@ -629,6 +672,24 @@ internal sealed class FakeArchiveExecutor : IArchiveExecutor
|
||||
=> Task.CompletedTask;
|
||||
}
|
||||
|
||||
internal sealed class FakeConversionExecutor : IMediaConversionProvider
|
||||
{
|
||||
public bool IsAvailable { get; set; } = true;
|
||||
public string MissingHint => FfmpegLocator.MissingHint;
|
||||
|
||||
public async Task ConvertAsync(
|
||||
string sourcePath,
|
||||
string destinationPath,
|
||||
ConversionKind kind,
|
||||
IProgress<ConversionProgress>? progress,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)!);
|
||||
await File.WriteAllTextAsync(destinationPath, "converted:" + kind, cancellationToken).ConfigureAwait(false);
|
||||
progress?.Report(new ConversionProgress(100, destinationPath));
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class AlwaysHydrate : IHydrationGuard
|
||||
{
|
||||
public bool WouldHydrateOnRead(FileSystemItem item) => true;
|
||||
|
||||
Reference in New Issue
Block a user