課題
ruby プログラムから メールを送信する。また そのテストを行う。
実装方針
- メール送信は actionmailer を直接使って行う。
- テスト時は、mailcatcher を起動させ、外部にはメール送信はされないようにする。
- mailcather の API を利用して、メール送信の成功有無や送信メール内容のチェックを行う。
- mailcatcher の API を利用法を MailcatcherDriver クラスとして独立させる。
- rspec で自動テストを行う。
実装例
https://github.com/katoy/mailer に作業途中のものを置いた。
残件
- 添付ファイルをつけたメールを送信する。そのテストをする。
==> 2014-07-30: 添付ファイル付きメールの送信と、それを mailcatche から読み取る事を実装した。 - 指定したメールだけを mailcatcher のメールボックスから削除するメソッドを実装する。
サンプル
# -*- coding: utf-8 -*-
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'src', 'mailer.rb')
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'src', 'mailcatcher-driver.rb')
mail_infos = {
from: 'youichikato@gmail.com',
to: 'youichikato@gmail.com',
subject: 'テストメール Subject',
body: 'テストメール本文',
}
# メールキャッチャーを開始する。既に開始済みなら何もしない。
mc = MailcatcherDriver.new
mc.start
# 現時点の全メッセージを得る
puts '--------------------------- messages_json before send'
ap mc.all_messages
# メールを送信する
MyMailer.send_mail mail_infos
# 現時点の全メッセージを得る
puts '--------------------------- messages_json after send'
ap mc.all_messages
# メール ID を全て得る。
puts '--------------------------- ids'
ids = mc.ids
ap ids
# 最後に送信されたメールの本文を得る。
puts '--------------------------- messages_plain'
ap mc.message :plain, [ids[-1]]
# json 形式で得る。
puts '--------------------------- messages_json'
ap mc.message :json, [ids[-1]]
puts '--------------------------- response get'
ap mc.response_get 'http://localhost:1080//messages'
# メールを全て削除する
#puts '--------------------------- clear'
#ap mc.clear
# 添付ファイル付きのメールを送る
mail_infos[:subject] = 'テストメール Subject (添付ファイル有り)'
mail_infos[:body] = 'テストメール本文 (添付ファイル有り)'
mail_infos[:files] =[
{ name: 'test-001.txt', content: '添付ファイルの内容' },
{ name: 'fish.png',
content: File.read(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'sample', 'fish.png'))}
]
MyMailer.send_mail mail_infos
puts '--------------------------- 添付ファイル付きのメール'
puts '--------------------------- ids'
ap mc.ids
# 本文を得る
puts '--------------------------- messages plain'
ap mc.message :plain, [1]
# 添付ファイルを得る
puts '--------------------------- attacheds'
attacheds = mc.attacheds 2
ap attacheds
attacheds.each do |at|
puts "--------添付ファイル: #{at['filename']} ------"
ap at
cont = mc.attached 2, at['cid']
if at['type'] == 'text/plain'
ap cont.toutf8
else
ap "#{cont}"[0..10] + " ..."
ap "#{cont.unpack('C*')[0..60]}" + " ... (snip) size: #{at['size']}"
end
end
puts '--------------------------- quit'
ap mc.quit
sample の実行結果
$ bundle exec ruby sample/sample-00.rb
--------------------------- messages_json before send
[]
--------------------------- messages_json after send
[
[0] {
"id" => 1,
"sender" => "<youichikato@gmail.com>",
"recipients" => [
[0] "<youichikato@gmail.com>"
],
"subject" => "テストメール Subject",
"size" => "397",
"created_at" => "2014-08-02T09:04:35+00:00"
}
]
--------------------------- ids
[
[0] 1
]
--------------------------- messages_plain
[
[0] "テストメール本文"
]
--------------------------- messages_json
[
[0] {
"id" => 1,
"sender" => "<youichikato@gmail.com>",
"recipients" => [
[0] "<youichikato@gmail.com>"
],
"subject" => "テストメール Subject",
"source" => "Date: Sat, 02 Aug 2014 18:04:35 +0900\nFrom: youichikato@gmail.com\nTo: youichikato@gmail.com\nMessage-ID: <53dca9a3bd10_1ea73fe9e0465bb866595@katoy-no-MacBook-Pro.local.mail>\nSubject: =?UTF-8?Q?=E3=83=86=E3=82=B9=E3=83=88=E3=83=A1=E3=83=BC=E3=83=AB?=\n =?UTF-8?Q?_Subject?=\nMime-Version: 1.0\nContent-Type: text/plain;\n charset=UTF-8\nContent-Transfer-Encoding: base64\n\n44OG44K544OI44Oh44O844Or5pys5paH",
"size" => "397",
"type" => "text/plain",
"created_at" => "2014-08-02T09:04:35+00:00",
"formats" => [
[0] "source",
[1] "plain"
],
"attachments" => []
}
]
--------------------------- response get
"[{\"id\":1,\"sender\":\"<youichikato@gmail.com>\",\"recipients\":[\"<youichikato@gmail.com>\"],\"subject\":\"\\u30c6\\u30b9\\u30c8\\u30e1\\u30fc\\u30eb Subject\",\"size\":\"397\",\"created_at\":\"2014-08-02T09:04:35+00:00\"}]"
--------------------------- 添付ファイル付きのメール
--------------------------- ids
[
[0] 1,
[1] 2
]
--------------------------- messages plain
[
[0] "テストメール本文"
]
--------------------------- attacheds
[
[0] {
"cid" => "53dca9a335ce4_1ea73fe9e0465bb8668d4@katoy-no-MacBook-Pro.local.mail",
"type" => "image/png",
"filename" => "fish.png",
"size" => 37477,
"href" => "/messages/2/parts/53dca9a335ce4_1ea73fe9e0465bb8668d4%40katoy-no-MacBook-Pro.local.mail"
},
[1] {
"cid" => "53dca9a334cc5_1ea73fe9e0465bb866757@katoy-no-MacBook-Pro.local.mail",
"type" => "text/plain",
"filename" => "test-001.txt",
"size" => 27,
"href" => "/messages/2/parts/53dca9a334cc5_1ea73fe9e0465bb866757%40katoy-no-MacBook-Pro.local.mail"
}
]
--------添付ファイル: fish.png ------
{
"cid" => "53dca9a335ce4_1ea73fe9e0465bb8668d4@katoy-no-MacBook-Pro.local.mail",
"type" => "image/png",
"filename" => "fish.png",
"size" => 37477,
"href" => "/messages/2/parts/53dca9a335ce4_1ea73fe9e0465bb8668d4%40katoy-no-MacBook-Pro.local.mail"
}
"\x89PNG\r\n\x1A\n\x00\x00\x00 ..."
"[137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 129, 0, 0, 0, 180, 8, 2, 0, 0, 0, 60, 117, 216, 25, 0, 0, 10, 65, 105, 67, 67, 80, 73, 67, 67, 32, 80, 114, 111, 102, 105, 108, 101, 0, 0, 72, 13, 157, 150, 119, 84, 83] ... (snip) size: 37477"
--------添付ファイル: test-001.txt ------
{
"cid" => "53dca9a334cc5_1ea73fe9e0465bb866757@katoy-no-MacBook-Pro.local.mail",
"type" => "text/plain",
"filename" => "test-001.txt",
"size" => 27,
"href" => "/messages/2/parts/53dca9a334cc5_1ea73fe9e0465bb866757%40katoy-no-MacBook-Pro.local.mail"
}
"添付ファイルの内容"
--------------------------- quit
204
rspec の実行結果
bundle exec rspec
[Coveralls] Set up the SimpleCov formatter.
[Coveralls] Using SimpleCov's default settings.
....*
Pending:
MailcatcherDriver start/stop delete mail
# delete_message return 500, Why?
# ./spec/units/mailcatche_driver_spec.rb:142
Finished in 7.71 seconds (files took 0.61161 seconds to load)
5 examples, 0 failures, 1 pending
Coverage report generated for RSpec to /Users/katoy/github/ruby/mailer/coverage. 66 / 79 LOC (83.54%) covered.
Coverage report Rcov style generated for RSpec to /Users/katoy/github/ruby/mailer/coverage/rcov
[Coveralls] Outside the Travis environment, not sending data.