Мне нужна помощь с тестированием моего контроллера rails, который использует javascript.Предположим, у меня есть рабочий элемент, и у этой модели рабочего элемента есть столбец, который complete типа boolean.У меня есть страница, где пользователь может пометить элемент как завершенный, когда он нажимает на ссылку.Я решил использовать JS, потому что хотел, чтобы функция оповещения подтверждала, действительно ли пользователь хочет пометить элемент как завершенный.Вот мой JS-файл (я использую Paloma для обработки разных JS-файлов для каждого действия контроллера):
let nichesChemicalController = Paloma.controller('Niches/Chemicals');
nichesChemicalController.prototype.index = function() {
$(function() {
$('.submit').on('click', 'a', function(e) {
e.preventDefault();
let workItemId = $('.submit').attr('data-id');
if (window.confirm("Are you sure you want to mark this item as complete?")) {
request = $.ajax({
type: "PUT",
url: '/work_items/' + workItemId,
data: { complete: true },
})
.done(function(json, code) {
console.log(json);
console.log(code);
})
.fail(function(xhr, code) {;
console.log(xhr);
console.log(code);
});
} else {
alert('cool');
}
});
});
};
В приведенном выше коде я отправляю запрос ajax на WorkItems # update ,Everythign работает.Заполненное поле обновляется с true или false в зависимости от complete param , который я отправляю Вот мой контроллер:
class WorkItemsController < ApplicationController
before_action :redirect_if_not_logged_in
def update
work_item = WorkItem.find(params[:id])
data = params[:complete]
message = "The work item has been marked as "
respond_to do |format|
format.js do
if data == 'true'
message += "completed"
work_item.update_column(:completed, true)
else
message += "incomplete"
work_item.update_column(:completed, false)
end
end
end
flash[:notice] = message
redirect_to login_path
end
Теперь, когда я тестирую в Rspec,У меня проблема с перенаправлением к корневой спецификации:
require 'rails_helper'
describe WorkItemsController do
describe "#update", js: true do
let(:work_item) { Fabricate(:work_item) }
before(:each) { set_current_user }
it_behaves_like "require_sign_in" do
let(:action) { put :update, params: {id: work_item.id} }
end
context "mark item as complete" do
before(:each) do
put :update, params: {id: work_item.id, complete: 'true'}, format: 'js'
end
it "redirects to the root" do
put :update, params: {id: work_item.id, complete: 'true'}, format: 'html'
expect(response).to redirect_to login_path
end
it "creates flash notice" do
expect(flash[:notice]).to be_present
end
it "marks the work item as completed"
end
end
end
Когда я запускаю тест, я получаю ошибку для этой спецификации.Он говорит:
Expected response to be a <200: ok>, but was a <302: Found> redirect to <http://test.host/login>
Response body: <html><body>You are being <a href="http://test.host/login">redirected</a>.</body></html>.
Expected: 200
Actual: 302
Когда я удаляю блок JS, тест, конечно, пройдет, так что я предполагаю, что это как-то связано с тем, что это AJAX-запрос.Несмотря на то, что я указал, что тест ожидает перенаправления, он все равно говорит, что ожидает перенаправления с кодом ответа 200.