我在Rails应用程序中有一个后台作业,该应用程序生成一个大的CSV文件并将其作为电子邮件的附件发送。要管理电子邮件的大小,请在附加之前压缩CSV。这很好用;我们在开发中有Letter Opener,我可以打开压缩附件并读取数据。我正在使用" rubyzip"宝石做拉链。
诀窍似乎在测试它。使用rspec,我可以验证邮件是否有附件,并且附件的类型是application/x-zip-encoded
,这一切都很好。我想要做的是解压缩附件并验证测试中的数据,并且这证明更加困难。附件是Mail :: Part类型的对象。如果我调用附件part
,我可以使用part.body.raw_source
,part.body.encoded
或part.decode_body
从中获取数据。 (第一个和第三个相同。)part.body.encoding
告诉我身体是二元的。当我尝试将数据提供给Zip :: InputStream对象(使用Zip::InputStream.open(part.body.raw_source)
或任何其他数据方法)时,我得到类似ArgumentError: string contains null byte
的内容。
如何打开此附件并在rspec中读取其数据?我有一个预感,我需要在这里做一个解码步骤。
错误look a lot like this question,但也没有答案。
答案 0 :(得分:1)
这里的解决方案有点不太理想,但它有效。我必须使用Mail库将附件写入文件,然后使用Zip::File
提取原始数据并进行验证。
it 'has a ZIP attachment' do
additional_fields = ["student_identifiers"]
expect(message.attachments.size).to eq(1)
message.attachments.first.tap do |zip|
expect(zip.content_type).to eq('application/x-zip-compressed')
tmpfile_name = "tmp/#{zip.filename}"
File.open(tmpfile_name, "w+b", 0644) { |f| f.write zip.decoded }
csv = Zip::File.open(tmpfile_name) do |zip_file|
entry = zip_file.glob('*.csv').first
entry.get_input_stream.read
end
csv.split("\n").tap do |rows|
expect(rows.size).to be(2)
rows.each do |row|
expect(CSV.parse_line(row).size).to eq(dimensions_count)
end
end
File.delete(tmpfile_name)
end
end