using System.Collections.Generic; using System.Linq; using Centron.BusinessLogic.Sales.Support; using Centron.DAO; using Centron.Data.Entities.CustomerArea.Support; using Centron.Tests.EndToEnd.Infrastructure; using Xunit; using Xunit.Abstractions; namespace Centron.Tests.EndToEnd.TicketTests.Ticket165605; /// /// Ticket 165605: mail-template variables for helpdesk mails. /// - Group "Kunde": uniform Betreuer1-6 variables (instead of only IDM). /// IDM/ADM are kept as hidden alternatives (backward compatibility). /// - New group "Ticket-Bearbeiter": comma-separated variables across all editors. /// public class Ticket165605Tests : EndToEndTest { public Ticket165605Tests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } public override void Execute() { this.VerifyAvailableVariables(); this.VerifyVariableCatalog(); this.VerifyEditorVariablesAreCommaSeparated(); this.VerifyEditorsResolveWhenTicketLoadedWithoutPreloadedEditors(); } // Regression: in the forwarding/mail flow the ticket is loaded via GetHelpdesk(), which does // NOT populate the (unmapped) Editors collection. The TicketBearbeiter variables must still // resolve the editors (loaded from the DB on demand). private void VerifyEditorsResolveWhenTicketLoadedWithoutPreloadedEditors() { var helpdeskI3D = this.Sql( "SELECT ISNULL((SELECT TOP 1 TicketI3D FROM cvw_TicketEditors WHERE LTRIM(RTRIM(ISNULL(EmployeeFullName, ''))) <> '' ORDER BY TicketI3D), 0)"); // The snapshot must contain at least one ticket with editors; otherwise this regression // would pass without ever exercising the on-demand load path -> fail loudly instead. Assert.True(helpdeskI3D > 0, "No ticket with editors found in the snapshot database."); using var session = new DAOSession(); // GetHelpdesk does NOT populate Editors -> reproduces the reported bug. var helpdesk = new HelpdeskBL(session).GetHelpdesk(helpdeskI3D); Assert.NotNull(helpdesk); Assert.True(helpdesk.Editors == null || helpdesk.Editors.Count == 0); var result = new HelpdeskReplacementBL(session).ReplaceVariablesInText("@@TicketBearbeiterName@@", helpdesk, null); Assert.False(string.IsNullOrWhiteSpace(result)); } // Full variable catalog as a snapshot (regression across all groups). private void VerifyVariableCatalog() { using var session = new DAOSession(); var variables = new HelpdeskReplacementBL(session).GetAvailableVariables(); this.Verifier.Verify("AvailableVariables", variables); } // GetAvailableVariables returns the names including the "@@...@@" delimiters. private static string V(string name) => $"@@{name}@@"; private void VerifyAvailableVariables() { using var session = new DAOSession(); var variables = new HelpdeskReplacementBL(session).GetAvailableVariables(); var names = variables.Select(f => f.Name).ToHashSet(); // All Betreuer 1-6 present uniformly, 7 fields each (Name, Vorname, Nachname, // Kurzzeichen, Telefon, Fax, EMail). foreach (var prefix in new[] { "Betreuer1", "Betreuer2", "Betreuer3", "Betreuer4", "Betreuer5", "Betreuer6" }) { foreach (var suffix in new[] { "Name", "Vorname", "Nachname", "Kurzzeichen", "Telefon", "Fax", "EMail" }) { Assert.Contains(V(prefix + suffix), names); } // Group assignment "Kunde" Assert.Equal("Kunde", variables.Single(f => f.Name == V(prefix + "Vorname")).Group); // The new "Name" and "Kurzzeichen" fields have no legacy alternative name. Assert.Empty(variables.Single(f => f.Name == V(prefix + "Name")).AlternativeNames); Assert.Empty(variables.Single(f => f.Name == V(prefix + "Kurzzeichen")).AlternativeNames); } // There are no IDM*/ADM* variables for the new fields (Name/Kurzzeichen are new). Assert.DoesNotContain(V("IDMName"), names); Assert.DoesNotContain(V("ADMName"), names); Assert.DoesNotContain(V("IDMKurzzeichen"), names); Assert.DoesNotContain(V("ADMKurzzeichen"), names); // New ticket-editor variables present, in their own group. foreach (var suffix in new[] { "Name", "Vorname", "Nachname", "Kurzzeichen", "EMail", "Telefon" }) { Assert.Contains(V("TicketBearbeiter" + suffix), names); } Assert.Equal("Ticket-Bearbeiter", variables.Single(f => f.Name == V("TicketBearbeiterName")).Group); // Legacy IDM/ADM names no longer appear in the selection ... Assert.DoesNotContain(V("IDMVorname"), names); Assert.DoesNotContain(V("ADMVorname"), names); // ... but still work as hidden alternatives (backward compatibility). Assert.Contains(V("IDMVorname"), variables.Single(f => f.Name == V("Betreuer1Vorname")).AlternativeNames); Assert.Contains(V("IDMEMail"), variables.Single(f => f.Name == V("Betreuer1EMail")).AlternativeNames); Assert.Contains(V("ADMVorname"), variables.Single(f => f.Name == V("Betreuer2Vorname")).AlternativeNames); } private void VerifyEditorVariablesAreCommaSeparated() { using var session = new DAOSession(); var helpdesk = new Helpdesk { Editors = new List { new() { EmployeeFullName = "Anna Mueller", EmployeeFirstName = "Anna", EmployeeLastName = "Mueller", EmployeeShortSign = "MUA", EmployeeEMail = "anna.mueller@example.com" }, new() { EmployeeFullName = "Felix Kroos", EmployeeFirstName = "Felix", EmployeeLastName = "Kroos", EmployeeShortSign = "KRF", EmployeeEMail = "felix.kroos@example.com" } } }; var bl = new HelpdeskReplacementBL(session); Assert.Equal("Anna Mueller, Felix Kroos", bl.ReplaceVariablesInText("@@TicketBearbeiterName@@", helpdesk, null)); Assert.Equal("Anna, Felix", bl.ReplaceVariablesInText("@@TicketBearbeiterVorname@@", helpdesk, null)); Assert.Equal("MUA, KRF", bl.ReplaceVariablesInText("@@TicketBearbeiterKurzzeichen@@", helpdesk, null)); Assert.Equal("anna.mueller@example.com, felix.kroos@example.com", bl.ReplaceVariablesInText("@@TicketBearbeiterEMail@@", helpdesk, null)); } }