public void ExecuteServicesTest()
        {
            // Arrange.
            var serviceGuid1 = new Guid("{E6F4F319-EAB4-4516-87DC-D1B3BE9A0D33}");
            var serviceGuid2 = new Guid("{0121E82D-0814-4C28-AAE7-D8F382142ED7}");
            var serviceGuid3 = new Guid("{7136053C-A748-4BF5-99E6-FE53A5DFFC02}");

            var editItem = new Mock<IEditableRoot>();
            var oldEditItem = new Mock<IEditableRoot>();

            var rule1 = new Mock<IActionRule>();
            rule1.Setup(x => x.CanExecute(editItem.Object, oldEditItem.Object)).Returns(true);

            var rule2 = new Mock<IActionRule>();
            rule2.Setup(x => x.CanExecute(editItem.Object, oldEditItem.Object)).Returns(false);

            var callDefinition1 = new Mock<IServiceCallDefinition>();
            callDefinition1.Setup(x => x.Guid).Returns(serviceGuid1);
            callDefinition1.Setup(x => x.Rules).Returns(new[] { rule1.Object });

            var callDefinition2 = new Mock<IServiceCallDefinition>();
            callDefinition2.Setup(x => x.Guid).Returns(serviceGuid2);
            callDefinition2.Setup(x => x.Rules).Returns(new[] { rule2.Object });

            var callDefinition3 = new Mock<IServiceCallDefinition>();
            callDefinition3.Setup(x => x.Guid).Returns(serviceGuid3);
            callDefinition3.Setup(x => x.Rules).Returns(new[] { rule1.Object, rule2.Object });

            var serviceCaller1 = new Mock<IServiceCaller>();
            serviceCaller1.Setup(x => x.Execute(It.IsAny<IEditableRoot>()))
                          .Callback(() => Assert.IsNotNull(ThreadLocalBypassPropertyCheckContext.Current));

            var serviceCaller2 = new Mock<IServiceCaller>();
            serviceCaller2.Setup(x => x.Execute(It.IsAny<IEditableRoot>()))
                          .Callback(() => Assert.IsNotNull(ThreadLocalBypassPropertyCheckContext.Current));

            var serviceCaller3 = new Mock<IServiceCaller>();
            serviceCaller3.Setup(x => x.Execute(It.IsAny<IEditableRoot>()))
                          .Callback(() => Assert.IsNotNull(ThreadLocalBypassPropertyCheckContext.Current));

            var serviceCallerFactory = new Mock<IServiceCallerFactory>();
            serviceCallerFactory.Setup(x => x.CreateServiceCaller(callDefinition1.Object)).Returns(serviceCaller1.Object);
            serviceCallerFactory.Setup(x => x.CreateServiceCaller(callDefinition2.Object)).Returns(serviceCaller2.Object);
            serviceCallerFactory.Setup(x => x.CreateServiceCaller(callDefinition3.Object)).Returns(serviceCaller3.Object);

            var callsManager = new TestServiceCallsManager { ServiceCallerFactory = serviceCallerFactory.Object };
            callsManager.Initialize(new[] { callDefinition1.Object, callDefinition2.Object, callDefinition3.Object });

            // Act.
            callsManager.ExecuteServices(editItem.Object, oldEditItem.Object);

            // Assert.
            serviceCaller1.Verify(x => x.Execute(editItem.Object), Times.Once());
            serviceCaller2.Verify(x => x.Execute(It.IsAny<IEditableRoot>()), Times.Never());
            serviceCaller3.Verify(x => x.Execute(editItem.Object), Times.Once());
        }
        public void GetServiceCallerTest()
        {
            // Arrange.
            var serviceGuid1 = new Guid("{71B4DAD4-8AF1-438B-8E0D-5BD50F90E3F9}");
            var serviceGuid2 = new Guid("{6C6115F1-5CB4-4417-B28F-6A3A5563804B}");
            var invalidGuid = new Guid("{692A348B-C92A-41B9-8EBA-5855F8E1EBEE}");

            var callDefinition1 = new Mock<IServiceCallDefinition>();
            callDefinition1.Setup(x => x.Guid).Returns(serviceGuid1);

            var callDefinition2 = new Mock<IServiceCallDefinition>();
            callDefinition2.Setup(x => x.Guid).Returns(serviceGuid2);

            var serviceCaller1 = new Mock<IServiceCaller>();

            var serviceCallerFactory = new Mock<IServiceCallerFactory>();
            serviceCallerFactory.Setup(x => x.CreateServiceCaller(callDefinition1.Object)).Returns(serviceCaller1.Object);

            var exception = new TestException();
            serviceCallerFactory.Setup(x => x.CreateServiceCaller(callDefinition2.Object)).Throws(exception);

            var logger = new Mock<ILogger>();

            var callsManager = new TestServiceCallsManager { ServiceCallerFactory = serviceCallerFactory.Object, Logger = logger.Object };
            callsManager.Initialize(new[] { callDefinition1.Object, callDefinition2.Object });

            // Act.
            TestsHelper.VerifyThrow<ArgumentException>(() => callsManager.GetServiceCaller(invalidGuid));
            TestsHelper.VerifyThrow<InvalidOperationException>(() => callsManager.GetServiceCaller(serviceGuid2));
            
            var result = callsManager.GetServiceCaller(serviceGuid1);

            // Assert.
            Assert.AreSame(serviceCaller1.Object, result);
            logger.Verify(x => x.Log(LogSeverity.Error, It.IsAny<string>(), exception), Times.Once());
        }
        public void WhenServiceCallFails_ServiceCallIsEnqueued()
        {
            // Arrange.
            var serviceGuid = new Guid("{71B4DAD4-8AF1-438B-8E0D-5BD50F90E3F9}");

            var item = Mock.Create<IEditableRoot>(Behavior.Loose);
            var oldItem = Mock.Create<IEditableRoot>(Behavior.Loose);

            var rule = Mock.Create<IActionRule>(Behavior.Loose);
            Mock.Arrange(() => rule.CanExecute(item, oldItem)).Returns(true);

            var callDefinition = Mock.Create<IServiceCallDefinition>(Behavior.Loose);
            Mock.Arrange(() => callDefinition.Guid).Returns(serviceGuid);
            Mock.Arrange(() => callDefinition.Rules).Returns(new[] { rule });
            
            var exception = new ServiceCallException();
            var serviceCaller = Mock.Create<IServiceCaller>(Behavior.Loose);
            Mock.Arrange(() => serviceCaller.Execute(item)).Throws(exception);

            var logger = Mock.Create<ILogger>(Behavior.Loose);
            var serviceCallerFactory = Mock.Create<IServiceCallerFactory>(Behavior.Loose);
            Mock.Arrange(() => serviceCallerFactory.CreateServiceCaller(callDefinition)).Returns(serviceCaller);

            var callsManager = new TestServiceCallsManager { ServiceCallerFactory = serviceCallerFactory, Logger = logger };
            callsManager.Initialize(new[] { callDefinition });

            // Act.
            callsManager.ExecuteServices(item, oldItem);

            // Assert.
            Mock.Assert(() => serviceCaller.EnqueueServiceCall(item), Occurs.Once());
            Mock.Assert(() => logger.Log(LogSeverity.Error, Arg.AnyString, exception), Occurs.Once());
        }