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

455 lines
17 KiB
Ruby

require "spec_helper"
describe ChallengeAssignmentsController do
include LoginMacros
include RedirectExpectationHelper
let(:gift_exchange) { create(:gift_exchange) }
let(:collection) { create(:collection, challenge: gift_exchange) }
let(:assignment) do
create(:challenge_assignment,
collection_id: collection.id,
sent_at: gift_exchange.assignments_sent_at)
end
let(:assignment_owner) { assignment.offering_user }
let(:collection_owner) { collection.owners.first.user }
let(:other_user) { create(:user) }
before { fake_login_known_user(user) }
describe "default" do
let(:gift_exchange) { create(:gift_exchange, assignments_sent_at: Faker::Time.backward) }
context "when logged in as the owner of the collection" do
let(:user) { collection_owner }
it "doesn't default the assignment, and redirects with an error" do
get :default, params: { collection_id: collection.name, id: assignment.id }
it_redirects_to_with_error(root_path, "You aren't the owner of that assignment.")
expect(assignment.reload.defaulted_at).to be_nil
end
end
context "when logged in as the owner of the assignment" do
let(:user) { assignment_owner }
it "defaults and redirects to the current user's assignments path" do
get :default, params: { collection_id: collection.name, id: assignment.id }
it_redirects_to_with_notice(user_assignments_path(user),
"We have notified the collection maintainers that you had to default on your assignment.")
expect(assignment.reload.defaulted_at).not_to be_nil
end
context "when assignments have not been sent" do
let(:gift_exchange) { create(:gift_exchange, assignments_sent_at: nil) }
it "doesn't default the assignment, and redirects with an error" do
get :default, params: { collection_id: collection.name, id: assignment.id }
it_redirects_to_with_error(collection_path(collection),
"Assignments have not been sent! You might want matching instead.")
expect(assignment.reload.defaulted_at).to be_nil
end
end
context "when the assignment doesn't exist" do
it "causes a 404 error" do
expect do
get :default, params: { collection_id: collection.name, id: -1 }
end.to raise_exception(ActiveRecord::RecordNotFound)
end
end
context "when the assignment is from another collection" do
let(:other_assignment) { create(:challenge_assignment) }
it "causes a 404 error" do
expect do
get :default, params: { collection_id: collection.name, id: other_assignment.id }
end.to raise_exception(ActiveRecord::RecordNotFound)
end
end
context "when the collection doesn't exist" do
it "redirects with an error" do
get :default, params: { collection_id: "--MISSING--", id: assignment.id }
it_redirects_to_with_error(root_path,
"What challenge did you want to work with?")
end
end
context "when the collection is not a challenge" do
let(:collection) { create(:collection) }
it "redirects with an error" do
get :default, params: { collection_id: collection.name, id: assignment.id }
it_redirects_to_with_error(collection_path(collection),
"What challenge did you want to work with?")
end
end
end
context "when logged in as a random user" do
let(:user) { other_user }
it "doesn't default the assignment, and redirects with an error" do
get :default, params: { collection_id: collection.name, id: assignment.id }
it_redirects_to_with_error(root_path, "You aren't the owner of that assignment.")
expect(assignment.reload.defaulted_at).to be_nil
end
end
end
describe "set" do
let(:signup1) { create(:challenge_signup, collection: assignment.collection) }
let(:signup2) { create(:challenge_signup, collection: assignment.collection) }
let(:params) do
{
collection_id: collection.name,
challenge_assignments: {
assignment.id => {
request_signup_pseud: signup1.pseud.byline,
offer_signup_pseud: signup2.pseud.byline
}
}
}
end
context "when logged in as the collection maintainer" do
let(:user) { collection_owner }
it "successfully updates the assignment" do
PotentialMatch.create(request_signup: signup1,
offer_signup: signup2,
collection: collection)
put :set, params: params
expect { assignment.reload }.to \
change { assignment.request_signup_id }.to(signup1.id).and \
change { assignment.offer_signup_id }.to(signup2.id)
it_redirects_to_with_notice(collection_potential_matches_path(collection),
"Assignments updated")
end
context "when there is no potential match" do
it "doesn't update the assignment, and renders the potential matches index" do
put :set, params: params
expect { assignment.reload }.not_to \
change { [assignment.request_signup_id, assignment.offer_signup_id] }
expect(flash[:error]).to eq("These assignments could not be saved because the two participants do not match. Did you mean to write in a giver?")
expect(assigns[:assignments]).to include(assignment)
expect(response).to render_template("potential_matches/index")
end
end
context "when assignments have been sent" do
let(:gift_exchange) { create(:gift_exchange, assignments_sent_at: Faker::Time.backward) }
it "doesn't update the assignment, and redirects with an error" do
put :set, params: params
expect { assignment.reload }.not_to \
change { [assignment.request_signup_id, assignment.offer_signup_id] }
it_redirects_to_with_error(collection_assignments_path(collection),
"Assignments have already been sent! If necessary, you can purge them.")
end
end
context "when the assignment is from another collection" do
let(:other_collection) { create(:collection, challenge: create(:gift_exchange)) }
let(:assignment) do
create(:challenge_assignment,
collection: other_collection,
sent_at: Faker::Time.backward)
end
it "silently ignores the assignment" do
put :set, params: params
expect { assignment.reload }.not_to \
change { [assignment.request_signup_id, assignment.offer_signup_id] }
it_redirects_to_with_notice(collection_potential_matches_path(collection),
"Assignments updated")
end
end
end
context "when logged in as a random user" do
let(:user) { other_user }
it "doesn't update the assignment, and redirects with an error" do
put :set, params: params
expect { assignment.reload }.not_to \
change { [assignment.request_signup_id, assignment.offer_signup_id] }
it_redirects_to_with_error(user_path(user),
"Sorry, you don't have permission to access the page you were trying to reach.")
end
end
end
describe "update_multiple" do
let(:gift_exchange) { create(:gift_exchange, assignments_sent_at: Faker::Time.backward) }
context "when logged in as the collection maintainer" do
let(:user) { collection_owner }
context "defaulting" do
let(:params) do
{
collection_id: collection.name,
"default_#{assignment.id}" => true
}
end
it "marks the assignment as defaulted" do
put :update_multiple, params: params
it_redirects_to_with_notice(collection_assignments_path(collection),
"Assignment updates complete!")
assignment.reload
expect(assignment.defaulted_at).not_to be_nil
end
context "when the assignment is from another collection" do
let(:other_collection) { create(:collection, challenge: create(:gift_exchange)) }
let(:assignment) do
create(:challenge_assignment,
collection: other_collection,
sent_at: Faker::Time.backward)
end
it "doesn't mark the assignment as defaulted, and redirects with an error" do
put :update_multiple, params: params
it_redirects_to_with_error(collection_assignments_path(collection),
["Couldn't find assignment with id #{assignment.id}!"])
assignment.reload
expect(assignment.defaulted_at).to be_nil
end
end
end
context "undefaulting" do
let(:params) do
{
collection_id: collection.name,
"undefault_#{assignment.id}" => true
}
end
before { assignment.update!(defaulted_at: Faker::Time.backward) }
it "marks the assignment as undefaulted" do
put :update_multiple, params: params
it_redirects_to_with_notice(collection_assignments_path(collection),
"Assignment updates complete!")
assignment.reload
expect(assignment.defaulted_at).to be_nil
end
end
context "approving" do
let(:params) do
{
collection_id: collection.name,
"approve_#{assignment.id}" => true
}
end
let(:work) do
create(:work, challenge_assignments: [assignment],
collections: [collection])
end
let(:collection_item) { work.collection_items.find_by(collection: collection) }
before do
collection_item.update!(collection_approval_status: CollectionItem::NEUTRAL)
end
it "marks the collection item as approved", pending: "AO3-6106" do
put :update_multiple, params: params
it_redirects_to_with_notice(collection_assignments_path(collection),
"Assignment updates complete!")
collection_item.reload
expect(collection_item.collection_approval_status).to eq(CollectionItem::APPROVED)
end
end
context "covering" do
let(:pinch_hitter) { create(:pseud) }
let(:params) do
{
collection_id: collection.name,
"cover_#{assignment.id}" => pinch_hitter.byline
}
end
before { assignment.update!(defaulted_at: Faker::Time.backward) }
it "marks the assignment as undefaulted" do
expect do
put :update_multiple, params: params
end.to change { ChallengeAssignment.count }.by(1)
it_redirects_to_with_notice(collection_assignments_path(collection),
"Assignment updates complete!")
assignment.reload
expect(assignment.covered_at).not_to be_nil
expect(collection.assignments.find_by(pinch_hitter: pinch_hitter)).not_to be_nil
end
end
end
end
describe "show" do
shared_examples "allowed to see assignment" do
it "shows the assignment" do
get :show, params: { id: assignment.id, collection_id: collection.name }
expect(response).to have_http_status(:success)
expect(response).to render_template :show
end
context "when the assignment is defaulted" do
before { assignment.update_attribute(:defaulted_at, Faker::Time.backward) }
it "shows a message" do
get :show, params: { id: assignment.id, collection_id: collection.name }
expect(flash[:notice]).to eq("This assignment has been defaulted-on.")
end
end
context "when the assignment is from a different collection" do
let(:assignment) { create(:challenge_assignment) }
it "causes a 404 error" do
expect do
get :show, params: { id: assignment.id, collection_id: collection.name }
end.to raise_exception(ActiveRecord::RecordNotFound)
end
end
end
context "when logged in as the owner of the assignment" do
let(:user) { assignment_owner }
include_examples "allowed to see assignment"
end
context "when logged in as a moderator of the collection" do
let(:user) { collection_owner }
include_examples "allowed to see assignment"
end
context "when logged in as a random user" do
let(:user) { other_user }
it "doesn't show the assignment" do
get :show, params: { id: assignment.id, collection_id: collection.name }
it_redirects_to_with_error(root_path, "You aren't allowed to see that assignment!")
end
end
end
describe "index" do
let(:gift_exchange) { create(:gift_exchange, assignments_sent_at: Faker::Time.backward) }
let!(:open_assignment) do
create(:challenge_assignment,
collection_id: collection.id,
sent_at: gift_exchange.assignments_sent_at)
end
let!(:defaulted_assignment) do
create(:challenge_assignment,
collection_id: collection.id,
sent_at: gift_exchange.assignments_sent_at,
defaulted_at: Faker::Time.backward)
end
context "when logged in as a maintainer of the collection", work_search: true, bookmark_search: true do
render_views
let(:user) { collection_owner }
it "shows defaulted assignments within a collection" do
get :index, params: { collection_id: collection.name }
expect(response).to have_http_status(:success)
expect(response.body).to include "Assignments for"
expect(response.body).to include collection.title
expect(response.body).to include defaulted_assignment.request_byline
expect(response.body).not_to include "No assignments to review!"
end
it "shows unfulfilled assignments within a collection" do
get :index, params: { collection_id: collection.name, unfulfilled: true }
expect(response).to have_http_status(:success)
expect(response.body).to include "Assignments for"
expect(response.body).to include collection.title
expect(response.body).to include open_assignment.request_byline
expect(response.body).not_to include "No assignments to review!"
end
end
context "when logged in as the owner of an open assignment" do
let(:user) { open_assignment.offering_user }
it "lists the assignment" do
get :index, params: { collection_id: collection.name, user_id: user.login }
expect(response).to have_http_status(:success)
expect(assigns[:challenge_assignments]).to include(open_assignment)
expect(assigns[:challenge_assignments]).not_to include(defaulted_assignment)
expect(response).to render_template(:index)
end
end
context "when logged in as the owner of a defaulted assignment" do
let(:user) { defaulted_assignment.offering_user }
it "doesn't list the assignment" do
get :index, params: { collection_id: collection.name, user_id: user.login }
expect(response).to have_http_status(:success)
expect(assigns[:challenge_assignments]).not_to include(defaulted_assignment)
expect(assigns[:challenge_assignments]).not_to include(open_assignment)
expect(response).to render_template(:index)
end
end
context "when logged in as a random user" do
let(:user) { other_user }
it "doesn't show any assignments" do
get :index, params: { collection_id: collection.name, user_id: user.login }
expect(response).to have_http_status(:success)
expect(assigns[:challenge_assignments]).not_to include(defaulted_assignment)
expect(assigns[:challenge_assignments]).not_to include(open_assignment)
expect(response).to render_template(:index)
end
context "when trying to access another user's assignments" do
it "redirects with an error" do
get :index, params: { collection_id: collection.name, user_id: open_assignment.offering_user.login }
it_redirects_to_with_error(root_path,
"You aren't allowed to see that user's assignments.")
end
end
context "when trying to access a non-existent user's assignments" do
it "redirects with an error" do
get :index, params: { collection_id: collection.name, user_id: "--MISSING--" }
it_redirects_to_with_error(user_path(user),
"Sorry, you don't have permission to access the page you were trying to reach.")
end
end
end
end
end