简体   繁体   English

如何在RSpec请求规范中模拟ActiveStorage上传

[英]How to Simulate ActiveStorage Uploads in RSpec Request Specs

I'm writing an API-Only Rails App (rails 5.2) and I need to make use of ActiveStorage. 我正在编写一个仅API的Rails应用程序(rails 5.2),我需要使用ActiveStorage。 I want to write an RSpec Request Spec to ensure that file uploads work properly, but that's proving very difficult. 我想编写一个RSpec Request Spec以确保文件上传正常工作,但是事实证明这非常困难。 Here's my spec so far: 到目前为止,这是我的规格:

RSpec.describe 'POST /profile/photos', type: :request do
  let(:url) { '/profile/photos' }
  let(:file) { fixture_file_upload('photo.jpg') }

  before do
    log_user_in

    ## Do a file upload ##
    post '/rails/active_storage/direct_uploads', params: {
      blob: {
        filename: "woman.jpg",
        content_type: "image/jpeg",
        byte_size: File.size(file.path),
        checksum:  Digest::MD5.base64digest(File.read(file.path))
      }
    }

    post url, params: {signed_id: json["signed_id"]}
  end

  it "Performs an upload" do
    # Never gets here, error instead
  end
end

I've tried using the put helper to upload the file between the first and second post call in the before step, but I keep running into 422 unprocessable entity errors, likely because the put helper doesn't support setting the raw request body. 我已经使用试过put助手上传的第一和第二之间的文件post调用的before一步,但我一直运行到422个无法处理的实体错误,可能是因为put助手不支持设置的原始请求主体。 But I'm not entirely sure what the format of that put should be, or if there's a better way to test this. 但是我不完全确定看跌期权的格式,或者是否有更好的测试方法。

I've tried using fixture_file_upload , as described in this question : 我试过使用fixture_file_upload ,如以下问题所述

put json["direct_upload"]["url"], params: {file: fixture_file_upload('photo.jpg')}

But that request returns 422 like all of my other attempts. 但是该请求像我所有其他尝试一样返回422。 I think the direct_upload URL really wants the body of the request to contain the file and nothing else. 我认为direct_upload URL确实希望请求的正文包含文件,而没有其他内容。

I suspect there's a lot wrong with my approach here, but the Rails docs are somewhat sparse on how to use ActiveStorage if you're not using the out-of-the-box javascript to hide most of the interactions. 我怀疑这里的方法有很多问题,但是如果您没有使用现成的javascript来隐藏大多数交互,那么Rails的文档在使用ActiveStorage方面就很少。

You probably don't care about testing the Active Storage engine so you don't need to post '/rails/active_storage/direct_uploads' , you just need a valid signature. 您可能不关心测试Active Storage引擎,因此不需要post '/rails/active_storage/direct_uploads' ,只需要一个有效的签名即可。

I ended up creating an ActiveStorage::Blob by hand and then I can ask it for the signature. 我最终手动创建了一个ActiveStorage::Blob ,然后我可以要求它提供签名。 Something like this off in a helper: 帮手这样的事情:

def blob_for(name)
  ActiveStorage::Blob.create_after_upload!(
    io: File.open(Rails.root.join(file_fixture(name)), 'rb'),
    filename: name,
    content_type: 'image/jpeg' # Or figure it out from `name` if you have non-JPEGs
  )
end

and then in your specs you can say: 然后在您的规格中您可以说:

post url, params: { signed_id: blob_for('photo.jpg').signed_id }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM