DeviseをRspecでテストしてみた


# 雛形をclone

雛形はこちらのリポジトリを使用します。
https://github.com/stivan622/rails_preset

設定内容はこちらを参照してください。
https://qiita.com/van_622/items/cbb86733a562b32cebde

# Deviseをインストール

### Gemファイルに追記

```rb
gem 'devise'
```

#### bundle install

```
$ bundle
```

#### generatorを実行

```
$ rails generate devise:install
Running via Spring preloader in process 21345
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===============================================================================
```

### development.rbを編集

```rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```

### application.html.slimを編集

```slim
doctype html
html
  head
    title
      | RailsPreset
    = csrf_meta_tags
    = csp_meta_tag
    = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
  body
    = notice
    = alert
    = yield
```

### 日本語化

下記の記事を参考

https://qiita.com/MasatoYoshioka@github/items/8d910e793e7c485403bb

### Userモデルを作成

```terminal

$ rails generate devise User
Running via Spring preloader in process 21493
      invoke  active_record
      create    db/migrate/20181106072923_devise_create_users.rb
      create    app/models/user.rb
      insert    app/models/user.rb
       route  devise_for :users
```

```terminal
$ bin/rails db:migrate RAILS_ENV=development
```

### 新規登録をテスト

http://localhost:3000/users/sign_up

<img width="521" alt="スクリーンショット 2018-11-06 16.31.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/310287/e9753862-6ba6-3349-0648-a7f4b6b24d15.png">

### helperを作成

`spec/support/helpers.rb`

```rb
require 'support/helpers/session_helpers'

RSpec.configure do |config|
  config.include Features::SessionHelpers, type: :feature
end
```

`spec/support/session_helpers.rb`

```rb
module Features

  module SessionHelpers

    def sign_up_with(email, password, confirmation)
      visit new_user_registration_path
      fill_in "Email", with: email
      fill_in "Password", with: password
      fill_in "Password confirmation", with: confirmation
      click_button "Sign up"
    end

    def sign_in(email, password)
      visit new_user_session_path
      fill_in "Email", with: email
      fill_in "Password", with: password
      click_button "Log in"
    end
  end
end
```

### Featureスペックを記述

`spec/features/sign_up_spec.rb`

```rb
require 'rails_helper'
 RSpec.feature "Sign Up", :devise do
  scenario "visitor can sign up with valid email and password" do
    sign_up_with("test@example.com", "password", "password")

    txts = [I18n.t("devise.registrations.signed_up"),
            I18n.t("devise.registrations.signed_up_but_unconfirmed")]
    expect(page).to have_content(/.*#{txts[0]}.*|.*#{txts[1]}.*/)
  end

  scenario "visitor cannot sign up with invalid email address" do
    sign_up_with("email", "password", "password")

    expect(page).to have_content("Emailは不正な値です")
  end

  scenario "visitor cannot sign up without password" do
    sign_up_with("test@example.com", "", "")

    expect(page).to have_content("Passwordを入力してください")
  end

  scenario "visitor cannot sign up with a short password" do
    sign_up_with("test@example.com", "1234", "1234")

    expect(page).to have_content("Passwordは6文字以上で入力してください")
  end

  scenario "visitor cannot sign up without password confirmation" do
    sign_up_with("test@example.com", "password", "")

    expect(page).to have_content("Password confirmationとPasswordの入力が一致しません")
  end

  scenario "visitor cannot sign up with mismatched password and confirmation" do
    sign_up_with("test@example.com", "password", "mismatch")

    expect(page).to have_content("Password confirmationとPasswordの入力が一致しません")
  end
end

```

### 確認

```
$ rspec spec/features/sign_up_spec.rb 
......

Finished in 0.461 seconds (files took 1.13 seconds to load)
6 examples, 0 failures
```