mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-20 07:39:09 +08:00
166 lines
6.4 KiB
C#
166 lines
6.4 KiB
C#
using System.Collections.ObjectModel;
|
|
using Avalonia.Platform.Storage;
|
|
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace AtomUI.Desktop.Controls.Tests.Upload;
|
|
|
|
public class UploadFileSelectionTests
|
|
{
|
|
static UploadFileSelectionTests()
|
|
{
|
|
AvaloniaTestApp.EnsureInitialized();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task File_Picker_Receives_The_Exact_AllowedFileTypes_And_Uses_The_FilePicker_Source()
|
|
{
|
|
var png = new FilePickerFileType("PNG") { Patterns = ["*.png"] };
|
|
var adapter = new TestStorageProviderAdapter
|
|
{
|
|
Files = [new TestStorageFile("image.png", "file:///image.png")]
|
|
};
|
|
var upload = CreateUpload(adapter);
|
|
upload.AllowedFileTypes = [png];
|
|
UploadInputBatchCompletedEventArgs? completed = null;
|
|
upload.InputBatchCompleted += (_, args) => completed = args;
|
|
|
|
await upload.SelectFilesAsync(TestContext.Current.CancellationToken);
|
|
|
|
adapter.LastFileOptions.ShouldNotBeNull();
|
|
adapter.LastFileOptions.FileTypeFilter.ShouldBeSameAs(upload.AllowedFileTypes);
|
|
completed.ShouldNotBeNull();
|
|
completed.Source.ShouldBe(UploadInputSource.FilePicker);
|
|
upload.Files!.Select(item => item.Name).ShouldBe(["image.png"]);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(false)]
|
|
[InlineData(true)]
|
|
public async Task Null_Or_Empty_AllowedFileTypes_Does_Not_Create_A_Synthetic_Filter(bool useEmptyList)
|
|
{
|
|
var adapter = new TestStorageProviderAdapter();
|
|
var upload = CreateUpload(adapter);
|
|
upload.AllowedFileTypes = useEmptyList ? [] : null;
|
|
|
|
await upload.SelectFilesAsync(TestContext.Current.CancellationToken);
|
|
|
|
adapter.LastFileOptions.ShouldNotBeNull();
|
|
adapter.LastFileOptions.FileTypeFilter.ShouldBeSameAs(upload.AllowedFileTypes);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(false)]
|
|
[InlineData(true)]
|
|
public async Task File_And_Directory_Pickers_Use_The_Same_Multiple_Input_Option(bool isMultipleEnabled)
|
|
{
|
|
var adapter = new TestStorageProviderAdapter();
|
|
var upload = CreateUpload(adapter);
|
|
upload.IsMultipleEnabled = isMultipleEnabled;
|
|
|
|
await upload.SelectFilesAsync(TestContext.Current.CancellationToken);
|
|
await upload.SelectDirectoriesAsync(TestContext.Current.CancellationToken);
|
|
|
|
adapter.LastFileOptions.ShouldNotBeNull();
|
|
adapter.LastFileOptions.AllowMultiple.ShouldBe(isMultipleEnabled);
|
|
adapter.LastFolderOptions.ShouldNotBeNull();
|
|
adapter.LastFolderOptions.AllowMultiple.ShouldBe(isMultipleEnabled);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Directory_Picker_Uses_TopLevelFiles_And_Preserves_Per_Item_Results()
|
|
{
|
|
var firstTopLevelFile = new TestStorageFile("first.txt", "file:///folder/first.txt");
|
|
var secondTopLevelFile = new TestStorageFile("second.txt", "file:///folder/second.txt");
|
|
var nestedFile = new TestStorageFile("nested.txt", "file:///folder/nested/nested.txt");
|
|
var nestedFolder = new TestStorageFolder("nested", "file:///folder/nested/", nestedFile);
|
|
var root = new TestStorageFolder(
|
|
"folder",
|
|
"file:///folder/",
|
|
firstTopLevelFile,
|
|
secondTopLevelFile,
|
|
nestedFolder);
|
|
var adapter = new TestStorageProviderAdapter { Folders = [root] };
|
|
var upload = CreateUpload(adapter);
|
|
UploadInputBatchCompletedEventArgs? completed = null;
|
|
upload.InputBatchCompleted += (_, args) => completed = args;
|
|
|
|
await upload.SelectDirectoriesAsync(TestContext.Current.CancellationToken);
|
|
|
|
upload.Files!.Select(item => item.Name).ShouldBe(["first.txt", "second.txt"]);
|
|
completed.ShouldNotBeNull();
|
|
completed.Source.ShouldBe(UploadInputSource.DirectoryPicker);
|
|
completed.RejectedItems.Single().Reason.ShouldBe(UploadRejectionReason.DirectoryNotAllowed);
|
|
nestedFolder.DisposeCount.ShouldBe(1);
|
|
nestedFile.DisposeCount.ShouldBe(0);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Empty_Picker_Result_Completes_One_Empty_Batch()
|
|
{
|
|
var adapter = new TestStorageProviderAdapter();
|
|
var upload = CreateUpload(adapter);
|
|
var events = new List<UploadInputBatchCompletedEventArgs>();
|
|
upload.InputBatchCompleted += (_, args) => events.Add(args);
|
|
|
|
await upload.SelectFilesAsync(TestContext.Current.CancellationToken);
|
|
|
|
events.Count.ShouldBe(1);
|
|
events[0].Source.ShouldBe(UploadInputSource.FilePicker);
|
|
events[0].AcceptedFiles.ShouldBeEmpty();
|
|
events[0].RejectedItems.ShouldBeEmpty();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Unavailable_Picker_Does_Not_Start_An_Input_Batch()
|
|
{
|
|
var adapter = new TestStorageProviderAdapter { CanOpenFiles = false };
|
|
var upload = CreateUpload(adapter);
|
|
var eventCount = 0;
|
|
upload.InputBatchCompleted += (_, _) => eventCount++;
|
|
|
|
await upload.SelectFilesAsync(TestContext.Current.CancellationToken);
|
|
|
|
adapter.LastFileOptions.ShouldBeNull();
|
|
eventCount.ShouldBe(0);
|
|
}
|
|
|
|
private static Desktop.Controls.Upload CreateUpload(TestStorageProviderAdapter adapter)
|
|
{
|
|
return new Desktop.Controls.Upload
|
|
{
|
|
AutoUpload = false,
|
|
Files = new ObservableCollection<UploadFileItem>(),
|
|
StorageProviderAdapter = adapter
|
|
};
|
|
}
|
|
|
|
private sealed class TestStorageProviderAdapter : IUploadStorageProviderAdapter
|
|
{
|
|
public bool CanOpenFiles { get; init; } = true;
|
|
public bool CanOpenFolders { get; init; } = true;
|
|
internal IReadOnlyList<IStorageFile> Files { get; init; } = [];
|
|
internal IReadOnlyList<IStorageFolder> Folders { get; init; } = [];
|
|
internal FilePickerOpenOptions? LastFileOptions { get; private set; }
|
|
internal FolderPickerOpenOptions? LastFolderOptions { get; private set; }
|
|
|
|
public Task<IReadOnlyList<IStorageFile>> OpenFilesAsync(
|
|
FilePickerOpenOptions options,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
LastFileOptions = options;
|
|
return Task.FromResult(Files);
|
|
}
|
|
|
|
public Task<IReadOnlyList<IStorageFolder>> OpenFoldersAsync(
|
|
FolderPickerOpenOptions options,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
LastFolderOptions = options;
|
|
return Task.FromResult(Folders);
|
|
}
|
|
}
|
|
}
|