diff --git a/spec/jobs/bibliographic_job_spec.rb b/spec/jobs/bibliographic_job_spec.rb index e7dd2024..b33cdffd 100644 --- a/spec/jobs/bibliographic_job_spec.rb +++ b/spec/jobs/bibliographic_job_spec.rb @@ -35,4 +35,56 @@ end + describe 'email notifications' do + let(:mailer_double) { instance_double(ActionMailer::MessageDelivery, deliver_now: true) } + + context 'when job succeeds' do + it 'sends completion email with attachments' do + fake_attachments = { + 'fake_completed.csv' => { mime_type: 'text/csv', content: 'csvdata' } + } + + allow_any_instance_of(BibliographicJob) + .to receive(:generate_attatchments) + .and_return(fake_attachments) + + expect(RequestMailer) + .to receive(:bibliographic_email) + .with( + email, + fake_attachments, + 'Host Bibliographic Upload - Completed', + 'When there is an attached log file, please review unusual MMS ID information.' + ).and_return(mailer_double) + + BibliographicJob.perform_now(host_bib_task) + + expect(host_bib_task.reload.status).to eq('succeeded') + end + end + + context 'when job fails' do + it 'sends failure email' do + host_bib = host_bib_task.host_bibs.create(mms_id: mms_id1, marc_status: 'pending') + + allow(Bibliographic::HostBib) + .to receive(:create_linked_bibs) + .with(host_bib) + .and_raise(StandardError.new('Error')) + + expect(RequestMailer) + .to receive(:bibliographic_email) + .with( + email, + [], + 'Host Bibliographic Upload - Failed', + 'Host Bibliographic upload failed, please reach out to our support team.' + ).and_return(mailer_double) + + expect { BibliographicJob.perform_now(host_bib_task) }.to raise_error(StandardError) + + expect(host_bib_task.reload.status).to eq('failed') + end + end + end end diff --git a/spec/jobs/patron_note_job_base_spec.rb b/spec/jobs/patron_note_job_base_spec.rb new file mode 100644 index 00000000..92e71df6 --- /dev/null +++ b/spec/jobs/patron_note_job_base_spec.rb @@ -0,0 +1,126 @@ +require 'rails_helper' + +describe PatronNoteJobBase, type: :job do + let(:patron_id) { '12345' } + let(:mailer_prefix) { 'test_prefix' } + let(:note_txt) { 'Test note text' } + + let(:job) do + described_class.new(mailer_prefix:, note_txt:) + end + + let(:patron) do + instance_double( + Alma::User, + email: 'mrperson@test.com', + id: patron_id, + name: 'Bud Powell' + ) + end + + let(:mail_double) do + instance_double(ActionMailer::MessageDelivery, deliver_now: true) + end + + before do + allow(Alma::User).to receive(:find_if_active).with(patron_id).and_return(patron) + + allow(patron).to receive(:delete_note) + allow(patron).to receive(:add_note) + allow(patron).to receive(:save) + end + + describe '#perform' do + it 'finds patron and adds note' do + expect(patron).to receive(:delete_note).with(note_txt) + expect(patron).to receive(:add_note).with(job.note) + expect(patron).to receive(:save) + + allow(RequestMailer) + .to receive(:send) + .and_return(mail_double) + + job.perform(patron_id) + end + + it 'sends confirmation email' do + expect(RequestMailer) + .to receive(:send) + .with("#{mailer_prefix}_confirmation_email", patron.email) + .and_return(mail_double) + + job.perform(patron_id) + end + + it 'formats note with date and tag' do + allow(RequestMailer).to receive(:send).and_return(mail_double) + + travel_to Date.new(2025, 1, 1) do + job.perform(patron_id) + expect(job.note).to eq("20250101 #{note_txt} [litscript]") + end + end + end + + describe 'when patron lookup fails' do + it 'logs and raises error' do + allow(Alma::User).to receive(:find_if_active).and_raise(StandardError.new('fail')) + + expect(job).to receive(:log_error).at_least(:once) + + expect { job.perform(patron_id) }.to raise_error(StandardError) + end + end + + describe 'when add_note fails' do + before do + allow(RequestMailer).to receive(:send).and_return(mail_double) + allow(patron).to receive(:add_note).and_raise(StandardError.new('boom')) + end + + it 'sends failure email' do + expect(RequestMailer) + .to receive(:send) + .with( + "#{mailer_prefix}_failure_email", + patron.id, + patron.name, + job.note + ) + .and_return(mail_double) + + expect { job.perform(patron_id) }.to raise_error(StandardError) + end + + it 'logs error' do + expect(job).to receive(:log_error).at_least(:once) + + expect { job.perform(patron_id) }.to raise_error(StandardError) + end + end + + describe 'when confirmation email fails' do + it 'logs and raises error' do + allow(RequestMailer) + .to receive(:send) + .and_raise(StandardError.new('mail fail')) + + expect(job).to receive(:log_error).at_least(:once) + + expect { job.perform(patron_id) }.to raise_error(StandardError) + end + end + + describe 'when failure email itself fails' do + before do + allow(patron).to receive(:add_note).and_raise(StandardError.new('note fail')) + allow(RequestMailer).to receive(:send).and_raise(StandardError.new('mail fail')) + end + + it 'logs and raises error' do + expect(job).to receive(:log_error).at_least(:once) + + expect { job.perform(patron_id) }.to raise_error(StandardError) + end + end +end diff --git a/spec/request/proxy_borrower_forms_request_spec.rb b/spec/request/proxy_borrower_forms_request_spec.rb index 0d8dcf8e..50f172f4 100644 --- a/spec/request/proxy_borrower_forms_request_spec.rb +++ b/spec/request/proxy_borrower_forms_request_spec.rb @@ -1,6 +1,9 @@ require 'forms_helper' describe 'Proxy Borrower Forms', type: :request do + include ActiveJob::TestHelper + after { clear_enqueued_jobs } + attr_reader :patron_id attr_reader :patron attr_reader :user @@ -189,5 +192,42 @@ expect(response).to have_http_status :unprocessable_entity expect(response.body).to match(/Please correct these and resubmit the form/) end + + it 'submission enqueues confirmation + alert emails' do + expect do + post(forms_proxy_borrower_request_dsp_path, params: { + proxy_borrower_requests: { + student_name: 'Veronica Names', + dsp_rep: 'DSP Rep', + research_last: 'last', + research_first: 'first', + date_term: Date.tomorrow, + renewal: 0 + } + }) + end.to have_enqueued_job(ActionMailer::MailDeliveryJob).exactly(2).times + + expect(response).to have_http_status(:created) + end + + it 'Faculty submission enqueues confirmation + alert emails' do + allow_any_instance_of(User).to receive(:ucb_faculty?).and_return(true) + + expect do + post(forms_proxy_borrower_request_faculty_path, params: { + proxy_borrower_requests: { + faculty_name: 'Thelonius Monk', + department: 'History', + research_last: 'Last', + research_first: 'First', + date_term: Date.tomorrow, + renewal: 0 + } + }) + end.to have_enqueued_job(ActionMailer::MailDeliveryJob).exactly(2).times + + expect(response).to have_http_status(:created) + end + end end diff --git a/spec/request/reference_card_forms_request_spec.rb b/spec/request/reference_card_forms_request_spec.rb index 370eb080..c297c076 100644 --- a/spec/request/reference_card_forms_request_spec.rb +++ b/spec/request/reference_card_forms_request_spec.rb @@ -1,6 +1,9 @@ require 'forms_helper' describe 'Reference Card Form', type: :request do + include ActiveJob::TestHelper + after { clear_enqueued_jobs } + attr_reader :patron_id attr_reader :patron attr_reader :user @@ -26,6 +29,7 @@ it 'rejects a submission with a captcha verification error' do expect_any_instance_of(Recaptcha::Verify).to receive(:verify_recaptcha).and_raise(Recaptcha::RecaptchaError) + params = { reference_card_form: { email: 'jrdoe@affiliate.test', @@ -37,13 +41,15 @@ local_id: '123456789' } } + post('/forms/reference-card', params:) expect(response).to redirect_to(action: :new, params:) + get response.header['Location'] expect(response.body).to match('RECaptcha Error') end - it 'accepts a submission with a valid date' do + it 'accepts a submission with a valid date and enqueues email' do params = { reference_card_form: { email: 'jrdoe@affiliate.test', @@ -55,15 +61,17 @@ local_id: '123456789' } } - post('/forms/reference-card', params:) + + expect { post('/forms/reference-card', params:) }.to have_enqueued_job(ActionMailer::MailDeliveryJob) + expect(response).to have_http_status :created end it 'rejects a submission with a requested end date before the start date' do params = { reference_card_form: { - email: 'jrdoe@affiliate.test', - name: 'Jane R. Doe', + email: 'jrdupree@affiliate.test', + name: 'Jane R. Duprie', affiliation: 'nowhere', research_desc: 'research goes here....', pass_date: Date.current, @@ -71,8 +79,10 @@ local_id: '123456789' } } + post('/forms/reference-card', params:) expect(response).to have_http_status :found + follow_redirect! expect(response.body).to include('Requested access end date must not precede access start date') end @@ -86,22 +96,24 @@ end it 'renders process form for unprocessed request' do - form = ReferenceCardForm.create(id: 1, email: 'openreq@test.com', name: 'John Doe', + form = ReferenceCardForm.create(id: 1, email: 'openreq@test.com', name: 'John Testy', pass_date: Date.current, pass_date_end: Date.current + 1, research_desc: 'This is research', affiliation: 'Affiliation 1', local_id: '8675309') + get "/forms/reference-card/#{form.id}" expect(response.body).to include('

This Reference Card request needs to be processed.

') end it 'renders processed page for processed request' do form = ReferenceCardForm.create( - email: 'closedreq@test.com', name: 'Jane Doe', + email: 'closedreq@test.com', name: 'Jane Testy', pass_date: Date.current, pass_date_end: Date.current + 1, research_desc: 'This is research', affiliation: 'Affiliation 1', local_id: '8675309', approvedeny: true, processed_by: 'Test Admin' ) + get "/forms/reference-card/#{form.id}" expect(response.body).to include('

This request has been processed

') end @@ -112,23 +124,41 @@ expect(response.body).to include(path) end - it 'allows an admin to deny a request' do + it 'allows an admin to deny a request and enqueues denial email' do form = ReferenceCardForm.create(email: 'openreq@test.com', name: 'John Doe', - affiliation: 'Red Bull', pass_date: Date.current, pass_date_end: Date.current + 1, local_id: '8675309') + affiliation: 'Red Bull', + pass_date: Date.current, + pass_date_end: Date.current + 1, + local_id: '8675309') - params = { - 'stack_pass_[approve_deny]' => false, - 'processed_by' => 'ADMIN USER', - 'denial_reason' => 'Item listed at another library' - } - patch("/forms/reference-card/#{form.id}", params:) - expect(response).to redirect_to(action: :show, id: 1) + expect do + patch("/forms/reference-card/#{form.id}", params: { + 'stack_pass_[approve_deny]' => false, + 'processed_by' => 'ADMIN USER', + 'denial_reason' => 'Item listed at another library' + }) + end.to have_enqueued_job(ActionMailer::MailDeliveryJob) + + expect(response).to redirect_to(action: :show, id: form.id) get(response.headers['Location']) - expect(response.body).to include(params['denial_reason']) + expect(response.body).to include('Item listed at another library') expect(response.body).to include('This request has been processed') end - end + it 'enqueues approval email when admin approves request' do + form = ReferenceCardForm.create(email: 'openreq@test.com', name: 'John Doe', + affiliation: 'Test', + pass_date: Date.current, + pass_date_end: Date.current + 1, + local_id: '8675309') + expect do + patch("/forms/reference-card/#{form.id}", params: { + 'stack_pass_[approve_deny]' => true, + 'processed_by' => 'ADMIN USER' + }) + end.to have_enqueued_job(ActionMailer::MailDeliveryJob) + end + end end diff --git a/spec/request/stack_pass_form_request_spec.rb b/spec/request/stack_pass_form_request_spec.rb index 629fffea..50a99f6b 100644 --- a/spec/request/stack_pass_form_request_spec.rb +++ b/spec/request/stack_pass_form_request_spec.rb @@ -1,6 +1,10 @@ require 'forms_helper' describe 'Stack Pass Form', type: :request do + include ActiveJob::TestHelper + + after { clear_enqueued_jobs } + attr_reader :patron_id attr_reader :patron attr_reader :user @@ -23,9 +27,9 @@ expect(response).to redirect_to(action: :new) end - it 'requires login if user is not a stack pass admin' do - form = StackPassForm.create(email: 'openreq@test.com', name: 'John Doe', - phone: '925-555-1234', pass_date: Date.current, main_stack: true) + it 'redirects to login if if user is not a stack pass admin' do + form = StackPassForm.create(email: 'openreq@test.com', name: 'John Testy', + phone: '510-222-2222', pass_date: Date.current, main_stack: true) get stack_pass_form_path(id: form.id) expect(response).to have_http_status :forbidden @@ -38,14 +42,16 @@ stack_pass_form: { email: 'jrdoe@affiliate.test', name: 'Jane R. Doe', - phone: '925-555-1212', + phone: '510-222-2222', main_stack: true, pass_date: '04/13/1996', local_id: '123456789' } } + post('/forms/stack-pass', params:) expect(response).to redirect_to(action: :new, params:) + get response.header['Location'] expect(response.body).to match('RECaptcha Error') end @@ -67,14 +73,16 @@ it 'renders process form for unprocessed request' do form = StackPassForm.create(email: 'openreq@test.com', name: 'John Doe', phone: '925-555-1234', pass_date: Date.current, main_stack: true, local_id: '8675309') + get "/forms/stack-pass/#{form.id}" expect(response.body).to include('

This request needs to be processed.

') end it 'renders processed page for processed request' do form = StackPassForm.create(email: 'closedreq@test.com', name: 'Jane Doe', - phone: '925-555-5678', pass_date: Date.current, main_stack: true, local_id: '8675309', - approvedeny: true, processed_by: 'Test Admin') + phone: '925-555-5678', pass_date: Date.current, main_stack: true, + local_id: '8675309', approvedeny: true, processed_by: 'Test Admin') + get "/forms/stack-pass/#{form.id}" expect(response.body).to include('

This request has been processed

') end @@ -85,28 +93,42 @@ expect(response.body).to include(path) end - it 'allows an admin to deny a request' do + it 'allows an admin to deny a request and enqueues denial email' do form = StackPassForm.create(email: 'openreq@test.com', name: 'John Doe', - phone: '925-555-1234', pass_date: Date.current, main_stack: true, local_id: '8675309') + phone: '925-555-1234', pass_date: Date.current + 1, + main_stack: true, local_id: '8675309') + + expect do + patch "/forms/stack-pass/#{form.id}", params: { + stack_pass_: { approve_deny: false }, + processed_by: 'ADMIN USER', + denial_reason: 'Item listed at another library' + } + end.to have_enqueued_job(ActionMailer::MailDeliveryJob) - params = { - 'stack_pass_[approve_deny]' => false, - 'processed_by' => 'ADMIN USER', - 'denial_reason' => 'Item listed at another library' - } - patch("/forms/stack-pass/#{form.id}", params:) - expect(response).to redirect_to(action: :show, id: 1) + expect(response).to redirect_to(action: :show, id: form.id) get(response.headers['Location']) - expect(response.body).to include(params['denial_reason']) + expect(response.body).to include('Item listed at another library') expect(response.body).to include('This request has been processed') end + it 'enqueues approval email when admin approves request' do + form = StackPassForm.create(email: 'openreq@test.com', name: 'John Testy', + phone: '510-222-2222', pass_date: Date.current + 1, + main_stack: true, local_id: '8675309') + + expect do + patch "/forms/stack-pass/#{form.id}", params: { + stack_pass_: { approve_deny: true }, + processed_by: 'ADMIN USER' + } + end.to have_enqueued_job(ActionMailer::MailDeliveryJob) + end end context 'specs with hard-coded admin privledges' do - - before do |_test| + before do admin_user = User.new(uid: '1707532', affiliations: ['EMPLOYEE-TYPE-ACADEMIC']) allow_any_instance_of(StackPassAdminController).to receive(:current_user).and_return(admin_user) allow_any_instance_of(StackRequestsController).to receive(:current_user).and_return(admin_user) @@ -131,7 +153,6 @@ get forms_stack_pass_admin_users_path expect(response).to have_http_status :ok end - end context 'specs with non-admin user logged in' do @@ -150,8 +171,7 @@ end context 'specs with user created administrators' do - before do |_test| - # Create the role, user and assignment: + before do Role.create(id: 1, role: 'stackpass_admin') admin_user = User.new(uid: '9999999', affiliations: ['EMPLOYEE-TYPE-ACADEMIC']) FrameworkUsers.create(id: 1, lcasid: '9999999', name: 'Test Dude', role: 'admin') @@ -177,5 +197,4 @@ expect(response.body).to include('Admin User') end end - end