発生している問題

現在 rails tutorial の 11 章をやっているのですが、送信メールのプレビューのテストが、テキスト通りに書いたコードが、テストに通らず ArgumentError を吐きだしてしまいます。

唯一プレビューを完成させるに当たって、 config/environments/development.rb の host の部分だけは、コピペできる内容ではなかったので、自分で調べて記入したのですが、そういった感じのエラーでもなさそうな感じがしています。

エラーの内容を見る限り account_activation メソッドの引数が期待値と異なっている為エラーを起こしているようなのですが、与えられた引数が 1 に対して期待値が 0 だったので混乱してます。

これらが関係してそうなコードを見て、もし心当たりがありそうな点があれば教えていただけたらと思います。

また、 development.rb の host の部分の記入に誤りがあれば、正しい記述を教えていただけたらと思います。


環境

  • CentOS 6
    (ip 指定しているので localhost:3000 ではなく ipアドレス:3000rails s 動かしてます)
  • rails 5.1.6

エラーの内容

Running via Spring preloader in process 18311
Started with run options --seed 18224

ERROR["test_account_activation", UserMailerTest, 1.4291797599980782]
 test_account_activation#UserMailerTest (1.43s)
ArgumentError:         ArgumentError: wrong number of arguments (given 
1, expected 0)
            app/mailers/user_mailer.rb:8:in `account_activation'
            test/mailers/user_mailer_test.rb:8:in `block in 
<class:UserMailerTest>'

  40/40: [=================================] 100% Time: 00:00:01, Time: 
00:00:01

Finished in 1.90915s
40 tests, 150 assertions, 0 failures, 1 errors, 0 skips

該当のソースコード

test/mailers/user_mailer_test.rb:

require 'test_helper'

class UserMailerTest < ActionMailer::TestCase
  test "account_activation" do
    user = users(:michael)
    user.activation_token = User.new_token
    mail = UserMailer.account_activation(user)
    assert_equal "Account activation", mail.subject
    assert_equal [user.email], mail.to
    assert_equal ["noreply@example.com"], mail.from
    assert_match user.name, mail.body.encoded
    assert_match user.activation_token, mail.body.encoded
    assert_match CGI.escape(user.email), mail.body.encoded
  end

  # test "password_reset" do
  #   mail = UserMailer.password_reset
  #   assert_equal "Password reset", mail.subject
  #   assert_equal ["to@example.org"], mail.to
  #   assert_equal ["from@example.com"], mail.from
  #   assert_match "Hi", mail.body.encoded
  # end

end

app/mailers/user_mailer.rb:

class UserMailer < ApplicationMailer

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.user_mailer.account_activation.subject
  #
  def account_activation(user)
    @user = user
    mail to: user.email, subject: "Account activation"
  end

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.user_mailer.password_reset.subject
  #
  def password_reset
    @greeting = "Hi"

    mail to: "to@example.org"
  end
end

app/views/user_mailer/account_activation.html.erb:

<h1>Sample App</h1>

<p>Hi <%= @user.name %>,</p>

<p>
  Welcome to the Sample App! Click on the link below to activate your 
  account:
</p>

<%= link_to "Activate", edit_account_activation_url(@user.activation_token,
                                                email: @user.email) %>

app/models/user.rb:

class User < ApplicationRecord
  attr_accessor :remember_token, :activation_token
  before_create :create_activation_digest
  before_save :downcase_email

  # email属性を小文字に変換
  before_save { self.email = email.downcase }

  # nameに対してのバリデーション presence(存在性)、length(文字数制限)
  validates :name,  presence: true, length: { maximum: 50 }


  # emailに対してのバリデーション presence(存在性)、length(文字数制限)、
  #                 format(テンプレート)、uniqueness(一意性)
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i


  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                                # メールアドレスの大小区別しない一意性の検証
                    uniqueness: { case_sensitive: false }


  # paswordに対してのバリデーション presence(存在性)、length(文字数制限)
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }, allow_nil: true

  class << self

    # 渡された文字列のハッシュ値を返す
    def digest(string)
      cost = ActiveModel::SecurePassword.min_cost ? 
             BCrypt::Engine::MIN_COST :
             BCrypt::Engine.cost
             BCrypt::Password.create(string, cost: cost)
    end

    # ランダムなトークンを返す
    def new_token
      SecureRandom.urlsafe_base64
    end
  end

  # 永続セッションのためにユーザーをデータベースに記憶する
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

  # 渡されたトークンがダイジェストと一致したらtrueを返す
  def authenticated?(remember_token)
    return false if remember_digest.nil?
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end

  # ユーザーのログイン情報を破棄する
  def forget
    update_attribute(:remember_digest, nil)
  end

  private

    # 有効化トークンと有効化ダイジェストを作成、代入する
    def create_activation_digest
      self.activation_token = User.new_token
      self.activation_digest = User.digest(activation_token)
    end

    # メールアドレスをすべて小文字にする
    def downcase_email
      email.downcase!
    end


end

db/seed:

User.create!(name:  "Example User",
             email: "example@railstutorial.org",
             password:              "foobar",
             password_confirmation: "foobar",
             admin:     true,
             activated: true,
             activated_at: Time.zone.now)

99.times do |n|
  name  = Faker::Name.name
  email = "example-#{n+1}@railstutorial.org"
  password = "password"
  User.create!(name:  name,
              email: email,
              password:              password,
              password_confirmation: password,
              activated: true,
              activated_at: Time.zone.now)
end

test/fixtures/users.yml:

michael:
  name: Michael Example
  email: michael@example.com
  password_digest: <%= User.digest('password') %>
  admin: true
  activated: true
  activated_at: <%= Time.zone.now %>

archer:
  name: Sterling Archer
  email: duchess@example.gov
  password_digest: <%= User.digest('password') %>
  activated: true
  activated_at: <%= Time.zone.now %>

lana:
  name: Lana Kane
  email: hands@example.gov
  password_digest: <%= User.digest('password') %>
  activated: true
  activated_at: <%= Time.zone.now %>

malory:
  name: Malory Archer
  email: boss@example.gov
  password_digest: <%= User.digest('password') %>
  activated: true
  activated_at: <%= Time.zone.now %>

<% 30.times do |n| %>
user_<%= n %>:
  name:  <%= "User #{n}" %>
  email: <%= "user-#{n}@example.com" %>
  password_digest: <%= User.digest('password') %>
  activated: true
  activated_at: <%= Time.zone.now %>
<% end %>

config/environments/development.rb:

Rails.application.configure do

  config.cache_classes = false

  config.eager_load = false

  config.consider_all_requests_local = true

  if Rails.root.join('tmp/caching-dev.txt').exist?
    config.action_controller.perform_caching = true

    config.cache_store = :memory_store
    config.public_file_server.headers = {
      'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}"
    }
  else
    config.action_controller.perform_caching = false

    config.cache_store = :null_store
  end

  config.action_mailer.raise_delivery_errors = false

  config.action_mailer.perform_caching = false

  config.active_support.deprecation = :log

  config.active_record.migration_error = :page_load

  config.assets.debug = true

  config.assets.quiet = true

  config.file_watcher = ActiveSupport::EventedFileUpdateChecker

  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :test
  host = 'localhost.localdomain'
  config.action_mailer.default_url_options = { host: host, protocol: 'http' }
  config.action_mailer.default_url_options = { host: 'example.com' }
end

以上です。

なにか足りない情報などありましたら、追記していきます。
よろしくお願いします。