otwarchive-symphonyarchive/spec/controllers/works/drafts_spec.rb
2026-03-11 22:22:11 +00:00

153 lines
6 KiB
Ruby

# frozen_string_literal: true
require "spec_helper"
describe WorksController do
include LoginMacros
include RedirectExpectationHelper
let(:drafts_user_pseud) { create(:pseud, name: "Visiting User Pseud") }
let(:drafts_user) do
user = create(:user)
user.pseuds << drafts_user_pseud
user
end
let!(:default_pseud_work) do
create(:draft, authors: [drafts_user.default_pseud], title: "Default pseud work")
end
let!(:other_pseud_work) do
create(:draft, authors: [drafts_user_pseud], title: "Other pseud work")
end
describe "drafts" do
context "when no user_id is specified" do
it "redirects to the user controller and display an appropriate error message" do
get :drafts
it_redirects_to_with_error(users_path, "Whose drafts did you want to look at?")
end
end
context "when logged out" do
before { fake_logout }
it "redirects to the login page and displays a error message" do
get :drafts, params: { user_id: drafts_user.login }
it_redirects_to_with_error(new_user_session_path,
"You can only see your own drafts, sorry!")
end
end
context "when logged in as an admin" do
before { fake_login_admin(create(:admin)) }
it "displays the drafts" do
get :drafts, params: { user_id: drafts_user.login }
expect(assigns[:works]).to contain_exactly(default_pseud_work,
other_pseud_work)
end
end
context "when logged in as the user with the desired user_id" do
before { fake_login_known_user(drafts_user) }
it "displays no errors" do
get :drafts, params: { user_id: drafts_user.login }
expect(response).to have_http_status(200)
expect(flash[:error]).to be_nil
end
it "displays all the user's drafts if no pseud_id is specified" do
get :drafts, params: { user_id: drafts_user.login }
expect(assigns(:works)).to include(other_pseud_work)
expect(assigns(:works)).to include(default_pseud_work)
end
it "displays only the drafts for a specific pseud if a pseud_id is specified" do
get :drafts, params: { user_id: drafts_user.login, pseud_id: drafts_user_pseud.name }
expect(assigns(:works)).to include(other_pseud_work)
expect(assigns(:works)).not_to include(default_pseud_work)
end
end
context "when logged in as another user" do
before { fake_login }
it "redirects to the current user's dashboard with an error message" do
get :drafts, params: { user_id: drafts_user.login }
it_redirects_to_with_error(user_path(controller.current_user),
"You can only see your own drafts, sorry!")
end
end
end
describe "post_draft" do
before do
fake_login_known_user(drafts_user)
end
it "should display an error if the current user is not the owner of the specified work" do
random_work = create(:draft)
put :post_draft, params: { id: random_work.id }
# There is code to return a different message in the action, but it is unreachable using a web request
# as the application_controller redirects the user first
it_redirects_to_with_error(work_path(random_work),
"Sorry, you don't have permission to access the page you were trying to reach.")
end
context "if the work is already posted" do
it "displays an error and redirects" do
drafts_user_work = create(:work, authors: [drafts_user.default_pseud])
put :post_draft, params: { id: drafts_user_work.id }
it_redirects_to_with_error(edit_user_work_path(drafts_user, drafts_user_work),
"That work is already posted. Do you want to edit it instead?")
end
end
it "should display an error and redirect if the work is invalid" do
drafts_user_work = create(:draft, authors: [drafts_user.default_pseud])
allow_any_instance_of(Work).to receive(:valid?).and_return(false)
put :post_draft, params: { id: drafts_user_work.id }
it_redirects_to_with_error(edit_user_work_path(drafts_user, drafts_user_work),
"There were problems posting your work.")
allow_any_instance_of(Work).to receive(:valid?).and_call_original
end
it "should display a notice message and redirect if the work is in a moderated collection" do
drafts_user_work = create(:draft, authors: [drafts_user.default_pseud])
draft_collection = create(:collection)
draft_collection.collection_preference.moderated = true
draft_collection.collection_preference.save
drafts_user_work.collections << draft_collection
controller.instance_variable_set("@collection", draft_collection)
put :post_draft, params: { id: drafts_user_work.id }
it_redirects_to_with_notice(work_path(drafts_user_work),
"Work was submitted to a moderated collection."\
" It will show up in the collection once approved.")
end
it "should post the draft if there is none of the aforementioned issues" do
draft = create(:draft, authors: [drafts_user.default_pseud])
put :post_draft, params: { id: draft.id }
it_redirects_to_with_notice(
work_path(draft),
"Your work was successfully posted."
)
end
it "should only count the words of the first, published, chapter after posting the draft" do
draft = create(:draft, authors: [drafts_user.default_pseud])
create(:chapter, :draft, work: draft)
draft.set_word_count
expect(draft.word_count).to eq(draft.chapters[0].word_count + draft.chapters[1].word_count)
put :post_draft, params: { id: draft.id }
it_redirects_to_with_notice(
work_path(draft),
"Your work was successfully posted."
)
expect(draft.reload.first_chapter.posted).to be true
expect(draft.word_count).to eq(draft.first_chapter.word_count)
end
end
end