Prueba de correos electrónicos multiparte de ActionMailer con RSpec
Actualmente estoy probando mis correos con RSpec, pero he empezado a configurar correos electrónicos multiparte como se describe en las Guías Rails aquí: http://guides.rubyonrails.org/action_mailer_basics.html#sending-multipart-emails
Tengo ambas plantillas de correo en formato texto y html, pero parece que mis pruebas solo están comprobando la parte HTML. ¿Hay alguna forma de revisar la plantilla de texto por separado?
Es solo comprobar la vista HTML porque es la primera en el valor predeterminado ¿orden?
4 answers
Para complementar la excelente respuesta de nilmethod, puede limpiar sus especificaciones probando versiones de texto y html utilizando un grupo de ejemplo compartido:
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
Su_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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-03 22:48:00
Esto se puede probar con expresiones regulares.
Encontrar cosas en la parte HTML (use #should después de esto para coincidir):
mail.body.parts.find {|p| p.content_type.match /html/}.body.raw_source
Encontrar cosas en la porción de texto sin formato (use #should después de esto para coincidir):
mail.body.parts.find {|p| p.content_type.match /plain/}.body.raw_source
Comprobando que está, de hecho, generando un mensaje multiparte:
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-05 20:43:41
Para hacer las cosas aún más simples, puede usar
message.text_part and
message.html_part
Para encontrar las partes respectivas. Esto funciona incluso para mensajes estructurados de varias partes / alternativos con archivos adjuntos. (Probado en Ruby 1.9.3 con Rails 3.0.14.)
Estos métodos emplean algún tipo de heurística para encontrar las partes del mensaje respectivas, por lo que si su mensaje tiene varias partes de texto (por ejemplo, como Apple Mail las crea) podría no hacer lo "correcto".
Esto cambiaría el método anterior a
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
Que funciona tanto para mensajes de texto plano (no multiparte) como para mensajes multiparte y prueba todos los cuerpos de mensajes contra una expresión regular específica.
Ahora, ¿algún voluntario para hacer un "verdadero" RSpec matcher de esto? :) Algo como
@mail.bodies_should_match /foobar/
Sería mucho mejor ...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-28 11:23:26
Si su correo electrónico tiene archivos adjuntos, las partes de texto y html se colocarán en una parte multipart/alternative
. Esto se indica en Enviar correos electrónicos con Archivos adjuntos en la Guía Rails 3.
Para manejar esto, primero simplifiqué el método get_message_part
anterior a:
def get_message_part(mail, content_type)
mail.body.parts.find { |p| p.content_type.match content_type }
end
Entonces en mi prueba:
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-27 16:38:21