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

397 lines
14 KiB
Ruby

require "spec_helper"
describe BookmarksController do
include LoginMacros
include RedirectExpectationHelper
def it_redirects_to_user_login
it_redirects_to_simple new_user_session_path
end
describe "new" do
context "without javascript" do
it "redirects logged out users" do
get :new
it_redirects_to_user_login
end
context "when logged in" do
it "renders the new form template" do
fake_login
get :new
expect(response).to render_template("new")
end
end
end
context "with javascript when logged in" do
it "renders the bookmark_form_dynamic form" do
fake_login
get :new, params: { format: :js }, xhr: true
expect(response).to render_template("bookmark_form_dynamic")
end
end
context "denies access for work that isn't visible to user" do
subject { get :new, params: { work_id: work } }
let(:success) { expect(response).to render_template("new") }
let(:success_admin) { it_redirects_to_with_error(new_user_session_path, "Sorry, you don't have permission to access the page you were trying to reach. Please log in.") }
include_examples "denies access for work that isn't visible to user"
end
end
describe "create" do
let(:work) { create(:work) }
context "when user is not logged in" do
it "redirects to login" do
post :create, params: { work_id: work.id }
it_redirects_to_user_login
end
end
context "when user is logged in" do
let(:user) { create(:user) }
let(:pseud) { user.default_pseud }
before do
fake_login_known_user(user)
end
context "when pseud doesn't belong to the user" do
let(:other_user) { create(:user) }
it "fails to bookmark the work" do
post :create, params: { work_id: work.id, bookmark: { pseud_id: other_user.default_pseud.id } }
it_redirects_to_with_error(root_path, "You can't bookmark with that pseud.")
end
end
context "when user never bookmarked the work before" do
shared_examples "all is correct" do
it "bookmarks successfully" do
post :create, params: { work_id: work.id, bookmark: { pseud_id: pseud.id } }
bookmark = assigns(:bookmark)
success_msg = "Bookmark was successfully created. It should appear in bookmark listings within the next few minutes."
it_redirects_to_with_notice(bookmark_path(bookmark), success_msg)
expect(bookmark.bookmarkable_id).to eq(work.id)
expect(bookmark.bookmarkable_type).to eq("Work")
expect(bookmark.pseud.id).to eq(pseud.id)
end
end
context "when user bookmarks a work" do
it_behaves_like "all is correct"
end
context "when user wants to bookmark a second work" do
let(:other_work) { create(:work) }
let!(:other_bookmark) { create(:bookmark, bookmarkable: other_work, pseud: pseud) }
it_behaves_like "all is correct"
end
context "when two users want to bookmark the same work" do
let(:other_user) { create(:user) }
let!(:other_bookmark) { create(:bookmark, bookmarkable: work, pseud: other_user.default_pseud) }
it_behaves_like "all is correct"
end
context "when user wants to bookmark a work with same id as bookmarked for other bookmarkable type" do
# no series created yet, all IDs are free
let(:series_with_same_id) { create(:series, id: work.id) }
let!(:series_bookmark) { create(:bookmark, bookmarkable: series_with_same_id, pseud: pseud) }
it_behaves_like "all is correct"
end
end
context "when user bookmarked the work before" do
shared_examples "work is already bookmarked by the user" do
it "fails to bookmark the work" do
post :create, params: { work_id: work.id, bookmark: { pseud_id: pseud.id } }
expect(response).to render_template("new")
expect(assigns(:bookmark).errors.full_messages).to include "You have already bookmarked that."
end
end
context "when user uses same pseud" do
let!(:old_bookmark) { create(:bookmark, bookmarkable: work, pseud: pseud) }
it_behaves_like "work is already bookmarked by the user"
end
context "when user uses different pseud" do
let(:other_pseud) { create(:pseud, user: user) }
let!(:old_bookmark) { create(:bookmark, bookmarkable: work, pseud: other_pseud) }
it_behaves_like "work is already bookmarked by the user"
end
end
context "as a tag wrangler" do
let(:user) { create(:tag_wrangler) }
let(:pseud) { user.default_pseud }
before { fake_login_known_user(user) }
it "does not set last wrangling activity when the bookmark has a new tag" do
bookmark_attributes = { pseud_id: pseud.id, tag_string: "My special new tag!" }
post :create, params: { work_id: work.id, bookmark: bookmark_attributes }
expect(user.last_wrangling_activity).to be_nil
end
end
end
end
describe "edit" do
context "with javascript" do
let(:bookmark) { create(:bookmark) }
it "renders the bookmark_form_dynamic form if logged in" do
fake_login_known_user(bookmark.pseud.user)
get :edit, params: { id: bookmark.id, format: :js }, xhr: true
expect(response).to render_template("bookmark_form_dynamic")
end
end
end
describe "update" do
context "when user updates old bookmarks created for the same bookmarkable (AO3-5565)" do
before do
# disable bookmarks validations to simulate previously created bookmarks
allow_any_instance_of(Bookmark).to receive(:validate).and_return(true)
allow_any_instance_of(Bookmark).to receive(:valid?).and_return(true)
fake_login_known_user(bookmark.pseud.user)
end
let(:user) { create(:user) }
let(:pseud) { user.default_pseud }
let(:other_pseud) { create(:pseud, user: user) }
let!(:bookmark) { create(:bookmark, pseud: pseud, bookmarker_notes: "My first Bookmark") }
let!(:bookmark2) { create(:bookmark, bookmarkable_id: bookmark.bookmarkable_id, pseud: other_pseud, bookmarker_notes: "My second Bookmark") }
it "first created bookmark can be updated" do
put :update, params: { bookmark: { bookmarker_notes: "Updated first bookmark", pseud_id: other_pseud.id }, id: bookmark.id }
it_redirects_to_with_notice(bookmark_path(bookmark), "Bookmark was successfully updated.")
expect(assigns(:bookmark).bookmarker_notes).to include("Updated first bookmark")
expect(assigns(:bookmark).pseud_id).to eq(other_pseud.id)
end
it "second created bookmark can be updated" do
put :update, params: { bookmark: { bookmarker_notes: "Updated second bookmark", pseud_id: other_pseud.id }, id: bookmark2.id }
it_redirects_to_with_notice(bookmark_path(bookmark2), "Bookmark was successfully updated.")
expect(assigns(:bookmark).bookmarker_notes).to include("Updated second bookmark")
expect(assigns(:bookmark).pseud_id).to eq(other_pseud.id)
end
end
end
describe "share" do
it "returns correct response for bookmark to revealed work" do
bookmark = create :bookmark
# Assert this bookmark is of an revealed work
expect(bookmark.bookmarkable.unrevealed?).to eq(false)
fake_login_known_user(bookmark.pseud.user)
get :share, params: { id: bookmark.id }, xhr: true
expect(response.status).to eq(200)
expect(response).to render_template("bookmarks/share")
end
it "returns a 404 response for bookmark to unrevealed work" do
unrevealed_collection = create :unrevealed_collection
unrevealed_work = create :work, collections: [unrevealed_collection]
unrevealed_bookmark = create :bookmark, bookmarkable_id: unrevealed_work.id
# Assert this bookmark is of an unrevealed work
expect(unrevealed_bookmark.bookmarkable.unrevealed?).to eq(true)
fake_login_known_user(unrevealed_bookmark.pseud.user)
get :share, params: { id: unrevealed_bookmark.id }, xhr: true
expect(response.status).to eq(404)
end
it "redirects to referer with an error for non-ajax warnings requests" do
bookmark = create(:bookmark)
fake_login_known_user(bookmark.pseud.user)
get :share, params: { id: bookmark.id }
it_redirects_to_with_error(root_path, "Sorry, you need to have JavaScript enabled for this.")
end
end
describe "index" do
let!(:external_work_bookmark) { create(:external_work_bookmark) }
let!(:series_bookmark) { create(:series_bookmark) }
let!(:work_bookmark) { create(:bookmark) }
context "with external_work_id parameters" do
it "loads the external work as the bookmarkable" do
params = { external_work_id: external_work_bookmark.bookmarkable.id }
get :index, params: params
expect(assigns(:bookmarkable)).to eq(external_work_bookmark.bookmarkable)
end
end
context "with user_id parameters" do
context "when user_id does not exist" do
it "raises a RecordNotFound error" do
params = { user_id: "nobody" }
expect { get :index, params: params }.to raise_error(
ActiveRecord::RecordNotFound,
"Couldn't find user named 'nobody'"
)
end
end
context "when user_id exists" do
context "when pseud_id does not exist" do
it "raises a RecordNotFound error for the pseud" do
params = { user_id: work_bookmark.pseud.user, pseud_id: "nobody" }
expect { get :index, params: params }.to raise_error(
ActiveRecord::RecordNotFound,
"Couldn't find pseud named 'nobody'"
)
end
end
end
end
context "with tag_id parameters" do
let(:tag) { create(:fandom) }
let(:merger) { create(:fandom, merger_id: canonical.id) }
let(:canonical) { create(:canonical_fandom) }
context "when tag_id does not exist" do
it "raises a RecordNotFound error" do
params = { tag_id: "nothingness" }
expect { get :index, params: params }.to raise_error(
ActiveRecord::RecordNotFound,
"Couldn't find tag named 'nothingness'"
)
end
end
context "when tag_id is not canonical" do
context "when tag_id is a synonym" do
it "redirects to the canonical's tag_bookmarks_path" do
params = { tag_id: merger }
get :index, params: params
expect(response).to redirect_to(tag_bookmarks_path(canonical))
end
end
context "when tag_id is not a synonym" do
it "redirects to tag_path" do
params = { tag_id: tag }
get :index, params: params
expect(response).to redirect_to(tag_path(tag))
end
end
end
end
context "without caching" do
before do
AdminSetting.first.update_attribute(:enable_test_caching, false)
end
it "returns work bookmarks" do
get :index
expect(assigns(:bookmarks)).to include(work_bookmark)
end
it "does not return external work bookmarks" do
get :index
expect(assigns(:bookmarks)).not_to include(external_work_bookmark)
end
it "does not return series bookmarks" do
get :index
expect(assigns(:bookmarks)).not_to include(series_bookmark)
end
it "returns the result with new bookmarks the second time" do
get :index
expect(assigns(:bookmarks)).to include(work_bookmark)
work_bookmark2 = create(:bookmark)
get :index
expect(assigns(:bookmarks)).to include(work_bookmark)
expect(assigns(:bookmarks)).to include(work_bookmark2)
end
end
context "with caching", bookmark_search: true do
before do
AdminSetting.first.update_attribute(:enable_test_caching, true)
run_all_indexing_jobs
end
it "returns work bookmarks" do
get :index
expect(assigns(:bookmarks)).to include(work_bookmark)
end
it "returns external work bookmarks" do
get :index
expect(assigns(:bookmarks)).to include(external_work_bookmark)
end
it "returns series bookmarks" do
get :index
expect(assigns(:bookmarks)).to include(series_bookmark)
end
it "returns the same result the second time when a new bookmark is created within the expiration time" do
get :index
expect(assigns(:bookmarks)).to include(external_work_bookmark)
expect(assigns(:bookmarks)).to include(series_bookmark)
expect(assigns(:bookmarks)).to include(work_bookmark)
work_bookmark2 = create(:bookmark)
run_all_indexing_jobs
get :index
expect(assigns(:bookmarks)).to include(external_work_bookmark)
expect(assigns(:bookmarks)).to include(series_bookmark)
expect(assigns(:bookmarks)).to include(work_bookmark)
expect(assigns(:bookmarks)).not_to include(work_bookmark2)
end
end
context "denies access for work that isn't visible to user" do
subject { get :index, params: { work_id: work } }
let(:success) { expect(response).to render_template("index") }
let(:success_admin) { success }
include_examples "denies access for work that isn't visible to user"
end
context "denies access for restricted work to guest" do
let(:work) { create(:work, restricted: true) }
it "redirects with an error" do
get :index, params: { work_id: work }
it_redirects_to_with_error(root_path, "Sorry, you don't have permission to access the page you were trying to reach. Please log in.")
end
end
end
describe "show" do
let(:chaptered_work) { create(:work, title: "Cool title") }
let(:chapter2) { create(:chapter, work: chaptered_work, position: 2, title: "Second title") }
let(:bookmark) { create(:bookmark, bookmarkable_id: chaptered_work.id) }
context "when logged in" do
it "returns a bookmark on a public multi-chapter work" do
fake_login_known_user(bookmark.pseud.user)
get :show, params: { id: bookmark }
expect(response).to have_http_status(:success)
expect(assigns(:bookmark)).to eq(bookmark)
end
end
end
end