Inheritance: WorkitemUpdateResult
        public void OnWorkitemStateChanged()
        {
            const string workitemId = "D-00001";
            var workitemResult = new WorkitemStateChangeResult(ExternalId, workitemId);
            workitemResult.Messages.Add("message 1");

            FullUpdateJiraIssue(ExternalId, config.OnStateChangeFieldName, config.OnStateChangeFieldValue,
                                workitemResult.Messages, config.ProgressWorkflowStateChanged, config.AssigneeStateChanged);

            Repository.ReplayAll();
            reader.OnWorkitemStateChanged(workitemResult);
            Repository.VerifyAll();
        }
        public void OnWorkitemStateChanged()
        {
            const string workitemId = "D-00001";
            var workitemResult = new WorkitemStateChangeResult(ExternalId, workitemId);
            workitemResult.Messages.Add("message 1");

            Expect.Call(ServiceFactory.CreateNew(Url)).Repeat.Twice().Return(SoapService);
            Expect.Call(SoapService.Dispose).Repeat.Twice();

            FullUpdateJiraIssue(ExternalId, config.OnStateChangeFieldName, config.OnStateChangeFieldValue,
                                workitemResult.Messages, config.ProgressWorkflowStateChanged, config.AssigneeStateChanged);

            Repository.ReplayAll();
            reader.OnWorkitemStateChanged(workitemResult);
            Repository.VerifyAll();
        }
        public void OnWorkitemStateChangedWithoutWorkflowProgress()
        {
            const string workitemId = "D-00001";
            var workitemResult = new WorkitemStateChangeResult(ExternalId, workitemId);
            workitemResult.Messages.Add("message 1");

            Expect.Call(ConnectorMock.Login);
            Expect.Call(ConnectorMock.UpdateIssue(ExternalId, config.OnStateChangeFieldName, config.OnStateChangeFieldValue)).Return(null);
            Expect.Call(() => ConnectorMock.AddComment(ExternalId, workitemResult.Messages[0])).Repeat.Once();
            Expect.Call(ConnectorMock.GetAvailableActions(ExternalId)).Return(new List<Item>());
            Expect.Call(ConnectorMock.Logout);

            Repository.ReplayAll();
            reader.OnWorkitemStateChanged(workitemResult);
            Repository.VerifyAll();
        }
        public void OnWorkitemStateChangedWithEmptyData()
        {
            const string workitemId = "D-00001";
            var workitemResult = new WorkitemStateChangeResult(ExternalId, workitemId);
            var localReader = new JiraIssueReaderUpdater(new JiraServiceConfiguration(), LoggerMock, ConnectorMock);

            Expect.Call(ConnectorMock.Login);
            Expect.Call(ConnectorMock.Logout);

            Repository.ReplayAll();
            localReader.OnWorkitemStateChanged(workitemResult);
            Repository.VerifyAll();
        }
		public bool OnDefectStateChange(WorkitemStateChangeResult stateChangeResult) 
        {
			logger.Log(LogMessage.SeverityType.Debug, stateChangeResult.ToString());
			var bugId = int.Parse(stateChangeResult.ExternalId);
			var bugzillaClient = bugzillaClientFactory.CreateNew(configuration.Url);

            bugzillaClient.Login(configuration.UserName, configuration.Password, true, configuration.IgnoreCert);

            // We do not need to push changes to Defects that have been processed as we could break their state.
            if(SkipCloseActions(bugId, bugzillaClient)) 
            {
                logger.Log(LogMessage.SeverityType.Info, string.Format("Defect {0} has already been processed, check CloseFieldId and CloseReassignValue.", bugId));
                return true;
            }

			if (configuration.OnStateChangeAccept && !bugzillaClient.AcceptBug(bugId , configuration.OnCreateResolveValue)) 
            {
    			logger.Log(LogMessage.SeverityType.Error, string.Format("Failed to accept bug {0}.", bugId));
			}

			if (!string.IsNullOrEmpty(configuration.OnStateChangeFieldName)) 
            {
				if (!bugzillaClient.UpdateBug(bugId, configuration.OnStateChangeFieldName, configuration.OnStateChangeFieldValue)) 
                {
					logger.Log(LogMessage.SeverityType.Error, string.Format("Failed to set {0} to {1}.", configuration.OnStateChangeFieldName, configuration.OnStateChangeFieldValue));
				}
			}

			if (!string.IsNullOrEmpty(configuration.OnStateChangeReassignValue)) 
            {
				if (!bugzillaClient.ReassignBug(bugId, configuration.OnStateChangeReassignValue)) 
                {
					logger.Log(LogMessage.SeverityType.Error, string.Format("Failed to reassign bug to {0}.", configuration.OnStateChangeReassignValue));
				}
			}

            ResolveBugIfRequired(configuration.OnStateChangeResolveValue, bugId, bugzillaClient);
			bugzillaClient.Logout();
			return true;
		}
		public void OnDefectStateChange(WorkitemStateChangeResult stateChangeResult)
		{
			logger.Log(LogMessage.SeverityType.Debug, stateChangeResult.ToString());

			query.UpdateStatesToClosed(stateChangeResult.ExternalId);
		}
        private void createJiraUpdateResult(WorkitemFromExternalSystem item, WorkitemStateChangeCollection results)
        {
            var jiraUpdate = new WorkitemStateChangeResult(item.ExternalId, item.Number, item.ChangeDateUtc);

            var StatusName = String.IsNullOrEmpty(item.StatusName) ? String.Empty : item.StatusName;
            jiraUpdate.FieldUpdates.Add(Entity.StatusNameProperty, StatusName);

            results.Add(jiraUpdate);
        }
        public WorkitemStateChangeCollection GetWorkitemsClosedSince(DateTime closedSince, string sourceName, string externalIdFieldName, string lastCheckedDefectId)
        {
            var results = new WorkitemStateChangeCollection();
            var lastCheckedDefectIdLocal = lastCheckedDefectId;
            var lastChangeDateLocal = closedSince;

            try {
                var filters = new List<IFilter> {
                    Filter.Closed(true),
                    Filter.OfTypes(VersionOneProcessor.StoryType, VersionOneProcessor.DefectType),
                    Filter.Equal(Entity.SourceNameProperty, sourceName),
                };

                if (closedSince != DateTime.MinValue) {
                    filters.Add(Filter.Greater(Entity.ChangeDateUtcProperty, closedSince));
                }

                var filter = GroupFilter.And(filters.ToArray());

                var workitems = v1Processor.GetPrimaryWorkitems(filter).Select(x => new WorkitemFromExternalSystem(x, externalIdFieldName));

                foreach(var item in workitems) {
                    var id = item.Number;
                    var changeDateUtc = item.ChangeDateUtc;

                    logger.Log(LogMessage.SeverityType.Debug, string.Format("Processing V1 Defect {0} closed at {1}", id, changeDateUtc));

                    if(lastCheckedDefectId.Equals(id)) {
                        logger.Log(LogMessage.SeverityType.Debug, "\tSkipped because this ID was processed last time");
                        continue;
                    }

                    if(closedSince.CompareTo(changeDateUtc) >= 0) {
                        logger.Log(LogMessage.SeverityType.Debug, "\tSkipped because the ChangeDate is less than the date/time we last checked for changes");
                        continue;
                    }

                    if((lastChangeDateLocal == DateTime.MinValue && changeDateUtc != DateTime.MinValue) || changeDateUtc.CompareTo(lastChangeDateLocal) > 0) {
                        logger.Log(LogMessage.SeverityType.Debug, "\tCaused an update to LastChangeID and dateLastChanged");
                        lastChangeDateLocal = changeDateUtc;
                        lastCheckedDefectIdLocal = id;
                    }

                    var result = new WorkitemStateChangeResult(item.ExternalId, item.Number, item.ChangeDateUtc);
                    result.FieldUpdates.Add(Entity.StatusNameProperty, JiraClosedStatus );
                    results.Add(result);
                }
            } catch(WebException ex) {
                string responseMessage = null;

                if(ex.Response != null) {
                    using(var reader = new StreamReader(ex.Response.GetResponseStream())) {
                        responseMessage = reader.ReadToEnd();
                    }
                }

                logger.Log(LogMessage.SeverityType.Error, string.Format("Error querying VersionOne ({0}) for closed external defects:\r\n{1}\r\n\r\n{2}", ex.Response.ResponseUri, responseMessage, ex));
            }

            results.LastCheckedDefectId = lastCheckedDefectIdLocal;
            results.QueryTimeStamp = lastChangeDateLocal;

            return results;
        }
        public bool OnDefectStateChange(WorkitemStateChangeResult stateChangeResult) {
            var project = GetProjectFromExternalId(stateChangeResult.ExternalId);

            if (project == null) {
                return false;
            }

            lock (this) {
                return project.OnDefectStateChange(stateChangeResult.ExternalId,
                                                   Combine(stateChangeResult.Messages, stateChangeResult.Warnings));
            }
        }
        public void OnWorkitemStateChangedWithEmptyData()
        {
            const string workitemId = "D-00001";
            var workitemResult = new WorkitemStateChangeResult(ExternalId, workitemId);
            var localReader = new JiraIssueReaderUpdater(new JiraServiceConfiguration());

            Expect.Call(ServiceFactory.CreateNew(null)).IgnoreArguments().Repeat.Once().Return(SoapService);
            Expect.Call(SoapService.Dispose).Repeat.Once();

            Expect.Call(SoapService.Login(null, null)).Return(Token);
            Expect.Call(SoapService.Logout(Token)).Return(true);

            Repository.ReplayAll();
            localReader.OnWorkitemStateChanged(workitemResult);
            Repository.VerifyAll();
        }
        public void OnWorkitemStateChangedWithoutWorkflowProgress()
        {
            const string workitemId = "D-00001";
            var workitemResult = new WorkitemStateChangeResult(ExternalId, workitemId);
            workitemResult.Messages.Add("message 1");

            Expect.Call(ServiceFactory.CreateNew(Url)).Repeat.Twice().Return(SoapService);
            Expect.Call(SoapService.Dispose).Repeat.Twice();

            Expect.Call(SoapService.Login(Username, Password)).Return(Token);
            Expect.Call(SoapService.UpdateIssue(Token, ExternalId, config.OnStateChangeFieldName, config.OnStateChangeFieldValue)).Return(null);
            Expect.Call(() => SoapService.AddComment(Token, ExternalId, workitemResult.Messages[0])).
                Repeat.Once();

            Expect.Call(SoapService.Login(Username, Password)).Return(Token + "1");
            Expect.Call(SoapService.GetAvailableActions(Token + "1", ExternalId))
                .Return(new List<Item>());
            Expect.Call(SoapService.Logout(Token + "1")).Return(true);

            Expect.Call(SoapService.Logout(Token)).Return(true);

            Repository.ReplayAll();
            reader.OnWorkitemStateChanged(workitemResult);
            Repository.VerifyAll();
        }