public AuctionRunner(IMainRepository repository, TimeSpan checkInterval)
        {
            this.checkInterval = checkInterval;
            this.timer = new Timer(this.Callback, null, Timeout.Infinite, Timeout.Infinite);

            this.auctioneer = new Auctioneer(repository);
        }
        public void AuctionHasStartTimeInPast_AuctioneerRuns_AuctionIsRunning()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));

            auctioneer.DoAllWork();

            Assert.IsFalse(auction.IsClosed);
            Assert.IsTrue(auction.IsRunning);
        }
        public void AuctionStartedAndEndedInThePast_AuctioneerRuns_DoNotGetsStarted()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            AuctionEventArgs raisedArgs = null;
            auctioneer.AuctionStarted += (sender, args) => raisedArgs = args;

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-2), DateTime.UtcNow.AddHours(-1));
            auction.IsRunning = false;
            auction.IsClosed = true;

            auctioneer.DoAllWork();

            Assert.IsNull(raisedArgs);
            Assert.IsTrue(auction.IsClosed);
            Assert.IsFalse(auction.IsRunning);
        }
        public void Auction_BidIsBelowStartPrice_HasNoImpact()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow, DateTime.UtcNow.AddHours(1));

            auctioneer.DoAllWork();

            var bidder = new Member() { DisplayName = "Bidder1", UniqueId = Guid.NewGuid().ToString() };
            repo.Add(bidder);

            repo.Add(new Bid() { ReceivedOnUtc = DateTime.UtcNow, Auction = auction, Amount = auction.StartPrice - 10, Bidder = bidder });

            auctioneer.DoAllWork();

            Assert.AreEqual(1, auction.Bids.Count);
            Assert.IsNull(auction.ActiveBid);
        }
        public void Bid_WhenDeclined_EventIsRaised()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));
            AddInitialBidToAuction(repo, auction);

            auctioneer.DoAllWork();

            ProcessedBidEventArgs raisedArgs = null;
            auctioneer.BidDeclined += (sender, args) => raisedArgs = args;

            var bidder2 = new Member() { DisplayName = "Bidder2", UniqueId = Guid.NewGuid().ToString() };
            repo.Add(bidder2);
            repo.Add(new Bid() { ReceivedOnUtc = DateTime.UtcNow, Bidder = bidder2, Amount = 51, Auction = auction });

            auctioneer.DoAllWork();

            Assert.NotNull(raisedArgs);
            Assert.NotNull(raisedArgs.Auction);
            Assert.NotNull(raisedArgs.Bid);
        }
        public void Bid_WhenAccepted_EventIsRaised()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));

            ProcessedBidEventArgs raisedArgs = null;
            auctioneer.BidAccepted += (sender, args) => raisedArgs = args;

            AddInitialBidToAuction(repo, auction);

            auctioneer.DoAllWork();

            Assert.NotNull(raisedArgs);
            Assert.NotNull(raisedArgs.Auction);
            Assert.NotNull(raisedArgs.Bid);
        }
        public void Auction_WhenStarted_EventIsRaised()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));

            AuctionEventArgs raisedArgs = null;
            auctioneer.AuctionStarted += (sender, args) => raisedArgs = args;

            auctioneer.DoAllWork();

            Assert.NotNull(raisedArgs);
            Assert.NotNull(raisedArgs.Auction);
            Assert.AreEqual(auction, raisedArgs.Auction);
        }
        public void Auction_WhenEnded_EventIsRaised()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));

            AuctionEventArgs raisedArgs = null;
            auctioneer.AuctionEnded += (sender, args) => raisedArgs = args;

            // Turn back the time
            auction.EndDateTimeUtc = DateTime.UtcNow;

            auctioneer.DoAllWork();

            Assert.NotNull(raisedArgs);
            Assert.NotNull(raisedArgs.Auction);
            Assert.NotNull(raisedArgs.IsSuccessful);
        }
        public void Auction_StartTimeHasArrived_AuctionGetsRunning()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));

            Assert.IsFalse(auction.IsRunning);

            auctioneer.DoAllWork();

            Assert.IsTrue(auction.IsRunning);

            // Turn back the time
            auction.EndDateTimeUtc = DateTime.UtcNow;

            auctioneer.DoAllWork();

            Assert.IsTrue(auction.IsClosed);
            Assert.IsFalse(auction.IsRunning);
        }
        public void Auction_HasOneBidAndEnds_TheBidderShouldBeTheWinner()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));

            auctioneer.DoAllWork();

            var bidder2 = new Member() { DisplayName = "Bidder2", UniqueId = Guid.NewGuid().ToString() };
            repo.Add(bidder2);
            repo.Add(new Bid() { ReceivedOnUtc = DateTime.UtcNow, Bidder = bidder2, Amount = 70, Auction = auction });

            // Turn back the time
            auction.EndDateTimeUtc = DateTime.UtcNow;

            auctioneer.DoAllWork();

            Assert.AreEqual(auction.Winner, bidder2);
        }
        public void Auction_HasNewerButLowerBid_HasNoImpact()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow, DateTime.UtcNow.AddHours(1));
            AddInitialBidToAuction(repo, auction);

            auctioneer.DoAllWork();

            var bidder2 = new Member() { DisplayName = "Bidder2", UniqueId = Guid.NewGuid().ToString() };
            repo.Add(bidder2);
            repo.Add(new Bid() { ReceivedOnUtc = DateTime.UtcNow, Bidder = bidder2, Amount = 51, Auction = auction });

            auctioneer.DoAllWork();

            Assert.AreEqual(2, auction.Bids.Count);
            Assert.AreEqual(60, auction.CurrentPrice);
        }
        public void Auction_GetsOlderButHigherBid_FailsWithException()
        {
            var repo = new InMemoryMainRepository();
            var auctioneer = new Auctioneer(repo);

            var auction = CreateAndStoreAuction(repo, DateTime.UtcNow.AddHours(-1), DateTime.UtcNow.AddHours(1));
            AddInitialBidToAuction(repo, auction);

            auctioneer.DoAllWork();

            var bidder2 = new Member() { DisplayName = "Bidder2", UniqueId = Guid.NewGuid().ToString() };
            repo.Add(bidder2);
            repo.Add(new Bid() { ReceivedOnUtc = DateTime.UtcNow.AddMinutes(-10), Bidder = bidder2, Amount = 70, Auction = auction });

            auctioneer.DoAllWork();
        }