Add patterned rename and Move to, and keep settings, selection, and queue speed from resetting.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
161
tests/Explorer.Application.Tests/DestinationPatternTests.cs
Normal file
161
tests/Explorer.Application.Tests/DestinationPatternTests.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using Explorer.Application;
|
||||
using Explorer.Domain;
|
||||
|
||||
namespace Explorer.Application.Tests;
|
||||
|
||||
public class DestinationPatternTests
|
||||
{
|
||||
private static RenameSubject File(string path, bool directory = false)
|
||||
=> new(path, PathRules.GetFileName(path), directory);
|
||||
|
||||
[Fact]
|
||||
public void Plex_style_folder_gets_the_file_inside()
|
||||
{
|
||||
Assert.True(DestinationPattern.TryResolve(
|
||||
@"\\10.0.0.31\media\movies\%filename_noext%",
|
||||
File(@"D:\downloads\Inception.mkv"),
|
||||
out var dest,
|
||||
out var error));
|
||||
Assert.Null(error);
|
||||
Assert.Equal(@"\\10.0.0.31\media\movies\Inception\Inception.mkv", dest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Explicit_filename_token_is_the_full_path()
|
||||
{
|
||||
Assert.True(DestinationPattern.TryResolve(
|
||||
@"\\10.0.0.31\media\movies\%filename_noext%\%filename%",
|
||||
File(@"D:\downloads\Inception.mkv"),
|
||||
out var dest,
|
||||
out _));
|
||||
Assert.Equal(@"\\10.0.0.31\media\movies\Inception\Inception.mkv", dest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Folder_moves_to_the_expanded_directory()
|
||||
{
|
||||
Assert.True(DestinationPattern.TryResolve(
|
||||
@"\\10.0.0.31\media\movies\%filename_noext%",
|
||||
File(@"D:\downloads\Inception", directory: true),
|
||||
out var dest,
|
||||
out _));
|
||||
Assert.Equal(@"\\10.0.0.31\media\movies\Inception", dest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Source_drive_year_and_parent_expand()
|
||||
{
|
||||
var fields = new MoveToFields(
|
||||
"clip.mp4",
|
||||
"clip",
|
||||
"mp4",
|
||||
"Vacation",
|
||||
"E:",
|
||||
new DateTimeOffset(new DateTime(2024, 8, 26, 0, 0, 0, DateTimeKind.Local)),
|
||||
null);
|
||||
Assert.True(DestinationPattern.TryExpand(
|
||||
@"%source_drive%\sorted\%year%\%month%\%parent%",
|
||||
fields,
|
||||
out var expanded,
|
||||
out _));
|
||||
Assert.Equal(@"E:\sorted\2024\08\Vacation", expanded);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Brace_tokens_match_percent_tokens()
|
||||
{
|
||||
Assert.True(DestinationPattern.TryResolve(
|
||||
@"{source_drive}\Media\{filename_noext}\{filename}",
|
||||
File(@"C:\tmp\Photo.jpg"),
|
||||
out var dest,
|
||||
out _));
|
||||
Assert.Equal(@"C:\Media\Photo\Photo.jpg", dest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Relative_paths_are_rejected()
|
||||
{
|
||||
Assert.False(DestinationPattern.TryResolve(
|
||||
@"%filename_noext%\%filename%",
|
||||
File(@"C:\tmp\a.mkv"),
|
||||
out _,
|
||||
out var error));
|
||||
Assert.Contains("full destination", error, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Unknown_placeholder_is_an_error()
|
||||
{
|
||||
Assert.False(DestinationPattern.TryExpand(
|
||||
@"C:\out\%nope%",
|
||||
new MoveToFields("a.txt", "a", "txt", "tmp", "C:", null, null),
|
||||
out _,
|
||||
out var error));
|
||||
Assert.Contains("%nope%", error, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
public class DestinationPatternsTests
|
||||
{
|
||||
[Fact]
|
||||
public void Combine_puts_saved_ahead_of_built_in()
|
||||
{
|
||||
var combined = DestinationPatterns.Combine([@"\\10.0.0.31\media\movies\%filename_noext%"]);
|
||||
Assert.Equal(@"\\10.0.0.31\media\movies\%filename_noext%", combined[0]);
|
||||
Assert.Contains(DestinationPatterns.BuiltIn[0], combined);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Normalize_does_not_persist_built_in_examples()
|
||||
{
|
||||
Assert.Empty(DestinationPatterns.Normalize([@"\\host\share\movies\%filename_noext%"]));
|
||||
}
|
||||
}
|
||||
|
||||
public class MoveToPlannerTests
|
||||
{
|
||||
[Fact]
|
||||
public void Queues_a_move_into_the_named_folder()
|
||||
{
|
||||
var plan = new MoveToPlanner().Build(
|
||||
[new RenameSubject(@"D:\downloads\Inception.mkv", "Inception.mkv", false)],
|
||||
@"\\10.0.0.31\media\movies\%filename_noext%");
|
||||
Assert.True(plan.CanEnqueue);
|
||||
Assert.Equal(TransferOp.Move, plan.Operations[0].Op);
|
||||
Assert.Equal(@"\\10.0.0.31\media\movies\Inception\Inception.mkv", plan.Operations[0].DestinationPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Collision_is_an_error()
|
||||
{
|
||||
var plan = new MoveToPlanner().Build(
|
||||
[
|
||||
new RenameSubject(@"D:\a\Inception.mkv", "Inception.mkv", false),
|
||||
new RenameSubject(@"D:\b\Inception.mkv", "Inception.mkv", false)
|
||||
],
|
||||
@"\\server\media\movies\%filename_noext%");
|
||||
Assert.False(plan.CanEnqueue);
|
||||
Assert.Contains(plan.Issues, i => i.Message.Contains("already exists", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Online_only_is_an_error()
|
||||
{
|
||||
var plan = new MoveToPlanner().Build(
|
||||
[new RenameSubject(@"C:\cloud\clip.mp4", "clip.mp4", false)],
|
||||
@"D:\out\%filename_noext%",
|
||||
wouldHydrate: _ => true);
|
||||
Assert.False(plan.CanEnqueue);
|
||||
Assert.Contains(plan.Issues, i => i.Message.Contains("online-only", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Example_host_is_rejected()
|
||||
{
|
||||
var plan = new MoveToPlanner().Build(
|
||||
[new RenameSubject(@"D:\downloads\Inception.mkv", "Inception.mkv", false)],
|
||||
@"\\host\share\movies\%filename_noext%");
|
||||
Assert.False(plan.CanEnqueue);
|
||||
Assert.Contains(plan.Issues, i => i.Message.Contains("Browse", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user