public void ConstructorTest()
        {
            // Arrange.
            const string DestinationField = "DestinationField";
            const DataTriggerModificationType ModificationType = DataTriggerModificationType.Update;

            var field1 = new DataTriggerFieldMapping("Test1", false, (s, d) => null);
            var field2 = new DataTriggerFieldMapping("Test2", false, (s, d) => null);

            var dataSources = new[]
                                  {
                                      new FieldMappingDataSourceDefinition("ds 1", "Process1", "Prop1.Prop2", true, true, true),
                                      new FieldMappingDataSourceDefinition("ds 2", "Process2", "Prop3", false, false, false),
                                  };

            // Act.
            var mapping = new DataTriggerListFieldMapping(dataSources, DestinationField, ModificationType, new List<DataTriggerFieldMapping> { field1, field2 });

            // Assert.
            Assert.AreEqual(2, mapping.DataSources.Count);
            Assert.AreSame(dataSources[0], mapping.DataSources.ElementAt(0));
            Assert.AreSame(dataSources[1], mapping.DataSources.ElementAt(1));
            Assert.AreEqual(DestinationField, mapping.DestinationFieldName);
            Assert.AreEqual(ModificationType, mapping.ModificationType);
            Assert.IsTrue(new[] { field1, field2 }.SequenceEqual(mapping.Fields));
            Assert.IsTrue(mapping.Fields.IsReadOnly);
        }
Пример #2
0
        public void InitializeTest()
        {
            // Arrange.
            const string ProcessName = "TestProcess";
            const string TriggerName = "Test Trigger";
            var triggerGuid = new Guid("{A05F4E80-E1C6-4115-8582-0A823081BB19}");
            const string ProcessToModify = "DestinationProcess";
            const string FilterDefinition = "Test Filter";
            const DataTriggerModificationType ModificationType = DataTriggerModificationType.Update;

            var fieldMapping1 = new DataTriggerFieldMapping("Field1", false, (s, d) => null);
            var fieldMapping2 = new DataTriggerFieldMapping("Field2", false, (s, d) => null);

            var listMapping1 = new DataTriggerListFieldMapping(
                Enumerable.Empty<FieldMappingDataSourceDefinition>(),
                "Field3",
                DataTriggerModificationType.Insert,
                Enumerable.Empty<DataTriggerFieldMapping>());

            var listMapping2 = new DataTriggerListFieldMapping(
                Enumerable.Empty<FieldMappingDataSourceDefinition>(),
                "Field4",
                DataTriggerModificationType.Insert,
                Enumerable.Empty<DataTriggerFieldMapping>());

            var triggerMap = new DataTriggerMap(new[] { fieldMapping1, fieldMapping2 }, new[] { listMapping1, listMapping2 });

            var triggerDefinition = new DataTriggerDefinition(TriggerName, triggerGuid, ProcessToModify, FilterDefinition, ModificationType, Enumerable.Empty<IActionRule>(), triggerMap);

            var fieldUpdater1 = Mock.Create<IFieldUpdater>();
            var fieldUpdater2 = Mock.Create<IFieldUpdater>();
            var fieldUpdaterFactory = Mock.Create<IFieldUpdaterFactory>();
            Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ProcessToModify, fieldMapping1)).Returns(fieldUpdater1);
            Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ProcessToModify, fieldMapping2)).Returns(fieldUpdater2);

            var listUpdater1 = Mock.Create<IListFieldUpdater>();
            var listUpdater2 = Mock.Create<IListFieldUpdater>();
            var listUpdaterFactory = Mock.Create<IListFieldUpdaterFactory>();
            Mock.Arrange(() => listUpdaterFactory.CreateFieldUpdater(ProcessToModify, listMapping1)).Returns(listUpdater1);
            Mock.Arrange(() => listUpdaterFactory.CreateFieldUpdater(ProcessToModify, listMapping2)).Returns(listUpdater2);

            var trigger = new DataTrigger { FieldUpdaterFactory = fieldUpdaterFactory, ListFieldUpdaterFactory = listUpdaterFactory };

            // Act.
            trigger.Initialize(ProcessName, triggerDefinition);

            // Assert.
            Assert.AreEqual(TriggerName, trigger.Name);
            Assert.AreEqual(triggerGuid, trigger.Guid);
            Assert.AreEqual(ModificationType, trigger.ModificationType);
            Assert.AreEqual(ProcessToModify, trigger.DestinationProcess);
            Assert.AreEqual(FilterDefinition, trigger.FilterDefinition);
            Assert.AreEqual(2, trigger.FieldUpdaters.Count);
            Assert.IsTrue(trigger.FieldUpdaters.Contains(fieldUpdater1));
            Assert.IsTrue(trigger.FieldUpdaters.Contains(fieldUpdater2));
            Assert.AreEqual(2, trigger.ListFieldUpdaters.Count);
            Assert.IsTrue(trigger.ListFieldUpdaters.Contains(listUpdater1));
            Assert.IsTrue(trigger.ListFieldUpdaters.Contains(listUpdater2));
        }
        public void CreateFieldUpdaterTest()
        {
            // Arrange.
            const string ProcessName = "TestProcess";

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

            var mapping = new DataTriggerListFieldMapping(
                Enumerable.Empty<FieldMappingDataSourceDefinition>(),
                TestsHelper.ExtractPropertyName(() => new TestEdit().MultiCR),
                DataTriggerModificationType.Insert,
                Enumerable.Empty<DataTriggerFieldMapping>());

            var mcrFactory = new ExportFactory<MultiCrossReferenceFieldUpdater>(
                () =>
                    {
                        var u = Mock.Create<MultiCrossReferenceFieldUpdater>();

                        return new Tuple<MultiCrossReferenceFieldUpdater, Action>(u, () => { });
                    });

            var factory = new ListFieldUpdaterFactory { DynamicTypeManager = dtm, MultiCrossReferenceFieldUpdaterFactory = mcrFactory };

            // Act.
            var updater = (MultiCrossReferenceFieldUpdater)factory.CreateFieldUpdater(ProcessName, mapping);

            // Assert.
            Assert.IsNotNull(updater);
            Mock.Assert(() => updater.Initialize(ProcessName, mapping), Occurs.Once());

            // Exceptions.
            TestsHelper.VerifyThrow<ArgumentNullException>(() => factory.CreateFieldUpdater(ProcessName, null));

            var invalidMapping1 = new DataTriggerListFieldMapping(
                Enumerable.Empty<FieldMappingDataSourceDefinition>(),
                "InvalidField",
                DataTriggerModificationType.Insert,
                Enumerable.Empty<DataTriggerFieldMapping>());

            var invalidMapping2 = new DataTriggerListFieldMapping(
                Enumerable.Empty<FieldMappingDataSourceDefinition>(),
                TestsHelper.ExtractPropertyName(() => new TestEdit().Text),
                DataTriggerModificationType.Insert,
                Enumerable.Empty<DataTriggerFieldMapping>());

            TestsHelper.VerifyThrow<InvalidOperationException>(() => factory.CreateFieldUpdater(ProcessName, invalidMapping1));
            TestsHelper.VerifyThrow<InvalidOperationException>(() => factory.CreateFieldUpdater(ProcessName, invalidMapping2));
        }
        /// <summary>
        /// Initializes the field updater.
        /// </summary>
        /// <param name="processName">
        /// The process name.
        /// </param>
        /// <param name="fieldMapping">
        /// The field mapping.
        /// </param>
        public void Initialize(string processName, DataTriggerListFieldMapping fieldMapping)
        {
            var type = DynamicTypeManager.GetEditableRootType(processName);
            if (type == null)
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Process \"{0}\" has not been loaded.", processName));

            if (fieldMapping == null)
                throw new ArgumentNullException("fieldMapping");

            Property = type.GetPropertyByName(fieldMapping.DestinationFieldName);
            if (Property == null)
                throw new ArgumentException(
                    string.Format(CultureInfo.InvariantCulture, "Destination field \"{0}\" not found.", fieldMapping.DestinationFieldName));

            var crAttr = Property.GetCustomAttribute<CrossRefFieldAttribute>(false);
            if (crAttr == null || crAttr.AllowMultiple)
                throw new InvalidOperationException("Invalid field type.");

            ReferencedProcessName = crAttr.ReferenceTableName;
            ModificationType = fieldMapping.ModificationType;
            SourceDataProcessName = fieldMapping.SourceDataProcessName;
            SourceDataFilterDefinition = fieldMapping.SourceDataFilterDefinition;

            var sampleFieldUpdaters = new List<IFieldUpdater>();

            FieldUpdaters.Clear();
            foreach (var subfield in fieldMapping.Fields)
            {
                var updater = FieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, subfield);

                if (updater is SampleFieldUpdater)
                {
                    // Sample field updaters should execute after SampleType, SampleSize and SamplingTechnique were updated, therefore we'll add them at the end.
                    sampleFieldUpdaters.Add(updater);
                }
                else
                {
                    FieldUpdaters.Add(updater);
                }
            }

            FieldUpdaters.AddRange(sampleFieldUpdaters);
        }
        public void UpdateCanInsertItems()
        {
            // Arrange.
            const string ProcessName = "TestProcess";
            const string DestinationFieldName = "TestField";
            const string ReferencedProcessName = "RefProcess";
            const string FieldName1 = "Field1";
            const string FieldName2 = "Field2";

            var dataSourceDefinition = new FieldMappingDataSourceDefinition("Test Data Source", ProcessName, "TestProperty", true, true, true);
            var fieldMapping1 = new DataTriggerFieldMapping(FieldName1, true, (s, d) => null);
            var fieldMapping2 = new DataTriggerFieldMapping(FieldName2, false, (s, d) => null);
            var mapping = new DataTriggerListFieldMapping(new[] { dataSourceDefinition }, DestinationFieldName, DataTriggerModificationType.Insert, new[] { fieldMapping1, fieldMapping2 });

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

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

            var sourceData1 = new DataTriggerSourceData();
            var sourceData2 = new DataTriggerSourceData();

            var sourceDataRetriever = Mock.Create<IFieldMappingSourceDataRetriever>();
            Mock.Arrange(() => sourceDataRetriever.GetSourceData(item, null)).Returns(() => new[] { sourceData1, sourceData2 });

            var savedDestinationItem1 = Mock.Create<IEditableRoot>();
            Mock.Arrange(() => savedDestinationItem1.Id).Returns(111);
            var newDestinationItem1 = Mock.Create<IEditableRootStub>();
            var savableDestinationItem1 = newDestinationItem1 as ISavable;
            Mock.Arrange(() => savableDestinationItem1.Save()).Returns(savedDestinationItem1);

            var savedDestinationItem2 = Mock.Create<IEditableRoot>();
            Mock.Arrange(() => savedDestinationItem2.Id).Returns(222);
            var newDestinationItem2 = Mock.Create<IEditableRootStub>();
            var savableDestinationItem2 = newDestinationItem2 as ISavable;
            Mock.Arrange(() => savableDestinationItem2.Save()).Returns(savedDestinationItem2);

            var newDestinationItems = new Queue<IEditableRoot>(new[] { newDestinationItem1, newDestinationItem2 });

            Mock.Arrange(() => dtm.NewEditableRoot<IEditableRoot>(ReferencedProcessName)).Returns(newDestinationItems.Dequeue);

            var fieldUpdater1 = Mock.Create<IFieldUpdater>();
            Mock.Arrange(() => fieldUpdater1.IsKey).Returns(true);
            var fieldUpdater2 = Mock.Create<IFieldUpdater>();

            var fieldUpdaterFactory = Mock.Create<IFieldUpdaterFactory>();
            Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, fieldMapping1)).Returns(fieldUpdater1);
            Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, fieldMapping2)).Returns(fieldUpdater2);

            var updater = new MultiCrossReferenceFieldUpdater
                              {
                                  DynamicTypeManager = dtm,
                                  FieldUpdaterFactory = fieldUpdaterFactory,
                                  SourceDataRetrieverFactory =
                                      new ExportFactory<IFieldMappingSourceDataRetriever>(
                                      () => new Tuple<IFieldMappingSourceDataRetriever, Action>(sourceDataRetriever, () => { }))
                              };

            updater.Initialize(ProcessName, mapping);

            var destination = new DestinationEdit();

            // Act.
            updater.BeforeItemUpdate(item, null);
            updater.AfterItemUpdate(item, null);
            updater.Update(item, destination);

            // Assert.
            Assert.AreEqual(2, destination.TestField.Count);
            Assert.IsTrue(destination.TestField.Any(x => x.Id == 111));
            Assert.IsTrue(destination.TestField.Any(x => x.Id == 222));

            Mock.Assert(() => fieldUpdater1.CalculateNewValue(sourceData1, newDestinationItem1), Occurs.Once());
            Mock.Assert(() => fieldUpdater1.Update(newDestinationItem1), Occurs.Once());

            Mock.Assert(() => fieldUpdater1.CalculateNewValue(sourceData2, newDestinationItem2), Occurs.Once());
            Mock.Assert(() => fieldUpdater1.Update(newDestinationItem2), Occurs.Once());

            Mock.Assert(() => fieldUpdater2.CalculateNewValue(sourceData1, newDestinationItem1), Occurs.Once());
            Mock.Assert(() => fieldUpdater2.Update(newDestinationItem1), Occurs.Once());

            Mock.Assert(() => fieldUpdater2.CalculateNewValue(sourceData2, newDestinationItem2), Occurs.Once());
            Mock.Assert(() => fieldUpdater2.Update(newDestinationItem2), Occurs.Once());

            Mock.Assert(() => savableDestinationItem1.Save(), Occurs.Once());
            Mock.Assert(() => savableDestinationItem2.Save(), Occurs.Once());
        }
        public void UpdateCanRemoveItems()
        {
            // Arrange.
            const string ProcessName = "TestProcess";
            const string DestinationFieldName = "TestField";
            const string ReferencedProcessName = "RefProcess";
            const string FieldName1 = "Field1";
            const string FieldName2 = "Field2";

            var dataSourceDefinition = new FieldMappingDataSourceDefinition("Test Data Source", ProcessName, "TestProperty", true, true, true);
            var fieldMapping1 = new DataTriggerFieldMapping(FieldName1, true, (s, d) => null);
            var fieldMapping2 = new DataTriggerFieldMapping(FieldName2, false, (s, d) => null);
            var mapping = new DataTriggerListFieldMapping(
                new[] { dataSourceDefinition }, DestinationFieldName, DataTriggerModificationType.Remove, new[] { fieldMapping1, fieldMapping2 });

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

            var sourceData1 = new DataTriggerSourceData();
            var sourceData2 = new DataTriggerSourceData();
            var sourceData3 = new DataTriggerSourceData();

            var sourceDataRetriever = Mock.Create<IFieldMappingSourceDataRetriever>();
            Mock.Arrange(() => sourceDataRetriever.GetSourceData(item, null)).Returns(() => new[] { sourceData1, sourceData2, sourceData3 });

            var oldDestinationItem1 = Mock.Create<IEditableRoot>();
            Mock.Arrange(() => oldDestinationItem1.Id).Returns(111);

            var oldDestinationItem2 = Mock.Create<IEditableRoot>();
            Mock.Arrange(() => oldDestinationItem2.Id).Returns(222);

            var destination = new DestinationEdit();
            destination.TestField.Assign(oldDestinationItem1.Id);
            destination.TestField.Assign(oldDestinationItem2.Id);

            Mock.Arrange(() => _dtm.GetEditableRootType(ProcessName)).Returns(typeof(DestinationEdit));
            SetupGetEditableRoot(ReferencedProcessName, oldDestinationItem1, oldDestinationItem2);

            var fieldUpdater1 = Mock.Create<IFieldUpdater>();
            Mock.Arrange(() => fieldUpdater1.IsKey).Returns(true);
            var fieldUpdater2 = Mock.Create<IFieldUpdater>();

            var fieldUpdaterFactory = Mock.Create<IFieldUpdaterFactory>();
            Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, fieldMapping1)).Returns(fieldUpdater1);
            Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, fieldMapping2)).Returns(fieldUpdater2);

            Mock.Arrange(() => fieldUpdater1.AreEqual(sourceData1, oldDestinationItem1)).Returns(true);

            var updater = new MultiCrossReferenceFieldUpdater
                              {
                                  DynamicTypeManager = _dtm,
                                  FieldUpdaterFactory = fieldUpdaterFactory,
                                  SourceDataRetrieverFactory =
                                      new ExportFactory<IFieldMappingSourceDataRetriever>(
                                      () => new Tuple<IFieldMappingSourceDataRetriever, Action>(sourceDataRetriever, () => { }))
                              };

            updater.Initialize(ProcessName, mapping);

            // Act.
            updater.BeforeItemUpdate(item, null);
            updater.AfterItemUpdate(item, null);
            updater.Update(item, destination);

            // Assert.
            Assert.AreEqual(1, destination.TestField.Count);
            Assert.IsTrue(destination.TestField.Any(x => x.Id == 222));
        }
Пример #7
0
        /// <summary>
        /// Creates the field updater.
        /// </summary>
        /// <param name="processName">
        /// Name of the process.
        /// </param>
        /// <param name="fieldMapping">
        /// The field mapping.
        /// </param>
        /// <returns>
        /// The <see cref="IListFieldUpdater"/>.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        /// The <paramref name="fieldMapping"/> parameter is null.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// Invalid destination field type.
        /// </exception>
        public IListFieldUpdater CreateFieldUpdater(string processName, DataTriggerListFieldMapping fieldMapping)
        {
            var type = DynamicTypeManager.GetEditableRootType(processName);

            if (fieldMapping == null)
                throw new ArgumentNullException("fieldMapping");

            var property = type.GetPropertyByName(fieldMapping.DestinationFieldName);
            if (property == null)
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Destination field \"{0}\" not found.", fieldMapping.DestinationFieldName));

            var crAttr = property.GetCustomAttribute<CrossRefFieldAttribute>();
            if (crAttr != null)
            {
                if (crAttr.AllowMultiple)
                {
                    var updater = MultiCrossReferenceFieldUpdaterFactory.CreateExport().Value;
                    updater.Initialize(processName, fieldMapping);

                    return updater;
                }
                else
                {
                    var updater = SingleCrossReferenceFieldUpdaterFactory.CreateExport().Value;
                    updater.Initialize(processName, fieldMapping);

                    return updater;
                }
            }

            throw new InvalidOperationException("Invalid destination field type.");
        }