public async Task The_value_returned_by_the_reservation_service_can_be_used_for_confirmation()
        {
            var reservationService = new SqlReservationService();

            // given a fixed quantity of some resource, e.g. promo codes:
            var ownerToken    = "owner-token-" + Any.Email();
            var promoCode     = "promo-code-" + Any.Word();
            var reservedValue = Any.Email();
            await reservationService.Reserve(reservedValue,
                                             scope : promoCode,
                                             ownerToken : ownerToken,
                                             lease : TimeSpan.FromDays(-1));

            //act
            var value = await reservationService.ReserveAny(
                scope : promoCode,
                ownerToken : ownerToken,
                lease : TimeSpan.FromMinutes(2));

            value.Should().NotBeNull();

            await reservationService.Confirm(value, promoCode, ownerToken);

            // assert
            using (var db = new ReservationServiceDbContext())
            {
                var reservation = db.Set <ReservedValue>()
                                  .Single(v => v.Value == reservedValue &&
                                          v.Scope == promoCode &&
                                          v.Expiration == null);
                reservation.ConfirmationToken.Should().Be(value);
            }
        }
        public async Task If_a_fixed_quantity_of_resource_had_been_depleted_then_reservations_cant_be_made()
        {
            var reservationService = new SqlReservationService();

            // given a fixed quantity of some resource where the resource has been used
            var word                 = Any.Word();
            var ownerToken           = Any.Guid().ToString();
            var promoCode            = "promo-code-" + word;
            var reservedValue        = Any.Guid().ToString();
            var userConfirmationCode = Any.Guid().ToString();
            await reservationService.Reserve(reservedValue, promoCode, reservedValue, TimeSpan.FromDays(-1));

            //act
            var result = await reservationService.ReserveAny(
                scope : promoCode,
                ownerToken : ownerToken,
                lease : TimeSpan.FromMinutes(-2), confirmationToken : userConfirmationCode);

            result.Should().Be(reservedValue);
            await reservationService.Confirm(userConfirmationCode, promoCode, ownerToken);

            //assert
            result = await reservationService.ReserveAny(
                scope : promoCode,
                ownerToken : Any.FullName(),
                lease : TimeSpan.FromMinutes(2), confirmationToken : Any.Guid().ToString());

            result.Should().BeNull();
        }
        public async Task Reservations_can_be_placed_for_one_of_a_fixed_quantity_of_a_resource()
        {
            var reservationService = new SqlReservationService();

            // given a fixed quantity of some resource, e.g. promo codes:
            var word                 = Any.Word();
            var ownerToken           = Any.Guid().ToString();
            var promoCode            = "promo-code-" + word;
            var reservedValue        = Any.Guid().ToString();
            var userConfirmationCode = Any.Guid().ToString();
            await reservationService.Reserve(reservedValue, promoCode, reservedValue, TimeSpan.FromDays(-1));

            //act
            var result = await reservationService.ReserveAny(
                scope : promoCode,
                ownerToken : ownerToken,
                lease : TimeSpan.FromMinutes(2), confirmationToken : userConfirmationCode);

            result.Should().Be(reservedValue);

            await reservationService.Confirm(userConfirmationCode, promoCode, ownerToken);

            // assert
            using (var db = new ReservationServiceDbContext())
            {
                db.Set <ReservedValue>()
                .Should().Contain(v => v.Value == reservedValue &&
                                  v.Scope == promoCode &&
                                  v.Expiration == null);
            }
        }