Я перевожу свое приложение Rails 4 (все еще использующее гем защищенных атрибутов) на Rails 5.1.4.В ходе этого действия мне нужно переписать много кода, чтобы заменить защищенные атрибуты сильными параметрами.
В настоящее время я застрял на одном конкретном контроллере, где мои тесты RSpec не пройдены, и я не знаю, как реализовать контроллер и логику тестирования таким образом, чтобы все было правильно и тесты проходили.
Приложение имеет административный бэкэнд, где пользователи могут добавлять (и, следовательно, загружать) фотографии в альбом.Соответствующий Admin :: PhotosController обрабатывает фотографии альбома.
Вот соответствующий отрывок из моего приложения:
def create
# @organizer_account is set by an before_filter
@album = @organizer_account.albums.find_by_id(params[:album_id])
@photo = @album.photos.new(photo_params)
@photo.organizer_account_id = @organizer_account.id
authorize! :create, @photo
respond_to do |format|
if @photo.save
format.html {
render :json => [@photo.to_jq_file].to_json, :content_type => 'text/html', :layout => false
}
format.json {
files = [ @photo.to_jq_file ]
render :json => {:files => [@photo.to_jq_file] }, :status => :created, :location => admin_album_photo_path(@album, @photo)
}
else
format.html {
render action: "new"
}
format.json {
render json: @photo.errors, status: :unprocessable_entity
}
end
end
end
Я определил следующие сильные параметры:
private
def photo_params
params.require(:photo).permit(:id, :album_id, :organizer_account_id, :file)
end
Неудачный тест RSpec выглядит следующим образом:
require 'spec_helper'
describe Admin::PhotosController, :type => :controller do
render_views
describe "post 'create'" do
describe "with valid parameters" do
before(:each) do
@organizer_account = FactoryBot.create(:organizer_account)
@user = FactoryBot.create(:user)
@user.organizer_account_id = @organizer_account.id
@user.add_role :admin, @organizer_account
@user.save
sign_in @user
@album = @organizer_account.albums.create(:title => "Album 1")
@photo_attrs = FactoryBot.attributes_for(:photo)
request.env["HTTP_REFERER"] = new_admin_album_path
controller.request.host = @organizer_account.subdomain + ".lvh.me"
end
it "should create a new photo record", :focus => true do
lambda {
post :create, params: {:photo => @photo_attrs, :album_id => @album.id }
}.should change(@organizer_account.albums.find_by_id(@album.id).photos, :count).by(1)
end
end
end
end
Я настоятельно предполагаю, что проблема заключается в параметрах a) пройденных
post :create, params: {:photo => @photo_attrs, :album_id => @album.id }
и затем обработанных
@photo = @album.photos.new(photo_params)
В то время как хэш параметров, пройденный тестом, содержит все необходимые записи
params: {"photo"=><ActionController::Parameters {"file"=>[#<ActionDispatch::Http::UploadedFile:0x00000010dd7560 @tempfile=#<Tempfile:C:/Users/PATRIC~1/AppData/Local/Temp/RackMultipart20180520-11424-avge07.gif>, @original_filename="image6.gif", @content_type="image/gif", @headers="Content-Disposition: form-data; name=\"photo[file][]\"; filename=\"image6.gif\"\r\nContent-Type: image/gif\r\nContent-Length: 46844\r\n">]} permitted: false>, "album_id"=>"1561", "controller"=>"admin/photos", "action"=>"create"}
, photo_params пуст:
photo_params: {}
Обновление # 1: определение фабрикидля фото
FactoryBot.define do
factory :photo, :class => Photo do
file Rack::Test::UploadedFile.new(Rails.root + 'spec/fixtures/photos/apfelkuchen.jpg', "image/jpg")
end
end
Обновление № 2: Фотомодель с вложенным файлом и конфигурацией обработки изображений
class Photo < ActiveRecord::Base
require 'rmagick'
include Magick
belongs_to :album
belongs_to :organizer_account
before_destroy { |photo| photo.file.destroy }
validates :album_id, :presence => true
validates :organizer_account_id, :presence => true
has_attached_file :file,
# Следующие типы иПараметры преобразования приводят к нарушению тестов RSpec.Если прокомментировано, тесты RSpec проходят.
:styles => {
:mini => "50x50#",
:thumb => "160x160#",
:large => "1200x1200>"
},
:convert_options => {
:mini => "-quality 75 -strip",
:thumb => "-quality 75 -strip"
}
validates :file, :presence => true
end