2014-10-17 87 views
1

我有一个Rails应用程序的后台工作,它会生成一个大的CSV文件并将其作为附件发送给电子邮件。为了管理电子邮件的大小,我在压缩CSV之前先将它压缩。这工作正常;我们开发了开信刀,我可以打开压缩附件并读取数据。我使用“rubyzip”宝石来做压缩。解压缩二进制电子邮件附件

这个技巧似乎在测试它。使用rspec,我可以验证消息是否有附件,并且附件的类型是application/x-zip-encoded,这是很好的。然而,我想要做的是解压缩附件并验证测试中的数据,这样证明会比较困难。附件是Mail :: Part类型的对象。如果我拨打附件part,我可以使用part.body.raw_sourcepart.body.encodedpart.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,但这里也没有答案。

+1

我可能会误解,但它听起来像你想验证宝石是在做它应该做的。如果是这样,你不应该这样做。你不应该写测试来覆盖另一个人的图书馆。他们应该进行自己的测试,如果他们不测试,你可以为项目提供测试,或者找到一个已经正确测试的库。 – 2014-10-17 14:10:02

+0

它看起来像,不是。我认为我的目标更多的是验证附加到电子邮件的数据是应该附加的,并且解决方案是解压缩数据并检查它;我陷入了解压缩步骤。 – pjmorse 2014-10-17 14:17:16

回答

1

这里的解决方案有点不理想,但它的工作原理。我不得不使用邮件库将附件写入文件,然后使用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 
+0

谢谢,它可以帮助我测试它;) – piton4eg 2017-11-01 13:15:30