public async Task NoBuildsStored_NoBuildsReturned_NoUpdate()
        {
            IList<Build> builds = new List<Build>();

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                AccountDetails = CreateAccountDetails()
            };

            IBuildService buildService = InitializeBuildService(builds);
            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });

            Assert.AreEqual(0, updates.Count);
            Assert.AreEqual(null, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(null, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual(null, subscribedBuild.CurrentBuildId);
        }
 private BuildUpdate CreateUpdate(SubscribedBuild subscribedBuild, Build build)
 {
     return new BuildUpdate
     {
         Name = subscribedBuild.Name,
         Id = subscribedBuild.BuildDefinitionId,
         RequestedFor = build.RequestedFor,
         Result = build.Result,
         Status = build.Status,
         BuildUrl = build.BuildUrl
     };
 }
        private void UpdateSubscribedBuild(SubscribedBuild subscribedBuild, Build build)
        {
            if (subscribedBuild.CurrentBuildStatus != build.Status)
            {
                subscribedBuild.LastBuildStatusChangeTime = build.LastChangedDate;

                if (build.Result != null)
                {
                    subscribedBuild.LastCompletedBuildResult = build.Result;
                    subscribedBuild.LastCompletedBuildRequestedFor = build.RequestedFor;
                    subscribedBuild.LastBuildResultChangeTime = build.LastChangedDate;
                }
            }

            subscribedBuild.CurrentBuildId = build.Id;
            subscribedBuild.CurrentBuildStatus = build.Status;
            subscribedBuild.CurrentBuildRequestedFor = build.RequestedFor;
        }
        private IList<BuildUpdate> CheckForUpdateInternal(List<Build> buildList, SubscribedBuild subscribedBuild)
        {
            IList<BuildUpdate> updates = new List<BuildUpdate>();

            List<Build> orderedBuilds = buildList.OrderByDescending(b => b.LastChangedDate).ToList();
            Build latestBuild = orderedBuilds.First(); // this method is only called if at least one build
            Build secondLatestBuild = orderedBuilds.Count < 2 ? null : orderedBuilds.Last();

            bool haveNotSeenEitherBuild = subscribedBuild.CurrentBuildId == null ||
                                          (!subscribedBuild.CurrentBuildId.Equals(latestBuild?.Id) &&
                                          !subscribedBuild.CurrentBuildId.Equals(secondLatestBuild?.Id));

            bool oneBuildIsCurrent = subscribedBuild.CurrentBuildId != null &&
                                     (subscribedBuild.CurrentBuildId.Equals(latestBuild.Id) ||
                                     (secondLatestBuild != null &&
                                      subscribedBuild.CurrentBuildId.Equals(secondLatestBuild.Id)));

            Build currentBuild = oneBuildIsCurrent
                ? (subscribedBuild.CurrentBuildId.Equals(latestBuild.Id)
                    ? latestBuild
                    : secondLatestBuild)
                : null;
            
            if (haveNotSeenEitherBuild)
            {
                UpdateSubscribedBuild(subscribedBuild, latestBuild);
                
                if (latestBuild != null && latestBuild.LastChangedDate > DateTime.Now.AddSeconds(-10))
                {
                    updates.Add(CreateUpdate(subscribedBuild, latestBuild));
                }
            }
            else if (oneBuildIsCurrent)
            {
                // Send update if older build changed
                if (currentBuild == secondLatestBuild && secondLatestBuild.Status != subscribedBuild.CurrentBuildStatus)
                {
                    subscribedBuild.LastCompletedBuildResult = secondLatestBuild.Result;
                    UpdateSubscribedBuild(subscribedBuild, secondLatestBuild);
                    updates.Add(CreateUpdate(subscribedBuild, secondLatestBuild));
                }

                if (currentBuild == secondLatestBuild || latestBuild.Status != subscribedBuild.CurrentBuildStatus)
                {
                    UpdateSubscribedBuild(subscribedBuild, latestBuild);
                    updates.Add(CreateUpdate(subscribedBuild, latestBuild));
                }
            }
            return updates;
        }
        public async Task BuildStored_TwoNewBuildsReturned_BuildDefinitionUpdated()
        {
            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.Completed,
                    Result = BuildResult.Succeeded,
                    Id = "1234",
                    LastChangedDate = DateTime.Now
                },
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.Completed,
                    Result = BuildResult.Succeeded,
                    Id = "5678",
                    LastChangedDate = DateTime.Now.AddMinutes(-1)
                }

            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                CurrentBuildId = "09876",
                LastCompletedBuildResult = BuildResult.Succeeded,
                CurrentBuildStatus = BuildStatus.Completed,
                Name = "First Definition",
                AccountDetails = CreateAccountDetails()
            };

            var buildService = InitializeBuildService(builds);

            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });


            Assert.AreEqual(BuildStatus.Completed, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(BuildResult.Succeeded, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual("1234", subscribedBuild.CurrentBuildId);
        }
        public async Task NotStartedStored_SameInProgressReturned_InProgressUpdates()
        {
            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.InProgress,
                    Id = "1234",
                    LastChangedDate = DateTime.Now
                },
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.InProgress,
                    Id = "1234",
                    LastChangedDate = DateTime.Now.AddMinutes(-1)
                }

            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                CurrentBuildId = "1234",
                LastCompletedBuildResult = BuildResult.Failed,
                CurrentBuildStatus = BuildStatus.NotStarted,
                Name = "First Definition",
                AccountDetails = CreateAccountDetails()
            };

            var buildService = InitializeBuildService(builds);

            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });


            Assert.AreEqual(1, updates.Count);
            Assert.AreEqual(BuildStatus.InProgress, updates.First().Status);
            Assert.IsNull(updates.First().Result);
            Assert.AreEqual("First Definition", updates.First().Name);
            Assert.AreEqual(BuildStatus.InProgress, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(BuildResult.Failed, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual("1234", subscribedBuild.CurrentBuildId);
        }
        public async Task InProgressStored_SameCompleteNewInProgressReturned_CompleteInProgressUpdates()
        {
            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.InProgress,
                    Id = "1234",
                    LastChangedDate = DateTime.Now
                },
                new Build
                {
                    BuildDefinitionId = "1",
                    Result = BuildResult.Succeeded,
                    Status = BuildStatus.Completed,
                    Id = "4567",
                    LastChangedDate = DateTime.Now.AddMinutes(-1)
                }

            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                CurrentBuildId = "4567",
                CurrentBuildStatus = BuildStatus.InProgress,
                LastCompletedBuildResult = BuildResult.Failed,
                Name = "First Definition",
                AccountDetails = CreateAccountDetails()
            };

            var buildService = InitializeBuildService(builds);

            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });


            Assert.AreEqual(2, updates.Count);
            Assert.IsTrue(updates.Any(u => u.Status == BuildStatus.Completed && u.Result == BuildResult.Succeeded && u.Name == "First Definition"));
            Assert.IsTrue(updates.Any(u => u.Status == BuildStatus.InProgress && u.Result == null && u.Name == "First Definition"));
            Assert.AreEqual(BuildStatus.InProgress, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(BuildResult.Succeeded, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual("1234", subscribedBuild.CurrentBuildId);
        }
        public async Task InProgressStored_SameInProgressOldCompleteReturned_NoUpdate()
        {
            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.InProgress,
                    Id = "1234",
                    LastChangedDate = DateTime.Now
                },
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.Completed,
                    Id = "4567",
                    LastChangedDate = DateTime.Now.AddMinutes(-1)
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                CurrentBuildId = "1234",
                CurrentBuildStatus = BuildStatus.InProgress,
                LastCompletedBuildResult = BuildResult.PartiallySucceeded,
                AccountDetails = CreateAccountDetails()
            };

            var buildService = InitializeBuildService(builds);

            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });


            Assert.AreEqual(0, updates.Count);
            Assert.AreEqual(BuildStatus.InProgress, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(BuildResult.PartiallySucceeded, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual("1234", subscribedBuild.CurrentBuildId);
        }
        public async Task InProgressStored_SameCompleteFailReturned_OneCompleteFailUpdate()
        {
            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Result = BuildResult.Failed,
                    Status = BuildStatus.Completed,
                    Id = "1234"
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                CurrentBuildId = "1234",
                CurrentBuildStatus = BuildStatus.InProgress,
                Name = "First Definition",
                AccountDetails = CreateAccountDetails()
            };

            var buildService = InitializeBuildService(builds);

            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });


            Assert.AreEqual(1, updates.Count);
            Assert.AreEqual(BuildStatus.Completed, updates.First().Status);
            Assert.AreEqual(BuildResult.Failed, updates.First().Result);
            Assert.AreEqual("First Definition", updates.First().Name);
            Assert.AreEqual(BuildStatus.Completed, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(BuildResult.Failed, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual("1234", subscribedBuild.CurrentBuildId);
        }
        public async Task CompleteStored_NewInProgressReturned_CurrentRequestedForUdatedOnly()
        {
            string firstRequestedPerson = "Nicky";
            string secondRequestedPerson = "Another Nicky";

            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.InProgress,
                    RequestedFor = secondRequestedPerson,
                    Id = "5678"
                },
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.Completed,
                    Result = BuildResult.PartiallySucceeded,
                    RequestedFor = firstRequestedPerson,
                    Id = "1234"
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                AccountDetails = CreateAccountDetails(),
                CurrentBuildStatus = BuildStatus.Completed,
                LastCompletedBuildRequestedFor = firstRequestedPerson,
                CurrentBuildRequestedFor = firstRequestedPerson,
                CurrentBuildId = "1234"
            };
            var buildService = InitializeBuildService(builds);

            await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });

            Assert.AreEqual(secondRequestedPerson, subscribedBuild.CurrentBuildRequestedFor);
            Assert.AreEqual(firstRequestedPerson, subscribedBuild.LastCompletedBuildRequestedFor);
        }
        public async Task InProgressStored_SameInProgressReturned_NoUpdate()
        {
            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.InProgress,
                    Id = "1234"
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                CurrentBuildId = "1234",
                CurrentBuildStatus = BuildStatus.InProgress,
                AccountDetails = CreateAccountDetails()
            };

            var buildService = InitializeBuildService(builds);

            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });


            Assert.AreEqual(0, updates.Count);
            Assert.AreEqual(BuildStatus.InProgress, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(null, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual("1234", subscribedBuild.CurrentBuildId);
        }
        public async Task InProgressStored_SameCompleteAndNewInProgressReturned_BothRequestedForUpdated()
        {
            string firstRequestedPerson = "Nicky";
            string secondRequestedPerson = "Another Nicky";

            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.InProgress,
                    RequestedFor = secondRequestedPerson,
                    LastChangedDate = DateTime.Now,
                    Id = "5678"
                },
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.Completed,
                    Result = BuildResult.PartiallySucceeded,
                    RequestedFor = firstRequestedPerson,
                    LastChangedDate = DateTime.Now.AddMinutes(-1),
                    Id = "1234"
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                AccountDetails = CreateAccountDetails(),
                CurrentBuildStatus = BuildStatus.InProgress,
                LastCompletedBuildRequestedFor = "Someone",
                CurrentBuildRequestedFor = "Someone else",
                CurrentBuildId = "1234"
            };
            var buildService = InitializeBuildService(builds);

            await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });

            Assert.AreEqual(secondRequestedPerson, subscribedBuild.CurrentBuildRequestedFor);
            Assert.AreEqual(firstRequestedPerson, subscribedBuild.LastCompletedBuildRequestedFor);
        }
        public async Task InProgressStored_SameCompleteReturned_LastCompletedRequestedForUpdatedCurrentBuildRequestedSame()
        {
            string requestedPerson = "Nicky";

            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.Completed,
                    Result = BuildResult.Failed,
                    RequestedFor = requestedPerson
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                AccountDetails = CreateAccountDetails(),
                LastCompletedBuildRequestedFor = "Someone else",
                CurrentBuildStatus = BuildStatus.InProgress
            };
            var buildService = InitializeBuildService(builds);

            await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });

            Assert.AreEqual(requestedPerson, subscribedBuild.CurrentBuildRequestedFor);
            Assert.AreEqual(requestedPerson, subscribedBuild.LastCompletedBuildRequestedFor);
        }
        public async Task NoBuildStored_OneNewInComplete_CurrentBuildAndLastCompletedRequestedForUpdated()
        {
            string requestedPerson = "Nicky";

            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Status = BuildStatus.Completed,
                    Result = BuildResult.Failed,
                    RequestedFor = requestedPerson
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                AccountDetails = CreateAccountDetails()
            };
            var buildService = InitializeBuildService(builds);

            await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });

            Assert.AreEqual(requestedPerson, subscribedBuild.CurrentBuildRequestedFor);
            Assert.AreEqual(requestedPerson, subscribedBuild.LastCompletedBuildRequestedFor);
        }
        public async Task NoBuildsStored_OneCompletedOldReturned_NoUpdate()
        {
            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Id = "1234",
                    Status = BuildStatus.Completed,
                    Result = BuildResult.Canceled,
                    LastChangedDate = DateTime.Now.AddDays(-1)
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                AccountDetails = CreateAccountDetails()
            };

            var buildService = InitializeBuildService(builds);

            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });

            Assert.AreEqual(0, updates.Count);
            Assert.AreEqual(BuildStatus.Completed, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(BuildResult.Canceled, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual("1234", subscribedBuild.CurrentBuildId);
        }
        public async Task NoBuildsStored_OneCompletedNewReturned_OneCompleteUpdate()
        {
            IList<Build> builds = new List<Build>
            {
                new Build
                {
                    BuildDefinitionId = "1",
                    Id = "1234",
                    Status = BuildStatus.Completed,
                    Result = BuildResult.PartiallySucceeded,
                    LastChangedDate = DateTime.Now
                }
            };

            SubscribedBuild subscribedBuild = new SubscribedBuild
            {
                BuildDefinitionId = "1",
                Name = "First Definition",
                AccountDetails = CreateAccountDetails()
            };

            IBuildService buildService = InitializeBuildService(builds);

            IList<BuildUpdate> updates = await buildService.CheckForUpdatedBuilds(new List<SubscribedBuild> { subscribedBuild });

            Assert.AreEqual(1, updates.Count);
            Assert.AreEqual(BuildStatus.Completed, updates.First().Status);
            Assert.AreEqual(BuildResult.PartiallySucceeded, updates.First().Result);
            Assert.AreEqual("First Definition", updates.First().Name);
            Assert.AreEqual(BuildStatus.Completed, subscribedBuild.CurrentBuildStatus);
            Assert.AreEqual(BuildResult.PartiallySucceeded, subscribedBuild.LastCompletedBuildResult);
            Assert.AreEqual("1234", subscribedBuild.CurrentBuildId);
        }