Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 5 additions & 12 deletions app/controllers/api/templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,29 +121,22 @@ def pdf
def process_documents(template, documents_params)
return [] if documents_params.blank?

documents_params.map.with_index do |doc_param, _index|
(doc_param[:file].length / 4.0 * 3).ceil
# Validate base64 string
documents_params.map do |doc_param|
raise ArgumentError, 'Invalid base64 string format' unless doc_param[:file].match?(%r{\A[A-Za-z0-9+/]*={0,2}\z})

# Decode base64 file data
file_data = Base64.decode64(doc_param[:file])
detected = Marcel::MimeType.for(StringIO.new(file_data), name: doc_param[:name])
content_type = detected.to_s.start_with?('image/') ? detected : 'application/pdf'

# Check if the decoded data looks like a PDF
file_data[0..3] if file_data.size >= 4

# Create a temporary file-like object
file = Tempfile.new(['document', '.pdf'])
file.binmode
file.write(file_data)
file.rewind

# Add original filename
file.define_singleton_method(:original_filename) { doc_param[:name] }
file.define_singleton_method(:content_type) { 'application/pdf' }
file.define_singleton_method(:content_type) { content_type }

result = Templates::CreateAttachments.handle_pdf_or_image(template, file, file_data, {}, extract_fields: true)
result
Templates::CreateAttachments.handle_pdf_or_image(template, file, file_data, {}, extract_fields: true)
ensure
file&.close
file&.unlink
Expand Down
59 changes: 59 additions & 0 deletions spec/requests/templates_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,65 @@
stored_field = Template.last.fields.find { |f| f['name'] == 'First Name' }
expect(stored_field['prefill']).to eq('employee_first_name')
end

it 'creates a template from a PNG document' do
png_base64 = Base64.strict_encode64(Rails.root.join('spec/fixtures/sample-image.png').binread)

post '/api/templates/pdf',
headers: { 'x-auth-token': author.access_token.token },
params: {
name: 'Image Template',
documents: [{ name: 'sample-image.png', file: png_base64 }]
}.to_json,
env: { 'CONTENT_TYPE' => 'application/json' }

expect(response).to have_http_status(:ok)

document = Template.last.documents.first
expect(document.content_type).to eq('image/png')
expect(document.preview_images).to be_present
end

it 'creates a template from a JPEG document' do
jpeg_data = Vips::Image.new_from_file(Rails.root.join('spec/fixtures/sample-image.png').to_s)
.write_to_buffer('.jpg')

post '/api/templates/pdf',
headers: { 'x-auth-token': author.access_token.token },
params: {
name: 'Jpeg Template',
documents: [{ name: 'sample-image.jpg', file: Base64.strict_encode64(jpeg_data) }]
}.to_json,
env: { 'CONTENT_TYPE' => 'application/json' }

expect(response).to have_http_status(:ok)
expect(Template.last.documents.first.content_type).to eq('image/jpeg')
end

it 'detects a PNG even when the document name ends in .pdf' do
png_base64 = Base64.strict_encode64(Rails.root.join('spec/fixtures/sample-image.png').binread)

post '/api/templates/pdf',
headers: { 'x-auth-token': author.access_token.token },
params: base_params.merge(documents: [{ name: 'scan.pdf', file: png_base64 }]).to_json,
env: { 'CONTENT_TYPE' => 'application/json' }

expect(response).to have_http_status(:ok)
expect(Template.last.documents.first.content_type).to eq('image/png')
end

it 'returns the existing error for a document that is not a PDF or image' do
post '/api/templates/pdf',
headers: { 'x-auth-token': author.access_token.token },
params: {
name: 'Bad Template',
documents: [{ name: 'notes.txt', file: Base64.strict_encode64('not a real file') }]
}.to_json,
env: { 'CONTENT_TYPE' => 'application/json' }

expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body['error']).to eq('Unable to create template')
end
end

describe 'POST /api/templates/:id/clone' do
Expand Down
Loading