ActionTextでテキストエディタを実装しましたが、
なかなかそのテストの仕方までは探しても見つからなかったので備忘録です。
参考:
* 【Rails6】Action TextでRSpecのエラーが出たときにすること
* ドキュメント
* Everyday Rails
#前提
Local
(地元民)がかくArticle
(記事)の作成機能をActionTextを使って作成。
articlesテーブル
にはtitle
属性があり、
ActionTextを使ってcontent(本文)
(画像付きもOK)を作成できるようにしている。
ちなみに今回の内容とは関係ないですが、
記事にはタグ(Tag
モデルで管理)をつけられるようにしてます.
Left align | バージョン |
---|---|
OS | macOS Big Sur 11.3 |
Ruby | 3.0.0 |
Rails | 6.1.3.1 |
Rspec | 3.10 |
#各関連ファイル
#####モデル
class Article < ApplicationRecord
has_rich_text :content
belongs_to :local
has_one :tag, dependent: :destroy
accepts_nested_attributes_for :tag, allow_destroy: true
default_scope -> { order(created_at: :desc)}
validates :title, presence: true, length: { maximum: 255 }
validate :content_required
private
def content_required
errors.add(:content, "を入力してください") unless content.body.present?
end
end
#####コントローラー
class ArticlesController < ApplicationController
skip_before_action :authenticate_user!, if: :local_signed_in?
skip_before_action :authenticate_local!, if: :user_signed_in?, only: [:index, :show]
before_action :correct_local, only: [:edit, :update, :destroy]
def index
@articles = Article.all
end
def show
@article = Article.find_by(id: params[:id])
end
def new
@article = Article.new
@article.build_tag
tags
end
def create
@article = current_local.articles.build(article_params)
if @article.save
flash[:success] = "投稿が完了しました"
redirect_to @article
else
render 'new'
end
end
def edit
未
end
def update
未
end
def destroy
未
end
private
def article_params
params.require(:article).permit(:title, :content, tag_attributes:[:hoge ...略])
end
def correct_local
@article = Article.find_by(id: [params[:id]])
@local = Local.find_by(id: @article.local_id)
redirect_to(top_url) unless @local == current_local
end
def tags
@tags = { hoge: "hoge" ...略 }
end
end
#####ビュー
<h1>Articles#new</h1>
<p>Find me in app/views/articles/new.html.erb</p>
<%= form_with(model: @article, local: true) do |form| %>
<div class="field">
<%= form.label :title, 'タイトル' %>
<%= form.text_field :title %>
</div>
<div class="field">
<%= form.label :content, '本文' %>
<%= form.rich_text_area :content %>
</div>
<p>タグ付け</p>
<div style="display: flex; flex-wrap: wrap;">
<%= form.fields_for :tag do |tag_form| %>
<% @tags.each do |key, jp| %>
<div class="field" style="padding: 5px;">
<%= tag_form.label key, jp %>
<%= tag_form.check_box key, {}, true, false %>
</div>
<% end %>
<% end %>
</div>
<div class="actions">
<%= form.submit "投稿" %>
</div>
<% end %>
<h1><%= @article.title %></h1>
<section>
<%= @article.content %>
</section>
#本題(テスト部分)
##ハマったことその① 本文(content)のテストが通らない
RSpec.describe 'Profiles', js: true, type: :system do
let(:local) { FactoryBot.create(:local) }
let(:article) { FactoryBot.build(:article) }
before do
local.confirm
@number_of_articles = Article.count
@number_of_tags = Tag.count
end
describe 'creating new article' do
it 'success to create an article' do
sign_in local
visit new_article_path
fill_in 'タイトル', with: article.title
fill_in '本文', with: article.content #←←← ここ
以下略
Failure/Error: fill_in '本文', with: article.content
Capybara::ElementNotFound:
Unable to find field '本文' that is not disabled
しばらく本文の2文字を書き間違えてないか見返したりしてたのですがそんなこともなく。。
正解は下記記事にありました!! ありがとうございました。
* 【Rails6】Action TextでRSpecのエラーが出たときにすること
###解決策
ざっくり概要をまとめると、
原因としては本文の部分はActionTextを使って入力フォームを作っていて、
そこの箇所はfill_in
の対象であるテキストエリアではないため、
カピバラさんが見つけられなかったよ、と仰っている。
そこで、action_text_helper.rb
を作成し、
その中でリッチテキストエディターを見つけてそこに書き込んでねー、というfill_in_rich_text_area
メソッドを作成。
※詳細は上記参考記事をご確認くださいませ。
すると以下で通るようになります。
RSpec.describe 'Profiles', js: true, type: :system do
let(:local) { FactoryBot.create(:local) }
let(:article) { FactoryBot.build(:article) }
before do
local.confirm
@number_of_articles = Article.count
@number_of_tags = Tag.count
end
describe 'creating new article' do
it 'success to create an article' do
sign_in local
visit new_article_path
fill_in 'タイトル', with: article.title
fill_in_rich_text_area '本文', with: article.content #←←← ここ
##ハマったことその② 画像添付のテストの書き方がわからない・・・
低レベルだなと思った方はスルーしてください。。
恥ずかしながらファイルのアップロードのテストについて、こう書く↓知識しかなく・・
attach_file "Attachment", "#{Rails.root}/spec/files/attachment.jpg"
ActionTextを使うとファイルアップロードのボタンはクリップマーク。。。
さてどうしよう。
###解決策
で、ドキュメントを確認したところ
# will attach file to whatever file input is triggered by the block
page.attach_file('/path/to/file.png') do
page.find('#upload_button').click
end
これで行けそう。
ということで、デベロッパーツールで使えそうなCSSを探し・・
RSpec.describe 'Profiles', js: true, type: :system do
let(:local) { FactoryBot.create(:local) }
let(:article) { FactoryBot.build(:article) }
before do
local.confirm
@number_of_articles = Article.count
@number_of_tags = Tag.count
end
describe 'creating new article' do
it 'success to create an article' do
sign_in local
visit new_article_path
fill_in 'タイトル', with: article.title
fill_in_rich_text_area '本文', with: article.content
page.attach_file("#{Rails.root}/spec/files/attachment.jpeg") do #←←←ここから
page.find('.trix-button--icon-attach').click
end #←←←ここまで
check 'tag'
check 'another_tag'
click_button '投稿'
expect(Article.count).to eq @number_of_articles +1
expect(Tag.count).to eq @number_of_tags +1
expect(page).to have_current_path article_path(Article.last)
expect(page).to have_content article.title
expect(page).to have_content 'this is my article!'
expect(page).to have_content "attachment.jpeg"
end
end
end
これで無事通りました!
#まとめ
とにかく困ったらドキュメント読め、と思いました。
しかしもっと良き書き方がありましたらご教示いただけますと幸いです!