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); }
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)); }
/// <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."); }