public void ShouldCreateSoftDeleteLog2() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; //create a softdeletable entity and soft delete it var deletable = new SoftDeletableModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.SoftDeletableModels.Add(deletable); //add ttc.SaveChanges(); //add deletable.AssertAuditForAddition(ttc, deletable.Id, null, x => x.Id); ttc.SoftDeletableModels.Remove(deletable); //soft delete ttc.SaveChanges(); //soft delete //assert for soft deletion deletable.AssertAuditForSoftDeletion(ttc, deletable.Id, null, new AuditLogDetail { NewValue = true.ToString(), OriginalValue = false.ToString(), PropertyName = nameof(deletable.IsDeleted) }); } }
public async Task Can_skip_tracking_of_property() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; string username = rdg.Get <string>(); //add enitties var entity = new ModelWithSkipTracking { TrackedProperty = Guid.NewGuid(), UnTrackedProperty = rdg.Get <string>() }; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.ModelWithSkipTrackings.Add(entity); await ttc.SaveChangesAsync(username, CancellationToken.None); //assert enity added entity.Id.AssertIsNotZero(); //assert addtion entity.AssertAuditForAddition(ttc, entity.Id, username, x => x.TrackedProperty, x => x.Id); } }
public void should_be_able_to_delete() { EntityTracker.TrackAllProperties <TrackedModelWithMultipleProperties>() .Except(x => x.IsSpecial); TrackedModelWithMultipleProperties existingModel = new TrackedModelWithMultipleProperties(); var newModel = new TrackedModelWithMultipleProperties { Id = existingModel.Id }; using (TestTrackerContext newContextInstance = GetNewContextInstance()) { newContextInstance.TrackedModelWithMultipleProperties.Attach(newModel); newContextInstance.Entry(newModel).State = EntityState.Deleted; newContextInstance.SaveChanges(); existingModel.AssertAuditForDeletion(newContextInstance, newModel.Id, null, model => model.Id, model => model.Name, model => model.StartDate, model => model.Value, model => model.Description ); } }
public void Should_Log_EmptyProperties_When_Configured_WhileDeleting() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; //arrange EntityTracker.TrackAllProperties <TrackedModelWithMultipleProperties>(); GlobalTrackingConfig.TrackEmptyPropertiesOnAdditionAndDeletion = true; var entity = new TrackedModelWithMultipleProperties(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.TrackedModelWithMultipleProperties.Add(entity); ttc.SaveChanges(); //act ttc.TrackedModelWithMultipleProperties.Remove(entity); ttc.SaveChanges(); //assert entity.AssertAuditForDeletion(ttc, entity.Id, null, x => x.Id, x => x.Description, x => x.IsSpecial, x => x.Name, x => x.StartDate, x => x.Value); } }
public void Can_track_deletion() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; string description = rdg.Get <string>(); string userName = rdg.Get <string>(); //add NormalModel normalModel = new NormalModel(); normalModel.Description = description; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.NormalModels.Add(normalModel); ttc.SaveChanges(userName); //remove ttc.NormalModels.Remove(normalModel); ttc.SaveChanges(userName); normalModel.AssertAuditForDeletion(ttc, normalModel.Id, userName, x => x.Description, x => x.Id); } }
public void Can_track_deletion_when_state_changed() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; string description = rdg.Get <string>(); //add NormalModel normalModel = new NormalModel(); normalModel.Description = description; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.NormalModels.Add(normalModel); ttc.SaveChanges(); //remove ttc.Entry(normalModel).State = EntityState.Deleted; ttc.SaveChanges(); //assert normalModel.AssertAuditForDeletion(ttc, normalModel.Id, null, x => x.Description, x => x.Id); } }
public void Should_Be_Soft_Deleted() { GlobalTrackingConfig.SetSoftDeletableCriteria <ISoftDeletable>(x => x.IsDeleted); SoftDeletableModel entity = new SoftDeletableModel(); SoftDeletableModel newEntity = new SoftDeletableModel { Id = entity.Id, Description = entity.Description }; using (TestTrackerContext newContext2 = GetNewContextInstance()) { newEntity.IsDeleted = true; newContext2.Entry(newEntity).State = EntityState.Modified; newContext2.SaveChanges(); newEntity.AssertAuditForSoftDeletion(newContext2, newEntity.Id, null, new AuditLogDetail { PropertyName = nameof(entity.IsDeleted), OriginalValue = false.ToString(), NewValue = true.ToString() }); } }
public void Should_Be_Able_To_Update() { NormalModel entity = new NormalModel(); NormalModel newEntity = new NormalModel { Id = entity.Id, Description = rdg.Get <string>() }; using (TestTrackerContext newContext2 = GetNewContextInstance()) { newContext2.NormalModels.Attach(newEntity); newContext2.Entry(newEntity).State = EntityState.Modified; newContext2.SaveChanges(); newEntity.AssertAuditForModification(newContext2, newEntity.Id, null, new AuditLogDetail { NewValue = newEntity.Description, OriginalValue = entity.Description, PropertyName = nameof(NormalModel.Description) }); } }
public async Task ShouldAddSingleMetadata_WhenSingleMetadataIsProvided_Async() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.ConfigureMetadata(m => { m.IpAddress = "192.168.2.23"; }); EntityTracker.TrackAllProperties <POCO>(); POCO entity = new POCO(); ttc.POCOes.Add(entity); await ttc.SaveChangesAsync("bilal"); entity.AssertAuditForAddition(ttc, entity.Id, "bilal", x => x.Color, x => x.Height, x => x.StartTime, x => x.Id); entity.AssertMetadata(ttc, entity.Id, new Dictionary <string, string> { ["IpAddress"] = "192.168.2.23" }); } }
public void Can_recognise_global_tracking_indicator_when_enabled() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; EntityTracker .TrackAllProperties <POCO>(); POCO model = new POCO { Color = "Red", Height = 67.4, StartTime = new DateTime(2015, 5, 5) }; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.POCOes.Add(model); ttc.SaveChanges(); model.AssertAuditForAddition(ttc, model.Id, null, x => x.Color, x => x.Id, x => x.Height, x => x.StartTime); } }
public void ShouldNotAddMetadata_WhenValueIsNull() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.ConfigureMetadata(m => { m.IpAddress = "192.168.2.23"; m.Country = null; m.Device = string.Empty; }); EntityTracker.TrackAllProperties <POCO>(); POCO entity = new POCO(); ttc.POCOes.Add(entity); ttc.SaveChanges(); entity.AssertAuditForAddition(ttc, entity.Id, null, x => x.Color, x => x.Height, x => x.StartTime, x => x.Id); entity.AssertMetadata(ttc, entity.Id, new Dictionary <string, string> { ["IpAddress"] = "192.168.2.23", ["Device"] = string.Empty }); } }
public void Can_track_composite_keys() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; string key1 = rdg.Get <string>(); string key2 = rdg.Get <string>(); string userName = rdg.Get <string>(); string descr = rdg.Get <string>(); ModelWithCompositeKey entity = new ModelWithCompositeKey(); entity.Description = descr; entity.Key1 = key1; entity.Key2 = key2; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.ModelWithCompositeKeys.Add(entity); ttc.SaveChanges(userName); string expectedKey = $"[{key1},{key2}]"; entity.AssertAuditForAddition(ttc, expectedKey, userName, x => x.Description, x => x.Key1, x => x.Key2); } }
public async Task Can_get_all_logs() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; string descr = rdg.Get <string>(); NormalModel model = new NormalModel(); model.Description = descr; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.NormalModels.Add(model); await ttc.SaveChangesAsync(rdg.Get <string>()); model.Id.AssertIsNotZero(); IEnumerable <AuditLog> logs = ttc.GetLogs("TrackerEnabledDbContext.Common.Tests.Models.NormalModel") .AssertCountIsNotZero("logs not found"); AuditLog lastLog = logs.LastOrDefault().AssertIsNotNull("last log is null"); IEnumerable <AuditLogDetail> details = lastLog.LogDetails .AssertIsNotNull("log details is null") .AssertCountIsNotZero("no log details found"); } }
public async Task ShouldCreateUnDeletedLogForMultiplePropertiesChanged() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; string oldDescription = rdg.Get <string>(); string newDescription = rdg.Get <string>(); var deletable = new SoftDeletableModel { Description = oldDescription }; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.Set <SoftDeletableModel>().Attach(deletable); ttc.Entry(deletable).State = EntityState.Added; await ttc.SaveChangesAsync(); deletable.AssertAuditForAddition(ttc, deletable.Id, null, x => x.Id, x => x.Description); deletable.IsDeleted = true; await ttc.SaveChangesAsync(); deletable.AssertAuditForSoftDeletion(ttc, deletable.Id, null, new AuditLogDetail { PropertyName = nameof(deletable.IsDeleted), OriginalValue = false.ToString(), NewValue = true.ToString() }); deletable.IsDeleted = false; deletable.Description = newDescription; await ttc.SaveChangesAsync(); deletable.AssertAuditForUndeletion(ttc, deletable.Id, null, new AuditLogDetail { PropertyName = nameof(deletable.IsDeleted), OriginalValue = true.ToString(), NewValue = false.ToString() }, new AuditLogDetail { PropertyName = nameof(deletable.Description), OriginalValue = oldDescription, NewValue = newDescription }); } }
private void InsertFakeLegacyLog() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; var log = new AuditLog { TypeFullName = "ModelWithCustomTableAndColumnNames", EventType = EventType.Added, RecordId = rdg.Get <int>().ToString(), EventDateUTC = rdg.Get <DateTime>(), UserName = "" }; var magnitudeLogDetail = new AuditLogDetail { Log = log, NewValue = rdg.Get <string>(), OriginalValue = rdg.Get <string>(), PropertyName = "MagnitudeOfForce" }; var directionLogDetail = new AuditLogDetail { Log = log, NewValue = rdg.Get <int>().ToString(), OriginalValue = rdg.Get <int>().ToString(), PropertyName = "Direction" }; var subjectLogDetail = new AuditLogDetail { Log = log, NewValue = rdg.Get <string>(), OriginalValue = rdg.Get <string>(), PropertyName = "Subject" }; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.AuditLogs.Add(log); ttc.AuditLogDetails.Add(magnitudeLogDetail); ttc.AuditLogDetails.Add(directionLogDetail); ttc.AuditLogDetails.Add(subjectLogDetail); ttc.SaveChanges(); } }
public async Task Can_save_async() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; NormalModel model = new NormalModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.Entry(model).State = EntityState.Added; await ttc.SaveChangesAsync(); } model.Id.AssertIsNotZero(); }
public void Can_save_model() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; NormalModel model = new NormalModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.NormalModels.Add(model); ttc.SaveChanges(); } model.Id.AssertIsNotZero(); }
public void Can_save_when_entity_state_changed() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; NormalModel model = new NormalModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.Entry(model).State = EntityState.Added; ttc.SaveChanges(); } model.Id.AssertIsNotZero(); }
public void Can_use_default_username() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.ConfigureUsername("rahul"); NormalModel model = new NormalModel(); ttc.NormalModels.Add(model); ttc.SaveChanges(); model.Id.AssertIsNotZero(); model.AssertAuditForAddition(ttc, model.Id, "rahul", x => x.Id, x => x.Description); } }
public void Can_track_navigational_property_change() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; //add enitties var parent1 = new ParentModel(); var child = new ChildModel { Parent = parent1 }; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.ChildModels.Add(child); ttc.SaveChanges(); child.Id.AssertIsNotZero(); //assert child saved parent1.Id.AssertIsNotZero(); //assert parent1 saved //save parent 2 var parent2 = new ParentModel(); ttc.ParentModels.Add(parent2); ttc.SaveChanges(); parent2.Id.AssertIsNotZero(); //assert parent2 saved //change parent child.Parent = parent2; ttc.SaveChanges(); AuditLogDetail[] expectedLog = new List <AuditLogDetail> { new AuditLogDetail { NewValue = parent2.Id.ToString(), OriginalValue = parent1.Id.ToString(), PropertyName = "ParentId" } }.ToArray(); //assert change child.AssertAuditForModification(ttc, child.Id, null, expectedLog); } }
public void Can_recognise_context_tracking_indicator_when_disabled() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; NormalModel model = new NormalModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.NormalModels.Add(model); ttc.TrackingEnabled = false; ttc.SaveChanges(); model.AssertNoLogs(ttc, model.Id); } }
public void Can_Create_AuditLogDetail_ForAddedEntity_WithoutQueryingDatabase() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; NormalModel model = new NormalModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.NormalModels.Add(model); ttc.ChangeTracker.DetectChanges(); var entry = ttc.ChangeTracker.Entries().First(); var auditor = new AdditionLogDetailsAuditor(entry, null); var auditLogDetails = auditor.CreateLogDetails().ToList(); } }
public void Should_Be_able_to_insert() { var entity = new NormalModel { Description = rdg.Get <string>() }; using (TestTrackerContext ttc = GetNewContextInstance()) { ttc.NormalModels.Add(entity); //ttc.Entry(entity).State = EntityState.Added; ttc.SaveChanges(); entity.AssertAuditForAddition(ttc, entity.Id, null, x => x.Id, x => x.Description); } }
public void Can_track_complex_type_property_change() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; //add enity string oldDescription = rdg.Get <string>(); string newDescription = rdg.Get <string>(); //only set one of the properties on the complex type var complexType = new ComplexType { Property1 = oldDescription }; var entity = new ModelWithComplexType { ComplexType = complexType }; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.Entry(entity).State = EntityState.Added; ttc.SaveChanges(); //modify entity entity.ComplexType.Property1 = newDescription; ttc.SaveChanges(); AuditLogDetail[] expectedLog = new List <AuditLogDetail> { new AuditLogDetail { NewValue = newDescription, OriginalValue = oldDescription, PropertyName = "ComplexType_Property1" } }.ToArray(); //assert entity.AssertAuditForModification(ttc, entity.Id, null, expectedLog); } }
public void InitializeTest() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; using (TestTrackerContext ttc = new TestTrackerContext(options)) { _migration = new LogDataMigration(ttc); } _migration.AuditLogUpdated += (sender, args) => { Debug.WriteLine($"\tAuditLog[{args.RecordId}] updated: {args.OldName} -> {args.NewName}"); }; _migration.AuditLogDetailUpdated += (sender, args) => { Debug.WriteLine($"\t\tAuditLogDetail[{args.RecordId}] updated: {args.OldName} -> {args.NewName}"); }; }
public void Can_track_addition_when_usermane_not_provided() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; string randomText = rdg.Get <string>(); NormalModel normalModel = new NormalModel(); normalModel.Description = randomText; using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.NormalModels.Add(normalModel); ttc.SaveChanges(); normalModel.AssertAuditForAddition(ttc, normalModel.Id, null, x => x.Description, x => x.Id); } }
public void Can_Create_AuditLogDetail_ForModifiedEntity_WithoutQueryingDatabase() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; NormalModel model = new NormalModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.NormalModels.Add(model); ttc.SaveChanges(); model.Description += rdg.Get <string>(); ttc.ChangeTracker.DetectChanges(); var entry = ttc.ChangeTracker.Entries().First(); var valuesWrapper = new DbEntryValuesWrapper(entry); var auditor = new ChangeLogDetailsAuditor(entry, null, valuesWrapper); var auditLogDetails = auditor.CreateLogDetails().ToList(); } }
public void ShouldCreateSoftDeleteLogForMultiplePropertiesChanged() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; //create a softdeletable entity and soft delete it var deletable = new SoftDeletableModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.SoftDeletableModels.Add(deletable); //save it to database ttc.SaveChanges(); deletable.AssertAuditForAddition(ttc, deletable.Id, null, x => x.Id); //soft delete entity deletable.IsDeleted = true; deletable.Description = rdg.Get <string>(); //save changes ttc.SaveChanges(); //assert for soft deletion deletable.AssertAuditForSoftDeletion(ttc, deletable.Id, null, new AuditLogDetail { NewValue = true.ToString(), OriginalValue = false.ToString(), PropertyName = nameof(deletable.IsDeleted) }, new AuditLogDetail { NewValue = deletable.Description, OriginalValue = null, PropertyName = nameof(deletable.Description) }); } }
public void Can_save_child_to_parent() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; var child = new ChildModel(); var parent = new ParentModel(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.ParentModels.Add(parent); ttc.SaveChanges(); child.Parent = parent; ttc.ChildModels.Add(child); ttc.SaveChanges(); } child.Id.AssertIsNotZero(); parent.Id.AssertIsNotZero(); }
public void Shoud_Not_Log_EmptyProperties_OnAddition() { var options = new DbContextOptionsBuilder <TestTrackerContext>() .UseSqlServer(TestConnectionString) .Options; //arrange EntityTracker.TrackAllProperties <TrackedModelWithMultipleProperties>(); var entity = new TrackedModelWithMultipleProperties(); using (TestTrackerContext ttc = new TestTrackerContext(options)) { ttc.TrackedModelWithMultipleProperties.Add(entity); //act ttc.SaveChanges(); //assert entity.AssertAuditForAddition(ttc, entity.Id, null, x => x.Id); } }