using ZB.MOM.WW.CBDDC.Core; using ZB.MOM.WW.CBDDC.Core.Storage; using ZB.MOM.WW.CBDDC.Core.Sync; using ZB.MOM.WW.CBDDC.Persistence.BLite; using Microsoft.Extensions.Logging.Abstractions; using System.Text.Json; namespace ZB.MOM.WW.CBDDC.Sample.Console.Tests; public class SampleDbContextTests : IDisposable { private readonly string _dbPath; private readonly SampleDbContext _context; /// /// Initializes a new test context backed by a temporary database file. /// public SampleDbContextTests() { _dbPath = Path.Combine(Path.GetTempPath(), $"test_sample_{Guid.NewGuid()}.db"); _context = new SampleDbContext(_dbPath); } /// /// Releases test resources and removes the temporary database file. /// public void Dispose() { _context?.Dispose(); if (File.Exists(_dbPath)) { try { File.Delete(_dbPath); } catch { } } } /// /// Verifies that required collections are initialized in the context. /// [Fact] public void Context_ShouldInitializeCollections() { // Verifica che le collezioni siano state inizializzate _context.ShouldNotBeNull(); _context.Users.ShouldNotBeNull("Users collection should be initialized by BLite"); _context.TodoLists.ShouldNotBeNull("TodoLists collection should be initialized by BLite"); _context.OplogEntries.ShouldNotBeNull("OplogEntries collection should be initialized by BLite"); } /// /// Verifies that inserting a user persists the document. /// [Fact] public async Task Users_Insert_ShouldPersist() { // Arrange var user = new User { Id = "user1", Name = "Alice", Age = 30, Address = new Address { City = "Rome" } }; // Act await _context.Users.InsertAsync(user); await _context.SaveChangesAsync(); // Assert var retrieved = _context.Users.FindById("user1"); retrieved.ShouldNotBeNull(); retrieved!.Name.ShouldBe("Alice"); retrieved.Age.ShouldBe(30); retrieved.Address?.City.ShouldBe("Rome"); } /// /// Verifies that updating a user modifies the existing document. /// [Fact] public async Task Users_Update_ShouldModifyExisting() { // Arrange var user = new User { Id = "user2", Name = "Bob", Age = 25 }; await _context.Users.InsertAsync(user); await _context.SaveChangesAsync(); // Act user.Age = 26; user.Address = new Address { City = "Milan" }; await _context.Users.UpdateAsync(user); await _context.SaveChangesAsync(); // Assert var retrieved = _context.Users.FindById("user2"); retrieved.ShouldNotBeNull(); retrieved!.Age.ShouldBe(26); retrieved.Address?.City.ShouldBe("Milan"); } /// /// Verifies that deleting a user removes the document. /// [Fact] public async Task Users_Delete_ShouldRemove() { // Arrange var user = new User { Id = "user3", Name = "Charlie", Age = 35 }; await _context.Users.InsertAsync(user); await _context.SaveChangesAsync(); // Act await _context.Users.DeleteAsync("user3"); await _context.SaveChangesAsync(); // Assert var retrieved = _context.Users.FindById("user3"); retrieved.ShouldBeNull(); } /// /// Verifies that inserting a todo list with items persists nested data. /// [Fact] public async Task TodoLists_InsertWithItems_ShouldPersist() { // Arrange var todoList = new TodoList { Id = "list1", Name = "Shopping", Items = new List { new() { Task = "Buy milk", Completed = false }, new() { Task = "Buy bread", Completed = true } } }; // Act await _context.TodoLists.InsertAsync(todoList); await _context.SaveChangesAsync(); // Assert var retrieved = _context.TodoLists.FindById("list1"); retrieved.ShouldNotBeNull(); retrieved!.Name.ShouldBe("Shopping"); retrieved.Items.Count.ShouldBe(2); retrieved.Items.ShouldContain(i => i.Task == "Buy milk" && !i.Completed); retrieved.Items.ShouldContain(i => i.Task == "Buy bread" && i.Completed); } /// /// Verifies that updating todo items modifies the nested collection. /// [Fact] public async Task TodoLists_UpdateItems_ShouldModifyNestedCollection() { // Arrange var todoList = new TodoList { Id = "list2", Name = "Work Tasks", Items = new List { new() { Task = "Write report", Completed = false } } }; await _context.TodoLists.InsertAsync(todoList); await _context.SaveChangesAsync(); // Act - Mark task as completed and add new task todoList.Items[0].Completed = true; todoList.Items.Add(new TodoItem { Task = "Review report", Completed = false }); await _context.TodoLists.UpdateAsync(todoList); await _context.SaveChangesAsync(); // Assert var retrieved = _context.TodoLists.FindById("list2"); retrieved.ShouldNotBeNull(); retrieved!.Items.Count.ShouldBe(2); retrieved.Items.First().Completed.ShouldBe(true); retrieved.Items.Last().Completed.ShouldBe(false); } /// /// Verifies that querying all users returns all inserted users. /// [Fact] public void Users_FindAll_ShouldReturnAllUsers() { // Arrange _context.Users.InsertAsync(new User { Id = "u1", Name = "User1", Age = 20 }).Wait(); _context.Users.InsertAsync(new User { Id = "u2", Name = "User2", Age = 30 }).Wait(); _context.Users.InsertAsync(new User { Id = "u3", Name = "User3", Age = 40 }).Wait(); _context.SaveChangesAsync().Wait(); // Act var allUsers = _context.Users.FindAll().ToList(); // Assert allUsers.Count.ShouldBe(3); allUsers.Select(u => u.Name).ShouldContain("User1"); allUsers.Select(u => u.Name).ShouldContain("User2"); allUsers.Select(u => u.Name).ShouldContain("User3"); } /// /// Verifies that predicate-based queries return only matching users. /// [Fact] public void Users_Find_WithPredicate_ShouldFilterCorrectly() { // Arrange _context.Users.InsertAsync(new User { Id = "f1", Name = "Young", Age = 18 }).Wait(); _context.Users.InsertAsync(new User { Id = "f2", Name = "Adult", Age = 30 }).Wait(); _context.Users.InsertAsync(new User { Id = "f3", Name = "Senior", Age = 65 }).Wait(); _context.SaveChangesAsync().Wait(); // Act var adults = _context.Users.Find(u => u.Age >= 30).ToList(); // Assert adults.Count.ShouldBe(2); adults.Select(u => u.Name).ShouldContain("Adult"); adults.Select(u => u.Name).ShouldContain("Senior"); } }