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

            var dataContext = Mock.Create<IDataContext>(Behavior.Loose);

            var mapping1 = Mock.Create<IProcessFieldMapping>(Behavior.Loose);
            Mock.Arrange(() => mapping1.IsKey).Returns(true);
            var mapping2 = Mock.Create<IProcessFieldMapping>(Behavior.Loose);
            Mock.Arrange(() => mapping2.IsKey).Returns(false);
            var mapping3 = Mock.Create<IProcessFieldMapping>(Behavior.Loose);
            Mock.Arrange(() => mapping3.IsKey).Returns(true);

            var filter1 = new ColumnFilter("Field1", null);
            Mock.Arrange(() => mapping1.TryCreateFilter(dataContext, out filter1)).Returns(true);

            var filter2 = new ColumnFilter("Field2", null);
            Mock.Arrange(() => mapping3.TryCreateFilter(dataContext, out filter2)).Returns(true);

            var newEdit = CreateEditableRoot(0);

            Mock.Arrange(() => _dtm.NewEditableRoot<IEditableRoot>(ProcessName)).Returns(newEdit);

            var runtimeDatabase = Mock.Create<IRuntimeDatabase>(Behavior.Loose);
            Mock.Arrange(() => runtimeDatabase.FindItems(ProcessName, Arg.IsAny<IEnumerable<ColumnFilter>>()))
                .Returns<string, IEnumerable<ColumnFilter>>(
                    (processName, filters) =>
                    {
                        var filtersArray = filters.ToArray();

                        if (filtersArray.Length == 2 && filtersArray.Contains(filter1) && filtersArray.Contains(filter2))
                            return new Collection<int>();

                        return null;
                    });

            var applicationContext = Mock.Create<IApplicationContext>(Behavior.Loose);

            var editableRootDataContextFactory = Mock.Create<IEditableRootDataContextFactory>(Behavior.Loose);
            var logger = Mock.Create<ILogger>(Behavior.Loose);

            var serviceMethod = new IntegrationServiceMethod(
                ProcessName,
                new[] { mapping1, mapping2, mapping3 },
                null,
                _dtm,
                applicationContext,
                runtimeDatabase,
                editableRootDataContextFactory,
                logger);

            // Act.
            var result = serviceMethod.Insert(dataContext);

            // Assert.
            Mock.Assert(() => mapping1.Update(dataContext, newEdit), Occurs.Once());
            Mock.Assert(() => mapping2.Update(dataContext, newEdit), Occurs.Once());
            Mock.Assert(() => mapping3.Update(dataContext, newEdit), Occurs.Once());
            Mock.Assert(() => newEdit.Save(), Occurs.Once());
            Assert.IsNull(result);
            Assert.IsTrue(applicationContext.User.Identity is IntegrationServiceIdentity);
        }
        public void WhenExistingItemsAreFoundInsertOrUpdateExecutesUpdate()
        {
            // Arrange.
            const string ProcessName = "TestProcess";

            var dataContext = Mock.Create<IDataContext>(Behavior.Loose);

            var mapping1 = Mock.Create<IProcessFieldMapping>(Behavior.Loose);
            Mock.Arrange(() => mapping1.IsKey).Returns(true);
            var mapping2 = Mock.Create<IProcessFieldMapping>(Behavior.Loose);
            Mock.Arrange(() => mapping2.IsKey).Returns(false);
            var mapping3 = Mock.Create<IProcessFieldMapping>(Behavior.Loose);
            Mock.Arrange(() => mapping3.IsKey).Returns(true);

            var filter1 = new ColumnFilter("Field1", null);
            Mock.Arrange(() => mapping1.TryCreateFilter(dataContext, out filter1)).Returns(true);

            var filter2 = new ColumnFilter("Field2", null);
            Mock.Arrange(() => mapping3.TryCreateFilter(dataContext, out filter2)).Returns(true);

            var itemEdit1 = CreateEditableRoot(111);
            var itemEdit2 = CreateEditableRoot(222);
            SetupGetEditableRoot(ProcessName, itemEdit1, itemEdit2);

            var runtimeDatabase = Mock.Create<IRuntimeDatabase>(Behavior.Loose);
            Mock.Arrange(() => runtimeDatabase.FindItems(ProcessName, Arg.IsAny<IEnumerable<ColumnFilter>>()))
                .Returns<string, IEnumerable<ColumnFilter>>(
                    (processName, filters) =>
                    {
                        var filtersArray = filters.ToArray();

                        if (filtersArray.Length == 2 && filtersArray.Contains(filter1) && filtersArray.Contains(filter2))
                            return new Collection<int> { 111, 222 };

                        return new Collection<int>();
                    });

            var applicationContext = Mock.Create<IApplicationContext>(Behavior.Loose);

            var dataContextFactory = Mock.Create<IEditableRootDataContextFactory>(Behavior.Loose);
            var logger = Mock.Create<ILogger>(Behavior.Loose);

            var itemUpdater = new IntegrationServiceMethod(
                ProcessName,
                new[] { mapping1, mapping2, mapping3 },
                null,
                _dtm,
                applicationContext,
                runtimeDatabase,
                dataContextFactory,
                logger);

            // Act.
            var result = itemUpdater.InsertOrUpdate(dataContext);

            // Assert.
            Mock.Assert(() => mapping1.Update(dataContext, itemEdit1), Occurs.Once());
            Mock.Assert(() => mapping1.Update(dataContext, itemEdit2), Occurs.Once());

            Mock.Assert(() => mapping2.Update(dataContext, itemEdit1), Occurs.Once());
            Mock.Assert(() => mapping2.Update(dataContext, itemEdit2), Occurs.Once());

            Mock.Assert(() => mapping3.Update(dataContext, itemEdit1), Occurs.Once());
            Mock.Assert(() => mapping3.Update(dataContext, itemEdit2), Occurs.Once());

            Mock.Assert(() => itemEdit1.Save(), Occurs.Once());
            Mock.Assert(() => itemEdit2.Save(), Occurs.Once());

            Assert.IsNull(result);
            Assert.IsTrue(applicationContext.User.Identity is IntegrationServiceIdentity);
        }