Exemple #1
0
        public async Task Set_Referral_Hotel_Status_To_Used_While_Using()
        {
            // arrange

            var model = new ReferralHotelUseModel
            {
                BuyerEmail   = _email,
                Location     = "location",
                Amount       = 10,
                CurrencyCode = "currencyCode"
            };

            _referralHotelsEncrypted.Add(new ReferralHotelEncrypted
            {
                Id                 = _referralId.ToString(),
                EmailHash          = _email.ToSha256Hash(),
                State              = ReferralHotelState.Confirmed,
                ExpirationDateTime = DateTime.UtcNow.AddHours(1)
            });

            // act

            var referralHotel = await _service.UseAsync(model);

            // assert

            _referralHotelsRepositoryMock.Verify(o => o.UpdateAsync(
                                                     It.Is <ReferralHotelEncrypted>(referralHotelEncrypted =>
                                                                                    referralHotelEncrypted.State == ReferralHotelState.Used &&
                                                                                    referralHotelEncrypted.Location == model.Location &&
                                                                                    referralHotelEncrypted.PartnerId == referralHotel.PartnerId)),
                                                 Times.Once);
        }
Exemple #2
0
        public async Task Set_Referral_Hotel_Status_To_Expired_While_Using()
        {
            // arrange

            var model = new ReferralHotelUseModel {
                BuyerEmail = _email
            };

            _referralHotelsEncrypted.Add(new ReferralHotelEncrypted
            {
                EmailHash          = _email.ToSha256Hash(),
                State              = ReferralHotelState.Confirmed,
                ExpirationDateTime = DateTime.UtcNow.AddHours(-1)
            });

            // act

            try
            {
                await _service.UseAsync(model);
            }
            catch
            {
                // ignored
            }

            // assert

            _referralHotelsRepositoryMock.Verify(o => o.UpdateAsync(
                                                     It.Is <ReferralHotelEncrypted>(referralHotelEncrypted =>
                                                                                    referralHotelEncrypted.State == ReferralHotelState.Expired)),
                                                 Times.Once);
        }
        public async Task Do_Not_Use_Referral_Hotel_If_Does_Not_Exist()
        {
            // arrange

            var model = new ReferralHotelUseModel {
                BuyerEmail = _email
            };

            // act

            var task = _service.UseAsync(model);

            // assert

            await Assert.ThrowsAsync <ReferralDoesNotExistException>(async() => await task);
        }
        public async Task Do_Not_Use_Referral_Hotel_If_Status_Expired()
        {
            // arrange

            var model = new ReferralHotelUseModel {
                BuyerEmail = _email
            };

            _referralHotelsEncrypted.Add(new ReferralHotelEncrypted
            {
                EmailHash = _email.ToSha256Hash(),
                State     = ReferralHotelState.Expired
            });

            // act

            var task = _service.UseAsync(model);

            // assert

            await Assert.ThrowsAsync <ReferralExpiredException>(async() => await task);
        }
        public async Task Publish_Referral_Hotel_Used_While_Using()
        {
            // arrange

            var model = new ReferralHotelUseModel
            {
                BuyerEmail   = _email,
                Location     = "location",
                PartnerId    = Guid.NewGuid().ToString("D"),
                Amount       = 10,
                CurrencyCode = "currencyCode"
            };

            _referralHotelsEncrypted.Add(new ReferralHotelEncrypted
            {
                Id                 = _referralId.ToString(),
                EmailHash          = _email.ToSha256Hash(),
                State              = ReferralHotelState.Confirmed,
                ExpirationDateTime = DateTime.UtcNow.AddHours(1),
                PartnerId          = model.PartnerId
            });

            // act

            var referralHotel = await _service.UseAsync(model);

            // assert

            _rabbitPublisherMock.Verify(o => o.PublishAsync(
                                            It.Is <HotelReferralUsedEvent>(message =>
                                                                           message.Amount == model.Amount &&
                                                                           message.CurrencyCode == model.CurrencyCode &&
                                                                           message.CustomerId == referralHotel.ReferrerId &&
                                                                           message.PartnerId == referralHotel.PartnerId &&
                                                                           message.LocationId == referralHotel.Location)),
                                        Times.Once);
        }
Exemple #6
0
        public async Task <ReferralHotel> UseAsync(ReferralHotelUseModel useModel)
        {
            await VerifyPartnerIdAsync(useModel.PartnerId);

            var buyerEmailHash = useModel.BuyerEmail.ToSha256Hash();

            var referrals = await _referralHotelsRepository.GetByEmailHashAsync(buyerEmailHash, useModel.PartnerId, null);

            referrals = referrals
                        .Where(x => (string.IsNullOrEmpty(x.PartnerId)) || x.PartnerId == useModel.PartnerId)
                        .ToList();

            if (referrals.Any() == false)
            {
                throw new ReferralDoesNotExistException();
            }

            var referralHotelEncrypted = referrals
                                         .Where(x => x.State != ReferralHotelState.Pending)
                                         .OrderByDescending(x => x.CreationDateTime)
                                         .FirstOrDefault();

            // Any check guarantees there is at least 1 item
            if (referralHotelEncrypted == null)
            {
                throw new ReferralNotConfirmedException(
                          referrals
                          .OrderByDescending(x => x.CreationDateTime)
                          .First()
                          .Id);
            }

            if (referralHotelEncrypted.State == ReferralHotelState.Used)
            {
                throw new ReferralAlreadyUsedException(referralHotelEncrypted.Id);
            }

            // Used should not be set to expired
            if (referralHotelEncrypted.State == ReferralHotelState.Expired || ReferralExpired(referralHotelEncrypted))
            {
                if (referralHotelEncrypted.State != ReferralHotelState.Expired)
                {
                    referralHotelEncrypted.State = ReferralHotelState.Expired;

                    await _referralHotelsRepository.UpdateAsync(referralHotelEncrypted);
                }

                throw new ReferralExpiredException(referralHotelEncrypted.Id);
            }

            // Guard Check
            var currency = await _currencyConverterClient.Converter.ConvertAsync(useModel.CurrencyCode, _globalBaseCurrencyCode, useModel.Amount);

            if (currency.ErrorCode == ConverterErrorCode.NoRate)
            {
                throw new InvalidCurrencyException();
            }

            if (referralHotelEncrypted.StakeEnabled)
            {
                await _stakeService.ReleaseStake(referralHotelEncrypted.Id, referralHotelEncrypted.CampaignId.Value, ConditionType);
            }

            await _rabbitPublisher.PublishAsync(new HotelReferralUsedEvent
            {
                CustomerId       = referralHotelEncrypted.ReferrerId,
                Amount           = useModel.Amount,
                CurrencyCode     = useModel.CurrencyCode,
                LocationId       = useModel.Location,
                PartnerId        = useModel.PartnerId,
                StakedCampaignId = referralHotelEncrypted.StakeEnabled ? referralHotelEncrypted.CampaignId : null,
                ReferralId       = referralHotelEncrypted.Id
            });

            referralHotelEncrypted.State     = ReferralHotelState.Used;
            referralHotelEncrypted.Location  = useModel.Location;
            referralHotelEncrypted.PartnerId = useModel.PartnerId;

            referralHotelEncrypted = await _referralHotelsRepository.UpdateAsync(referralHotelEncrypted);

            _log.Info("Referral hotel used", context: $"referralHotelId: {referralHotelEncrypted.Id}");

            return(await DecryptAsync(referralHotelEncrypted));
        }