using AIStudio.Components;
using AIStudio.Tools.Mail;
using MudBlazor;
namespace AIStudio.Tests.Components;
///
/// Checks how the folder tree of a mailbox is built from what the server lists.
///
///
/// Servers differ in how they lay out their folders: one separates with a slash, another with a
/// dot, one keeps everything below the inbox, another lists a folder whose parent it never lists.
/// Whatever it lists has to show up exactly once, in the place its parent gives it.
///
[TestFixture]
public sealed class MailFolderPickerTests
{
private const string WHOLE_MAILBOX = "Whole mailbox";
[Test]
public void FoldersNestBelowTheWholeMailboxWithTheInboxFirst()
{
var root = BuildRoot(
Folder("Projects"),
Folder("Projects/Alpha", "Projects"),
Folder("Archive", specialUse: MailFolderSpecialUse.ARCHIVE),
Folder("INBOX", isInbox: true));
Assert.Multiple(() =>
{
Assert.That(root.Value, Is.Empty, "The root does not stand for the whole mailbox.");
Assert.That(root.Text, Is.EqualTo(WHOLE_MAILBOX));
Assert.That(ValuesOf(root), Is.EqualTo(new[] { "INBOX", "Archive", "Projects" }), "The top level is not ordered with the inbox first.");
Assert.That(ValuesOf(Child(root, "Projects")), Is.EqualTo(new[] { "Projects/Alpha" }), "The subfolder did not land below its parent.");
});
}
[Test]
public void FoldersBelowTheInboxNestThere()
{
var root = BuildRoot(
Folder("INBOX", isInbox: true, separator: '.'),
Folder("INBOX.Sent", "INBOX", separator: '.', specialUse: MailFolderSpecialUse.SENT),
Folder("INBOX.Drafts", "INBOX", separator: '.', specialUse: MailFolderSpecialUse.DRAFTS));
Assert.Multiple(() =>
{
Assert.That(ValuesOf(root), Is.EqualTo(new[] { "INBOX" }));
Assert.That(ValuesOf(Child(root, "INBOX")), Is.EqualTo(new[] { "INBOX.Drafts", "INBOX.Sent" }));
});
}
[Test]
public void AFolderWhoseParentIsNotListedGoesToTheTopLevel()
{
var root = BuildRoot(Folder("INBOX", isInbox: true), Folder("[Gmail]/Sent Mail", "[Gmail]", specialUse: MailFolderSpecialUse.SENT));
Assert.That(ValuesOf(root), Is.EqualTo(new[] { "INBOX", "[Gmail]/Sent Mail" }));
}
[Test]
public void AFolderListedTwiceShowsUpOnce()
{
var root = BuildRoot(Folder("Projects"), Folder("Projects"));
Assert.That(ValuesOf(root), Is.EqualTo(new[] { "Projects" }));
}
[Test]
public void FoldersWhichAreEachOthersParentDoNotHangTheTree()
{
var tree = MailFolderPicker.BuildTree([Folder("A", "B"), Folder("B", "A")], "A", WHOLE_MAILBOX);
Assert.That(tree.Single().Children, Is.Empty);
}
[Test]
public void TheWayToThePickedFolderIsExpanded()
{
var folders = new[]
{
Folder("Projects"),
Folder("Projects/Alpha", "Projects"),
Folder("Projects/Alpha/Reports", "Projects/Alpha"),
Folder("Private"),
Folder("Private/Travel", "Private"),
};
var root = MailFolderPicker.BuildTree(folders, "Projects/Alpha/Reports", WHOLE_MAILBOX).Single();
Assert.Multiple(() =>
{
Assert.That(root.Expanded, Is.True, "The whole mailbox is collapsed.");
Assert.That(Child(root, "Projects").Expanded, Is.True, "The way to the picked folder is collapsed.");
Assert.That(Child(Child(root, "Projects"), "Projects/Alpha").Expanded, Is.True, "The way to the picked folder is collapsed.");
Assert.That(Child(root, "Private").Expanded, Is.False, "A folder off the way to the picked folder is expanded.");
});
}
[TestCase(MailFolderSpecialUse.NONE, ExpectedResult = true)]
[TestCase(MailFolderSpecialUse.ARCHIVE, ExpectedResult = true)]
[TestCase(MailFolderSpecialUse.SENT, ExpectedResult = true)]
[TestCase(MailFolderSpecialUse.ALL, ExpectedResult = true)]
[TestCase(MailFolderSpecialUse.TRASH, ExpectedResult = false)]
[TestCase(MailFolderSpecialUse.JUNK, ExpectedResult = false)]
public bool TheTrashAndTheJunkFolderCannotBePicked(MailFolderSpecialUse specialUse) => MailFolderPicker.CanBeSelected(Folder("Folder", specialUse: specialUse));
private static MailServerFolder Folder(string fullName, string parentFullName = "", char separator = '/', MailFolderSpecialUse specialUse = MailFolderSpecialUse.NONE, bool isInbox = false)
{
var name = fullName[(fullName.LastIndexOf(separator) + 1)..];
return new MailServerFolder(fullName, name, parentFullName, separator, specialUse, isInbox, true);
}
private static TreeItemData BuildRoot(params MailServerFolder[] folders) => MailFolderPicker.BuildTree(folders, string.Empty, WHOLE_MAILBOX).Single();
private static IEnumerable ValuesOf(TreeItemData item) => item.Children?.Select(child => child.Value) ?? [];
private static TreeItemData Child(TreeItemData item, string fullName) => item.Children!.Single(child => child.Value == fullName);
}