Дразнящая ссылка на скачивание / проверка генерации ссылки на методы контроллера с Capybara - PullRequest
0 голосов
/ 24 мая 2018

В спецификации функций Capybara для определенной страницы у меня есть ссылка для скачивания:

download_link = find_link(expected_link_text)

Я хочу проверить, является ли созданная ссылка правильной для загрузки файла, т. Е. Что она будетвызовите download() на моем FileController с правильным объектом модели.

RSpec-Rails кажется , чтобы получить много способов получить то, что я хочу.Например, в спецификации контроллера я мог бы использовать обычное утверждение RSpec на контроллере:

expect(controller).to receive(:download).with(expected_id)
# download_link = find_link(expected_link_text) # can't do this in a controller spec
# visit(download_link)                          # can't do this in a controller spec

В спецификации маршрутизации я мог бы использовать route_to():

# download_link = find_link(expected_link_text)       # can't do this in a routing spec
expect(get: download_link[href]).to route_to(controller: 'file', action: 'download', id: expected_id)

Но в спецификации функций ни controller, ни route_to() недоступны.

Со следующими махинациями и большим количеством возни в отладчике я былвозможность включить route_to() в мой тест:

describe 'the page' do
  it 'should let the user download a file' do
    self.class.send(:include, RSpec::Rails::Matchers::RoutingMatchers)       # hack to get routing matchers into feature test
    self.class.send(:include, ActionDispatch::Assertions::RoutingAssertions) # RoutingMatchers uses this internally
    self.class.send(:define_method, :message) { |msg, _| msg }               # RoutingAssertions expects message() to be included from somewhere
    @routes = Rails.application.routes                                       # RoutingAssertions needs @routes

    download_link = find_link(expected_link_text)
    expect(get: download_link[href]).to route_to(controller: 'file', action: 'download', id: expected_id) # works!
  end
end

Это действительно работает, но это бананы.Есть ли какой-нибудь из готовых способов смешать Capybara с другими типами спецификаций или смешать другие виды спецификаций с характеристиками характеристик?Или просто более чистый Rails-y (может не-RSpec) способ получить маршрут?


Примечание: маршрут не назван, поэтому я не могу использоватьПомощник по URL (я не думаю);и сам путь URL по историческим причинам является бессвязным шумом, поэтому я не хочу просто утверждать href в виде строки.

1 Ответ

0 голосов
/ 24 мая 2018

Как вы заявили, если вы хотите проверить, вызывается ли конкретный метод контроллера, это будет спецификация контроллера, если вы хотите проверить маршрут, это будет спецификация маршрутизации.С Capybara вы должны писать спецификации функций / системные тесты - это означает отсутствие насмешек / заглушек и вместо этого запуск сквозных тестов.Настройте драйвер для загрузки файлов, затем щелкните ссылку, загрузите файл и убедитесь, что был загружен правильный файл.Другой вариант - просто использовать url_for вместо того, чтобы пытаться включить все дополнительные элементы, и просто сделать

expect(download_link[href]).to eq url_for(controller: 'file', action: 'download', id: expected_id)

или еще лучше

expect(page).to have_link(expected_link_text, href: url_for(controller: 'file', action: 'download', id: expected_id))

Но если вы тестируете файлскачать, вам действительно нужно просто скачать файл.

Если вам приходится иметь дело с проблемами кодирования, вы можете переписать ожидание с помощью блока фильтра и проанализировать оба пути / URL для нормализации

expect(page).to have_link(expected_link_text) do |link|
  Addressable::URI.parse(link[:href]) == Addressable::URI.parse(url_for(controller: 'file', action: 'download', id: expected_id))
end
...