Files
fizzy/test/models/zip_file_test.rb
Jeremy Daer 953942694f Handle MissingEOCD as invalid zip file, not job failure (#2572)
ZipKit::FileReader raises MissingEOCD for truncated, corrupted, or
non-zip files. This exception is a direct StandardError subclass, not
a subclass of InvalidStructure or ReadError, so it escaped as an
unhandled job failure instead of being caught and surfaced to the user.

Broaden the rescue in ZipFile::Reader#initialize to catch ReadError
(parent of InvalidStructure), MissingEOCD, and UnsupportedFeature.
2026-02-18 15:18:56 -08:00

146 lines
3.7 KiB
Ruby

require "test_helper"
class ZipFileTest < ActiveSupport::TestCase
test "writer adds files with content" do
tempfile = Tempfile.new([ "test", ".zip" ])
tempfile.binmode
writer = ZipFile::Writer.new(tempfile)
writer.add_file("hello.txt", "Hello, World!")
writer.close
assert writer.exists?("hello.txt")
assert_not writer.exists?("missing.txt")
end
test "writer adds files with block" do
tempfile = Tempfile.new([ "test", ".zip" ])
tempfile.binmode
writer = ZipFile::Writer.new(tempfile)
writer.add_file("hello.txt") { |sink| sink.write("Hello, World!") }
writer.close
assert writer.exists?("hello.txt")
end
test "writer globs entries" do
tempfile = Tempfile.new([ "test", ".zip" ])
tempfile.binmode
writer = ZipFile::Writer.new(tempfile)
writer.add_file("docs/readme.txt", "Readme")
writer.add_file("docs/guide.txt", "Guide")
writer.add_file("images/logo.png", "PNG data")
writer.close
assert_equal [ "docs/guide.txt", "docs/readme.txt" ], writer.glob("docs/*.txt")
assert_equal [ "images/logo.png" ], writer.glob("**/*.png")
end
test "reader reads file content" do
tempfile = create_test_zip("hello.txt" => "Hello, World!")
reader = ZipFile::Reader.new(tempfile)
content = reader.read("hello.txt")
assert_equal "Hello, World!", content
end
test "reader reads file with block" do
tempfile = create_test_zip("hello.txt" => "Hello, World!")
reader = ZipFile::Reader.new(tempfile)
content = nil
reader.read("hello.txt") { |io| content = io.read }
assert_equal "Hello, World!", content
end
test "reader raises for missing file" do
tempfile = create_test_zip("hello.txt" => "Hello")
reader = ZipFile::Reader.new(tempfile)
assert_raises(ArgumentError) { reader.read("missing.txt") }
end
test "reader checks file existence" do
tempfile = create_test_zip("hello.txt" => "Hello")
reader = ZipFile::Reader.new(tempfile)
assert reader.exists?("hello.txt")
assert_not reader.exists?("missing.txt")
end
test "reader globs entries" do
tempfile = create_test_zip(
"docs/readme.txt" => "Readme",
"docs/guide.txt" => "Guide",
"images/logo.png" => "PNG"
)
reader = ZipFile::Reader.new(tempfile)
assert_equal [ "docs/guide.txt", "docs/readme.txt" ], reader.glob("docs/*.txt")
end
test "reader io provides size" do
tempfile = create_test_zip("hello.txt" => "Hello, World!")
reader = ZipFile::Reader.new(tempfile)
reader.read("hello.txt") do |io|
assert_equal 13, io.size
end
end
test "reader io supports rewind" do
tempfile = create_test_zip("hello.txt" => "Hello, World!")
reader = ZipFile::Reader.new(tempfile)
reader.read("hello.txt") do |io|
first_read = io.read
io.rewind
second_read = io.read
assert_equal first_read, second_read
end
end
test "reader io tracks eof" do
tempfile = create_test_zip("hello.txt" => "Hello")
reader = ZipFile::Reader.new(tempfile)
reader.read("hello.txt") do |io|
assert_not io.eof?
io.read
assert io.eof?
end
end
test "reader raises InvalidFileError for non-zip file" do
tempfile = Tempfile.new([ "not_a_zip", ".zip" ])
tempfile.write("this is not a zip file at all")
tempfile.rewind
assert_raises(ZipFile::InvalidFileError) { ZipFile::Reader.new(tempfile) }
ensure
tempfile&.close
tempfile&.unlink
end
private
def create_test_zip(files)
tempfile = Tempfile.new([ "test", ".zip" ])
tempfile.binmode
writer = ZipFile::Writer.new(tempfile)
files.each { |path, content| writer.add_file(path, content) }
writer.close
tempfile.rewind
tempfile
end
end