2

I'm trying to test specific content inside a pdf document which is being generated via the prawn gem and attached to an ActionMailer email. I'm using RSpec and Capybara for testing.

I've managed to test the filename like this expect(ActionMailer::Base.deliveries[0].filename).to eq("my_file.pdf")

I thought that I've read somewhere that I have to test the pdf itself like this but it doesn't work. `expect(ActionMailer::Base.deliveries[0].body.encoded).to have_content(user.first_name)``

When running the test, I get the following error:

Failure/Error: expect(ActionMailer::Base.deliveries[0].body.encoded).to have_content(user.first_name)
       expected to find text "John" in "JVBERi0xLjQKJf////8KMSAwIG9iago8PCAvQ3JlYXRvciA8ZmVmZjAwNTAw MDcyMDA2MTAwNzcwMDZlPgovUHJvZHVjZXIgPGZlZmYwMDUwMDA3MjAwNjEw MDc3MDA2ZT4KPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cK L1BhZ2VzIDMgMCBSCj4+CmVuZG9iagozIDAgb2JqCjw8IC9UeXBlIC9QYWdl cwovQ291bnQgMQovS2lkcyBbNSAwIFJdCj4+CmVuZG9iago0IDAgb2JqCjw8 IC9MZW5ndGggMzE2NAo+PgpzdHJlYW0KcQpxCi9UcjEgZ3MKMjA2LjAwMCA2 NTYuMDAwIDIwMC4wMDAgMTAwLjAwMCByZQpTClEKCnEKNDAwLjAwMCAwIDAg NTAuMDAwIDEwNi4wMDAgNzA2LjAwMCBjbQovSTEgRG8KUQpxCi9UcjEgZ3MK MjA2LjAwMCA2NTYuMDAwIDIwMC4wMDAgMTAwLjAwMCByZQpTClEKCkJUCjIx OC40ODI1NTg1OTM3NSA2NDIuODk2IFRkCi9GMS4wIDE4IFRmCls8NTQ+IDEx MC44Mzk4NDM3NSA8NjU2OTZjNmU2MTY4NmQ2NTYyNjU3Mzc0OGE3NDY5Njc3 NTZlNjc+XSBUSgpFVAoKCkJUCjM2IDYyMy4zMjk5OTk5OTk5OTk5IFRkCkVU CgoKQlQKMzYgNjAzLjc2Mzk5OTk5OTk5OTkgVGQKRVQKCgpCVAoyNDguODUy

This text continues a long time.

Maybe it's just me, but this doesn't exactly look "testable" to me. Does someone know to do this? Thanks!

Linus
  • 4,643
  • 8
  • 49
  • 74
  • You are trying to find a non-cyphered string "John" in an cyphered string. Cypher "John" with the same process as you did for the string OR don't cypher your emails in your test environment. (by cypher I mean encode) – MrYoshiji Feb 28 '14 at 16:28

1 Answers1

3

Firstly, your PDF-generation code should really be separate from your mailer code, and should have its own tests separate from your mailer tests. Please do this first.

Once you've separated your PDF-generation code and tests you can generate your PDF and test its content using the pdf-inspector gem, which is helpfully maintained by the same folks who make Prawn. Then in your mailer tests you can simply check whether the file is attached, using something like this.

P.S. The reason the email content looks garbled (JVBERi0xLjQ...) is that email attachments are (usually) Base64-encoded. But even if you decoded it, you might not be able to search the PDF content for a plaintext string without a library like pdf-inspector because it might be compressed (I don't know if Prawn does this by default). But really, your PDF code and tests and your email code and tests should be completely separate.

Community
  • 1
  • 1
Jordan Running
  • 102,619
  • 17
  • 182
  • 182
  • Awesome, thanks! I didn't know they've made a testing gem. They should maybe mention this in their prawm docs. – Linus Feb 28 '14 at 16:47
  • 1
    FWIW it was the first result on Google for ["ruby testing prawn output"](https://www.google.com/search?q=ruby+testing+prawn+output). I agree, though, that they should mention it in the Prawn README. P.S. I changed my answer a little regarding PDF compression vs. attachment encoding. Worth a glance, perhaps. – Jordan Running Feb 28 '14 at 16:50
  • Oh ok, well I did a similar google search and didn't find anything, though. Thanks for the good explanation! – Linus Feb 28 '14 at 16:57
  • @Linus any success with the pdf-insepctor gem? I've been trying to use it and can't get it to work for the life of me. – maahd Feb 10 '16 at 09:14
  • 1
    @maahd yes, I'm using it like this: `rendered_pdf = PdfClass.new(params).render text_analysis = PDF::Inspector::Text.analyze(rendered_pdf) expect(text_analysis.strings).to include("Some text")` (using version "~>1.1") – Linus Feb 10 '16 at 09:18
  • @Linus thanks for your answer. The first line fails for me. The official documentation says `rendered_pdf = your_pdf_document.render`. I'm not sure how to access my pdf document? In specific, what is your `PdfClass`? – maahd Feb 10 '16 at 11:53
  • @maahd I think if you substitute `your_pdf_document ` with `PdfClass.new(params)` it should work? – Linus Feb 10 '16 at 11:58
  • I am debugging a problem where my pdf is generated perfectly (when I save the file from prawn) but when it is mailed, the attachment only contains garbage. From this, I don't agree that it should be completely separate. It should at least be tested that the attachment is a valid PDF. – Kjell Dec 25 '20 at 21:54