Как смоделировать загрузки ActiveStorage в спецификации запроса RSpec - PullRequest
1 голос
/ 28 апреля 2019

Я пишу приложение только для API Rails (rails 5.2) и мне нужно использовать ActiveStorage.Я хочу написать спецификацию запроса RSpec, чтобы обеспечить правильную загрузку файлов, но это оказалось очень сложно.Вот моя спецификация:

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

Я пытался использовать помощник put для загрузки файла между первым и вторым вызовом post на шаге before, но я продолжаю сталкиваться с422 ошибки необработанного объекта, вероятно, из-за того, что помощник put не поддерживает установку необработанного тела запроса.Но я не совсем уверен, какой должен быть формат этого ввода, или есть ли лучший способ проверить это.

Я пытался использовать fixture_file_upload, как описано в в этом вопросе :

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

Но этот запрос возвращает 422, как и все мои другие попытки.Я думаю, что URL-адрес direct_upload действительно хочет, чтобы тело запроса содержало файл и ничего больше.

Я подозреваю, что с моим подходом здесь много неправильного, но документы Rails немного разбираются в том, как использовать ActiveStorage, если вы не используете готовый JavaScript, чтобы скрыть большинство взаимодействий..

1 Ответ

1 голос
/ 28 апреля 2019

Вам, вероятно, нет дела до тестирования движка Active Storage, поэтому вам не нужно post '/rails/active_storage/direct_uploads', вам нужна только действительная подпись.

В итоге я создал ActiveStorage::Blob вручную, а затем могу попросить подпись. Что-то вроде этого в помощнике:

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

и тогда в своих спецификациях вы можете сказать:

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