otwarchive-symphonyarchive/spec/controllers/external_authors_controller_spec.rb

415 lines
16 KiB
Ruby
Raw Normal View History

2026-03-11 22:22:11 +00:00
# frozen_string_literal: true
require 'spec_helper'
describe ExternalAuthorsController do
include LoginMacros
include RedirectExpectationHelper
let(:user) { create(:user) }
let(:invitation) { create(:invitation, external_author: external_author) }
let(:external_author) { create(:external_author) }
before(:each) do
fake_login_known_user(user)
end
describe "GET #claim" do
context "with invalid invitation token" do
it "redirects with an error" do
get :claim, params: { invitation_token: "None existent" }
it_redirects_to_with_error(root_path, "You need an invitation to do that.")
end
end
context "with valid invitation token" do
it "assigns invitation" do
get :claim, params: { invitation_token: invitation.token }
expect(assigns(:invitation)).to eq(invitation)
assert_equal response.status, 200
end
end
context "without works to claim" do
it "redirects with an error" do
no_story_invitation = create(:invitation)
get :claim, params: { invitation_token: no_story_invitation.token }
it_redirects_to_with_error(signup_path(no_story_invitation.token), "There are no stories to claim on this invitation. Did you want to sign up instead?")
end
end
end
describe "GET #complete_claim" do
it "redirects with a success message" do
expect(external_author.user).to be_nil
expect(external_author.claimed?).to be_falsy
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).to be_nil
get :complete_claim, params: { invitation_token: invitation.token }
it_redirects_to_with_notice(user_external_authors_path(user), "We have added the stories imported under #{external_author.email} to your account.")
external_author.reload
expect(external_author.user).to eq(user)
expect(external_author.claimed?).to be_truthy
invitation.reload
expect(invitation.invitee).to eq(user)
expect(invitation.redeemed_at).not_to be_nil
end
end
describe "PUT #update" do
it "redirects with an error if the user does not have permission" do
wrong_external_author = create(:external_author)
someone_elses_invitation = create(:invitation, external_author: wrong_external_author)
put :update, params: { invitation_token: someone_elses_invitation.token, id: external_author.id }
it_redirects_to_with_error(root_path, "You don't have permission to do that.")
end
context "when the logged in user is the external author" do
before(:each) do
external_author.claim!(user)
end
context "when not modifying preferences" do
context "when doing nothing with imported works" do
it "redirects with a success message" do
parameters = {
user_id: user.login,
id: external_author.id,
imported_stories: "nothing",
external_author: {
do_not_email: external_author.do_not_email,
do_not_import: external_author.do_not_import
}
}
put :update, params: parameters
it_redirects_to_with_notice(user_external_authors_path(user), "Okay, we'll leave things the way they are! You can use the email link any time if you change your mind. Your preferences have been saved.")
end
end
context "when orphaning imported works" do
it "redirects with a success message" do
parameters = {
user_id: user.login,
id: external_author.id,
imported_stories: "orphan",
external_author: {
do_not_email: external_author.do_not_email,
do_not_import: external_author.do_not_import
}
}
put :update, params: parameters
it_redirects_to_with_notice(user_external_authors_path(user), "Your imported stories have been orphaned. Thank you for leaving them in the archive! Your preferences have been saved.")
end
end
context "when deleting imported works" do
it "redirects with a success message" do
parameters = {
user_id: user.login,
id: external_author.id,
imported_stories: "delete",
external_author: {
do_not_email: external_author.do_not_email,
do_not_import: external_author.do_not_import
}
}
put :update, params: parameters
it_redirects_to_with_notice(user_external_authors_path(user), "Your imported stories have been deleted. Your preferences have been saved.")
end
end
end
context "when successfully updating preferences" do
it "saves preferences and redirects with a success message" do
parameters = {
user_id: user.login,
id: external_author.id,
external_author: {
do_not_email: 1,
do_not_import: 1
}
}
put :update, params: parameters
it_redirects_to_with_notice(user_external_authors_path(user), "Your preferences have been saved.")
external_author.reload
expect(external_author.do_not_email).to be_truthy
expect(external_author.do_not_import).to be_truthy
end
end
context "when unsuccessfully updating preferences" do
it "renders edit template with an error" do
parameters = {
user_id: user.login,
id: external_author.id,
external_author: {
do_not_email: true,
do_not_import: true
}
}
allow_any_instance_of(ExternalAuthor).to receive(:update).and_return(false)
put :update, params: parameters
expect(response).to render_template :edit
expect(flash[:error]).to eq "There were problems saving your preferences."
end
end
end
context "when the user has permission through an invitation" do
context "when not modifying preferences" do
context "when doing nothing with imported works" do
it "does not mark invitation redeemed and redirects with a success message" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "nothing",
external_author: {
do_not_email: external_author.do_not_email,
do_not_import: external_author.do_not_import
}
}
put :update, params: parameters
it_redirects_to_with_notice(root_path, "Okay, we'll leave things the way they are! You can use the email link any time if you change your mind. Your preferences have been saved.")
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).to be_nil
end
end
context "when successfully updating preferences" do
it "does not mark invitation redeemed, saves preferences, and redirects with a success message" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "nothing",
external_author: {
do_not_email: 1,
do_not_import: 1
}
}
put :update, params: parameters
it_redirects_to_with_notice(root_path, "Okay, we'll leave things the way they are! You can use the email link any time if you change your mind. Your preferences have been saved.")
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).to be_nil
external_author.reload
expect(external_author.do_not_email).to be_truthy
expect(external_author.do_not_import).to be_truthy
end
end
context "when unsuccessfully updating preferences" do
it "does not mark invitation redeemed and renders edit template with a success message for doing nothing and an error for preferences" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "nothing",
external_author: {
do_not_email: 1,
do_not_import: 1
}
}
allow_any_instance_of(ExternalAuthor).to receive(:update).and_return(false)
put :update, params: parameters
expect(response).to render_template :edit
expect(flash[:notice]).to eq "Okay, we'll leave things the way they are! You can use the email link any time if you change your mind. "
expect(flash[:error]).to eq "There were problems saving your preferences."
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).to be_nil
end
end
end
context "when orphaning imported works" do
context "when not modifying preferences" do
it "marks invitation redeemed and redirects with a success message" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "orphan",
external_author: {
do_not_email: external_author.do_not_email,
do_not_import: external_author.do_not_import
}
}
put :update, params: parameters
it_redirects_to_with_notice(root_path, "Your imported stories have been orphaned. Thank you for leaving them in the archive! Your preferences have been saved.")
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).not_to be_nil
end
end
context "when successfully updating preferences" do
it "marks invitation redeemed, saves preferences, and redirects with a success message" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "orphan",
external_author: {
do_not_email: true,
do_not_import: true
}
}
put :update, params: parameters
it_redirects_to_with_notice(root_path, "Your imported stories have been orphaned. Thank you for leaving them in the archive! Your preferences have been saved.")
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).not_to be_nil
external_author.reload
expect(external_author.do_not_email).to be_truthy
expect(external_author.do_not_import).to be_truthy
end
end
context "when unsuccessfully updating preferences" do
it "marks invitation redeemed and renders edit template with a success message for orphaning and an error for preferences" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "orphan",
external_author: { do_not_email: true }
}
allow_any_instance_of(ExternalAuthor).to receive(:update).and_return(false)
put :update, params: parameters
expect(response).to render_template :edit
expect(flash[:notice]).to eq "Your imported stories have been orphaned. Thank you for leaving them in the archive! "
expect(flash[:error]).to eq "There were problems saving your preferences."
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).not_to be_nil
end
end
end
context "when deleting imported works" do
context "when not modifying preferences" do
it "marks invitation redeemed and redirects with a success message" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "delete",
external_author: {
do_not_email: external_author.do_not_email,
do_not_import: external_author.do_not_import
}
}
put :update, params: parameters
it_redirects_to_with_notice(root_path, "Your imported stories have been deleted. Your preferences have been saved.")
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).not_to be_nil
end
end
context "when successfully updating preferences" do
it "marks invitation redeemed, saves preferences, and redirects with a success message" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "delete",
external_author: {
do_not_email: true,
do_not_import: true
}
}
put :update, params: parameters
it_redirects_to_with_notice(root_path, "Your imported stories have been deleted. Your preferences have been saved.")
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).not_to be_nil
external_author.reload
expect(external_author.do_not_email).to be_truthy
expect(external_author.do_not_import).to be_truthy
end
end
context "when unsuccessfully updating preferences" do
it "marks invitation redeemed and renders edit template with a success message for deleting and an error for preferences" do
parameters = {
invitation_token: invitation.token,
id: external_author.id,
imported_stories: "delete",
external_author: {
do_not_email: true
}
}
allow_any_instance_of(ExternalAuthor).to receive(:update).and_return(false)
put :update, params: parameters
expect(response).to render_template :edit
expect(flash[:notice]).to eq "Your imported stories have been deleted. "
expect(flash[:error]).to eq "There were problems saving your preferences."
invitation.reload
expect(invitation.invitee).to be_nil
expect(invitation.redeemed_at).not_to be_nil
end
end
end
end
end
describe "GET #edit" do
it "assigns external_author" do
get :edit, params: { id: external_author.id, user_id: user.login }
expect(assigns(:external_author)).to eq(external_author)
end
end
describe "GET #index" do
context "when logged out" do
before(:each) do
fake_logout
end
it "redirects with notice" do
get :index
it_redirects_to_with_notice(root_path, "You can't see that information.")
end
end
context "when logged in as user" do
context "without archivist permissions" do
it "assigns external_authors" do
external_author.claim!(user)
get :index, params: { user_id: user.login }
expect(assigns(:external_authors)).to eq([external_author])
end
it "redirects" do
get :index
it_redirects_to(user_external_authors_path(user))
end
end
end
context "with archivist permissions" do
before(:each) do
allow_any_instance_of(User).to receive(:is_archivist?).and_return(true)
end
it "assigns external_authors and renders index" do
get :index
expect(assigns(:external_authors)).to eq([])
expect(response).to render_template :index
end
end
end
end