Примечание: Я прочитал вопрос this и ответ, но по какой-то причине код для меня не работает. (см. ниже для ошибки, которую я получаю)Метод уничтожения RSpec (Rails Tutorial 3.2 Ch. 9, пример 10)
Упражнение 10 из главы 9 учебного пособия Rails просит: Изменить действие уничтожения [для пользователей], чтобы пользователи admin не уничтожали самих себя. (Напишите сначала тест.)
Трудная часть здесь проверяет его, потому что приложение уже скрывает ссылку «удалить» для текущего пользователя, поэтому вам нужно напрямую выполнить HTTP-запрос.
Я получил код и протестировал его, удалив фрагмент кода, который скрывает ссылку удаления для текущего пользователя. Разумеется, если я нажму ссылку на удаление для текущего зарегистрированного пользователя, он перенаправляет меня и дает мне уведомление.
От users_controller.rb
def destroy
@user = User.find(params[:id])
if current_user?(@user)
redirect_to users_path, notice: "You can't destroy yourself."
else
@user.destroy
flash[:success] = "User destroyed."
redirect_to users_path
end
end
Проблема у меня в написании тестов для этого, что будет посылать запрос удаления и вызвать метод уничтожения. Я попробовал решение от Rspec test for destroy if no delete link, который Я копирую здесь:
От user_pages_spec.rb
describe "destroy" do
let(:admin) { FactoryGirl.create(:admin) }
it "should not allow the admin to delete herself" do
sign_in admin
#expect { delete user_path(admin), method: :delete }.should change(User, :count)
expect { delete :destroy, :id => admin.id }.should_not change(User, :count)
end
end
Но когда я запускаю это, я получаю эту ошибку от RSpec
Failures:
1) User Pages destroy should not allow the admin to delete herself
Failure/Error: expect { delete :destroy, :id => admin.id }.should_not change(User, :count)
ArgumentError:
bad argument (expected URI object or URI string)
# ./spec/requests/user_pages_spec.rb:180:in `block (4 levels) in <top (required)>'
# ./spec/requests/user_pages_spec.rb:180:in `block (3 levels) in <top (required)>'
Итак, мои вопросы: 1) Почему этот код выше не работает? 2) Как смоделировать «удаление», чтобы вызвать действие destroy в моем контроллере?
Окружающая среда: Mac OSX рубин 1.9.3p194 Rails 3.2.3
Gems для тестирования:
группа: тест сделать камень 'RSpec рельсы', '2.9.0' камень «водосвинка ',' 1.1.2 ' gem' rb-fsevent ',' 0.4.3.1 ',: require => false gem' growl ',' 1.0.3 ' gem' guard-spork ',' 0.3.2 ' gem 'spork', '0.9.0' gem 'factory_girl_rails', '1.4.0' конец
Подробнее Я попробовал тонну способов, чтобы попытаться имитировать нажатия на ссылку удалить, и никто не похоже на работу. Я использую камень отладчика, чтобы узнать, вызван ли метод destroy. В тесте, который нажимает на ссылку, чтобы удалить другой пользователь, метод уничтожения вызывается и она отлично работает:
it "should be able to delete another user" do
expect { click_link('delete') }.to change(User, :count).by(-1)
end
Но я ничего не пытался сформировать запрос удаления непосредственно работал, чтобы вызвать метод уничтожения.
Благодарим за помощь!
Будет
** UPDATE **
Я попытался предложение для DVG:
describe "destroy" do
let(:admin) { FactoryGirl.create(:admin) }
it "should not allow the admin to delete herself" do
sign_in admin
#expect { delete user_path(admin), method: :delete }.should change(User, :count)
expect { delete :destroy, :id => admin }.to_not change(User, :count)
end
end
И получил эту ошибку:
6) User Pages destroy should not allow the admin to delete herself
Failure/Error: expect { delete :destroy, :id => admin }.to_not change(User, :count)
ArgumentError:
bad argument (expected URI object or URI string)
# ./spec/requests/user_pages_spec.rb:190:in `block (4 levels) in <top (required)>'
# ./spec/requests/user_pages_spec.rb:190:in `block (3 levels) in <top (required)>'
РЕШЕНИЕ
Я понял это после НАВСЕГДА.
Мне пришлось использовать Rack :: Test для запроса DELETE, но Capybara и Rack :: Test не используют одно и то же MockSession, поэтому мне пришлось вытащить файлы cookie: remember_token и:! Sample_app_session и поместить их в запрос DELETE вручную. Вот что сработало. (Другая проблема у меня была, перечисленных ниже, было то, что я имел force_ssl заявление, что не отпускал мою уничтожить действие дозвонились.
describe "destroy" do
let!(:admin) { FactoryGirl.create(:admin) }
before do
sign_in admin
end
it "should delete a normal user" do
user = FactoryGirl.create(:user)
expect { delete user_path(user), {},
'HTTP_COOKIE' => "remember_token=#{admin.remember_token},
#{Capybara.current_session.driver.response.headers["Set-Cookie"]}" }.
to change(User, :count).by(-1)
end
it "should not allow the admin to delete herself" do
expect { delete user_path(admin), {},
'HTTP_COOKIE' => "remember_token=#{admin.remember_token},
#{Capybara.current_session.driver.response.headers["Set-Cookie"]}" }.
to_not change(User, :count)
end
end
Я имел force_ssl заявление после моего before_filters в моем users_controller.rb и это было как-то бросали вещи, так что я никогда не должен разрушающего действия.
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:edit, :update, :index]
before_filter :existing_user, only: [:new, :create]
before_filter :correct_user, only: [:edit, :update]
before_filter :admin_user, only: :destroy
#force_ssl
def index
@users = User.paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
@microposts = @user.microposts.paginate(page: params[:page])
end
def destroy
@user = User.find(params[:id])
if current_user?(@user)
redirect_to users_path, notice: "You can't destroy yourself."
else
@user.destroy
flash[:success] = "User destroyed."
redirect_to users_path
end
end
Они были полезны в получении решения
https://gist.github.com/484787
http://collectiveidea.com/blog/archives/2012/01/05/capybara-cucumber-and-how-the-cookie-crumbles/
Одна вещь, которую я только что обнаружил, что не моя проблема точно, но может быть * а * проблема в том, что метод пусть ленится, так что я мог себе представить, что щуря ожидать to_not изменить функциональность. Поэтому я скорректировал код для использования let! при создании пользователя admin. –
Каков сценарий, который вы тестируете? Администратор входит в систему, ссылка на удаление скрыта, но он каким-то образом обрабатывает запрос на удаление? (просто спрашиваю) –
Хороший вопрос. В основном ответ заключается в том, что это было упражнение в Rails Tutorial. Оказывается, это было хорошее упражнение, потому что я изучил всевозможные вещи о куках, http-запросах, Capybara и Rack :: Test. Я предполагаю, что я могу протестировать сценарий, в котором код для скрытия ссылки на удаление не удался, и я хочу, чтобы у моего контроллера была резервная копия. –