diff --git a/app/models/attachment.rb b/app/models/attachment.rb index a1cc062a0..c6b4e1d80 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -37,6 +37,7 @@ class Attachment < ApplicationRecord belongs_to :account belongs_to :message has_one_attached :file + before_save :set_extension validate :acceptable_file validates :external_url, length: { maximum: Limits::URL_LENGTH_LIMIT } enum file_type: { :image => 0, :audio => 1, :video => 2, :file => 3, :location => 4, :fallback => 5, :share => 6, :story_mention => 7, @@ -111,6 +112,7 @@ class Attachment < ApplicationRecord def file_metadata metadata = { extension: extension, + content_type: file.content_type, data_url: file_url, thumb_url: thumb_url, file_size: file.byte_size, @@ -154,6 +156,13 @@ class Attachment < ApplicationRecord } end + def set_extension + return unless file.attached? + return if extension.present? + + self.extension = File.extname(file.filename.to_s).delete_prefix('.').presence + end + def should_validate_file? return unless file.attached? # we are only limiting attachment types in case of website widget diff --git a/spec/models/attachment_spec.rb b/spec/models/attachment_spec.rb index a17839174..5e1dd2107 100644 --- a/spec/models/attachment_spec.rb +++ b/spec/models/attachment_spec.rb @@ -187,6 +187,44 @@ RSpec.describe Attachment do end end + describe 'set_extension' do + it 'sets extension from filename on save' do + attachment = message.attachments.new(account_id: message.account_id, file_type: :file) + attachment.file.attach(io: StringIO.new('fake pdf'), filename: 'test.pdf', content_type: 'application/pdf') + attachment.save! + + expect(attachment.extension).to eq('pdf') + end + + it 'does not overwrite extension if already set' do + attachment = message.attachments.new(account_id: message.account_id, file_type: :file, extension: 'doc') + attachment.file.attach(io: StringIO.new('fake pdf'), filename: 'test.pdf', content_type: 'application/pdf') + attachment.save! + + expect(attachment.extension).to eq('doc') + end + + it 'handles filenames without extension' do + attachment = message.attachments.new(account_id: message.account_id, file_type: :file) + attachment.file.attach(io: StringIO.new('fake data'), filename: 'README', content_type: 'text/plain') + attachment.save! + + expect(attachment.extension).to be_nil + end + end + + describe 'push_event_data includes extension and content_type' do + it 'returns extension and content_type for file attachments' do + attachment = message.attachments.new(account_id: message.account_id, file_type: :file) + attachment.file.attach(io: StringIO.new('fake pdf'), filename: 'test.pdf', content_type: 'application/pdf') + attachment.save! + + event_data = attachment.push_event_data + expect(event_data[:extension]).to eq('pdf') + expect(event_data[:content_type]).to eq('application/pdf') + end + end + describe 'file size validation' do let(:attachment) { message.attachments.new(account_id: message.account_id, file_type: :image) }