public void InitializeTest()
        {
            // Arrange.
            const string ProcessName = "TestProcess";

            var dtm = Mock.Create<IDynamicTypeManager>();
            Mock.Arrange(() => dtm.GetEditableRootType(ProcessName)).Returns(typeof(TestEdit));

            var childMapping = new DataTriggerFieldMapping("FirstName", false, (data, root) => null);
            var mapping = new DataTriggerFieldMapping(
                ReflectionHelper.GetPropertyName<TestEdit>(x => x.Person),
                true,
                (s, d) => null,
                new[] { childMapping });

            var childUpdater = Mock.Create<IFieldUpdater>(Behavior.Loose);

            var updaterFactory = Mock.Create<IFieldUpdaterFactory>(Behavior.Loose);
            Mock.Arrange(() => updaterFactory.CreateFieldUpdater(Constants.BasePersonProcessName, childMapping)).Returns(childUpdater);

            var updater = new SingleCrossReferenceFieldUpdater { DynamicTypeManager = dtm, FieldUpdaterFactory = updaterFactory };

            // Act.
            updater.Initialize(ProcessName, mapping);

            // Assert.
            Assert.AreEqual(ReflectionHelper.GetPropertyName<TestEdit>(x => x.Person), updater.FieldName);
            Assert.IsTrue(updater.IsKey);
            Assert.AreSame(mapping.ValueCalculator, updater.ValueCalculator);
            Assert.AreEqual(Constants.BasePersonProcessName, updater.ReferencedProcessName);
            Assert.AreEqual(1, updater.ChildMappings.Count);
            Assert.IsTrue(updater.ChildMappings.Contains(childUpdater));

            // Exceptions.
            var invalidMapping1 = new DataTriggerFieldMapping("InvalidField", false, (data, root) => null);
            var invalidMapping2 = new DataTriggerFieldMapping(
                ReflectionHelper.GetPropertyName<TestEdit>(x => x.PersonList),
                false,
                (data, root) => null);

            TestsHelper.VerifyThrow<ArgumentNullException>(() => updater.Initialize(ProcessName, null));
            TestsHelper.VerifyThrow<ArgumentException>(() => updater.Initialize(ProcessName, invalidMapping1));
            TestsHelper.VerifyThrow<ArgumentException>(() => updater.Initialize(ProcessName, invalidMapping2));
        }
        public void CalculateNewValueWithValueCalculator()
        {
            // Arrange.
            var updater = new SingleCrossReferenceFieldUpdater
                           {
                               FieldName = ReflectionHelper.GetPropertyName<TestEdit>(x => x.Person),
                               ReferencedProcessName = Constants.BasePersonProcessName,
                               ValueCalculator = (data, root) => 123
                           };

            // Act.
            updater.CalculateNewValue(new DataTriggerSourceData(), new TestEdit());

            // Assert.
            Assert.AreEqual(123, updater.NewValue);

            // Exceptions.
            TestsHelper.VerifyThrow<ArgumentNullException>(() => updater.CalculateNewValue(null, new TestEdit()));
            TestsHelper.VerifyThrow<ArgumentNullException>(() => updater.CalculateNewValue(new DataTriggerSourceData(), null));
        }
        public void UpdateTest()
        {
            // Arrange.
            var updater = new SingleCrossReferenceFieldUpdater
                          {
                              FieldName = ReflectionHelper.GetPropertyName<TestEdit>(x => x.Person),
                              ReferencedProcessName = Constants.BasePersonProcessName,
                              NewValue = 123
                          };

            var destination = new TestEdit();

            // Act.
            updater.Update(destination);

            // Assert.
            Assert.AreEqual(123, destination.Person);

            // Exceptions.
            TestsHelper.VerifyThrow<ArgumentNullException>(() => updater.Update(null));
        }
        public void AreEqualTest()
        {
            // Arrange.
            var updater = new SingleCrossReferenceFieldUpdater
                          {
                              FieldName = ReflectionHelper.GetPropertyName<TestEdit>(x => x.Person),
                              ReferencedProcessName = Constants.BasePersonProcessName,
                              ValueCalculator = (data, root) => 123
                          };

            var item1 = new TestEdit { Person = 123 };
            var item2 = new TestEdit { Person = 100 };

            // Act / Assert.
            Assert.IsTrue(updater.AreEqual(new DataTriggerSourceData(), item1));
            Assert.IsFalse(updater.AreEqual(new DataTriggerSourceData(), item2));

            // Exceptions.
            TestsHelper.VerifyThrow<ArgumentNullException>(() => updater.AreEqual(null, new TestEdit()));
            TestsHelper.VerifyThrow<ArgumentNullException>(() => updater.AreEqual(new DataTriggerSourceData(), null));
        }
        public void CalculateNewValueWithChildMappings()
        {
            // Arrange.
            var dtm = Mock.Create<IDynamicTypeManager>(Behavior.Loose);
            var updater = new SingleCrossReferenceFieldUpdater
                          {
                              FieldName = ReflectionHelper.GetPropertyName<TestEdit>(x => x.Person),
                              ReferencedProcessName = Constants.BasePersonProcessName,
                              DynamicTypeManager = dtm
                          };

            var sourceData = new DataTriggerSourceData();
            var destination = new TestEdit();
            
            var childUpdater1 = Mock.Create<IFieldUpdater>(Behavior.Loose);
            Mock.Arrange(() => childUpdater1.IsKey).Returns(true);

            var childUpdater2 = Mock.Create<IFieldUpdater>(Behavior.Loose);
            Mock.Arrange(() => childUpdater2.IsKey).Returns(false);

            updater.ChildMappings.Add(childUpdater1);
            updater.ChildMappings.Add(childUpdater2);

            var filter = Mock.Create<IFilterDescriptor>(Behavior.Loose);
            Mock.Arrange(() => childUpdater1.TryCreateFilter(sourceData, destination, out filter)).Returns(true);

            var infoItem = Mock.Create<IInfoClass>(Behavior.Loose);
            Mock.Arrange(() => infoItem.Id).Returns(123);
            var infoList = new InfoListBase { infoItem };

            Mock.Arrange(
                () => dtm.GetList<IInfoList>(Constants.BasePersonProcessName, string.Empty, 0, int.MaxValue, null, Arg.IsAny<FilterList>(), false))
                .Returns<string, string, int, int, SortList, FilterList, bool>(
                    (processName, filterString, pageNumber, pageSize, sortList, filterList, security) =>
                    {
                        if (filterList != null && filterList.Count == 1 && filterList.Contains(filter))
                            return infoList;

                        return null;
                    });

            // Act.
            updater.CalculateNewValue(sourceData, destination);

            // Assert.
            Assert.AreEqual(123, updater.NewValue);
        }