diff --git a/app/controllers/case_contacts_controller.rb b/app/controllers/case_contacts_controller.rb index cb350158eb..2265f1326b 100644 --- a/app/controllers/case_contacts_controller.rb +++ b/app/controllers/case_contacts_controller.rb @@ -20,11 +20,20 @@ def index ) || return @pagy, @filtered_case_contacts = pagy(@filterrific.find) - case_contacts = CaseContact.case_hash_from_cases(@filtered_case_contacts) - case_contacts = case_contacts.select { |k, _v| current_user.casa_cases.pluck(:id).include?(k) } if current_user.volunteer? - case_contacts = case_contacts.select { |k, _v| k == params[:casa_case_id].to_i } if params[:casa_case_id].present? + + casa_case_id_to_case_contacts = CaseContact.case_hash_from_cases(@filtered_case_contacts) + binding.pry + if params[:casa_case_id].present? + binding.pry + casa_case_id_to_case_contacts = casa_case_id_to_case_contacts.select { |k, _v| k == params[:casa_case_id].to_i } + end + if current_user.volunteer? + binding.pry + current_user_casa_case_ids = current_user.casa_cases.pluck(:id) + casa_case_id_to_case_contacts = casa_case_id_to_case_contacts.select { |case_contact_id, _cases| current_user_casa_case_ids.include?(case_contact_id) } + end - @presenter = CaseContactPresenter.new(case_contacts) + @presenter = CaseContactPresenter.new(casa_case_id_to_case_contacts) end def drafts diff --git a/spec/controllers/case_contacts_controller_spec.rb b/spec/controllers/case_contacts_controller_spec.rb new file mode 100644 index 0000000000..ddf16058ba --- /dev/null +++ b/spec/controllers/case_contacts_controller_spec.rb @@ -0,0 +1,43 @@ +require "rails_helper" + +RSpec.describe CaseContactsController, type: :controller do + describe "GET #index" do + # Create test data in before block to keep tests DRY + before do + sign_in user + + @casa_case1 = create(:casa_case) + @casa_case2 = create(:casa_case) + + @contact1 = create(:case_contact, casa_case: @casa_case1) + @contact2 = create(:case_contact, casa_case: @casa_case1) + @contact3 = create(:case_contact, casa_case: @casa_case2) + end + + context "when casa_case_id param is present" do + it "filters case contacts for the specified casa case" do + get :index, params: { casa_case_id: @casa_case1.id } + + # Access the instance variable that was set in the controller + case_contacts_hash = assigns(:casa_case_id_to_case_contacts) + + # Should only include contacts from casa_case1 + expect(case_contacts_hash.keys).to contain_exactly(@casa_case1.id) + expect(case_contacts_hash[@casa_case1.id]).to contain_exactly(@contact1, @contact2) + end + end + + context "when casa_case_id param is not present" do + it "includes case contacts for all casa cases" do + get :index + + case_contacts_hash = assigns(:casa_case_id_to_case_contacts) + + # Should include contacts from both cases + expect(case_contacts_hash.keys).to contain_exactly(@casa_case1.id, @casa_case2.id) + expect(case_contacts_hash[@casa_case1.id]).to contain_exactly(@contact1, @contact2) + expect(case_contacts_hash[@casa_case2.id]).to contain_exactly(@contact3) + end + end + end +end \ No newline at end of file diff --git a/spec/models/case_contact_spec.rb b/spec/models/case_contact_spec.rb index 2f9e6118bc..8f3e9dac62 100644 --- a/spec/models/case_contact_spec.rb +++ b/spec/models/case_contact_spec.rb @@ -656,4 +656,32 @@ end end end + + describe '.case_hash_from_cases' do + it 'returns a hash mapping casa case ids to their case contacts' do + # Create test data + casa_case1 = create(:casa_case) + casa_case2 = create(:casa_case) + + contact1 = create(:case_contact, casa_case: casa_case1) + contact2 = create(:case_contact, casa_case: casa_case1) + contact3 = create(:case_contact, casa_case: casa_case2) + + contacts = [contact1, contact2, contact3] + + # Call the method + result = described_class.case_hash_from_cases(contacts) + + # Verify the result + expect(result).to eq({ + casa_case1.id => [contact1, contact2], + casa_case2.id => [contact3] + }) + end + + it 'returns empty hash for empty contacts' do + result = described_class.case_hash_from_cases([]) + expect(result).to eq({}) + end + end end diff --git a/spec/requests/casa_cases_spec.rb b/spec/requests/casa_cases_spec.rb index 858c2a3c33..cc3846f118 100644 --- a/spec/requests/casa_cases_spec.rb +++ b/spec/requests/casa_cases_spec.rb @@ -1,5 +1,5 @@ require "rails_helper" - +# hi RSpec.describe "/casa_cases", type: :request do let(:date_in_care) { Date.today } let(:organization) { build(:casa_org) } @@ -611,9 +611,24 @@ end describe "GET /index" do - it "shows only cases assigned to user" do - mine = build(:casa_case, casa_org: organization, case_number: SecureRandom.hex(32)) - other = build(:casa_case, casa_org: organization, case_number: SecureRandom.hex(32)) + context "with casa_case_id" do + it "shows only cases assigned to user" do + mine = build(:casa_case, casa_org: organization, case_number: SecureRandom.hex(32)) + other = build(:casa_case, casa_org: organization, case_number: SecureRandom.hex(32)) + + user.casa_cases << mine + + get casa_cases_url(casa_case_id: mine.id) + + expect(response).to be_successful + expect(response.body).to include(mine.case_number) + expect(response.body).not_to include(other.case_number) + end + + context "without casa_case_id" do + it "shows only cases assigned to user" do + mine = build(:casa_case, casa_org: organization, case_number: SecureRandom.hex(32)) + other = build(:casa_case, casa_org: organization, case_number: SecureRandom.hex(32)) user.casa_cases << mine diff --git a/spec/requests/case_contacts_spec.rb b/spec/requests/case_contacts_spec.rb index 217040a4a0..4e9a899a79 100644 --- a/spec/requests/case_contacts_spec.rb +++ b/spec/requests/case_contacts_spec.rb @@ -1,9 +1,11 @@ require "rails_helper" - +# hi RSpec.describe "/case_contacts", type: :request do - let(:organization) { build(:casa_org) } + let(:organization) { create(:casa_org) } let(:admin) { create(:casa_admin, casa_org: organization) } let(:volunteer) { create(:volunteer, casa_org: organization) } + let(:supervisor) { create(:supervisor, casa_org: organization) } + let(:casa_case) { create(:casa_case, casa_org: organization) } before { sign_in admin } @@ -14,25 +16,36 @@ response end - let!(:casa_case) { create(:casa_case, casa_org: organization) } let!(:past_contact) { create(:case_contact, casa_case: casa_case, occurred_at: 3.weeks.ago) } let!(:recent_contact) { create(:case_contact, casa_case: casa_case, occurred_at: 3.days.ago) } let(:filterrific) { {} } it { is_expected.to have_http_status(:success) } - it "returns all case contacts" do - page = request.parsed_body.to_html - expect(page).to include(past_contact.creator.display_name, recent_contact.creator.display_name) - end - - context "with filters applied" do - let(:filterrific) { {occurred_starting_at: 1.week.ago} } - + context "when logged in as an admin" do it "returns all case contacts" do page = request.parsed_body.to_html - expect(page).to include(recent_contact.creator.display_name) - expect(page).not_to include(past_contact.creator.display_name) + expect(page).to include(past_contact.creator.display_name, recent_contact.creator.display_name) + end + + context "with filters applied" do + let(:filterrific) { {occurred_starting_at: 1.week.ago} } + + it "returns filtered case contacts" do + page = request.parsed_body.to_html + expect(page).to include(recent_contact.creator.display_name) + expect(page).not_to include(past_contact.creator.display_name) + end + end + + context "with sorting" do + let(:filterrific) { {sorted_by: "occurred_at_desc"} } + + it "returns sorted case contacts" do + page = request.parsed_body.to_html + expect(page).to include(recent_contact.creator.display_name) + expect(page).to include(past_contact.creator.display_name) + end end end @@ -41,14 +54,24 @@ let(:unassigned_case) { casa_case } let(:volunteer) { assigned_case.assigned_volunteers.first } let!(:assigned_case_contact) { create(:case_contact, casa_case: assigned_case, creator: volunteer) } - let!(:unassigned_case_contact) { create(:case_contact, casa_case: unassigned_case, creator: volunteer, duration_minutes: 180) } + let!(:unassigned_case_contact) { create(:case_contact, casa_case: unassigned_case, creator: volunteer) } before { sign_in volunteer } it "returns only currently assigned cases" do page = request.parsed_body.to_html - expect(page).to include("60 minutes") - expect(page).not_to include("3 hours") + binding.pry + expect(page).to include(assigned_case_contact.creator.display_name) + expect(page).not_to include(unassigned_case_contact.creator.display_name) + end + end + + context "when logged in as a supervisor" do + before { sign_in supervisor } + + it "returns all case contacts" do + page = request.parsed_body.to_html + expect(page).to include(past_contact.creator.display_name, recent_contact.creator.display_name) end end end @@ -83,6 +106,15 @@ expect(CaseContact.started.last.contact_topic_answers).to be_empty end end + + context "with draft case ids" do + let(:draft_case_ids) { [casa_case.id] } + + it "creates case contact with draft case ids" do + get new_case_contact_path(draft_case_ids: draft_case_ids) + expect(CaseContact.last.draft_case_ids).to eq(draft_case_ids) + end + end end describe "GET /edit" do @@ -100,6 +132,16 @@ request expect(response).to redirect_to(case_contact_form_path(:details, case_contact_id: case_contact.id)) end + + context "when user is not authorized" do + let(:unauthorized_volunteer) { create(:volunteer, casa_org: organization) } + before { sign_in unauthorized_volunteer } + + it "redirects to root path" do + request + expect(response).to redirect_to(authenticated_user_root_path) + end + end end describe "GET /drafts" do @@ -109,8 +151,17 @@ response end + let!(:draft_contact) { create(:case_contact, status: "started") } + let!(:active_contact) { create(:case_contact, status: "active") } + it { is_expected.to have_http_status(:success) } + it "returns only draft contacts" do + page = request.parsed_body.to_html + expect(page).to include(draft_contact.creator.display_name) + expect(page).not_to include(active_contact.creator.display_name) + end + context "when user is volunteer" do before { sign_in volunteer } @@ -137,9 +188,19 @@ it "soft deletes the case_contact" do expect { request }.to change { case_contact.reload.deleted? }.from(false).to(true) end + + context "when user is not authorized" do + let(:unauthorized_volunteer) { create(:volunteer, casa_org: organization) } + before { sign_in unauthorized_volunteer } + + it "redirects to root path" do + request + expect(response).to redirect_to(authenticated_user_root_path) + end + end end - describe "GET /restore" do + describe "POST /restore" do subject(:request) do post restore_case_contact_path(case_contact), headers: {HTTP_REFERER: case_contacts_path} @@ -157,9 +218,19 @@ expect(flash[:notice]).to eq("Contact is successfully restored.") end - it "soft deletes the case_contact" do + it "restores the case_contact" do expect { request }.to change { case_contact.reload.deleted? }.from(true).to(false) end + + context "when user is not authorized" do + let(:unauthorized_volunteer) { create(:volunteer, casa_org: organization) } + before { sign_in unauthorized_volunteer } + + it "redirects to root path" do + request + expect(response).to redirect_to(authenticated_user_root_path) + end + end end xdescribe "GET /leave" do