mirror of
https://github.com/we-promise/sure.git
synced 2026-04-09 07:14:47 +00:00
* feat(transaction): add support for file attachments using Active Storage * feat(attachments): implement transaction attachments with upload, show, and delete functionality * feat(attachments): enhance attachment upload functionality to support multiple files and improved error handling * feat(attachments): add attachment upload form and display functionality in transaction views * feat(attachments): implement attachment validation for count, size, and content type; enhance upload form with validation hints * fix(attachments): use correct UI components * feat(attachments): Implement Turbo Stream responses for creating and deleting transaction attachments. * fix(attachments): include auth in activestorage controller * test(attachments): add test coverage for turbostream and auth * feat(attachments): extract strings to i18n * fix(attachments): ensure only newly added attachments are purged when transaction validation fails. * fix(attachments): validate attachment params * refactor(attachments): use stimulus declarative actions * fix(attachments): add auth for other representations * refactor(attachments): use Browse component for attachment uploads * fix(attachments): reject empty values on attachment upload * fix(attachments): hide the upload form if reached max uploads * fix(attachments): correctly purge only newly added attachments on upload failure * fix(attachments): ensure attachment count limit is respected within a transaction lock * fix(attachments): update attachment parameter handling to avoid `ParameterMissing` errors. * fix(components): adjust icon_only logic for buttonish --------- Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
145 lines
5.3 KiB
Ruby
145 lines
5.3 KiB
Ruby
require "test_helper"
|
|
|
|
class TransactionAttachmentsControllerTest < ActionDispatch::IntegrationTest
|
|
setup do
|
|
sign_in @user = users(:family_admin)
|
|
@entry = entries(:transaction)
|
|
@transaction = @entry.entryable
|
|
end
|
|
|
|
test "should upload attachment to transaction" do
|
|
file = fixture_file_upload("test.txt", "application/pdf")
|
|
|
|
assert_difference "@transaction.attachments.count", 1 do
|
|
post transaction_attachments_path(@transaction), params: { attachment: file }
|
|
end
|
|
|
|
assert_redirected_to transaction_path(@transaction)
|
|
assert_match "Attachment uploaded successfully", flash[:notice]
|
|
end
|
|
|
|
test "should upload multiple attachments to transaction" do
|
|
file1 = fixture_file_upload("test.txt", "application/pdf")
|
|
file2 = fixture_file_upload("test.txt", "image/jpeg")
|
|
|
|
assert_difference "@transaction.attachments.count", 2 do
|
|
post transaction_attachments_path(@transaction), params: { attachments: [ file1, file2 ] }
|
|
end
|
|
|
|
assert_redirected_to transaction_path(@transaction)
|
|
assert_match "2 attachments uploaded successfully", flash[:notice]
|
|
end
|
|
|
|
test "should ignore blank attachments in array" do
|
|
file = fixture_file_upload("test.txt", "application/pdf")
|
|
|
|
assert_difference "@transaction.attachments.count", 1 do
|
|
# Simulate Rails behavior where an empty string is often sent in the array
|
|
post transaction_attachments_path(@transaction), params: { attachments: [ file, "" ] }
|
|
end
|
|
|
|
assert_redirected_to transaction_path(@transaction)
|
|
assert_match "Attachment uploaded successfully", flash[:notice] # Should be singular
|
|
end
|
|
|
|
test "should handle upload with no files" do
|
|
assert_no_difference "@transaction.attachments.count" do
|
|
post transaction_attachments_path(@transaction), params: {}
|
|
end
|
|
|
|
assert_redirected_to transaction_path(@transaction)
|
|
assert_match "No files selected for upload", flash[:alert]
|
|
end
|
|
|
|
test "should reject unsupported file types" do
|
|
file = fixture_file_upload("test.txt", "text/plain")
|
|
|
|
assert_no_difference "@transaction.attachments.count" do
|
|
post transaction_attachments_path(@transaction), params: { attachment: file }
|
|
end
|
|
|
|
assert_redirected_to transaction_path(@transaction)
|
|
assert_match "unsupported format", flash[:alert]
|
|
end
|
|
|
|
test "should reject exceeding attachment count limit" do
|
|
# Fill up to the limit
|
|
(Transaction::MAX_ATTACHMENTS_PER_TRANSACTION).times do |i|
|
|
@transaction.attachments.attach(
|
|
io: StringIO.new("content #{i}"),
|
|
filename: "file#{i}.pdf",
|
|
content_type: "application/pdf"
|
|
)
|
|
end
|
|
|
|
file = fixture_file_upload("test.txt", "application/pdf")
|
|
|
|
assert_no_difference "@transaction.attachments.count" do
|
|
post transaction_attachments_path(@transaction), params: { attachment: file }
|
|
end
|
|
|
|
assert_redirected_to transaction_path(@transaction)
|
|
assert_match "Cannot exceed #{Transaction::MAX_ATTACHMENTS_PER_TRANSACTION} attachments", flash[:alert]
|
|
end
|
|
|
|
test "should show attachment for authorized user" do
|
|
@transaction.attachments.attach(
|
|
io: StringIO.new("test content"),
|
|
filename: "test.pdf",
|
|
content_type: "application/pdf"
|
|
)
|
|
|
|
attachment = @transaction.attachments.first
|
|
get transaction_attachment_path(@transaction, attachment)
|
|
|
|
assert_response :redirect
|
|
end
|
|
|
|
test "should upload attachment via turbo_stream" do
|
|
file = fixture_file_upload("test.txt", "application/pdf")
|
|
|
|
assert_difference "@transaction.attachments.count", 1 do
|
|
post transaction_attachments_path(@transaction), params: { attachment: file }, as: :turbo_stream
|
|
end
|
|
|
|
assert_response :success
|
|
assert_match(/turbo-stream action="replace" target="transaction_attachments_#{@transaction.id}"/, response.body)
|
|
assert_match(/turbo-stream action="append" target="notification-tray"/, response.body)
|
|
assert_match("Attachment uploaded successfully", response.body)
|
|
end
|
|
|
|
test "should show attachment inline" do
|
|
@transaction.attachments.attach(io: StringIO.new("test"), filename: "test.pdf", content_type: "application/pdf")
|
|
attachment = @transaction.attachments.first
|
|
|
|
get transaction_attachment_path(@transaction, attachment, disposition: :inline)
|
|
|
|
assert_response :redirect
|
|
assert_match(/disposition=inline/, response.redirect_url)
|
|
end
|
|
|
|
test "should show attachment as download" do
|
|
@transaction.attachments.attach(io: StringIO.new("test"), filename: "test.pdf", content_type: "application/pdf")
|
|
attachment = @transaction.attachments.first
|
|
|
|
get transaction_attachment_path(@transaction, attachment, disposition: :attachment)
|
|
|
|
assert_response :redirect
|
|
assert_match(/disposition=attachment/, response.redirect_url)
|
|
end
|
|
|
|
test "should delete attachment via turbo_stream" do
|
|
@transaction.attachments.attach(io: StringIO.new("test"), filename: "test.pdf", content_type: "application/pdf")
|
|
attachment = @transaction.attachments.first
|
|
|
|
assert_difference "@transaction.attachments.count", -1 do
|
|
delete transaction_attachment_path(@transaction, attachment), as: :turbo_stream
|
|
end
|
|
|
|
assert_response :success
|
|
assert_match(/turbo-stream action="replace" target="transaction_attachments_#{@transaction.id}"/, response.body)
|
|
assert_match(/turbo-stream action="append" target="notification-tray"/, response.body)
|
|
assert_match("Attachment deleted successfully", response.body)
|
|
end
|
|
end
|