Files
Christoph Schwörer f045b99a25 Codebasis als Dateien ins Arbeitsrepo statt als Gitlink
QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142)
getrackt, ohne .gitmodules und ohne erreichbares Remote. Der
Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar
gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege
der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen.

Umstellung:
- Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert
  (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6)
- Gitlink aus dem Index entfernt
- Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB

Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte
bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
2026-08-26 07:43:51 +02:00

1078 lines
36 KiB
C#

using Centron.BusinessLogic.NexusViews;
using Centron.Data.Entities.Administration.Logins;
using Centron.Data.Entities.NexusTicketViews;
using Centron.Interfaces;
using Centron.DAO;
using Centron.DAO.Mappings;
using Centron.DAO.Mappings.Administration.Employees;
using Centron.DAO.Mappings.Administration.Logins;
using Centron.DAO.Mappings.NexusTicketViews;
using Centron.DAO.Mappings.CustomerArea.Support;
using Centron.DAO.Mappings.CustomerArea;
using Centron.DAO.Mappings.CustomerArea.CustomerDetails;
using Centron.DAO.Mappings.Administration.Company;
using Centron.DAO.Mappings.States;
using Centron.DAO.Mappings.Administration;
using Centron.Data.Entities.Ticketing;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using JetBrains.Annotations;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
using Centron.Tests.BL.SetupUtils;
using Centron.DAO.Mappings.Accounts;
using Centron.DAO.Mappings.CustomerArea.CRM.Activities;
using Centron.DAO.Mappings.Administration.Applications;
using Centron.DAO.Mappings.Administration.Settings;
using Centron.DAO.Mappings.Administration.FileManagement;
using Centron.DAO.Mappings.EmployeeArea;
using Centron.DAO.Mappings.Logistics.Warehousing;
using Centron.DAO.Mappings.Merchandise.Articles;
using Centron.DAO.Mappings.Merchandise.Materialgroups;
using Centron.DAO.Mappings.Sales.Customers;
using Centron.DAO.Mappings.Warehousing;
using Centron.DAO.Mappings.Warehousing.InventoryManagement;
using Centron.DAO.Mappings.Warehousing.StockManagement;
using Centron.Tests.BL.DatabaseMappings;
namespace Centron.Tests.BL.NexusTicketViews;
[TestSubject(typeof(NexusTicketViewBL))]
public class NexusTicketViewBLTest
{
[Fact]
public void GetTicketViewById_ExistingTicketView_ReturnsTicketView()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var ticketView = new NexusTicketView
{
I3D = 1,
Caption = "Test View",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(ticketView, 1);
session.Flush();
// Act
var result = bl.GetTicketViewById(1);
// Assert
Assert.NotNull(result);
Assert.Equal(1, result.I3D);
Assert.Equal("Test View", result.Caption);
}
[Fact]
public void GetTicketViewById_NonExistingTicketView_ReturnsNull()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
// Act
var result = bl.GetTicketViewById(999);
// Assert
Assert.Null(result);
}
[Fact]
public void SaveTicketView_NewTicketView_EmployeeLogin_CreatesTicketView()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
var ticketView = new NexusTicketView
{
Caption = "New View",
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
// Act
var result = bl.SaveTicketView(ticketView, loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal(1, result.CreatedByI3D);
Assert.Equal(1, result.ChangedBy);
Assert.Equal("New View", result.Caption);
Assert.Equal(CentronObjectKindNumeric.EmployeeClass, result.CreatedByObjectKind);
}
[Fact]
public void SaveTicketView_NewTicketView_WebAccountLogin_CreatesTicketView()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var webAccount = DbSetupUtils.SaveWebAccount(session, "webuser", "web@example.com", 2, "webpass");
var ticket = new Ticket { UserI3D = 2, WebAccount = webAccount };
var loggedInUser = new LoggedInUser(null, ticket);
var ticketView = new NexusTicketView
{
Caption = "Web Account View",
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
// Act
var result = bl.SaveTicketView(ticketView, loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal(2, result.CreatedByI3D);
Assert.Equal(2, result.ChangedBy);
Assert.Equal("Web Account View", result.Caption);
Assert.Equal(CentronObjectKindNumeric.Webaccount, result.CreatedByObjectKind);
}
[Fact]
public void SaveTicketView_ExistingTicketView_UpdatesTicketView()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
var existingTicketView = new NexusTicketView
{
I3D = 1,
Caption = "Original View",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(existingTicketView, 1);
session.Flush();
existingTicketView.Caption = "Updated View";
// Act
var result = bl.SaveTicketView(existingTicketView, loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal("Updated View", result.Caption);
Assert.Equal(1, result.ChangedBy);
}
[Fact]
public void DeleteTicketView_ExistingTicketView_DeletesTicketView()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
var ticketView = new NexusTicketView
{
I3D = 1,
Caption = "To Delete",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(ticketView, 1);
session.Flush();
// Act
bl.DeleteTicketView(1);
// Assert
var deletedTicketView = session.Get<NexusTicketView>(1);
Assert.Null(deletedTicketView);
}
[Fact]
public void IsGlobalViewUsedByOthers_GlobalViewUsedByOthers_ReturnsTrue()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
// Create global view
var globalView = new NexusTicketView
{
I3D = 1,
Caption = "Global View",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = true,
Configuration = "{}"
};
session.Save(globalView, 1);
// Create reference by another user
var referenceView = new NexusTicketView
{
I3D = 2,
Caption = "Reference View",
CreatedByI3D = 2,
IsDefault = false,
IsGlobal = false,
GlobalViewI3D = 1,
Configuration = "{}"
};
session.Save(referenceView, 2);
session.Flush();
// Act
var result = bl.IsGlobalViewUsedByOthers(1, appUser);
// Assert
Assert.True(result);
}
[Fact]
public void IsGlobalViewUsedByOthers_GlobalViewNotUsedByOthers_ReturnsFalse()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
// Create global view
var globalView = new NexusTicketView
{
I3D = 1,
Caption = "Global View",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = true,
Configuration = "{}"
};
session.Save(globalView, 1);
session.Flush();
// Act
var result = bl.IsGlobalViewUsedByOthers(1, appUser);
// Assert
Assert.False(result);
}
[Fact]
public void GlobalViewWithSameNameExists_SameNameExists_ReturnsTrue()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var globalView = new NexusTicketView
{
I3D = 1,
Caption = "Test Global View",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = true,
Configuration = "{}"
};
session.Save(globalView, 1);
session.Flush();
// Act
var result = bl.GlobalViewWithSameNameExists(2, "Test Global View");
// Assert
Assert.True(result);
}
[Fact]
public void GlobalViewWithSameNameExists_SameNameDoesNotExist_ReturnsFalse()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var globalView = new NexusTicketView
{
I3D = 1,
Caption = "Test Global View",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = true,
Configuration = "{}"
};
session.Save(globalView, 1);
session.Flush();
// Act
var result = bl.GlobalViewWithSameNameExists(2, "Different Name");
// Assert
Assert.False(result);
}
[Fact]
public void DeleteGlobalView_GlobalViewWithReferences_DeletesGlobalViewAndUpdatesReferences()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
// Create global view
var globalView = new NexusTicketView
{
I3D = 1,
Caption = "Global View",
CreatedByI3D = appUser.Employee.I3D,
IsDefault = false,
IsGlobal = true,
Configuration = "{\"test\": \"config\"}"
};
session.Save(globalView, 1);
// Create reference
var referenceView = new NexusTicketView
{
I3D = 2,
Caption = "Reference View",
CreatedByI3D = 2,
IsDefault = false,
IsGlobal = false,
GlobalViewI3D = 1,
Configuration = "{}"
};
session.Save(referenceView, 2);
session.Flush();
// Act
bl.DeleteGlobalView(1, false, appUser);
// Assert
var deletedGlobalView = session.Get<NexusTicketView>(1);
Assert.Null(deletedGlobalView);
var updatedReference = session.Get<NexusTicketView>(2);
Assert.NotNull(updatedReference);
Assert.Null(updatedReference.GlobalViewI3D);
Assert.Equal("{\"test\": \"config\"}", updatedReference.Configuration);
}
[Fact]
public void RenameTicketView_NonGlobalView_RenamesTicketView()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
var ticketView = new NexusTicketView
{
I3D = 1,
Caption = "Original Name",
CreatedByI3D = appUser.Employee.I3D,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(ticketView, 1);
session.Flush();
// Act
var result = bl.RenameTicketView(1, "New Name", loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal("New Name", result.Caption);
Assert.Equal(1, result.ChangedBy);
}
[Fact]
public void RenameTicketView_GlobalView_RenamesGlobalViewAndReferences()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
// Create global view
var globalView = new NexusTicketView
{
I3D = 1,
Caption = "Global View",
CreatedByI3D = appUser.Employee.I3D,
IsDefault = false,
IsGlobal = true,
Configuration = "{}"
};
session.Save(globalView, 1);
// Create reference
var referenceView = new NexusTicketView
{
I3D = 2,
Caption = "Reference View",
CreatedByI3D = 2,
IsDefault = false,
IsGlobal = false,
GlobalViewI3D = 1,
Configuration = "{}"
};
session.Save(referenceView, 2);
session.Flush();
// Act
var result = bl.RenameTicketView(1, "Renamed Global View", loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal("Renamed Global View", result.Caption);
var updatedReference = session.Get<NexusTicketView>(2);
Assert.Equal("Renamed Global View", updatedReference.Caption);
}
[Fact]
public void SetTicketViewToDefault_ExistingTicketViews_SetsCorrectDefault()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
// Create multiple ticket views
var view1 = new NexusTicketView
{
I3D = 1,
Caption = "View 1",
CreatedByI3D = appUser.Employee.I3D,
CreatedByObjectKind = CentronObjectKindNumeric.EmployeeClass,
IsDefault = true,
IsGlobal = false,
Configuration = "{}"
};
session.Save(view1, 1);
var view2 = new NexusTicketView
{
I3D = 2,
Caption = "View 2",
CreatedByI3D = appUser.Employee.I3D,
CreatedByObjectKind = CentronObjectKindNumeric.EmployeeClass,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(view2, 2);
session.Flush();
// Act
var result = bl.SetTicketViewToDefault(2, true, loggedInUser);
// Assert
Assert.NotNull(result);
Assert.True(result.IsDefault);
var updatedView1 = session.Get<NexusTicketView>(1);
Assert.False(updatedView1.IsDefault);
var updatedView2 = session.Get<NexusTicketView>(2);
Assert.True(updatedView2.IsDefault);
}
[Fact]
public void SetTicketViewToGlobal_EmployeeLogin_SetsGlobalFlag()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var ticketView = new NexusTicketView
{
I3D = 1,
Caption = "Test View",
CreatedByI3D = appUser.Employee.I3D,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(ticketView, 1);
session.Flush();
// Act
var result = bl.SetTicketViewToGlobal(1, true, appUser);
// Assert
Assert.NotNull(result);
Assert.True(result.IsGlobal);
Assert.Equal(1, result.ChangedBy);
}
[Fact]
public void DuplicateTicketView_ExistingTicketView_CreatesDuplicate()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
var originalView = new NexusTicketView
{
I3D = 1,
Caption = "Original View",
CreatedByI3D = appUser.Employee.I3D,
IsDefault = true,
IsGlobal = false,
Configuration = "{\"test\": \"config\"}"
};
session.Save(originalView, 1);
session.Flush();
// Act
var result = bl.DuplicateTicketView(1, loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal("Original View (Copy)", result.Caption);
Assert.False(result.IsDefault);
Assert.False(result.IsGlobal);
Assert.Null(result.GlobalViewI3D);
Assert.Equal("{\"test\": \"config\"}", result.Configuration);
Assert.Equal(1, result.CreatedByI3D);
}
[Fact]
public void ReorderTicketViews_ListOfTicketViews_ReordersAndReturnsUpdatedList()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
// Create ticket views
var view1 = new NexusTicketView
{
I3D = 1,
Caption = "View 1",
CreatedByI3D = appUser.Employee.I3D,
CreatedByObjectKind = CentronObjectKindNumeric.EmployeeClass,
IsDefault = false,
IsGlobal = false,
IndexOf = 1,
Configuration = "{}"
};
session.Save(view1, 1);
var view2 = new NexusTicketView
{
I3D = 2,
Caption = "View 2",
CreatedByI3D = appUser.Employee.I3D,
CreatedByObjectKind = CentronObjectKindNumeric.EmployeeClass,
IsDefault = false,
IsGlobal = false,
IndexOf = 2,
Configuration = "{}"
};
session.Save(view2, 2);
session.Flush();
var ticketViewList = new List<NexusTicketView>
{
session.Get<NexusTicketView>(2),
session.Get<NexusTicketView>(1)
};
// Update the IndexOf values on the existing entities
ticketViewList[0].IndexOf = 1;
ticketViewList[1].IndexOf = 2;
// Act
var result = bl.ReorderTicketViews(ticketViewList, loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal(2, result.Count);
Assert.Equal(1, result[0].IndexOf);
Assert.Equal(2, result[1].IndexOf);
}
[Fact]
public void GetAllTicketViews_EmployeeLogin_ReturnsEmployeeViews()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
// Create ticket views for employee
var view1 = new NexusTicketView
{
I3D = 1,
Caption = "Employee View 1",
CreatedByI3D = appUser.Employee.I3D,
CreatedByObjectKind = CentronObjectKindNumeric.EmployeeClass,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(view1, 1);
var view2 = new NexusTicketView
{
I3D = 2,
Caption = "Employee View 2",
CreatedByI3D = appUser.Employee.I3D,
CreatedByObjectKind = CentronObjectKindNumeric.EmployeeClass,
IsDefault = true,
IsGlobal = false,
Configuration = "{}"
};
session.Save(view2, 2);
// Create ticket view for different employee
var view3 = new NexusTicketView
{
I3D = 3,
Caption = "Other Employee View",
CreatedByI3D = 2,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(view3, 3);
session.Flush();
// Act
var result = bl.GetAllTicketViews(loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal(2, result.Count);
Assert.All(result, view => Assert.Equal(1, view.CreatedByI3D));
Assert.All(result, view => Assert.False(view.IsGlobal));
Assert.All(result, view => Assert.Equal(CentronObjectKindNumeric.EmployeeClass, view.CreatedByObjectKind));
}
[Fact]
public void GetAllTicketViews_WebAccountLogin_ReturnsWebAccountViews()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var webAccount = DbSetupUtils.SaveWebAccount(session, "webuser", "web@example.com", 2, "webpass");
var ticket = new Ticket { UserI3D = 2, WebAccount = webAccount };
var loggedInUser = new LoggedInUser(null, ticket);
// Create ticket views for web account
var view1 = new NexusTicketView
{
I3D = 1,
Caption = "Web Account View 1",
CreatedByI3D = webAccount.I3D,
CreatedByObjectKind = CentronObjectKindNumeric.Webaccount,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(view1, 1);
var view2 = new NexusTicketView
{
I3D = 2,
Caption = "Web Account View 2",
CreatedByI3D = webAccount.I3D,
CreatedByObjectKind = CentronObjectKindNumeric.Webaccount,
IsDefault = true,
IsGlobal = false,
Configuration = "{}"
};
session.Save(view2, 2);
// Create ticket view for different web account
var view3 = new NexusTicketView
{
I3D = 3,
Caption = "Other Web Account View",
CreatedByI3D = 3,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(view3, 3);
session.Flush();
// Act
var result = bl.GetAllTicketViews(loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal(2, result.Count);
Assert.All(result, view => Assert.Equal(2, view.CreatedByI3D));
Assert.All(result, view => Assert.False(view.IsGlobal));
Assert.All(result, view => Assert.Equal(CentronObjectKindNumeric.Webaccount, view.CreatedByObjectKind));
}
[Fact]
public void GetAllTicketViews_CollidingI3D_IsolatesByCreatedByObjectKind()
{
// Arrange — an employee and a web account that share the same numeric I3D (1).
// This is the core collision scenario the CreatedByObjectKind discriminator must resolve.
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "EmployeeUser", "emp@example.com", 1);
var webAccount = DbSetupUtils.SaveWebAccount(session, "webuser", "web@example.com", 1, "webpass");
var employeeView = new NexusTicketView
{
I3D = 1,
Caption = "Employee View",
CreatedByI3D = 1,
CreatedByObjectKind = CentronObjectKindNumeric.EmployeeClass,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(employeeView, 1);
var webAccountView = new NexusTicketView
{
I3D = 2,
Caption = "Web Account View",
CreatedByI3D = 1,
CreatedByObjectKind = CentronObjectKindNumeric.Webaccount,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(webAccountView, 2);
session.Flush();
var employeeLogin = new LoggedInUser(appUser);
var ticket = new Ticket { UserI3D = 1, WebAccount = webAccount };
var webAccountLogin = new LoggedInUser(null, ticket);
// Act
var employeeResult = bl.GetAllTicketViews(employeeLogin);
var webAccountResult = bl.GetAllTicketViews(webAccountLogin);
// Assert — each side sees only its own view despite the shared CreatedByI3D
Assert.Single(employeeResult);
Assert.Equal("Employee View", employeeResult[0].Caption);
Assert.Equal(CentronObjectKindNumeric.EmployeeClass, employeeResult[0].CreatedByObjectKind);
Assert.Single(webAccountResult);
Assert.Equal("Web Account View", webAccountResult[0].Caption);
Assert.Equal(CentronObjectKindNumeric.Webaccount, webAccountResult[0].CreatedByObjectKind);
}
[Fact]
public void GetAllTicketViews_LegacyRowsDefaultToEmployee_NotVisibleToWebAccount()
{
// Arrange — simulate pre-migration rows: CreatedByObjectKind defaults to EmployeeClass
// (DB default 215), and CreatedByI3D collides with the logging-in web account's I3D.
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var webAccount = DbSetupUtils.SaveWebAccount(session, "webuser", "web@example.com", 1, "webpass");
var legacyView = new NexusTicketView
{
I3D = 1,
Caption = "Legacy Employee View",
CreatedByI3D = 1,
CreatedByObjectKind = CentronObjectKindNumeric.EmployeeClass,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(legacyView, 1);
session.Flush();
var ticket = new Ticket { UserI3D = 1, WebAccount = webAccount };
var webAccountLogin = new LoggedInUser(null, ticket);
// Act
var result = bl.GetAllTicketViews(webAccountLogin);
// Assert — legacy (Employee-owned) rows never leak to a web account, even with a colliding I3D
Assert.Empty(result);
}
[Fact]
public void GetGlobalViews_ReturnsAllGlobalViews()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
// Create global views
var globalView1 = new NexusTicketView
{
I3D = 1,
Caption = "Global View A",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = true,
Configuration = "{}"
};
session.Save(globalView1, 1);
var globalView2 = new NexusTicketView
{
I3D = 2,
Caption = "Global View B",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = true,
Configuration = "{}"
};
session.Save(globalView2, 2);
// Create non-global view
var nonGlobalView = new NexusTicketView
{
I3D = 3,
Caption = "Non Global View",
CreatedByI3D = 1,
IsDefault = false,
IsGlobal = false,
Configuration = "{}"
};
session.Save(nonGlobalView, 3);
session.Flush();
// Act
var result = bl.GetGlobalViews();
// Assert
Assert.NotNull(result);
Assert.Equal(2, result.Count);
Assert.All(result, view => Assert.True(view.IsGlobal));
Assert.Equal("Global View A", result[0].Caption);
Assert.Equal("Global View B", result[1].Caption);
}
[Fact]
public void AddGlobalViewAsOwn_ValidGlobalView_CreatesOwnReference()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
// Create global view
var globalView = new NexusTicketView
{
I3D = 1,
Caption = "Global View",
CreatedByI3D = 2,
IsDefault = false,
IsGlobal = true,
Configuration = "{\"test\": \"config\"}"
};
session.Save(globalView, 1);
session.Flush();
// Act
var result = bl.AddGlobalViewAsOwn(1, loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal("Global View", result.Caption);
Assert.Equal(appUser.Employee.I3D, result.CreatedByI3D);
Assert.Equal(globalView.I3D, result.GlobalViewI3D);
Assert.Equal(1, result.IndexOf);
Assert.False(result.IsDefault);
Assert.False(result.IsGlobal);
}
[Fact]
public void AddGlobalViewAsOwn_WebAccountLogin_CreatesOwnReference()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var webAccount = DbSetupUtils.SaveWebAccount(session, "webuser", "web@example.com", 2, "webpass");
var ticket = new Ticket { UserI3D = 2, WebAccount = webAccount };
var loggedInUser = new LoggedInUser(null, ticket);
// Create global view
var globalView = new NexusTicketView
{
I3D = 1,
Caption = "Global View",
CreatedByI3D = 3,
IsDefault = false,
IsGlobal = true,
Configuration = "{\"test\": \"config\"}"
};
session.Save(globalView, 1);
session.Flush();
// Act
var result = bl.AddGlobalViewAsOwn(1, loggedInUser);
// Assert
Assert.NotNull(result);
Assert.Equal("Global View", result.Caption);
Assert.Equal(webAccount.I3D, result.CreatedByI3D);
Assert.Equal(globalView.I3D, result.GlobalViewI3D);
Assert.Equal(1, result.IndexOf);
Assert.False(result.IsDefault);
Assert.False(result.IsGlobal);
}
[Fact]
public void AddGlobalViewAsOwn_NonExistingGlobalView_ReturnsNull()
{
// Arrange
var session = CreateSession();
var daoSession = new DAOSession(session);
var bl = new NexusTicketViewBL(daoSession);
var appUser = DbSetupUtils.SaveAppUser(session, "TestUser", "test@example.com", 1);
var loggedInUser = new LoggedInUser(appUser);
// Act
var result = bl.AddGlobalViewAsOwn(999, loggedInUser);
// Assert
Assert.Null(result);
}
private static ISession CreateSession()
{
var fluentConfiguration = Fluently.Configure()
.Database(SQLiteConfiguration.Standard.InMemory)
.Mappings(m => m.FluentMappings.Add<NexusTicketViewMaps>())
.Mappings(m => m.FluentMappings.Add<AppUserMaps>())
.Mappings(m => m.FluentMappings.Add<EmployeeCompactMaps>())
.Mappings(m => m.FluentMappings.Add<WebAccountMaps>())
.Mappings(m => m.FluentMappings.Add<TicketMaps>())
.Mappings(m => m.FluentMappings.Add<SupportLevelMaps>())
.Mappings(m => m.FluentMappings.Add<MandatorMaps>())
.Mappings(m => m.FluentMappings.Add<CountryMaps>())
.Mappings(m => m.FluentMappings.Add<FederalStateMaps>())
.Mappings(m => m.FluentMappings.Add<AppUserGroupMaps>())
.Mappings(m => m.FluentMappings.Add<WebRightsMaps>())
.Mappings(m => m.FluentMappings.Add<WebRightsCategoriesMaps>())
.Mappings(m => m.FluentMappings.Add<AppRightMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerMapsForTest>())
.Mappings(m => m.FluentMappings.Add<AccountMaps>())
.Mappings(m => m.FluentMappings.Add<AccountAddressMaps>())
.Mappings(m => m.FluentMappings.Add<AccountAddressContactMaps>())
.Mappings(m => m.FluentMappings.Add<GeoInfoMaps>())
.Mappings(m => m.FluentMappings.Add<AddressMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerBusinessLineMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerInterestMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerProductMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerArticleMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerSpecialPriceMaps>())
.Mappings(m => m.FluentMappings.Add<ActivityMaps>())
.Mappings(m => m.FluentMappings.Add<AppSettingMaps>())
.Mappings(m => m.FluentMappings.Add<EmployeeDepartmentMaps>())
.Mappings(m => m.FluentMappings.Add<EmployeeArticleMaps>())
.Mappings(m => m.FluentMappings.Add<ApplicationVersionMaps>())
.Mappings(m => m.FluentMappings.Add<WebRightsCategoriesMaps>())
.Mappings(m => m.FluentMappings.Add<ContactPersonMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerCompactMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerDepartmentMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerSalutationMaps>())
.Mappings(m => m.FluentMappings.Add<BusinessLineMaps>())
.Mappings(m => m.FluentMappings.Add<SupplierMaps>())
.Mappings(m => m.FluentMappings.Add<ArticleMaps>())
.Mappings(m => m.FluentMappings.Add<ArticleUnitMaps>())
.Mappings(m => m.FluentMappings.Add<ArticleLightMaps>())
.Mappings(m => m.FluentMappings.Add<PartListArticleMaps>())
.Mappings(m => m.FluentMappings.Add<ArticleCompactMaps>())
.Mappings(m => m.FluentMappings.Add<ArticleStockInfoMaps>())
.Mappings(m => m.FluentMappings.Add<SecondaryStockArticleMaps>())
.Mappings(m => m.FluentMappings.Add<ValueAddedTaxMaps>())
.Mappings(m => m.FluentMappings.Add<CostObjectMaps>())
.Mappings(m => m.FluentMappings.Add<StockMaps>())
.Mappings(m => m.FluentMappings.Add<StorageAreaMaps>())
.Mappings(m => m.FluentMappings.Add<SpecialAgreementMaps>())
.Mappings(m => m.FluentMappings.Add<SpecialAgreementArticleMaps>())
.Mappings(m => m.FluentMappings.Add<InterestMaps>())
.Mappings(m => m.FluentMappings.Add<ProductMaps>())
.Mappings(m => m.FluentMappings.Add<MaterialGroupMaps>())
.Mappings(m => m.FluentMappings.Add<MaterialGroupCompactMaps>())
.Mappings(m => m.FluentMappings.Add<MaterialMarkupMaps>())
.Mappings(m => m.FluentMappings.Add<SecondaryMaterialGroupMaps>())
.Mappings(m => m.FluentMappings.Add<SecondaryMaterialGroupCompactMaps>())
.Mappings(m => m.FluentMappings.Add<SecondaryMaterialMarkupMaps>())
.Mappings(m => m.FluentMappings.Add<DirectoryMaps>())
.Mappings(m => m.FluentMappings.Add<CustomerDirectoryMaps>())
.Mappings(m => m.FluentMappings.Add<DocumentMaps>())
.Mappings(m => m.FluentMappings.Add<CostCenterMaps>())
.Mappings(m => m.FluentMappings.Add<TicketMaps>())
.Mappings(m => m.FluentMappings.Add<EmployeeMaps>());
var sessionFactory = fluentConfiguration.BuildSessionFactory();
var session = sessionFactory.OpenSession();
new SchemaExport(fluentConfiguration.BuildConfiguration()).Execute(true, true, false, session.Connection,
Console.Out);
return session;
}
}