public void TestNoAccess() { // Create an employer. var employer = CreateEmployer(); // Create a member. var member = CreateMember(); // Create a view with no access. Should still be sent with no problems (it is not up to the email to decide whether it can be sent or not). var view = new ProfessionalView(member, 0, ProfessionalContactDegree.NotContacted, true, false); var communication = new ContactCandidateEmail(view, null, employer, Subject, SimpleContent); _emailsCommand.TrySend(communication); // Check. var email = _emailServer.AssertEmailSent(); email.AssertAddresses(employer, Return, member); email.AssertSubject(Subject); email.AssertViewChecks(MediaTypeNames.Text.Html); email.AssertView(MediaTypeNames.Text.Html, GetBody(communication, member, GetContent(member, employer, SimpleContent))); email.AssertView(MediaTypeNames.Text.Plain, GetPlainBody(communication, GetPlainContent(member, employer, SimpleContent))); email.AssertNoAttachments(); AssertCompatibleAddresses(email); }
public void DisplayExperienceToEmployer(Member member, Resume resume, ProfessionalView view, IResumeHighlighter highlighter) { _highlighter = highlighter ?? _highlighterFactory.Create(ResumeHighlighterKind.Null, null, new HighlighterConfiguration()); _hideRecentEmployers = !view.CanAccess(ProfessionalVisibility.RecentEmployers); DisplayExperienceInternal(member, resume); }
private static void CheckVisibility(ProfessionalView view, MemberAccessReason reason) { // This check is here is to ensure that the member does in fact have something the employer wants to see // and that it is visible, even after exercising a credit. switch (reason) { case MemberAccessReason.PhoneNumberViewed: // Must have a phone number. if (!view.HasPhoneNumbers || !view.VisibilitySettings.Professional.EmploymentVisibility.IsFlagSet(ProfessionalVisibility.Resume) || !view.VisibilitySettings.Professional.EmploymentVisibility.IsFlagSet(ProfessionalVisibility.PhoneNumbers)) { throw new NotVisibleException(); } break; default: // Must have a visible resume. Really should be checking for view.Resume != null but that means // loading a lot of information from the database for a rare case. It is basically assumed // that if it gets to here the member has a resume. if (!view.VisibilitySettings.Professional.EmploymentVisibility.IsFlagSet(ProfessionalVisibility.Resume)) { throw new NotVisibleException(); } break; } }
private MemberAccess AccessMember(ChannelApp app, IEmployer employer, ProfessionalView view, MemberAccessReason reason) { // An anonymous employer means insufficient credits. if (employer == null) { throw new InsufficientCreditsException { Available = 0, Required = 1 } } ; // Make sure the details are visible. CheckVisibility(view, reason); // Check against limits. CheckAccessLimit(employer.Id, view.Id, reason); // Exercise the credit. var exercisedCreditId = _employerCreditsCommand.ExerciseContactCredit(employer, view); // Record the access. return(CreateMemberAccess(app, employer.Id, view.Id, reason, exercisedCreditId)); }
public void TestFinsia() { _activeCommunity = ActiveCommunity.Finsia; // Create an employer. var employer = _employerAccountsCommand.CreateTestEmployer(0, _organisationsCommand.CreateTestOrganisation(0)); // Create a member. var community = TestCommunity.Finsia.CreateTestCommunity(_communitiesCommand, _verticalsCommand, _contentEngine); var member = _memberAccountsCommand.CreateTestMember(0, community.Id); var representee = _memberAccountsCommand.CreateTestMember(1); var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); var communication = new RepresentativeContactCandidateEmail(view, NewEmployerEmail, employer, representee, Subject, Content); _emailsCommand.TrySend(communication); // Check. var email = _emailServer.AssertEmailSent(); email.AssertAddresses(new EmailRecipient(NewEmployerEmail, employer.FullName), Return, member); email.AssertSubject(Subject); email.AssertViewChecks(MediaTypeNames.Text.Html); email.AssertView(MediaTypeNames.Text.Html, GetBody(communication, member, GetContent(member, representee, employer, Content))); email.AssertNoAttachments(); AssertCompatibleAddresses(email); }
public void TestNoAccess() { // Create an employer. var employer = _employerAccountsCommand.CreateTestEmployer(0, _organisationsCommand.CreateTestOrganisation(0)); // Create a member. var member = _memberAccountsCommand.CreateTestMember(0); var representee = _memberAccountsCommand.CreateTestMember(1); // Send. var view = new ProfessionalView(member, 0, ProfessionalContactDegree.NotContacted, false, false); var representeeView = new ProfessionalView(representee, 0, ProfessionalContactDegree.NotContacted, false, false); var communication = new RepresentativeContactCandidateEmail(view, null, employer, representeeView, Subject, Content); _emailsCommand.TrySend(communication); // Check. var email = _emailServer.AssertEmailSent(); email.AssertAddresses(employer, Return, member); email.AssertSubject(Subject); email.AssertViewChecks(MediaTypeNames.Text.Html); email.AssertView(MediaTypeNames.Text.Html, GetBody(communication, member, GetContent(member, representee, employer, Content))); email.AssertNoAttachments(); AssertCompatibleAddresses(email); }
public void TestAutoPeople() { // Create an employer. var employer = _employerAccountsCommand.CreateTestEmployer(0, _organisationsCommand.CreateTestOrganisation(0)); // Create a member. var member = _memberAccountsCommand.CreateTestMember(0); var representee = _memberAccountsCommand.CreateTestMember(1); // Send in the context of Autopeople. Should still be a standard email because the member is not a member of Autopeople. Community community = TestCommunity.Autopeople.CreateTestCommunity(_communitiesCommand, _verticalsCommand, _contentEngine); ActivityContext.Current.Community.Set(community); var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); var communication = new RepresentativeContactCandidateEmail(view, NewEmployerEmail, employer, representee, Subject, Content); _emailsCommand.TrySend(communication); // Check. var email = _emailServer.AssertEmailSent(); email.AssertAddresses(new EmailRecipient(NewEmployerEmail, employer.FullName), Return, member); email.AssertSubject(Subject); email.AssertViewChecks(MediaTypeNames.Text.Html); email.AssertView(MediaTypeNames.Text.Html, GetBody(communication, member, GetContent(member, representee, employer, Content))); email.AssertNoAttachments(); AssertCompatibleAddresses(email); }
public void TestNotificationsOff() { var employer = CreateEmployer(); var member = CreateMember(); // No settings so notification should get through. var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); _emailsCommand.TrySend(new ContactCandidateEmail(view, null, employer, Subject, SimpleContent)); _emailServer.AssertEmailSent(); // Turn off. var category = _settingsQuery.GetCategory("EmployerToMemberNotification"); _settingsCommand.SetFrequency(member.Id, category.Id, Frequency.Never); _emailsCommand.TrySend(new ContactCandidateEmail(view, null, employer, Subject, SimpleContent)); _emailServer.AssertNoEmailSent(); // Turn on. _settingsCommand.SetFrequency(member.Id, category.Id, Frequency.Immediately); _emailsCommand.TrySend(new ContactCandidateEmail(view, null, employer, Subject, SimpleContent)); _emailServer.AssertEmailSent(); }
public void TestNotificationsOff() { var employer = _employerAccountsCommand.CreateTestEmployer(FromLoginId, _organisationsCommand.CreateTestOrganisation(0)); var member = _memberAccountsCommand.CreateTestMember(To); // No settings so notification should get through. var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); _emailsCommand.TrySend(new RejectCandidateEmail(view, FromEmailAddress, employer, Subject, Content)); _emailServer.AssertEmailSent(); // Turn off. var category = _settingsQuery.GetCategory("EmployerToMemberNotification"); _settingsCommand.SetFrequency(member.Id, category.Id, Frequency.Never); _emailsCommand.TrySend(new RejectCandidateEmail(view, FromEmailAddress, employer, Subject, Content)); _emailServer.AssertNoEmailSent(); // Turn on. _settingsCommand.SetFrequency(member.Id, category.Id, Frequency.Immediately); _emailsCommand.TrySend(new RejectCandidateEmail(view, FromEmailAddress, employer, Subject, Content)); _emailServer.AssertEmailSent(); }
public void TestHtmlContent() { // Create an employer. var employer = CreateEmployer(); // Create a member. var member = CreateMember(); // Send. var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); var communication = new ContactCandidateEmail(view, null, employer, Subject, HtmlContent); _emailsCommand.TrySend(communication); // Check. var email = _emailServer.AssertEmailSent(); email.AssertAddresses(employer, Return, member); email.AssertSubject(Subject); //email.AssertViewChecks(MediaTypeNames.Text.Html); email.AssertView(MediaTypeNames.Text.Html, GetBody(communication, member, GetContent(member, employer, HtmlContent))); email.AssertView(MediaTypeNames.Text.Plain, GetPlainBody(communication, GetPlainContent(member, employer, PlainHtmlContent))); email.AssertNoAttachments(); AssertCompatibleAddresses(email); }
public override TemplateEmail GeneratePreview(Community community) { var member = _memberAccountsCommand.CreateTestMember(To, community != null ? community.Id : (Guid?)null); var employer = _employerAccountsCommand.CreateTestEmployer(FromLoginId, _organisationsCommand.CreateTestOrganisation(0)); // Send. var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); return(new RejectCandidateEmail(view, FromEmailAddress, employer, Subject, Content)); }
void IEmployerMemberContactsCommand.RejectMember(IEmployer employer, ProfessionalView view, RejectionMemberMessage messageTemplate) { var cleaner = new MemberMessageCleaner(); var cleanedBody = cleaner.CleanBody(messageTemplate.Body); var cleanedSubject = cleaner.CleanSubject(messageTemplate.Subject); // Save the message. var handlers = MessageCreated; var representativeId = _memberContactsQuery.GetRepresentativeContact(view.Id); ContactMember(messageTemplate, employer, view, cleanedSubject, cleanedBody, representativeId, null, handlers); }
private ContactCandidateEmail CreateContactCandidateEmail(string emailAddress) { var view = new ProfessionalView(_memberUser, null, ProfessionalContactDegree.Contacted, true, false); var email = new ContactCandidateEmail(view, null, _employerUser, "This is the subject", "Blah\nBlah blah\nBlah blah blah\nBlah blah blah blah\nBlah blah blah blah blah"); _memberUser.EmailAddresses = new List <EmailAddress> { new EmailAddress { Address = emailAddress } }; email.To = _memberUser; return(email); }
public override TemplateEmail GeneratePreview(Community community) { // Create an employer. var employer = CreateEmployer(); // Create a member. var member = CreateMember(community); // Send. var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); return(new ContactCandidateEmail(view, null, employer, Subject, SimpleContent)); }
public override TemplateEmail GeneratePreview(Community community) { // Create an employer. var employer = _employerAccountsCommand.CreateTestEmployer(0, _organisationsCommand.CreateTestOrganisation(0)); // Create a member. var member = _memberAccountsCommand.CreateTestMember(0, community != null ? community.Id : (Guid?)null); var representee = _memberAccountsCommand.CreateTestMember(1); // Send. var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); return(new RepresentativeContactCandidateEmail(view, null, employer, representee, Subject, Content)); }
public static string GetCandidateStatusChangeMessage(ProfessionalView view, ApplicantStatus newStatus) { string verb; switch (newStatus) { case ApplicantStatus.Rejected: verb = "rejected"; break; case ApplicantStatus.Shortlisted: verb = "shortlisted"; break; default: throw new ArgumentException("Unexpected value of newStatus: " + newStatus); } return("\"" + HtmlUtil.TextToHtml(view.GetFullNameDisplayText()) + "\" has been " + verb + "."); }
public void TestMailContents() { Member member = _memberAccountsCommand.CreateTestMember(To); Employer employer = _employerAccountsCommand.CreateTestEmployer(FromLoginId, _organisationsCommand.CreateTestOrganisation(0)); // Send. var view = new ProfessionalView(member, null, ProfessionalContactDegree.Contacted, true, false); var communication = new RejectCandidateEmail(view, FromEmailAddress, employer, Subject, Content); _emailsCommand.TrySend(communication); // Check. var email = _emailServer.AssertEmailSent(); email.AssertAddresses(new EmailRecipient(FromEmailAddress, employer.FullName), Return, new EmailRecipient(To, member.FullName)); email.AssertSubject(Subject); email.AssertHtmlViewChecks(); email.AssertHtmlView(GetBody(communication, GetContent(Content))); email.AssertNoAttachments(); AssertCompatibleAddresses(email); }
private void CheckCanAccessMember(IEmployer employer, ProfessionalView view, MemberAccessReason reason) { // An anonymous employer means insufficient credits. if (employer == null) { throw new InsufficientCreditsException { Available = 0, Required = 1 } } ; // Make sure the details are visible. CheckVisibility(view, reason); // Check against limits. CheckAccessLimit(employer.Id, view.Id, reason); // Check the credit. _employerCreditsCommand.CheckCanExerciseContactCredit(employer, view); }
Guid?IEmployerCreditsCommand.ExerciseContactCredit(IEmployer employer, ProfessionalView view) { // No employer automatically means not enough credits. if (employer == null) { throw new InsufficientCreditsException { Available = 0, Required = 1 } } ; return(ExerciseContactCredits(employer.Id, new[] { view }, view.ContactCredits)[view.Id]); } void IEmployerCreditsCommand.CheckCanExerciseContactCredit(IEmployer employer, ProfessionalView view) { // No employer automatically means not enough credits. if (employer == null) { throw new InsufficientCreditsException { Available = 0, Required = 1 } } ; CheckCanExerciseContactCredits(new[] { view }, view.ContactCredits); } IDictionary <Guid, Guid?> IEmployerCreditsCommand.ExerciseContactCredits(IEmployer employer, ProfessionalViews views) { // No employer automatically means not enough credits. if (employer == null) { throw new InsufficientCreditsException { Available = 0, Required = views.Count() } } ; return(ExerciseContactCredits(employer.Id, views, views.ContactCredits)); } void IEmployerCreditsCommand.CheckCanExerciseContactCredits(IEmployer employer, ProfessionalViews views) { // No employer automatically means not enough credits. if (employer == null) { throw new InsufficientCreditsException { Available = 0, Required = views.Count() } } ; CheckCanExerciseContactCredits(views, views.ContactCredits); } Guid?IEmployerCreditsCommand.ExerciseApplicantCredit(InternalApplication application, IJobAd jobAd) { var hierarchyPath = _recruitersQuery.GetOrganisationHierarchyPath(jobAd.PosterId); // If the employer has already purchased this applicant or they have already applied then don't exercise a credit // because they already have access. if (_exercisedCreditsQuery.HasExercisedCredit <ContactCredit>(hierarchyPath, application.ApplicantId)) { return(ExerciseCredit(hierarchyPath, false, application, jobAd)); } // If the poster has unlimited credits or zero credits then nothing to do. var allocation = GetEffectiveActiveAllocation <ApplicantCredit>(hierarchyPath); if (allocation.RemainingQuantity == null || allocation.RemainingQuantity == 0) { return(ExerciseCredit(hierarchyPath, false, application, jobAd)); } // If the applicant has applied for another job ad from this employer then don't exercise // - one credit used for each applicant for each poster. // The application that triggered this event will be returned so look for more than 1 applications. var employer = _employersQuery.GetEmployer(jobAd.PosterId); if (employer == null) { return(ExerciseCredit(hierarchyPath, false, application, jobAd)); } if (_jobAdApplicantsQuery.GetApplications(employer, application.ApplicantId).Count > 1) { return(ExerciseCredit(hierarchyPath, false, application, jobAd)); } // Check whether the job ad threshold has already been passed. var applicantList = _jobAdApplicantsQuery.GetApplicantList(employer, jobAd); if (applicantList == null) { return(ExerciseCredit(hierarchyPath, false, application, jobAd)); } var applicants = _jobAdApplicantsQuery.GetApplicantCount(employer, applicantList); if (applicants > _maxCreditsPerJobAd) { return(ExerciseCredit(hierarchyPath, false, application, jobAd)); } // Need to adjust an allocation. return(ExerciseCredit(hierarchyPath, true, application, jobAd)); } Guid?IEmployerCreditsCommand.ExerciseJobAdCredit(JobAdEntry jobAd) { if (jobAd.Status != JobAdStatus.Draft) { return(null); } // Check has both job ad and applicant credits. var hierarchyPath = _recruitersQuery.GetOrganisationHierarchyPath(jobAd.PosterId); var jobAdCreditId = _creditsQuery.GetCredit <JobAdCredit>().Id; var applicantCreditId = _creditsQuery.GetCredit <ApplicantCredit>().Id; var allocations = GetEffectiveActiveAllocations(hierarchyPath, new[] { jobAdCreditId, applicantCreditId }); if (allocations == null || allocations.Any(a => a.Value.RemainingQuantity == 0)) { throw new InsufficientCreditsException { Available = 0, Required = 1 } } ; // Exercise. var credit = _creditsQuery.GetCredit <JobAdCredit>(); return(_exercisedCreditsCommand.ExerciseCredit(credit.Id, hierarchyPath, true, jobAd.PosterId, null, jobAd.Id)); } private IDictionary <Guid, Guid?> ExerciseContactCredits(Guid employerId, IEnumerable <ProfessionalView> views, int?contactCredits) { // Split by statuses. var statuses = GetStatuses(views); // If there are any that cannot contact at this stage then simply reject. It is really up to the caller to ensure that this does not happen. if (statuses[CanContactStatus.No].Count > 0 || statuses[CanContactStatus.YesIfHadCredit].Count > 0) { throw new InsufficientCreditsException { Available = contactCredits, Required = statuses[CanContactStatus.No].Count + statuses[CanContactStatus.YesWithCredit].Count + statuses[CanContactStatus.YesIfHadCredit].Count } } ; // Check the number of credits available. if (statuses[CanContactStatus.YesWithCredit].Count > 0) { // Really you can't get this combination but just throw just in case. if (contactCredits == null) { throw new InsufficientCreditsException { Available = contactCredits, Required = statuses[CanContactStatus.YesWithCredit].Count } } ; // Check that there are enough. if (contactCredits.Value < statuses[CanContactStatus.YesWithCredit].Count) { throw new InsufficientCreditsException { Available = contactCredits, Required = statuses[CanContactStatus.YesWithCredit].Count } } ; } // Exercise credits as necessary. var hierarchyPath = _recruitersQuery.GetOrganisationHierarchyPath(employerId); // For those who need a credit used adjust allocations. var yesWithCredits = statuses[CanContactStatus.YesWithCredit]; var exercisedCredits = yesWithCredits.Count > 0 ? ExerciseCredits(hierarchyPath, true, employerId, from y in yesWithCredits select y.Id) : new Dictionary <Guid, Guid?>(); var yesWithoutCredits = statuses[CanContactStatus.YesWithoutCredit]; if (yesWithoutCredits.Count > 0) { // For those who don't need a credit used only exercise a credit for those who have not been contacted. var hasContacted = _exercisedCreditsQuery.HasExercisedCredits <ContactCredit>(hierarchyPath, from y in yesWithoutCredits select y.Id); foreach (var id in hasContacted) { exercisedCredits[id] = null; } var hasNotContacted = (from y in yesWithoutCredits select y.Id).Except(hasContacted); if (hasNotContacted.Any()) { var hasNotContactedExercisedCreditIds = ExerciseCredits(hierarchyPath, false, employerId, hasNotContacted); foreach (var id in hasNotContacted) { exercisedCredits[id] = hasNotContactedExercisedCreditIds[id]; } } } return(exercisedCredits); } private static void CheckCanExerciseContactCredits(IEnumerable <ProfessionalView> views, int?contactCredits) { // Split by statuses. var statuses = GetStatuses(views); // If there are any that cannot contact at this stage then simply reject. It is really up to the caller to ensure that this does not happen. if (statuses[CanContactStatus.No].Count > 0 || statuses[CanContactStatus.YesIfHadCredit].Count > 0) { throw new InsufficientCreditsException { Available = contactCredits, Required = statuses[CanContactStatus.No].Count + statuses[CanContactStatus.YesWithCredit].Count + statuses[CanContactStatus.YesIfHadCredit].Count } } ; // Check the number of credits available. if (statuses[CanContactStatus.YesWithCredit].Count > 0) { // Really you can't get this combination but just throw just in case. if (contactCredits == null) { throw new InsufficientCreditsException { Available = contactCredits, Required = statuses[CanContactStatus.YesWithCredit].Count } } ; // Check that there are enough. if (contactCredits.Value < statuses[CanContactStatus.YesWithCredit].Count) { throw new InsufficientCreditsException { Available = contactCredits, Required = statuses[CanContactStatus.YesWithCredit].Count } } ; } }
void IEmployerMemberContactsCommand.CheckCanContactMember(ChannelApp app, IEmployer employer, ProfessionalView view) { _employerMemberViewsCommand.CheckCanAccessMember(app, employer, view, MemberAccessReason.MessageSent); }
void IEmployerMemberContactsCommand.ContactMember(ChannelApp app, IEmployer employer, ProfessionalView view, ContactMemberMessage messageTemplate) { var cleaner = new MemberMessageCleaner(); var cleanedBody = cleaner.CleanBody(messageTemplate.Body); var cleanedSubject = cleaner.CleanSubject(messageTemplate.Subject); // Messages are being sent so exercise a credit. var access = _employerMemberViewsCommand.AccessMember(app, employer, view, MemberAccessReason.MessageSent); // Save the message. if (access != null) { var handlers = MessageCreated; var representativeId = _memberContactsQuery.GetRepresentativeContact(view.Id); ContactMember(messageTemplate, employer, view, cleanedSubject, cleanedBody, representativeId, access, handlers); } }
public static string GetFullNameDisplayText(this ProfessionalView view) { return(view.FullName ?? "Anonymous member"); }
void IEmployerMemberViewsCommand.CheckCanAccessMember(ChannelApp app, IEmployer employer, ProfessionalView view, MemberAccessReason reason) { CheckCanAccessMember(employer, view, reason); }
MemberAccess IEmployerMemberViewsCommand.AccessMember(ChannelApp app, IEmployer employer, ProfessionalView view, MemberAccessReason reason) { return(AccessMember(app, employer, view, reason)); }
private void AccessMember(IEmployer employer, ProfessionalView view) { _employerMemberViewsCommand.AccessMember(_app, employer, view, MemberAccessReason.MessageSent); }
private void AccessMemberViewingPhoneNumber(IEmployer employer, ProfessionalView view) { _employerMemberViewsCommand.AccessMember(_app, employer, view, MemberAccessReason.PhoneNumberViewed); }