[Ruby] Actionmailer を使ってメールを出し、Mailcatcher でテストをする。

# 課題
ruby プログラムから メールを送信する。また そのテストを行う。

# 実装方針

* メール送信は actionmailer を直接使って行う。
* テスト時は、mailcatcher を起動させ、外部にはメール送信はされないようにする。
* mailcather の API を利用して、メール送信の成功有無や送信メール内容のチェックを行う。
* mailcatcher の API を利用法を MailcatcherDriver  クラスとして独立させる。 
* rspec で自動テストを行う。

# 実装例

https://github.com/katoy/mailer  に作業途中のものを置いた。

## 残件
*  添付ファイルをつけたメールを送信する。そのテストをする。  
　　==> 2014-07-30: 添付ファイル付きメールの送信と、それを mailcatche  から読み取る事を実装した。
* 指定したメールだけを mailcatcher のメールボックスから削除するメソッドを実装する。

# サンプル

[sample/sample-001.rb](https://github.com/katoy/mailer/blob/master/sample/sample-00.rb)

```rb
# -*- 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.
```