using Core.Entities; using Core.Utility; using Tests.Builders; namespace Tests.Utility; [TestFixture] public class TeamClipboardMatcher_Tests { private List _availableTeams = []; [SetUp] public void SetUp() { BuilderExtensions.ResetAllBuilders(); // Create test teams var construction = EventDefinitionBuilder.Team("Construction Challenge", 2, 4).Build(); var flight = EventDefinitionBuilder.Individual("Flight").Build(); var robotics = EventDefinitionBuilder.Team("Robotics", 2, 5).Build(); var coding = EventDefinitionBuilder.Individual("Coding").Build(); var medicalTech = EventDefinitionBuilder.Team("Medical Technology", 2, 3).Build(); _availableTeams = [ TeamBuilder.Create(construction).WithIdentifier("2").Build(), TeamBuilder.Create(flight).Build(), TeamBuilder.Create(robotics).Build(), TeamBuilder.Create(coding).Build(), TeamBuilder.Create(medicalTech).Build() ]; } [Test] public void MatchTeamsFromClipboard_ExactMatch_ReturnsMatchingTeam() { // Arrange var clipboardText = "Construction Challenge (2)"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(1)); Assert.That(result[0].Event.Name, Is.EqualTo("Construction Challenge")); Assert.That(result[0].Identifier, Is.EqualTo("2")); } [Test] public void MatchTeamsFromClipboard_ExactMatchWithoutIdentifier_ReturnsMatchingTeam() { // Arrange var clipboardText = "Flight"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(1)); Assert.That(result[0].Event.Name, Is.EqualTo("Flight")); } [Test] public void MatchTeamsFromClipboard_ClipboardFormatWithStudentList_ExtractsTeamName() { // Arrange var clipboardText = "Construction Challenge (2) - John Doe, Jane Smith"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(1)); Assert.That(result[0].Event.Name, Is.EqualTo("Construction Challenge")); } [Test] public void MatchTeamsFromClipboard_MultipleTeams_ReturnsAllMatches() { // Arrange var clipboardText = "Flight\r\nRobotics\r\nCoding"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(3)); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Flight")); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Robotics")); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Coding")); } [Test] public void MatchTeamsFromClipboard_FuzzyMatch_ReturnsBestMatch() { // Arrange var clipboardText = "Construcion Challange"; // Intentional typos // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(1)); Assert.That(result[0].Event.Name, Is.EqualTo("Construction Challenge")); } [Test] public void MatchTeamsFromClipboard_CaseInsensitive_MatchesCorrectly() { // Arrange var clipboardText = "FLIGHT\r\nconstruction challenge (2)"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(2)); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Flight")); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Construction Challenge")); } [Test] public void MatchTeamsFromClipboard_SkipsEmptyLines_IgnoresEmptyEntries() { // Arrange var clipboardText = "Flight\r\n\r\nRobotics\r\n \r\nCoding"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(3)); } [Test] public void MatchTeamsFromClipboard_SkipsMetadataHeaders_IgnoresSpecialMarkers() { // Arrange var clipboardText = "--Unscheduled\r\nFlight\r\n--Another Header\r\nRobotics\r\nUnscheduled"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(2)); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Flight")); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Robotics")); } [Test] public void MatchTeamsFromClipboard_NoMatches_ReturnsEmptyList() { // Arrange var clipboardText = "NonExistent Team Name"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Is.Empty); } [Test] public void MatchTeamsFromClipboard_BelowThreshold_ReturnsEmptyList() { // Arrange var clipboardText = "XYZ"; // Very different from any team name var highThreshold = 95; // Very high threshold // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams, highThreshold); // Assert Assert.That(result, Is.Empty); } [Test] public void MatchTeamsFromClipboard_CustomThreshold_RespectsThreshold() { // Arrange var clipboardText = "Construction Challeng"; // Close match, should work with lower threshold var lowThreshold = 70; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams, lowThreshold); // Assert Assert.That(result, Has.Count.EqualTo(1)); Assert.That(result[0].Event.Name, Is.EqualTo("Construction Challenge")); } [Test] public void MatchTeamsFromClipboard_EmptyClipboard_ReturnsEmptyList() { // Arrange var clipboardText = ""; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Is.Empty); } [Test] public void MatchTeamsFromClipboard_NullClipboard_ReturnsEmptyList() { // Arrange string? clipboardText = null; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText!, _availableTeams); // Assert Assert.That(result, Is.Empty); } [Test] public void MatchTeamsFromClipboard_EmptyTeamsList_ReturnsEmptyList() { // Arrange var clipboardText = "Flight"; var emptyTeams = new List(); // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, emptyTeams); // Assert Assert.That(result, Is.Empty); } [Test] public void MatchTeamsFromClipboard_DuplicateTeamNames_ReturnsSingleInstance() { // Arrange var clipboardText = "Flight\r\nFlight\r\nFlight"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(1)); Assert.That(result[0].Event.Name, Is.EqualTo("Flight")); } [Test] public void MatchTeamsFromClipboard_MultipleLinesWithDifferentFormats_HandlesAllFormats() { // Arrange var clipboardText = "Flight\r\nRobotics - Student List\r\nMedical Technology (1) - More Students"; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(3)); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Flight")); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Robotics")); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Medical Technology")); } [Test] public void MatchTeamsFromClipboard_WhitespaceAroundTeamName_TrimsCorrectly() { // Arrange var clipboardText = " Flight \r\n Robotics "; // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result, Has.Count.EqualTo(2)); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Flight")); Assert.That(result.Select(t => t.Event.Name), Contains.Item("Robotics")); } [Test] public void MatchTeamsFromClipboard_ReturnsTeamsFromInputCollection_MaintainsReferenceEquality() { // Arrange var clipboardText = "Flight"; var inputTeam = _availableTeams.First(t => t.Event.Name == "Flight"); // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, _availableTeams); // Assert Assert.That(result[0], Is.SameAs(inputTeam)); } [Test] public void MatchTeamsFromClipboard_BestMatchSelected_ReturnsHighestScoringMatch() { // Arrange // Create teams with similar names var construction1 = EventDefinitionBuilder.Team("Construction Challenge", 2, 4).Build(); var construction2 = EventDefinitionBuilder.Team("Construction Challenge Advanced", 2, 4).Build(); var teams = new[] { TeamBuilder.Create(construction1).Build(), TeamBuilder.Create(construction2).Build() }; var clipboardText = "Construction Challenge"; // Should match the first one exactly // Act var result = TeamClipboardMatcher.MatchTeamsFromClipboard(clipboardText, teams); // Assert Assert.That(result, Has.Count.EqualTo(1)); // The exact match should be selected (higher score) Assert.That(result[0].Event.Name, Is.EqualTo("Construction Challenge")); } }