using System.Collections; using AyCode.Core.Enums; using AyCode.Core.Extensions; using AyCode.Core.Helpers; using AyCode.Core.Serializers.Jsons; using AyCode.Core.Tests.TestModels; using AyCode.Services.Server.SignalRs; using AyCode.Services.SignalRs; namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources; #region Abstract Test Base /// /// Base class for SignalR DataSource tests with full round-trip coverage. /// Tests the complete path: DataSource -> SignalRClient -> SignalRHub -> Service -> Response -> SignalRClient -> DataSource /// Derived classes specify the serializer type and collection type. /// /// The concrete DataSource type /// The inner list type (List or AcObservableCollection) public abstract class SignalRDataSourceTestBase where TDataSource : AcSignalRDataSource where TIList : class, IList { protected abstract AcSerializerOptions SerializerOption { get; } protected abstract TDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags); protected TestLogger _logger = null!; protected TestableSignalRHub2 _hub = null!; protected TestableSignalRClient2 _client = null!; protected TestSignalRService2 _service = null!; protected SignalRCrudTags _crudTags = null!; [TestInitialize] public void Setup() { _logger = new TestLogger(); _hub = new TestableSignalRHub2(); _service = new TestSignalRService2(); _client = new TestableSignalRClient2(_hub, _logger); _hub.SetSerializerType(SerializerOption); _hub.RegisterService(_service, _client); _crudTags = new SignalRCrudTags( TestSignalRTags.DataSourceGetAll, TestSignalRTags.DataSourceGetItem, TestSignalRTags.DataSourceAdd, TestSignalRTags.DataSourceUpdate, TestSignalRTags.DataSourceRemove ); } #region LoadDataSource Tests [TestMethod] public virtual async Task LoadDataSource_ReturnsAllItems() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); Assert.AreEqual(3, dataSource.Count); Assert.AreEqual("Product A", dataSource[0].ProductName); Assert.AreEqual("Product B", dataSource[1].ProductName); Assert.AreEqual("Product C", dataSource[2].ProductName); } [TestMethod] public virtual async Task LoadDataSource_ClearsChangeTracking_ByDefault() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 999, ProductName = "Tracked" }); Assert.AreEqual(1, dataSource.GetTrackingItems().Count); await dataSource.LoadDataSource(); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task LoadDataSource_PreservesChangeTracking_WhenFalse() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); dataSource.Add(new TestOrderItem { Id = 999, ProductName = "Tracked" }); await dataSource.LoadDataSource(clearChangeTracking: false); Assert.AreEqual(1, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task LoadDataSource_InvokesOnDataSourceLoaded() { var dataSource = CreateDataSource(_client, _crudTags); var callbackInvoked = false; dataSource.OnDataSourceLoaded = () => { callbackInvoked = true; return Task.CompletedTask; }; await dataSource.LoadDataSource(); Assert.IsTrue(callbackInvoked); } [TestMethod] public virtual async Task LoadDataSource_MultipleCalls_RefreshesData() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var firstCount = dataSource.Count; await dataSource.LoadDataSource(); var secondCount = dataSource.Count; Assert.AreEqual(firstCount, secondCount); Assert.AreEqual(3, secondCount); } #endregion #region LoadDataSourceAsync Tests [TestMethod] public virtual async Task LoadDataSourceAsync_LoadsDataViaCallback() { var dataSource = CreateDataSource(_client, _crudTags); var loadCompleted = false; dataSource.OnDataSourceLoaded = () => { loadCompleted = true; return Task.CompletedTask; }; await dataSource.LoadDataSourceAsync(); Assert.IsTrue(TaskHelper.WaitTo(() => loadCompleted, 5000)); Assert.AreEqual(3, dataSource.Count); } #endregion #region LoadItem Tests [TestMethod] public virtual async Task LoadItem_ReturnsSingleItem() { var dataSource = CreateDataSource(_client, _crudTags); var result = await dataSource.LoadItem(2); Assert.IsNotNull(result); Assert.AreEqual(2, result.Id); Assert.AreEqual("Product B", result.ProductName); } [TestMethod] public virtual async Task LoadItem_AddsToDataSource_WhenNotExists() { var dataSource = CreateDataSource(_client, _crudTags); Assert.AreEqual(0, dataSource.Count); await dataSource.LoadItem(1); Assert.AreEqual(1, dataSource.Count); Assert.AreEqual("Product A", dataSource[0].ProductName); } [TestMethod] public virtual async Task LoadItem_UpdatesExisting_WhenAlreadyLoaded() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var originalItem = dataSource[0]; var reloaded = await dataSource.LoadItem(originalItem.Id); Assert.AreEqual(3, dataSource.Count); Assert.IsNotNull(reloaded); } [TestMethod] public virtual async Task LoadItem_InvokesOnDataSourceItemChanged() { var dataSource = CreateDataSource(_client, _crudTags); ItemChangedEventArgs? eventArgs = null; dataSource.OnDataSourceItemChanged = args => { eventArgs = args; return Task.CompletedTask; }; await dataSource.LoadItem(1); Assert.IsNotNull(eventArgs); Assert.AreEqual(TrackingState.Get, eventArgs.TrackingState); Assert.AreEqual(1, eventArgs.Item.Id); } [TestMethod] public virtual async Task LoadItem_ReturnsNull_WhenNotFound() { var dataSource = CreateDataSource(_client, _crudTags); var result = await dataSource.LoadItem(9999); Assert.IsNull(result); } #endregion #region Add Tests [TestMethod] public virtual async Task Add_WithAutoSave_AddsItem() { var dataSource = CreateDataSource(_client, _crudTags); var newItem = new TestOrderItem { Id = 100, ProductName = "New Product", Quantity = 5, UnitPrice = 50m }; var result = await dataSource.Add(newItem, autoSave: true); Assert.AreEqual(1, dataSource.Count); Assert.AreEqual("New Product", result.ProductName); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual void Add_WithoutAutoSave_AddsToTrackingOnly() { var dataSource = CreateDataSource(_client, _crudTags); var newItem = new TestOrderItem { Id = 100, ProductName = "New Product" }; dataSource.Add(newItem); Assert.AreEqual(1, dataSource.Count); Assert.AreEqual(1, dataSource.GetTrackingItems().Count); Assert.AreEqual(TrackingState.Add, dataSource.GetTrackingItems()[0].TrackingState); } [TestMethod] public virtual void Add_DuplicateId_ThrowsException() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 100, ProductName = "First" }); Assert.ThrowsExactly(() => { dataSource.Add(new TestOrderItem { Id = 100, ProductName = "Duplicate" }); }); } [TestMethod] public virtual void Add_DefaultId_ThrowsException() { var dataSource = CreateDataSource(_client, _crudTags); Assert.ThrowsExactly(() => { dataSource.Add(new TestOrderItem { Id = 0, ProductName = "Invalid" }); }); } [TestMethod] public virtual void AddRange_AddsMultipleItems() { var dataSource = CreateDataSource(_client, _crudTags); var items = new[] { new TestOrderItem { Id = 101, ProductName = "Item 1" }, new TestOrderItem { Id = 102, ProductName = "Item 2" }, new TestOrderItem { Id = 103, ProductName = "Item 3" } }; dataSource.AddRange(items); Assert.AreEqual(3, dataSource.Count); } #endregion #region AddOrUpdate Tests [TestMethod] public virtual async Task AddOrUpdate_AddsNew_WhenNotExists() { var dataSource = CreateDataSource(_client, _crudTags); var newItem = new TestOrderItem { Id = 200, ProductName = "Brand New" }; var result = await dataSource.AddOrUpdate(newItem, autoSave: true); Assert.AreEqual(1, dataSource.Count); Assert.AreEqual("Brand New", result.ProductName); } [TestMethod] public virtual async Task AddOrUpdate_UpdatesExisting_WhenExists() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var existingId = dataSource[0].Id; var updatedItem = new TestOrderItem { Id = existingId, ProductName = "Updated Name", Quantity = 999 }; _ = await dataSource.AddOrUpdate(updatedItem, autoSave: true); Assert.AreEqual(3, dataSource.Count); Assert.AreEqual("Updated Name", dataSource[0].ProductName); } #endregion #region Insert Tests [TestMethod] public virtual void Insert_AtIndex_InsertsCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" }); dataSource.Add(new TestOrderItem { Id = 3, ProductName = "Third" }); dataSource.Insert(1, new TestOrderItem { Id = 2, ProductName = "Second" }); Assert.AreEqual(3, dataSource.Count); Assert.AreEqual("Second", dataSource[1].ProductName); Assert.AreEqual(3, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task Insert_WithAutoSave_SavesImmediately() { var dataSource = CreateDataSource(_client, _crudTags); var newItem = new TestOrderItem { Id = 500, ProductName = "Inserted" }; _ = await dataSource.Insert(0, newItem, autoSave: true); Assert.AreEqual(1, dataSource.Count); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } #endregion #region Update Tests [TestMethod] public virtual async Task Update_ByIndex_UpdatesCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var updatedItem = new TestOrderItem { Id = dataSource[0].Id, ProductName = "Updated Product", Quantity = 100 }; _ = await dataSource.Update(0, updatedItem, autoSave: true); Assert.AreEqual("Updated Product", dataSource[0].ProductName); Assert.AreEqual(100, dataSource[0].Quantity); } [TestMethod] public virtual async Task Update_ByItem_UpdatesCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var updatedItem = new TestOrderItem { Id = dataSource[1].Id, ProductName = "Updated B", Quantity = 50 }; _ = await dataSource.Update(updatedItem, autoSave: true); Assert.AreEqual("Updated B", dataSource[1].ProductName); } [TestMethod] public virtual void Indexer_Set_TracksUpdate() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Original" }); dataSource[0] = new TestOrderItem { Id = 1, ProductName = "Modified" }; Assert.AreEqual(1, dataSource.GetTrackingItems().Count); Assert.AreEqual(TrackingState.Add, dataSource.GetTrackingItems()[0].TrackingState); } #endregion #region Remove Tests [TestMethod] public virtual async Task Remove_ById_RemovesItem() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var idToRemove = dataSource[0].Id; var result = await dataSource.Remove(idToRemove, autoSave: true); Assert.IsTrue(result); Assert.AreEqual(2, dataSource.Count); } [TestMethod] public virtual async Task Remove_ByItem_RemovesItem() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var itemToRemove = dataSource[1]; var result = await dataSource.Remove(itemToRemove, autoSave: true); Assert.IsTrue(result); Assert.AreEqual(2, dataSource.Count); } [TestMethod] public virtual void Remove_WithoutAutoSave_TracksRemoval() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "ToRemove" }); dataSource.GetTrackingItems().Clear(); dataSource.Remove(dataSource[0]); Assert.AreEqual(0, dataSource.Count); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); Assert.AreEqual(TrackingState.Remove, dataSource.GetTrackingItems()[0].TrackingState); } [TestMethod] public virtual void RemoveAt_RemovesCorrectItem() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" }); dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Second" }); dataSource.Add(new TestOrderItem { Id = 3, ProductName = "Third" }); dataSource.GetTrackingItems().Clear(); dataSource.RemoveAt(1); Assert.AreEqual(2, dataSource.Count); Assert.AreEqual("First", dataSource[0].ProductName); Assert.AreEqual("Third", dataSource[1].ProductName); } [TestMethod] public virtual async Task RemoveAt_WithAutoSave_SavesImmediately() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); await dataSource.RemoveAt(0, autoSave: true); Assert.AreEqual(2, dataSource.Count); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual void TryRemove_ReturnsTrue_WhenExists() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Test" }); var result = dataSource.TryRemove(1, out var removedItem); Assert.IsTrue(result); Assert.IsNotNull(removedItem); Assert.AreEqual("Test", removedItem.ProductName); } [TestMethod] public virtual void TryRemove_ReturnsFalse_WhenNotExists() { var dataSource = CreateDataSource(_client, _crudTags); var result = dataSource.TryRemove(9999, out var removedItem); Assert.IsFalse(result); Assert.IsNull(removedItem); } #endregion #region SaveChanges Tests [TestMethod] public virtual async Task SaveChanges_SavesTrackedItems() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 101, ProductName = "Item 1" }); dataSource.Add(new TestOrderItem { Id = 102, ProductName = "Item 2" }); var unsaved = await dataSource.SaveChanges(); Assert.AreEqual(0, unsaved.Count); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task SaveChangesAsync_ClearsTracking() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 103, ProductName = "Item 3" }); await dataSource.SaveChangesAsync(); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task SaveItem_ById_SavesSpecificItem() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 201, ProductName = "Specific" }); var result = await dataSource.SaveItem(201); Assert.AreEqual("Specific", result.ProductName); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task SaveItem_WithTrackingState_SavesCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var item = dataSource[0]; var result = await dataSource.SaveItem(item, TrackingState.Update); Assert.IsNotNull(result); } #endregion #region Tracking Tests [TestMethod] public virtual void SetTrackingStateToUpdate_MarksItemForUpdate() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Test" }); //await dataSource.SaveChanges(); // Előbb mentsük el, hogy ne Add legyen a tracking state dataSource.SetTrackingStateToUpdate(dataSource[0]); Assert.AreEqual(1, dataSource.GetTrackingItems().Count); Assert.AreEqual(TrackingState.Update, dataSource.GetTrackingItems()[0].TrackingState); } [TestMethod] public virtual void SetTrackingStateToUpdate_DoesNotChangeAddState() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "New Item" }); dataSource.SetTrackingStateToUpdate(dataSource[0]); Assert.AreEqual(TrackingState.Add, dataSource.GetTrackingItems()[0].TrackingState); } [TestMethod] public virtual void TryGetTrackingItem_ReturnsTrue_WhenTracked() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Tracked" }); var result = dataSource.TryGetTrackingItem(1, out var trackingItem); Assert.IsTrue(result); Assert.IsNotNull(trackingItem); Assert.AreEqual(TrackingState.Add, trackingItem.TrackingState); } [TestMethod] public virtual void TryGetTrackingItem_ReturnsFalse_WhenNotTracked() { var dataSource = CreateDataSource(_client, _crudTags); var result = dataSource.TryGetTrackingItem(9999, out var trackingItem); Assert.IsFalse(result); Assert.IsNull(trackingItem); } #endregion #region Rollback Tests [TestMethod] public virtual void TryRollbackItem_RevertsAddedItem() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Added" }); var result = dataSource.TryRollbackItem(1, out var originalValue); Assert.IsTrue(result); Assert.AreEqual(0, dataSource.Count); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task TryRollbackItem_RevertsUpdatedItem() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var originalName = dataSource[0].ProductName; dataSource[0] = new TestOrderItem { Id = dataSource[0].Id, ProductName = "Changed" }; var result = dataSource.TryRollbackItem(dataSource[0].Id, out var originalValue); Assert.IsTrue(result); Assert.IsNotNull(originalValue); } [TestMethod] public virtual void Rollback_RevertsAllChanges() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" }); dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" }); dataSource.Rollback(); Assert.AreEqual(0, dataSource.Count); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } #endregion #region Collection Operations Tests [TestMethod] public virtual async Task Count_ReturnsCorrectValue() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); Assert.AreEqual(3, dataSource.Count); } [TestMethod] public virtual void Clear_RemovesAllItems() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" }); dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" }); dataSource.Clear(); Assert.AreEqual(0, dataSource.Count); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual void Clear_WithoutClearingTracking_PreservesTracking() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" }); dataSource.Clear(clearChangeTracking: false); Assert.AreEqual(0, dataSource.Count); Assert.AreEqual(1, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task Contains_ReturnsTrue_WhenItemExists() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); Assert.IsTrue(dataSource.Contains(dataSource[0])); } [TestMethod] public virtual void Contains_ReturnsFalse_WhenItemNotExists() { var dataSource = CreateDataSource(_client, _crudTags); Assert.IsFalse(dataSource.Contains(new TestOrderItem { Id = 9999 })); } [TestMethod] public virtual async Task IndexOf_ReturnsCorrectIndex() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); Assert.AreEqual(0, dataSource.IndexOf(dataSource[0])); Assert.AreEqual(1, dataSource.IndexOf(dataSource[1])); Assert.AreEqual(2, dataSource.IndexOf(dataSource[2])); } [TestMethod] public virtual void IndexOf_ById_ReturnsCorrectIndex() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 5, ProductName = "Item5" }); Assert.AreEqual(0, dataSource.IndexOf(5)); } [TestMethod] public virtual void TryGetIndex_ReturnsTrue_WhenExists() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 10, ProductName = "Test" }); var result = dataSource.TryGetIndex(10, out var index); Assert.IsTrue(result); Assert.AreEqual(0, index); } [TestMethod] public virtual async Task TryGetValue_ReturnsItem_WhenExists() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var result = dataSource.TryGetValue(1, out var item); Assert.IsTrue(result); Assert.IsNotNull(item); Assert.AreEqual("Product A", item.ProductName); } [TestMethod] public virtual void TryGetValue_ReturnsFalse_WhenNotExists() { var dataSource = CreateDataSource(_client, _crudTags); var result = dataSource.TryGetValue(9999, out var item); Assert.IsFalse(result); Assert.IsNull(item); } [TestMethod] public virtual async Task CopyTo_CopiesAllItems() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var array = new TestOrderItem[3]; dataSource.CopyTo(array); Assert.AreEqual("Product A", array[0].ProductName); Assert.AreEqual("Product B", array[1].ProductName); Assert.AreEqual("Product C", array[2].ProductName); } [TestMethod] public virtual async Task GetEnumerator_EnumeratesAllItems() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var count = dataSource.Count(); Assert.AreEqual(3, count); } [TestMethod] public virtual async Task AsReadOnly_ReturnsReadOnlyCollection() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var readOnly = dataSource.AsReadOnly(); Assert.AreEqual(3, readOnly.Count); Assert.IsInstanceOfType(readOnly, typeof(System.Collections.ObjectModel.ReadOnlyCollection)); } #endregion #region Working Reference List Tests [TestMethod] public virtual async Task SetWorkingReferenceList_SetsNewInnerList() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var externalList = Activator.CreateInstance(); dataSource.SetWorkingReferenceList(externalList); Assert.IsTrue(dataSource.HasWorkingReferenceList); Assert.AreEqual(3, dataSource.Count); } [TestMethod] public virtual async Task GetReferenceInnerList_ReturnsInnerList() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); var innerList = dataSource.GetReferenceInnerList(); Assert.IsNotNull(innerList); Assert.AreEqual(3, innerList.Count); } #endregion #region Sync State Tests [TestMethod] public virtual void IsSyncing_IsFalse_Initially() { var dataSource = CreateDataSource(_client, _crudTags); Assert.IsFalse(dataSource.IsSyncing); } [TestMethod] public virtual async Task OnSyncingStateChanged_Fires_DuringLoad() { var dataSource = CreateDataSource(_client, _crudTags); var syncStarted = false; var syncEnded = false; dataSource.OnSyncingStateChanged += isSyncing => { if (isSyncing) syncStarted = true; else syncEnded = true; }; await dataSource.LoadDataSource(); Assert.IsTrue(syncStarted); Assert.IsTrue(syncEnded); } #endregion #region Context and Filter Tests [TestMethod] public virtual void ContextIds_CanBeSetAndRetrieved() { var dataSource = CreateDataSource(_client, _crudTags); var contextIds = new object[] { 1, "test", Guid.NewGuid() }; dataSource.ContextIds = contextIds; Assert.AreEqual(3, dataSource.ContextIds?.Length); } [TestMethod] public virtual void FilterText_CanBeSetAndRetrieved() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.FilterText = "search term"; Assert.AreEqual("search term", dataSource.FilterText); } #endregion #region IList Interface Tests [TestMethod] public virtual void IList_Add_ReturnsCorrectIndex() { var dataSource = CreateDataSource(_client, _crudTags); var item = new TestOrderItem { Id = 1, ProductName = "Test" }; var index = ((IList)dataSource).Add(item); Assert.AreEqual(0, index); } [TestMethod] public virtual void IList_Contains_WorksCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); var item = new TestOrderItem { Id = 1, ProductName = "Test" }; dataSource.Add(item); Assert.IsTrue(((IList)dataSource).Contains(item)); } [TestMethod] public virtual void IList_IndexOf_WorksCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); var item = new TestOrderItem { Id = 1, ProductName = "Test" }; dataSource.Add(item); Assert.AreEqual(0, ((IList)dataSource).IndexOf(item)); } [TestMethod] public virtual void IList_Insert_WorksCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" }); var newItem = new TestOrderItem { Id = 2, ProductName = "Inserted" }; ((IList)dataSource).Insert(0, newItem); Assert.AreEqual("Inserted", dataSource[0].ProductName); } [TestMethod] public virtual void IList_Remove_WorksCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); var item = new TestOrderItem { Id = 1, ProductName = "Test" }; dataSource.Add(item); ((IList)dataSource).Remove(item); Assert.AreEqual(0, dataSource.Count); } [TestMethod] public virtual void IList_Indexer_GetSet_WorksCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Original" }); ((IList)dataSource)[0] = new TestOrderItem { Id = 1, ProductName = "Modified" }; Assert.AreEqual("Modified", dataSource[0].ProductName); } [TestMethod] public virtual void ICollection_CopyTo_WorksCorrectly() { var dataSource = CreateDataSource(_client, _crudTags); dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" }); dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" }); var array = new TestOrderItem[2]; ((ICollection)dataSource).CopyTo(array, 0); Assert.AreEqual("Item1", array[0].ProductName); Assert.AreEqual("Item2", array[1].ProductName); } [TestMethod] public virtual void IsSynchronized_ReturnsTrue() { var dataSource = CreateDataSource(_client, _crudTags); Assert.IsTrue(dataSource.IsSynchronized); } [TestMethod] public virtual void SyncRoot_IsNotNull() { var dataSource = CreateDataSource(_client, _crudTags); Assert.IsNotNull(dataSource.SyncRoot); } [TestMethod] public virtual void IsFixedSize_ReturnsFalse() { var dataSource = CreateDataSource(_client, _crudTags); Assert.IsFalse(dataSource.IsFixedSize); } [TestMethod] public virtual void IsReadOnly_ReturnsFalse() { var dataSource = CreateDataSource(_client, _crudTags); Assert.IsFalse(((IList)dataSource).IsReadOnly); } #endregion #region Edge Cases [TestMethod] public virtual async Task Indexer_OutOfRange_ThrowsException() { var dataSource = CreateDataSource(_client, _crudTags); await dataSource.LoadDataSource(); Assert.ThrowsExactly(() => _ = dataSource[999]); } [TestMethod] public virtual void Add_ThenRemove_ClearsTracking() { var dataSource = CreateDataSource(_client, _crudTags); var item = new TestOrderItem { Id = 1, ProductName = "Temporary" }; dataSource.Add(item); Assert.AreEqual(1, dataSource.GetTrackingItems().Count); dataSource.Remove(item); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); } [TestMethod] public virtual async Task ComplexWorkflow_AddUpdateRemoveSave() { var dataSource = CreateDataSource(_client, _crudTags); // Add items dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1", Quantity = 10 }); dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2", Quantity = 20 }); Assert.AreEqual(2, dataSource.GetTrackingItems().Count); // Save await dataSource.SaveChanges(); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); // Update dataSource[0] = new TestOrderItem { Id = 1, ProductName = "Updated1", Quantity = 100 }; Assert.AreEqual(1, dataSource.GetTrackingItems().Count); Assert.AreEqual(TrackingState.Update, dataSource.GetTrackingItems()[0].TrackingState); // Remove dataSource.Remove(dataSource[1]); Assert.AreEqual(2, dataSource.GetTrackingItems().Count); // Save all changes await dataSource.SaveChanges(); Assert.AreEqual(0, dataSource.GetTrackingItems().Count); Assert.AreEqual(1, dataSource.Count); } #endregion } #endregion