Skip to content

Commit 8eeec92

Browse files
authored
Merge pull request #77 from CareerPlug/CP-14339-guard-nil-area-page
CP-14339 - Guard against a missing area page in result attachment generation
2 parents 4fa58ea + 0bda0e2 commit 8eeec92

2 files changed

Lines changed: 91 additions & 0 deletions

File tree

lib/submissions/generate_result_attachments.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,16 @@ def fill_submitter_fields(submitter, account, pdfs_index, with_signature_id:, is
194194

195195
next if pdf.nil?
196196

197+
# HexaPDF's pages[nil] does `nil < 0` and raises. `page` is a
198+
# permitted-but-not-required area param, so a malformed/imported area
199+
# can omit it. Skip it, but log so silently-incomplete signed docs stay visible.
200+
if area['page'].nil?
201+
Rails.logger.warn(
202+
"Skipping field area with no page (submitter=#{submitter.id}, attachment=#{area['attachment_uuid']})"
203+
)
204+
next
205+
end
206+
197207
page = pdf.pages[area['page']]
198208

199209
next if page.nil?
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe Submissions::GenerateResultAttachments do
6+
let(:account) { create(:account) }
7+
let(:user) { create(:user, account:) }
8+
let(:template) { create(:template, account:, author: user) }
9+
let(:submission) { create(:submission, template:, created_by_user: user) }
10+
let(:submitter) { create(:submitter, submission:, uuid: SecureRandom.uuid) }
11+
let(:attachment_uuid) { SecureRandom.uuid }
12+
13+
# A single-page in-memory PDF keyed by the area's attachment_uuid, so the
14+
# `pdf.nil?` guard passes and we reach the `pdf.pages[area['page']]` index.
15+
let(:pdfs_index) do
16+
doc = HexaPDF::Document.new
17+
doc.pages.add
18+
{ attachment_uuid => doc }
19+
end
20+
21+
# Point the submitter's submission at a single text field whose one area is
22+
# `area`, so `fill_submitter_fields` reaches the page lookup for that area.
23+
def assign_field_area(area)
24+
submitter.submission.update!(
25+
template_fields: [
26+
{ 'uuid' => SecureRandom.uuid, 'submitter_uuid' => submitter.uuid,
27+
'type' => 'text', 'areas' => [area] }
28+
]
29+
)
30+
end
31+
32+
def fill
33+
described_class.send(
34+
:fill_submitter_fields, submitter, account, pdfs_index,
35+
with_signature_id: false, is_flatten: false, with_headings: false
36+
)
37+
end
38+
39+
before { allow(Rails.logger).to receive(:warn) }
40+
41+
describe '.fill_submitter_fields with a missing area page' do
42+
context 'when the area omits the page key' do
43+
before { assign_field_area('attachment_uuid' => attachment_uuid) }
44+
45+
it 'skips the area instead of raising (regression: HexaPDF pages[nil])' do
46+
expect { fill }.not_to raise_error
47+
end
48+
49+
it 'logs that the area was skipped' do
50+
fill
51+
expect(Rails.logger).to have_received(:warn).with(/Skipping field area with no page/)
52+
end
53+
end
54+
55+
context 'when the area page is explicitly nil' do
56+
before { assign_field_area('attachment_uuid' => attachment_uuid, 'page' => nil) }
57+
58+
it 'skips the area instead of raising' do
59+
expect { fill }.not_to raise_error
60+
end
61+
62+
it 'logs that the area was skipped' do
63+
fill
64+
expect(Rails.logger).to have_received(:warn).with(/Skipping field area with no page/)
65+
end
66+
end
67+
68+
context 'when the area page is out of range' do
69+
before { assign_field_area('attachment_uuid' => attachment_uuid, 'page' => 5) }
70+
71+
it 'does not raise (existing next-if-page-nil handling still applies)' do
72+
expect { fill }.not_to raise_error
73+
end
74+
75+
it 'does not log a skipped-no-page warning (the guard only catches nil)' do
76+
fill
77+
expect(Rails.logger).not_to have_received(:warn).with(/Skipping field area with no page/)
78+
end
79+
end
80+
end
81+
end

0 commit comments

Comments
 (0)