public async Task ShouldSendEmailWithCorrectFirstNameAndLastName_WhenValidDataIsPassed()
        {
            // Arrange
            var          fixture      = new NotificationPublisherServiceTestsFixture();
            const string confirmToken = "token";
            var          phone        = PhoneUtils.GetE164FormattedNumber(fixture.PhoneNumber, fixture.CountryCode);

            fixture.ShortenUrlResponseModel = new ShortenUrlResponseModel
            {
                ShortenedUrl = "short token" + confirmToken
            };

            // Act
            await fixture.Service.LeadConfirmRequestAsync(
                fixture.CustomerId.ToString(),
                phone,
                confirmToken);

            // Assert
            fixture.SmsEventMock.Verify(c =>
                                        c.PublishAsync(It.Is <SmsEvent>(x =>
                                                                        x.TemplateParameters.ContainsKey("target_phonenumber") && x.TemplateParameters.ContainsValue(phone) &&
                                                                        x.TemplateParameters.ContainsKey("AcceptLink") && x.TemplateParameters.ContainsValue(fixture.ShortenUrlResponseModel.ShortenedUrl) &&
                                                                        x.CustomerId == fixture.CustomerId.ToString())));

            //string.Format(_leadConfirmEmailLinkFormat, confirmToken)
        }
        public async Task <CustomerProfileErrorCodes> UpdateAsync(string customerId, string firstName, string lastName,
                                                                  string phoneNumber, int countryPhoneCodeId, int countryOfResidenceId)
        {
            var countryPhoneCode = await _dictionariesClient.Salesforce.GetCountryPhoneCodeByIdAsync(countryPhoneCodeId);

            if (countryPhoneCode == null)
            {
                return(CustomerProfileErrorCodes.InvalidCountryPhoneCodeId);
            }

            var e164FormattedNumber = PhoneUtils.GetE164FormattedNumber(phoneNumber, countryPhoneCode.IsoCode);

            if (e164FormattedNumber == null)
            {
                return(CustomerProfileErrorCodes.InvalidPhoneNumber);
            }

            var isPhoneNumberUsedByAnotherCustomer =
                await _customerProfileRepository.IsPhoneNumberUsedByAnotherCustomer(customerId, e164FormattedNumber);

            if (isPhoneNumberUsedByAnotherCustomer)
            {
                return(CustomerProfileErrorCodes.PhoneAlreadyExists);
            }

            var result = await _customerProfileRepository.UpdateAsync(customerId, firstName, lastName, e164FormattedNumber,
                                                                      phoneNumber, countryPhoneCodeId, countryOfResidenceId);

            if (result == CustomerProfileErrorCodes.CustomerProfileDoesNotExist)
            {
                _log.Warning("Customer profile does not exist so it was not updated", context: customerId);
            }

            return(result);
        }
        public async Task <ICustomerProfile> GetByCustomerPhoneAsync(string phone, bool includeNotVerified = false, bool includeNotActive = false)
        {
            var e164FormattedNumber = PhoneUtils.GetE164FormattedNumber(phone);

            if (string.IsNullOrEmpty(e164FormattedNumber))
            {
                _log.Warning("Invalid phone number. Failed to convert to E164 format", null, phone);
                return(null);
            }

            var encryptedPhone = _encryptionService.EncryptValue(e164FormattedNumber);

            using (var context = _contextFactory.CreateDataContext())
            {
                var result = includeNotVerified
                    ? await context.CustomerProfiles
                             .Include(c => c.LoginProviders)
                             .IgnoreQueryFilters()
                             .Where(c => includeNotActive || c.Status == CustomerProfileStatus.Active)
                             .FirstOrDefaultAsync(c => c.PhoneNumber == encryptedPhone)
                    : await context.CustomerProfiles
                             .Include(c => c.LoginProviders)
                             .Where(c => includeNotActive || c.Status == CustomerProfileStatus.Active)
                             .FirstOrDefaultAsync(c => c.PhoneNumber == encryptedPhone);

                if (result == null)
                {
                    return(null);
                }

                result = _encryptionService.Decrypt(result);

                return(new CustomerProfileModel
                {
                    CustomerId = result.CustomerId,
                    Registered = result.Registered,
                    FirstName = result.FirstName,
                    LastName = result.LastName,
                    Email = result.Email,
                    IsEmailVerified = result.IsEmailVerified,
                    PhoneNumber = result.PhoneNumber,
                    ShortPhoneNumber = result.ShortPhoneNumber,
                    CountryPhoneCodeId = result.CountryPhoneCodeId,
                    CountryOfResidenceId = result.CountryOfResidenceId,
                    CountryOfNationalityId = result.CountryOfNationalityId,
                    TierId = result.TierId,
                    IsPhoneVerified = result.IsPhoneVerified,
                    LoginProviders = new List <LoginProvider>(
                        result.LoginProviders.Select(x => x.LoginProvider)),
                    Status = result.Status,
                });
            }
        }
Exemplo n.º 4
0
        public async Task ShouldCreateReferral_WhenValidDataIsPassed()
        {
            // Arrange
            var fixture = new ReferralLeadServiceTestsFixture();

            // Act
            await fixture.Service.CreateReferralLeadAsync(fixture.ReferralLead);

            // Assert

            fixture.ReferralLeadRepositoryMock.Verify(
                x => x.CreateAsync(
                    It.Is <ReferralLeadEncrypted>(c =>
                                                  c.AgentId == fixture.AgentId &&
                                                  c.PhoneNumberHash != fixture.PhoneNumber)),
                Times.Once);

            fixture.AgentManagementServiceMock.Verify(
                x => x.Agents.GetByCustomerIdAsync(
                    It.Is <Guid>(c => c == fixture.ReferralLead.AgentId)),
                Times.Once);
            var phoneNumberE164 = PhoneUtils.GetE164FormattedNumber(fixture.ReferralLead.PhoneNumber, fixture.CountryCode.ToString());

            fixture.NotificationPublisherServiceMock.Verify(
                x => x.LeadConfirmRequestAsync(
                    It.Is <string>(c => c == fixture.ReferralLead.AgentId.ToString()),
                    It.Is <string>(c => c == phoneNumberE164),
                    It.Is <string>(c => c == fixture.ReferralLead.ConfirmationToken)),
                Times.Once);

            fixture.NotificationPublisherServiceMock.Verify(
                x => x.LeadAlreadyConfirmedAsync(
                    It.IsAny <string>(),
                    It.IsAny <string>(),
                    It.IsAny <string>(),
                    It.IsAny <string>()),
                Times.Never);

            fixture.LeadStateChangePublisherMock.Verify(
                x =>
                x.PublishAsync(
                    It.Is <LeadStateChangedEvent>(
                        c =>
                        c.State == Contract.Enums.ReferralLeadState.Pending)),
                Times.Once);
        }
Exemplo n.º 5
0
        public void When_FullPhonePassedWithPlus_Expect_E164FormattedNumber()
        {
            //Arange
            var fullPhoneNumber = "+459 886 660 177";

            //Act
            var formatedPhoneNumber = PhoneUtils.GetE164FormattedNumber(fullPhoneNumber);

            //Assert
            var preparedNumber = new string(fullPhoneNumber.Where(char.IsDigit).ToArray());

            preparedNumber = preparedNumber.TrimStart('0');
            preparedNumber = $"+{preparedNumber}";

            var e164FormattedNumber = preparedNumber.ToE164Number();

            Assert.Equal(e164FormattedNumber, formatedPhoneNumber);
        }
Exemplo n.º 6
0
        public void When_EmptyStringPassed_Expect_PlusSign()
        {
            //Arange
            var emptyNumber = " ";

            //Act
            var formatedPhoneNumber = PhoneUtils.GetE164FormattedNumber(emptyNumber);

            //Assert
            var preparedNumber = new string(emptyNumber.Where(char.IsDigit).ToArray());

            preparedNumber = preparedNumber.TrimStart('0');
            preparedNumber = $"+{preparedNumber}";

            var e164FormattedNumber = preparedNumber.ToE164Number();

            Assert.Equal(e164FormattedNumber, formatedPhoneNumber);
        }
Exemplo n.º 7
0
        public void When_PhoneWithExtraSpaces_Expect_E164FormatOfOnlyNumbers()
        {
            //Arange
            var extraSpacesNumber = "  +45  9     8  8    6     6 6  0      1 77";

            //Act
            var formatedPhoneNumber = PhoneUtils.GetE164FormattedNumber(extraSpacesNumber);

            //Assert
            var preparedNumber = new string(extraSpacesNumber.Where(char.IsDigit).ToArray());

            preparedNumber = preparedNumber.TrimStart('0');
            preparedNumber = $"+{preparedNumber}";

            var e164FormattedNumber = preparedNumber.ToE164Number();

            Assert.Equal(e164FormattedNumber, formatedPhoneNumber);
        }
        public async Task <CustomerProfileErrorCodes> UpdatePhoneInfoAsync(string customerId, string phoneNumber, int countryPhoneCodeId)
        {
            var customerProfile =
                await _customerProfileRepository.GetByCustomerIdAsync(customerId, includeNotVerified : true);

            if (customerProfile == null)
            {
                return(CustomerProfileErrorCodes.CustomerProfileDoesNotExist);
            }

            var countryPhoneCode = await _dictionariesClient.Salesforce.GetCountryPhoneCodeByIdAsync(countryPhoneCodeId);

            if (countryPhoneCode == null)
            {
                return(CustomerProfileErrorCodes.InvalidCountryPhoneCodeId);
            }

            var e164FormattedNumber = PhoneUtils.GetE164FormattedNumber(phoneNumber, countryPhoneCode.IsoCode);

            if (e164FormattedNumber == null)
            {
                return(CustomerProfileErrorCodes.InvalidPhoneNumber);
            }

            var isPhoneNumberUsedByAnotherCustomer =
                await _customerProfileRepository.IsPhoneNumberUsedByAnotherCustomer(customerId, e164FormattedNumber);

            if (isPhoneNumberUsedByAnotherCustomer)
            {
                return(CustomerProfileErrorCodes.PhoneAlreadyExists);
            }

            if (customerProfile.PhoneNumber == e164FormattedNumber &&
                customerProfile.ShortPhoneNumber == phoneNumber &&
                customerProfile.CountryPhoneCodeId == countryPhoneCodeId)
            {
                return(CustomerProfileErrorCodes.None);
            }

            var result = await _customerProfileRepository.UpdatePhoneInfoAsync(customerId, e164FormattedNumber,
                                                                               phoneNumber, countryPhoneCodeId, isPhoneVerified : false);

            return(result);
        }
Exemplo n.º 9
0
        public void When_PhoneAndIsoCodePassed_Expect_E164FormattedNumber()
        {
            //Arange
            var shortPhoneNumber = "886 660 177";
            var isoCode          = "459";

            //Act
            var formatedPhoneNumber = PhoneUtils.GetE164FormattedNumber(shortPhoneNumber, isoCode);

            //Assert
            var fullPhoneNumber = $"{isoCode} {shortPhoneNumber}";

            var preparedNumber = new string(fullPhoneNumber.Where(char.IsDigit).ToArray());

            preparedNumber = preparedNumber.TrimStart('0');
            preparedNumber = $"+{preparedNumber}";

            var e164FormattedNumber = preparedNumber.ToE164Number();

            Assert.Equal(e164FormattedNumber, formatedPhoneNumber);
        }
        public async Task Save_Encrypted_Sensitive_Data_Of_Referral_Lead_While_Creating()
        {
            // arrange

            var profileFixture = new CustomerProfileResponse()
            {
                Profile = new CustomerProfile.Client.Models.Responses.CustomerProfile()
                {
                    Email = "*****@*****.**"
                },
                ErrorCode = CustomerProfileErrorCodes.None
            };

            _customerProfileClientMock.Setup(c => c.CustomerProfiles.GetByCustomerIdAsync(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>()))
            .ReturnsAsync(profileFixture);

            var emailHash = _referralLeadCreateInfo.Email.ToSha256Hash();

            var phoneNumberE164 =
                PhoneUtils.GetE164FormattedNumber(_referralLeadCreateInfo.PhoneNumber, _countryPhoneCode.IsoCode);

            var phoneNumberHash = phoneNumberE164.ToSha256Hash();

            // act

            await _service.CreateReferralLeadAsync(_referralLeadCreateInfo);

            // assert

            _referralLeadRepositoryMock.Verify(o => o.CreateAsync(
                                                   It.Is <ReferralLeadEncrypted>(referralLeadEncrypted =>
                                                                                 referralLeadEncrypted.EmailHash == emailHash &&
                                                                                 referralLeadEncrypted.PhoneNumberHash == phoneNumberHash &&
                                                                                 referralLeadEncrypted.PhoneCountryCodeId == _countryPhoneCode.Id &&
                                                                                 referralLeadEncrypted.AgentId == _referralLeadCreateInfo.AgentId &&
                                                                                 referralLeadEncrypted.AgentSalesforceId == _agent.SalesforceId &&
                                                                                 referralLeadEncrypted.State == ReferralLeadState.Pending)),
                                               Times.Once);
        }
        public async Task Create_Referral_Lead_Profile_While_Creating()
        {
            // arrange

            var phoneNumberE164 =
                PhoneUtils.GetE164FormattedNumber(_referralLeadCreateInfo.PhoneNumber, _countryPhoneCode.IsoCode);

            var profileFixture = new CustomerProfileResponse
            {
                Profile = new CustomerProfile.Client.Models.Responses.CustomerProfile
                {
                    Email = "*****@*****.**"
                },
                ErrorCode = CustomerProfileErrorCodes.None
            };

            _customerProfileClientMock.Setup(c => c.CustomerProfiles.GetByCustomerIdAsync(It.IsAny <string>(), false, false))
            .ReturnsAsync(profileFixture);

            // act

            await _service.CreateReferralLeadAsync(_referralLeadCreateInfo);

            // assert

            _customerProfileClientMock.Verify(o => o.ReferralLeadProfiles.AddAsync(
                                                  It.Is <ReferralLeadProfileRequest>(request =>
                                                                                     request.ReferralLeadId == _referralId &&
                                                                                     request.FirstName == _referralLeadCreateInfo.FirstName &&
                                                                                     request.LastName == _referralLeadCreateInfo.LastName &&
                                                                                     request.Email == _referralLeadCreateInfo.Email &&
                                                                                     request.PhoneNumber == phoneNumberE164 &&
                                                                                     request.Note == _referralLeadCreateInfo.Note
                                                                                     )),
                                              Times.Once);
        }
Exemplo n.º 12
0
        public async Task <ReferralLead> CreateReferralLeadAsync(ReferralLead referralLead)
        {
            ReferralLead createdReferralLead = null;

            try
            {
                var agentCustomer = await _customerProfileClient.CustomerProfiles
                                    .GetByCustomerIdAsync(referralLead.AgentId.ToString());

                if (agentCustomer.ErrorCode == CustomerProfileErrorCodes.CustomerProfileDoesNotExist)
                {
                    throw new CustomerDoesNotExistException($"Customer '{referralLead.AgentId}' does not exist.");
                }

                var agent = await _agentManagementClient.Agents.GetByCustomerIdAsync(referralLead.AgentId);

                if (agent == null || agent.Status != AgentStatus.ApprovedAgent)
                {
                    throw new CustomerNotApprovedAgentException("Customer isn't an approved agent.");
                }

                var countryPhoneCode = await _dictionariesClient.Salesforce
                                       .GetCountryPhoneCodeByIdAsync(referralLead.PhoneCountryCodeId);

                if (countryPhoneCode == null)
                {
                    throw new CountryCodeDoesNotExistException(
                              $"Country information for Country code id '{referralLead.PhoneCountryCodeId}' does not exist.");
                }

                var emailHash = referralLead.Email.ToSha256Hash();

                var phoneNumberE164 = PhoneUtils.GetE164FormattedNumber(referralLead.PhoneNumber, countryPhoneCode.IsoCode);

                if (string.IsNullOrEmpty(phoneNumberE164))
                {
                    _log.Error(message: "Referral lead has invalid phone number.",
                               context: $"agentId: {referralLead.AgentId}");

                    throw new InvalidPhoneNumberException();
                }

                var phoneNumberHash = phoneNumberE164.ToSha256Hash();

                var referralLeadEncrypted = new ReferralLeadEncrypted
                {
                    PhoneCountryCodeId = referralLead.PhoneCountryCodeId,
                    PhoneNumberHash    = phoneNumberHash,
                    EmailHash          = emailHash,
                    AgentId            = referralLead.AgentId,
                    AgentSalesforceId  = agent.SalesforceId,
                    ConfirmationToken  = GenerateConfirmationToken(),
                    // State is automatically approved
                    State = ReferralLeadState.Pending
                };

                referralLeadEncrypted = await _referralLeadRepository.CreateAsync(referralLeadEncrypted);

                createdReferralLead = _mapper.Map <ReferralLead>(referralLeadEncrypted);

                createdReferralLead.FirstName   = referralLead.FirstName;
                createdReferralLead.LastName    = referralLead.LastName;
                createdReferralLead.Email       = referralLead.Email;
                createdReferralLead.PhoneNumber = phoneNumberE164;
                createdReferralLead.Note        = referralLead.Note;

                var response = await _customerProfileClient.ReferralLeadProfiles.AddAsync(new ReferralLeadProfileRequest
                {
                    ReferralLeadId = referralLeadEncrypted.Id,
                    FirstName      = createdReferralLead.FirstName,
                    LastName       = createdReferralLead.LastName,
                    PhoneNumber    = createdReferralLead.PhoneNumber,
                    Email          = createdReferralLead.Email,
                    Note           = createdReferralLead.Note
                });

                if (response.ErrorCode != ReferralLeadProfileErrorCodes.None)
                {
                    _log.Error(message: "An error occurred while creating referral lead profile",
                               context: $"referralLeadId: {createdReferralLead.Id}");
                }

                await _notificationPublisherService.LeadConfirmRequestAsync(
                    referralLead.AgentId.ToString(),
                    phoneNumberE164,
                    referralLeadEncrypted.ConfirmationToken);
            }
            catch (Exception e)
            {
                _log.Error("Demo service failed to process the request.", e);
            }

            return(createdReferralLead);
        }
Exemplo n.º 13
0
        public async Task <ReferralLead> CreateReferralLeadAsync(ReferralLead referralLead)
        {
            var agentCustomer = await _customerProfileClient.CustomerProfiles
                                .GetByCustomerIdAsync(referralLead.AgentId.ToString(), false, false);

            if (agentCustomer.ErrorCode == CustomerProfileErrorCodes.CustomerProfileDoesNotExist)
            {
                throw new CustomerDoesNotExistException($"Customer '{referralLead.AgentId}' does not exist.");
            }

            var agent = await _agentManagementClient.Agents.GetByCustomerIdAsync(referralLead.AgentId);

            if (agent == null || agent.Status != AgentStatus.ApprovedAgent)
            {
                throw new CustomerNotApprovedAgentException("Customer isn't an approved agent.");
            }

            var countryPhoneCode = await _dictionariesClient.Salesforce
                                   .GetCountryPhoneCodeByIdAsync(referralLead.PhoneCountryCodeId);

            if (countryPhoneCode == null)
            {
                throw new CountryCodeDoesNotExistException(
                          $"Country information for Country code id '{referralLead.PhoneCountryCodeId}' does not exist.");
            }

            if (agentCustomer.Profile.Email == referralLead.Email ||
                agentCustomer.Profile.CountryPhoneCodeId == referralLead.PhoneCountryCodeId &&
                (agentCustomer.Profile.PhoneNumber == referralLead.PhoneNumber ||
                 agentCustomer.Profile.ShortPhoneNumber == referralLead.PhoneNumber))
            {
                throw new ReferYourselfException("You can not refer yourself as lead.");
            }

            var emailHash = referralLead.Email.ToSha256Hash();

            var phoneNumberE164 = PhoneUtils.GetE164FormattedNumber(referralLead.PhoneNumber, countryPhoneCode.IsoCode);

            if (string.IsNullOrEmpty(phoneNumberE164))
            {
                _log.Error(message: "Referral lead has invalid phone number.",
                           context: $"agentId: {referralLead.AgentId}");

                throw new InvalidPhoneNumberException();
            }

            var phoneNumberHash = phoneNumberE164.ToSha256Hash();

            if (await ReferralLeadAlreadyExistsAsync(referralLead.AgentId, emailHash, referralLead.PhoneCountryCodeId, phoneNumberHash))
            {
                throw new ReferralAlreadyExistException("Lead with the same Phone or Email is already referred from you.");
            }

            if (await ConfirmedLeadExistsAsync(emailHash, referralLead.PhoneCountryCodeId, phoneNumberHash))
            {
                await _notificationPublisherService.LeadAlreadyConfirmedAsync(
                    referralLead.AgentId.ToString(), referralLead.FirstName, referralLead.LastName, phoneNumberE164);

                throw new ReferralLeadAlreadyConfirmedException("Lead with the same Phone or Email already confirmed.");
            }

            if (agent == null || agent.Status != AgentStatus.ApprovedAgent)
            {
                throw new CustomerNotApprovedAgentException("Customer isn't an approved agent.");
            }

            var referralStake = await _stakeService.GetReferralStake(referralLead.CampaignId, EstatePurchaseConditionName);

            var referralLeadEncrypted = new ReferralLeadEncrypted
            {
                Id = Guid.NewGuid(),
                PhoneCountryCodeId = referralLead.PhoneCountryCodeId,
                PhoneNumberHash    = phoneNumberHash,
                EmailHash          = emailHash,
                AgentId            = referralLead.AgentId,
                AgentSalesforceId  = agent.SalesforceId,
                ConfirmationToken  = GenerateConfirmationToken(),
                State        = ReferralLeadState.Pending,
                CampaignId   = referralLead.CampaignId,
                StakeEnabled = referralStake != null
            };

            if (referralStake != null)
            {
                await _stakeService.SetStake(
                    referralStake,
                    referralLead.AgentId.ToString("D"),
                    referralLeadEncrypted.Id.ToString("D"));
            }

            referralLeadEncrypted = await _referralLeadRepository.CreateAsync(referralLeadEncrypted);

            var createdReferralLead = _mapper.Map <ReferralLead>(referralLeadEncrypted);

            createdReferralLead.FirstName   = referralLead.FirstName;
            createdReferralLead.LastName    = referralLead.LastName;
            createdReferralLead.Email       = referralLead.Email;
            createdReferralLead.PhoneNumber = phoneNumberE164;
            createdReferralLead.Note        = referralLead.Note;

            var response = await _customerProfileClient.ReferralLeadProfiles.AddAsync(new ReferralLeadProfileRequest
            {
                ReferralLeadId = referralLeadEncrypted.Id,
                FirstName      = createdReferralLead.FirstName,
                LastName       = createdReferralLead.LastName,
                PhoneNumber    = createdReferralLead.PhoneNumber,
                Email          = createdReferralLead.Email,
                Note           = createdReferralLead.Note
            });

            if (response.ErrorCode != ReferralLeadProfileErrorCodes.None)
            {
                _log.Error(message: "An error occurred while creating referral lead profile",
                           context: $"referralLeadId: {createdReferralLead.Id}");
            }

            await _notificationPublisherService.LeadConfirmRequestAsync(referralLead.AgentId.ToString(),
                                                                        phoneNumberE164, referralLeadEncrypted.ConfirmationToken);

            await PublishLeadChangeStateEvent(referralLeadEncrypted.Id.ToString(),
                                              _mapper.Map <Contract.Enums.ReferralLeadState>(referralLead.State));

            return(createdReferralLead);
        }