162 lines
5.3 KiB
C#
162 lines
5.3 KiB
C#
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));
|
|
}
|
|
}
|