Использование RSpec для проверки макета

Каков наилучший способ проверки логики в режиме рельсов 3?

Пример: когда пользователь подписывается на мой сайт, если они не завершили процесс onboarding, я покажу им предупреждение в верхней части экрана на всех страницах. Эта логика была помещена в макет приложения. Я просто проверяю зарегистрированного пользователя на конкретный ключ. Если ключ НЕ присутствует, я показываю предупреждение. Как только ключ присутствует (что означает, что они завершили сборку), я НЕ показываю предупреждение.

В настоящее время я пытаюсь сделать это с помощью теста просмотра, но я получаю всевозможные ActionView::Template::Error: undefined method authenticate 'для ошибок nil: NilClass, включая макет приложения, и я не могу проверить эту функцию.

Мне нужно убедиться, что у меня это под тестированием, потому что если по какой-то причине один из моих разработчиков случайно сломал эту функцию (просмотр с включенным onboarding не завершен), нам нужно сразу узнать о сборке.

Код, который я пытаюсь проверить в моем макете, выглядит следующим образом:

<% if user_signed_in? %>
    <% unless current_user.has_completed_onboarding? %>
      <div class="alert">
        You cannot accept payments from your clients until you set up your payment gateway.
        <%= link_to "Set up your", payment_gateway_path %> payment gateway. Its quick, we promise. :)
      </div>
    <% end %>
<% end %>

Я хочу убедиться, что если они не будут проинформированы о деталях, которые будут показаны, и если они были предоставлены, не показывайте это сообщение.

Ответ 1

Вы можете протестировать свой макет, как и любой другой вид. Просто создайте файл application.html.erb_spec.rb (при необходимости замените erb на haml) в spec/views/layouts/, и в этом файле напишите свои спецификации, как обычно, например:

require 'spec_helper'

describe 'layouts/application' do

  context 'signed-in user' do

    before { view.stub(:user_signed_in?) { true } }

    context 'completed onboarding' do

      before do
        user = double('user')
        user.stub(:has_completed_onboarding?) { false }
        assign(:current_user, user)
      end

      it "should display alert" do
        render
        rendered.should have_selector('.alert')
      end

    end

    ...

  end

  context 'signed-out user' do
    ...
  end

  ...

end

Я делаю это с одним из моих приложений, и он не работает, поэтому я не понимаю, почему он не будет работать и для вашего дела.

Ответ 2

Ошибка, которую вы получили ActionView::Template::Error: undefined method authenticate for nil:NilClass, вызвана вызовом метода user_signed_in? в представлении. Вы можете справиться с этим, наведя метод user_signed_in? в своих тестах, как показано в коде @shioyama.

В следующем коде показано, как заглушить метод user_signed_in? и вернуть true, если вы хотите, чтобы оператор if в вашем представлении выполнялся или false, если вы этого не сделаете. view.stub(:user_signed_in?).and_return(true)