Testowanie wieloczęściowych wiadomości e-mail ActionMailer za pomocą RSpec
Obecnie testuję moje mailery z RSpec, ale zacząłem konfigurować wieloczęściowe e-maile, jak opisano w przewodnikach Rails tutaj: http://guides.rubyonrails.org/action_mailer_basics.html#sending-multipart-emails
Mam zarówno szablony Mailera w formacie tekstowym, jak i html, ale wygląda na to, że moje testy sprawdzają tylko część HTML. Czy istnieje sposób na osobne sprawdzenie szablonu tekstowego?
Czy to tylko sprawdzanie widoku HTML bo jest pierwszy w domyślnym zamówienie?
4 answers
Aby uzupełnić doskonałą odpowiedź nilmethod, możesz wyczyścić swoje specyfikacje, testując zarówno wersje tekstowe, jak i html za pomocą udostępnionej grupy przykładowej:
Spec_helper.rb
def get_message_part (mail, content_type)
mail.body.parts.find { |p| p.content_type.match content_type }.body.raw_source
end
shared_examples_for "multipart email" do
it "generates a multipart message (plain text and html)" do
mail.body.parts.length.should eq(2)
mail.body.parts.collect(&:content_type).should == ["text/plain; charset=UTF-8", "text/html; charset=UTF-8"]
end
end
Your_email_spec.rb
let(:mail) { YourMailer.action }
shared_examples_for "your email content" do
it "has some content" do
part.should include("the content")
end
end
it_behaves_like "multipart email"
describe "text version" do
it_behaves_like "your email content" do
let(:part) { get_message_part(mail, /plain/) }
end
end
describe "html version" do
it_behaves_like "your email content" do
let(:part) { get_message_part(mail, /html/) }
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-03 22:48:00
Można to przetestować za pomocą wyrażeń regularnych.
Znajdowanie rzeczy w części HTML (użyj #should po tym, aby dopasować):
mail.body.parts.find {|p| p.content_type.match /html/}.body.raw_source
Znajdowanie rzeczy w części zwykłego tekstu (użyj #should po tym, aby dopasować):
mail.body.parts.find {|p| p.content_type.match /plain/}.body.raw_source
Sprawdzanie, czy rzeczywiście generuje wieloczęściową wiadomość:
it "generates a multipart message (plain text and html)" do
mail.body.parts.length.should == 2
mail.body.parts.collect(&:content_type).should == ["text/html; charset=UTF-8", "text/plain; charset=UTF-8"]
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-05 20:43:41
Aby wszystko było jeszcze prostsze, możesz użyć
message.text_part and
message.html_part
Aby znaleźć odpowiednie części. Działa to nawet w przypadku zorganizowanych wiadomości wieloczęściowych/alternatywnych z załącznikami. (Testowane na Ruby 1.9.3 z Rails 3.0.14.)
Te metody wykorzystują pewien rodzaj heurystyki, aby znaleźć odpowiednie części wiadomości, więc jeśli wiadomość ma wiele części tekstu (np. gdy tworzy je Apple Mail), może to nie zrobić "właściwej rzeczy".
To zmieni powyższą metodę na
def body_should_match_regex(mail, regex)
if mail.multipart?
["text", "html"].each do |part|
mail.send("#{part}_part").body.raw_source.should match(regex)
end
else
mail.body.raw_source.should match(regex)
end
end
Który działa zarówno dla wiadomości tekstowych (nie-wieloczęściowych), jak i wieloczęściowych i testuje wszystkie ciała wiadomości pod kątem określonego wyrażenia regularnego.
Jacyś ochotnicy do zrobienia z tego" prawdziwego " matchera RSpec? :) Coś jak@mail.bodies_should_match /foobar/
Byłoby o wiele milej ...Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-28 11:23:26
Jeśli twój e-mail zawiera załączniki, części tekstowe i html zostaną umieszczone w części multipart/alternative
. Jest to odnotowane w sekcji wysyłanie wiadomości e-mail z załącznikami w Przewodniku Rails 3 .
Aby sobie z tym poradzić, najpierw uprościłem metodę get_message_part
powyżej do:
def get_message_part(mail, content_type)
mail.body.parts.find { |p| p.content_type.match content_type }
end
Potem w moim teście:
multipart = get_message_part(email, /multipart/)
html = get_message_part(multipart, /html/)
html_body = html.body.raw_source
assert_match 'some string', html_body
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-27 16:38:21