public void HookedDbContext_MustOnlyHookWhenObjectIsInTheSameState()
        {
            var context = new LocalContext();

            context.RegisterHook(new TimestampPreInsertHook());
            context.RegisterHook(new TimestampPreUpdateHook());

            var tsEntity = new TimestampedSoftDeletedEntity();

            tsEntity.CreatedAt = DateTime.Now;
            context.Entities.Add(tsEntity);
            context.SaveChanges();

            Assert.AreEqual(DateTime.Today, tsEntity.CreatedAt.Date);
            Assert.IsFalse(tsEntity.ModifiedAt.HasValue);
        }
        public void HookedDbContext_AfterConstruction_CanRegisterNewHooks()
        {
            var context = new LocalContext();

            context.RegisterHook(new TimestampPreInsertHook());

            var entity = new TimestampedSoftDeletedEntity();

            context.Entities.Add(entity);
            context.SaveChanges();

            Assert.AreEqual(entity.CreatedAt.Date, DateTime.Today);
        }
        public void HookedDbContext_CanLateBindPostActionHooks()
        {
            var context = new LocalContext();

            context.RegisterHook(new TimestampPostInsertHook());

            var tsEntity = new TimestampedSoftDeletedEntity();

            tsEntity.CreatedAt = DateTime.Now;
            context.Entities.Add(tsEntity);
            context.SaveChanges();

            Assert.AreEqual(DateTime.Today, tsEntity.ModifiedAt.Value.Date);
        }
        public void HookedDbContext_ShouldNotHook_IfAnyChangedObjectsAreInvalid()
        {
            var context = new LocalContext();

            context.RegisterHook(new TimestampPreInsertHook());
            var tsEntity  = new TimestampedSoftDeletedEntity();
            var valEntity = new ValidatedEntity();

            context.Entities.Add(tsEntity);
            context.ValidatedEntities.Add(valEntity);

            Assert.Throws <DbEntityValidationException>(() => context.SaveChanges());

            Assert.AreNotEqual(tsEntity.CreatedAt.Date, DateTime.Today);
        }
        public void HookedDbContext_MustCallHooks_IfModelIsInvalidButUnchanged()
        {
            var context = new LocalContext();

            context.RegisterHook(new TimestampPreInsertHook());
            var tsEntity  = new TimestampedSoftDeletedEntity();
            var valEntity = new ValidatedEntity();

            context.Entities.Add(tsEntity);
            context.Entry(valEntity).State = EntityState.Unchanged;

            Assert.DoesNotThrow(() => context.SaveChanges());

            Assert.AreEqual(tsEntity.CreatedAt.Date, DateTime.Today);
        }
        public void HookedDbContext_PostActionHookMethod_MustHaveTheContextPassedInTheMetadata()
        {
            var context    = new LocalContext();
            var postAction = A.Fake <PostInsertHook <ITimeStamped> >();

            A.CallTo(() => postAction.HookStates).Returns(EntityState.Added);

            context.RegisterHook(postAction);

            // We aren't testing the hook here
            var entity = new TimestampedSoftDeletedEntity {
                CreatedAt = DateTime.Now
            };

            context.Entities.Add(entity);
            context.SaveChanges();
            A.CallTo(() => postAction.Hook(entity, A <HookEntityMetadata> .That.Matches(m => m.CurrentContext == context))).MustHaveHappened();
        }
        public void HookedDbContext_ShouldHook_IfValidateBeforeSaveIsDisabled_AndChangedObjectsAreInvalid()
        {
            var context = new LocalContext();

            context.Configuration.ValidateOnSaveEnabled = false;
            context.RegisterHook(new TimestampPreInsertHook());
            var tsEntity  = new TimestampedSoftDeletedEntity();
            var valEntity = new ValidatedEntity();

            context.Entities.Add(tsEntity);
            context.ValidatedEntities.Add(valEntity);

            Assert.IsTrue(context.GetValidationErrors().Any(x => !x.IsValid));

            Assert.Throws <DbUpdateException>(() => context.SaveChanges());

            Assert.AreEqual(tsEntity.CreatedAt.Date, DateTime.Today);
            Assert.AreEqual(valEntity.CreatedAt.Date, DateTime.Today);
        }