diff --git a/app/jobs/hearings/fetch_webex_recordings_details_job.rb b/app/jobs/hearings/fetch_webex_recordings_details_job.rb index 31d425f18dc..108f68bca79 100644 --- a/app/jobs/hearings/fetch_webex_recordings_details_job.rb +++ b/app/jobs/hearings/fetch_webex_recordings_details_job.rb @@ -15,15 +15,17 @@ class Hearings::FetchWebexRecordingsDetailsJob < CaseflowJob retry_on(Caseflow::Error::WebexApiError, wait: :exponentially_longer) do |job, exception| recording_id = job.arguments&.first&.[](:recording_id) host_email = job.arguments&.first&.[](:host_email) + meeting_title = job.arguments&.first&.[](:meeting_title) query = "?hostEmail=#{host_email}" error_details = { error: { type: "retrieval", explanation: "retrieve recording details from Webex" }, provider: "webex", + api_call: + "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}recordings/#{recording_id}#{query}", + response: { status: exception.code, message: exception.message }.to_json, recording_id: recording_id, host_email: host_email, - api_call: "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}/#{recording_id}#{query}", - response: { status: exception.code, message: exception.message }.to_json, - docket_number: nil + meeting_title: meeting_title } job.log_error(exception) job.send_transcription_issues_email(error_details) diff --git a/app/jobs/hearings/fetch_webex_recordings_list_job.rb b/app/jobs/hearings/fetch_webex_recordings_list_job.rb index a0c3229aa3c..e4512cb323c 100644 --- a/app/jobs/hearings/fetch_webex_recordings_list_job.rb +++ b/app/jobs/hearings/fetch_webex_recordings_list_job.rb @@ -14,14 +14,16 @@ class Hearings::FetchWebexRecordingsListJob < CaseflowJob retry_on(Caseflow::Error::WebexApiError, wait: :exponentially_longer) do |job, exception| max = 100 id = job.arguments&.first&.[](:meeting_id) - query = "?max=#{max}?meetingId=#{id}" + meeting_title = job.arguments&.first&.[](:meeting_title) + query = "?max=#{max}&meetingId=#{id}" error_details = { error: { type: "retrieval", explanation: "retrieve a list of recordings from Webex" }, provider: "webex", - api_call: "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}#{query}", + api_call: + "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}admin/recordings/#{query}", response: { status: exception.code, message: exception.message }.to_json, meeting_id: id, - docket_number: nil + meeting_title: meeting_title } job.log_error(exception) job.send_transcription_issues_email(error_details) diff --git a/app/jobs/hearings/fetch_webex_room_meeting_details_job.rb b/app/jobs/hearings/fetch_webex_room_meeting_details_job.rb index dfb072efcd0..11b85179059 100644 --- a/app/jobs/hearings/fetch_webex_room_meeting_details_job.rb +++ b/app/jobs/hearings/fetch_webex_room_meeting_details_job.rb @@ -11,13 +11,16 @@ class Hearings::FetchWebexRoomMeetingDetailsJob < CaseflowJob attr_reader :room_id, :meeting_title retry_on(Caseflow::Error::WebexApiError, wait: :exponentially_longer) do |job, exception| + room_id = job.arguments&.first&.[](:room_id) + meeting_title = job.arguments&.first&.[](:meeting_title) error_details = { error: { type: "retrieval", explanation: "retrieve details of room from Webex" }, provider: "webex", - api_call: "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}", + api_call: + "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}rooms/#{room_id}/meetingInfo", response: { status: exception.code, message: exception.message }.to_json, - times: nil, - docket_number: nil + room_id: room_id, + meeting_title: meeting_title } job.log_error(exception) job.send_transcription_issues_email(error_details) diff --git a/app/jobs/hearings/fetch_webex_rooms_list_job.rb b/app/jobs/hearings/fetch_webex_rooms_list_job.rb index ab65ecf4c99..bef06609155 100644 --- a/app/jobs/hearings/fetch_webex_rooms_list_job.rb +++ b/app/jobs/hearings/fetch_webex_rooms_list_job.rb @@ -12,14 +12,12 @@ class Hearings::FetchWebexRoomsListJob < CaseflowJob retry_on(Caseflow::Error::WebexApiError, wait: :exponentially_longer) do |job, exception| sort_by = "created" max = 1000 - query = { "sortBy": sort_by, "max": max } + query = "?sortBy=#{sort_by}&max=#{max}" error_details = { error: { type: "retrieval", explanation: "retrieve a list of rooms from Webex" }, provider: "webex", - api_call: "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}#{query}", - response: { status: exception.code, message: exception.message }.to_json, - times: nil, - docket_number: nil + api_call: "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}rooms#{query}", + response: { status: exception.code, message: exception.message }.to_json } job.log_error(exception) job.send_transcription_issues_email(error_details) diff --git a/app/workflows/transcription_transformer.rb b/app/workflows/transcription_transformer.rb index 14bb1f18a33..b49ea66439c 100644 --- a/app/workflows/transcription_transformer.rb +++ b/app/workflows/transcription_transformer.rb @@ -136,7 +136,7 @@ def create_footer_and_spacing(document) # count - amount of line breaks to add def insert_line_breaks(row, count) breaks = 0 - while i < count + while breaks < count row.line_break breaks += 1 end diff --git a/spec/jobs/hearings/fetch_webex_recordings_details_job_spec.rb b/spec/jobs/hearings/fetch_webex_recordings_details_job_spec.rb index 7d3772b1588..e790be37750 100644 --- a/spec/jobs/hearings/fetch_webex_recordings_details_job_spec.rb +++ b/spec/jobs/hearings/fetch_webex_recordings_details_job_spec.rb @@ -56,11 +56,12 @@ { error: { type: "retrieval", explanation: "retrieve recording details from Webex" }, provider: "webex", + api_call: + "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}recordings/#{id}#{query}", + response: { status: exception.code, message: exception.message }.to_json, recording_id: id, host_email: email, - api_call: "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}/#{id}#{query}", - response: { status: exception.code, message: exception.message }.to_json, - docket_number: nil + meeting_title: meeting_title } end diff --git a/spec/jobs/hearings/fetch_webex_recordings_list_job_spec.rb b/spec/jobs/hearings/fetch_webex_recordings_list_job_spec.rb index 910bf2f861a..3e90f1d8013 100644 --- a/spec/jobs/hearings/fetch_webex_recordings_list_job_spec.rb +++ b/spec/jobs/hearings/fetch_webex_recordings_list_job_spec.rb @@ -3,7 +3,7 @@ describe Hearings::FetchWebexRecordingsListJob, type: :job do include ActiveJob::TestHelper let(:id) { "f91b6edce9864428af084977b7c68291_I_166641849979635652" } - let(:title) { "Virtual Visit - 221218-977_933_Hearing-20240508 1426-1" } + let(:title) { "221218-977_933_Hearing" } subject { described_class.perform_now(meeting_id: id, meeting_title: title) } @@ -39,15 +39,16 @@ context "job errors" do let(:exception) { Caseflow::Error::WebexApiError.new(code: 400, message: "Fake Error") } - let(:query) { "?max=100?meetingId=#{id}" } + let(:query) { "?max=100&meetingId=#{id}" } let(:error_details) do { error: { type: "retrieval", explanation: "retrieve a list of recordings from Webex" }, provider: "webex", - api_call: "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}#{query}", + api_call: + "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}admin/recordings/#{query}", response: { status: exception.code, message: exception.message }.to_json, meeting_id: id, - docket_number: nil + meeting_title: title } end diff --git a/spec/jobs/hearings/fetch_webex_room_meeting_details_job_spec.rb b/spec/jobs/hearings/fetch_webex_room_meeting_details_job_spec.rb index d8c7ab705da..6516e7254a9 100644 --- a/spec/jobs/hearings/fetch_webex_room_meeting_details_job_spec.rb +++ b/spec/jobs/hearings/fetch_webex_room_meeting_details_job_spec.rb @@ -17,12 +17,23 @@ let(:room_id) do "Y2lzY29zcGFyazovL3VybjpURUFNOnVzLWdvdi13ZXN0LTFfYTEvUk9PTS85YTZjZTRjMC0xNmM5LTExZWYtYjIxOC1iMWE5YTQ2" end - let(:meeting_title) { "Virtual Visit - 221218-977_933_Hearing-20240508 1426-1" } + let(:meeting_title) { "221218-977_933_Hearing" } let(:exception) { Caseflow::Error::WebexApiError.new(code: 300, message: "Error", title: "Bad Error") } + let(:error_details) do + { + error: { type: "retrieval", explanation: "retrieve details of room from Webex" }, + provider: "webex", + api_call: + "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}rooms/#{room_id}/meetingInfo", + response: { status: exception.code, message: exception.message }.to_json, + room_id: room_id, + meeting_title: meeting_title + } + end subject { described_class.perform_now(room_id: room_id, meeting_title: meeting_title) } - describe "#perform" do + context "#perform" do it "can run the job" do subject @@ -35,14 +46,36 @@ it "returns correct response" do expect(described_class.new.send(:fetch_room_details, room_id).resp.raw_body).to eq(room_details) end + end - it "retries and logs errors" do + context "job errors" do + before do allow_any_instance_of(described_class) .to receive(:fetch_room_details) .and_raise(exception) + end + it "retries and logs errors" do + subject expect(Rails.logger).to receive(:error).at_least(:once) perform_enqueued_jobs { described_class.perform_later(room_id: room_id, meeting_title: meeting_title) } end + + it "mailer receives correct params" do + allow(TranscriptionFileIssuesMailer).to receive(:issue_notification).and_call_original + expect(TranscriptionFileIssuesMailer).to receive(:issue_notification) + .with(error_details) + expect_any_instance_of(described_class).to receive(:log_error).once + perform_enqueued_jobs { described_class.perform_later(room_id: room_id, meeting_title: meeting_title) } + end + + context "mailer fails to send email" do + it "captures external delivery error" do + allow(TranscriptionFileIssuesMailer).to receive(:issue_notification).with(error_details) + .and_raise(GovDelivery::TMS::Request::Error.new(500)) + expect_any_instance_of(described_class).to receive(:log_error).twice + perform_enqueued_jobs { described_class.perform_later(room_id: room_id, meeting_title: meeting_title) } + end + end end end diff --git a/spec/jobs/hearings/fetch_webex_rooms_list_job_spec.rb b/spec/jobs/hearings/fetch_webex_rooms_list_job_spec.rb index 8976bf05e08..77cde33a304 100644 --- a/spec/jobs/hearings/fetch_webex_rooms_list_job_spec.rb +++ b/spec/jobs/hearings/fetch_webex_rooms_list_job_spec.rb @@ -18,6 +18,17 @@ # rubocop:enable Layout/LineLength context "job errors" do + let(:query) { "?sortBy=created&max=1000" } + let(:error_details) do + { + error: { type: "retrieval", explanation: "retrieve a list of rooms from Webex" }, + provider: "webex", + api_call: + "GET #{ENV['WEBEX_HOST_MAIN']}#{ENV['WEBEX_DOMAIN_MAIN']}#{ENV['WEBEX_API_MAIN']}rooms#{query}", + response: { status: 400, message: "Fake Error" }.to_json + } + end + before do allow_any_instance_of(WebexService) .to receive(:fetch_rooms_list) @@ -34,6 +45,23 @@ expect(Rails.logger).to receive(:error).at_least(:once) perform_enqueued_jobs { described_class.perform_later } end + + it "mailer receives correct params" do + allow(TranscriptionFileIssuesMailer).to receive(:issue_notification).and_call_original + expect(TranscriptionFileIssuesMailer).to receive(:issue_notification) + .with(error_details) + expect_any_instance_of(described_class).to receive(:log_error).once + perform_enqueued_jobs { described_class.perform_later } + end + + context "mailer fails to send email" do + it "captures external delivery error" do + allow(TranscriptionFileIssuesMailer).to receive(:issue_notification).with(error_details) + .and_raise(GovDelivery::TMS::Request::Error.new(500)) + expect_any_instance_of(described_class).to receive(:log_error).twice + perform_enqueued_jobs { described_class.perform_later } + end + end end # The third & fourth titles returned have an invalid format diff --git a/spec/mailers/previews/transcription_file_issues_mailer_preview.rb b/spec/mailers/previews/transcription_file_issues_mailer_preview.rb index 07afeee9f29..1b57cefd335 100644 --- a/spec/mailers/previews/transcription_file_issues_mailer_preview.rb +++ b/spec/mailers/previews/transcription_file_issues_mailer_preview.rb @@ -5,6 +5,8 @@ # http://localhost:3000/rails/mailers/transcription_file_issues_mailer/file_upload_issues # http://localhost:3000/rails/mailers/transcription_file_issues_mailer/file_conversion_issues # http://localhost:3000/rails/mailers/transcription_file_issues_mailer/file_name_issues +# http://localhost:3000/rails/mailers/transcription_file_issues_mailer/webex_rooms_list_issues +# http://localhost:3000/rails/mailers/transcription_file_issues_mailer/webex_room_meeting_details_issues # http://localhost:3000/rails/mailers/transcription_file_issues_mailer/webex_recording_list_issues # http://localhost:3000/rails/mailers/transcription_file_issues_mailer/webex_recording_details_issues class TranscriptionFileIssuesMailerPreview < ActionMailer::Preview @@ -50,16 +52,47 @@ def file_name_issues TranscriptionFileIssuesMailer.issue_notification(details) end + def webex_rooms_list_issues + sort_by = "created" + max = 1000 + query = "?sortBy=#{sort_by}&max=#{max}" + + details = { + error: { type: "retrieval", explanation: "retrieve a list of rooms from Webex" }, + provider: "webex", + api_call: "GET https://api-usgov.webex.com/v1/rooms#{query}", + response: { status: 400, message: "Sample error message" }.to_json + } + TranscriptionFileIssuesMailer.issue_notification(details) + end + + def webex_room_meeting_details_issues + room_id = "1234567" + meeting_title = "221218-977_933_Hearing" + details = { + error: { type: "retrieval", explanation: "retrieve a list of room details from Webex" }, + provider: "webex", + api_call: "GET https://api-usgov.webex.com/v1/rooms/#{room_id}/meetingInfo", + response: { status: 400, message: "Sample error message" }.to_json, + room_id: room_id, + meeting_title: meeting_title + } + TranscriptionFileIssuesMailer.issue_notification(details) + end + def webex_recording_list_issues - query = "?max=100?meetingId=123abc" + max = 100 + meeting_id = "123abc" + meeting_title = "221218-977_933_Hearing" + query = "?max=#{max}&meetingId=#{meeting_id}" details = { error: { type: "retrieval", explanation: "retrieve a list of recordings from Webex" }, provider: "webex", - api_call: "GET webex.com/recordings/list/#{query}", + api_call: "GET https://api-usgov.webex.com/v1/admin/recordings/#{query}", response: { status: 400, message: "Sample error message" }.to_json, meeting_id: "123abc", - docket_number: nil + meeting_title: meeting_title } TranscriptionFileIssuesMailer.issue_notification(details) end @@ -67,15 +100,16 @@ def webex_recording_list_issues def webex_recording_details_issues recording_id = "12345" host_email = "fake@email.com" + meeting_title = "221218-977_933_Hearing" query = "?hostEmail=#{host_email}" details = { error: { type: "retrieval", explanation: "retrieve recording details from Webex" }, provider: "webex", + api_call: "GET https://api-usgov.webex.com/v1/recordings/#{recording_id}#{query}", + response: { status: 400, message: "Sample error message" }.to_json, recording_id: recording_id, host_email: host_email, - api_call: "GET webex.com/recordings/details/#{recording_id}#{query}", - response: { status: 400, message: "Sample error message" }.to_json, - docket_number: nil + meeting_title: meeting_title } TranscriptionFileIssuesMailer.issue_notification(details) end