我正在将我的Rails 4应用程序(仍然使用受保护的属性gem)迁移到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,
#以下tyles和convert选项导致RSpec测试失败。如果注释,RSpec测试通过。
:styles => {
:mini => "50x50#",
:thumb => "160x160#",
:large => "1200x1200>"
},
:convert_options => {
:mini => "-quality 75 -strip",
:thumb => "-quality 75 -strip"
}
validates :file, :presence => true
end