Skip to content

Commit

Permalink
MailSenderをMailGeneratorに改名し、テストを追加する
Browse files Browse the repository at this point in the history
refs #71

送信処理は mail.deliver のみだったので、改名でメインの生成処理を
強調する
  • Loading branch information
ochaochaocha3 committed Jan 8, 2018
1 parent 7b3a0a1 commit d2d847f
Show file tree
Hide file tree
Showing 3 changed files with 320 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,17 @@ module RGRB
module Plugin
# サーバーリレー監視プラグイン
module ServerConnectionReport
# メール送信を司るクラス
class MailSender
# メール生成を司るクラス
class MailGenerator
# メールテンプレートの読み込みに失敗した際に発生するエラー
class MailTemplateLoadError < StandardError; end

# メールの送信先
# @return [String]
attr_reader :to
# メールの件名
# @return [String]
attr_reader :subject
attr_accessor :subject
# メールの本文
# @return [String]
attr_reader :body
attr_accessor :body

# ボットの接続先ホスト名
# @return [String]
Expand All @@ -36,9 +33,13 @@ class MailTemplateLoadError < StandardError; end
# @return [String]
attr_accessor :irc_network

# メールの送信先
# @return [String]
attr_reader :to

# 送信データを初期化する
# @param [Hash] config 設定
# @param [Object] logger ロガー
# @param [Object?] logger ロガー
# @option [String] to 送信先
# @option [Hash] smtp 送信に利用するSMTPサーバーの設定
def initialize(config, logger = nil)
Expand Down Expand Up @@ -119,18 +120,19 @@ def load_mail_template_file(path)
disconnected: '切断'
}.freeze

# メールを送信する
# メールの内容を生成する
# @param [String] server 対象のサーバー
# @param [Symbol] status サーバーのステータス
# @param [DateTime] time 接続・切断時間
# @param [String] message 補足メッセージ
# @return [String]
def send(server, status, time, message)
# @return [MailData]
def generate(server, status, time, message)
data_parts = {
host: @irc_host,
nick: @irc_nick,
network: @irc_network,
time: time.strftime('%Y年%m月%d日 %H:%M:%S'),
server: server,
message: message,
rgrb_version: RGRB::VERSION,
status1: STATUS_1[status],
Expand All @@ -139,21 +141,22 @@ def send(server, status, time, message)

mail = Mail.new
mail.delivery_method(:smtp, @mail_config)
mail['charset'] = 'utf-8'
mail['to'] = @to
mail.charset = 'utf-8'
mail.to = @to
{
from: '%{nick} on %{network} <rgrb-%{nick}@%{host}>',
subject: @subject,
body: @body
}.each do |key, value|
mail[key] = value % data_parts
end
puts "Subject: #{mail.subject}\n"
puts mail.body
puts mail.to_s
mail.deliver

mail
end

# Hashのキーをシンボルに変えたものを返す
# @param [Hash] hash 変換元のハッシュテーブル
# @return [Hash]
def symbolize_keys(hash)
hash.map { |key, value|
[key.to_sym, value]
Expand Down
300 changes: 300 additions & 0 deletions spec/rgrb/plugin/server_connection_report/mail_generator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
# vim: fileencoding=utf-8

require_relative '../../../spec_helper'

require 'yaml'
require 'lumberjack'
require 'rgrb/plugin/server_connection_report/mail_generator'

describe RGRB::Plugin::ServerConnectionReport::MailGenerator do
let(:test_data_dir) { File.expand_path('data', __dir__) }
let(:test_data_file_path) {
->file_name { "#{test_data_dir}/#{file_name}" }
}

let(:template_cre_path) { test_data_file_path['cre.txt'] }

let(:null_logger) { Lumberjack::Logger.new('/dev/null') }
let(:smtp_config) {
{
'SMTP' => {
'address' => 'localhost',
'port' => 25,
'domain' => 'smtp.example.net',
'authentication' => false,
'ssl' => false,
'enable_starttls_auto' => false
}
}
}
let(:mail_generator) { described_class.new(smtp_config, null_logger) }

describe '#initialize' do
it 'インスタンスを初期化することができる' do
expect(mail_generator).to be_truthy
end

it 'subject を正しく設定する' do
expect(mail_generator.subject).to eq('')
end

it 'body を正しく設定する' do
expect(mail_generator.body).to eq('')
end

it 'irc_host を正しく設定する' do
expect(mail_generator.irc_host).to eq('')
end

it 'irc_nick を正しく設定する' do
expect(mail_generator.irc_nick).to eq('')
end

it 'irc_network を正しく設定する' do
expect(mail_generator.irc_network).to eq('')
end

describe '@to' do
context '指定されていなかった場合' do
it 'to を正しい既定値に設定する' do
expect(mail_generator.to).to eq('root@localhost')
end
end

context '指定されていた場合' do
let(:mail_address) { 'someone@example.net' }
let(:config) {
{ 'To' => mail_address }
}

let(:generator) { described_class.new(config, null_logger) }

it 'to を設定する' do
expect(generator.to).to eq(mail_address)
end
end
end

describe '@mail_config' do
let(:mail_config_hash_1) {
YAML.load(<<-YAML)
SMTP:
address: localhost
port: 25
YAML
}

let(:expected_1) {
{
address: 'localhost',
port: 25
}
}

let(:mail_config_hash_2) {
YAML.load(<<-YAML)
SMTP:
authentication: false
# YAMLではnilではなくnull
invalid_key: null
YAML
}

let(:expected_2) {
{
authentication: false
}
}

it 'キーを文字列からシンボルに変換する' do
mail_generator_2 = described_class.new(mail_config_hash_1, null_logger)
expect(mail_generator_2.instance_variable_get(:@mail_config)).
to eq(expected_1)
end

it 'nullの項目を除く' do
mail_generator_2 = described_class.new(mail_config_hash_2, null_logger)
expect(mail_generator_2.instance_variable_get(:@mail_config)).
to eq(expected_2)
end
end
end

describe 'メールテンプレート読み込み' do
let(:empty_file_path) { test_data_file_path['empty.txt'] }
let(:only_subject_file_path) { test_data_file_path['only_subject.txt'] }

let(:cre_subject) { 'IRC サーバ%{status2}通知 (%{server})' }
let(:cre_body) { %Q("%{server}" がネットワーク%{status1}ました。\n) }

describe '#load_mail_template' do
context '空のファイル' do
let(:content) { File.read(empty_file_path) }

it '読み込みに失敗する' do
expect(content.length).to eq(0)
expect { mail_generator.load_mail_template(content) }.
to raise_error(described_class::MailTemplateLoadError)
end
end

context '件名のみ' do
let(:content) { File.read(only_subject_file_path) }

it '読み込みに失敗する' do
expect(content.lines.length).to eq(2)
expect { mail_generator.load_mail_template(content) }.
to raise_error(described_class::MailTemplateLoadError)
end
end

context 'cre' do
let(:content) { File.read(template_cre_path) }

it 'self を返す' do
expect(content.lines.length).to be > 2
expect(mail_generator.load_mail_template(content)).to be(mail_generator)
end

it '件名を正しく設定する' do
expect(content.lines.length).to be > 2

mail_generator.load_mail_template(content)
expect(mail_generator.subject).to eq(cre_subject)
end

it '本文を正しく設定する' do
expect(content.lines.length).to be > 2

mail_generator.load_mail_template(content)
expect(mail_generator.body).to eq(cre_body)
end
end
end

describe '#load_mail_template_file' do
context '空のファイル' do
it '読み込みに失敗する' do
expect {
mail_generator.load_mail_template_file(empty_file_path)
}.to raise_error(described_class::MailTemplateLoadError)
end
end

context '件名のみ' do
it '読み込みに失敗する' do
expect {
mail_generator.load_mail_template_file(only_subject_file_path)
}.to raise_error(described_class::MailTemplateLoadError)
end
end

context 'cre' do
let(:cre_mail_generator) {
mail_generator.load_mail_template_file(template_cre_path)
}

it 'self を返す' do
expect(cre_mail_generator).to be(mail_generator)
end

it '件名を正しく設定する' do
expect(cre_mail_generator.subject).to eq(cre_subject)
end

it '本文を正しく設定する' do
expect(cre_mail_generator.body).to eq(cre_body)
end
end
end

describe '#generate' do
let(:cre_mail_generator) {
mail_generator.load_mail_template_file(template_cre_path)
mail_generator.irc_host = 'irc.cre.jp'
mail_generator.irc_nick = 'RGRB'
mail_generator.irc_network = "Creator'sNetworkIRC"

mail_generator
}

let(:mail_data_joined) {
cre_mail_generator.generate(
'irc.kazagakure.net',
:joined,
Time.new(2018, 1, 23, 4, 56, 12, '+09:00'),
'ネットワークへの参加'
)
}

let(:mail_data_disconnected) {
cre_mail_generator.generate(
'irc.kazagakure.net',
:disconnected,
Time.new(2018, 1, 23, 4, 56, 12, '+09:00'),
'ネットワークからの切断'
)
}

it 'deliver メソッドが存在する' do
expect(mail_data_joined.respond_to?(:deliver)).to be(true)
end

it 'from を正しく設定する' do
expect(mail_data_joined.from[0]).to eq('rgrb-RGRB@irc.cre.jp')
expect(mail_data_joined['from'].display_names[0]).
to eq("RGRB on Creator'sNetworkIRC")
end

context 'ネットワークへの参加' do
it 'subject を正しく設定する' do
expect(mail_data_joined.subject).to eq(
'IRC サーバ接続通知 (irc.kazagakure.net)'
)
end

it 'body を正しく設定する' do
expect(mail_data_joined.body).to eq(
%Q("irc.kazagakure.net" がネットワークに参加しました。\n)
)
end
end

context 'ネットワークからの切断' do
it 'subject を正しく設定する' do
expect(mail_data_disconnected.subject).to eq(
'IRC サーバ切断通知 (irc.kazagakure.net)'
)
end

it 'body を正しく設定する' do
expect(mail_data_disconnected.body).to eq(
%Q("irc.kazagakure.net" がネットワークから切断されました。\n)
)
end
end

describe 'パーツの置換' do
it 'time を正しく置換する' do
cre_mail_generator.body = '%{time}'
expect(mail_data_joined.body).to eq('2018年01月23日 04:56:12')
end

it 'server を正しく置換する' do
cre_mail_generator.body = '%{server}'
expect(mail_data_joined.body).to eq('irc.kazagakure.net')
end

it 'message を正しく置換する' do
cre_mail_generator.body = '%{message}'
expect(mail_data_joined.body).to eq('ネットワークへの参加')
end

it 'rgrb_version を正しく置換する' do
cre_mail_generator.body = '%{rgrb_version}'
expect(mail_data_joined.body).to eq(RGRB::VERSION)
end
end
end
end
end
Loading

0 comments on commit d2d847f

Please sign in to comment.