398 lines
14 KiB
Ruby
398 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
|