Skip to content

Commit

Permalink
additional expenses and contact topic answer controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
thejonroberts committed Sep 25, 2024
1 parent 54064b6 commit fea791a
Show file tree
Hide file tree
Showing 12 changed files with 495 additions and 2 deletions.
32 changes: 32 additions & 0 deletions app/controllers/additional_expenses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class AdditionalExpensesController < ApplicationController
def create
@additional_expense = AdditionalExpense.new(additional_expense_params)
authorize @additional_expense

respond_to do |format|
if @additional_expense.save
format.json { render json: @additional_expense, status: :created }
else
format.json { render json: @additional_expense.errors, status: :unprocessable_entity }
end
end
end

def destroy
@additional_expense = AdditionalExpense.find(params[:id])
authorize @additional_expense

@additional_expense.destroy!

respond_to do |format|
format.json { head :no_content }
end
end

private

def additional_expense_params
params.require(:additional_expense)
.permit(:case_contact_id, :other_expense_amount, :other_expenses_describe)
end
end
32 changes: 32 additions & 0 deletions app/controllers/contact_topic_answers_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class ContactTopicAnswersController < ApplicationController
def create
@contact_topic_answer = ContactTopicAnswer.new(contact_topic_answer_params)
authorize @contact_topic_answer

respond_to do |format|
if @contact_topic_answer.save
format.json { render json: @contact_topic_answer, status: :created }
else
format.json { render json: @contact_topic_answer.errors, status: :unprocessable_entity }
end
end
end

def destroy
@contact_topic_answer = ContactTopicAnswer.find(params[:id])
authorize @contact_topic_answer

@contact_topic_answer.destroy!

respond_to do |format|
format.json { head :no_content }
end
end

private

def contact_topic_answer_params
params.require(:contact_topic_answer)
.permit(:id, :contact_topic_id, :case_contact_id, :value, :_destroy)
end
end
12 changes: 10 additions & 2 deletions app/models/additional_expense.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
class AdditionalExpense < ApplicationRecord
belongs_to :case_contact
has_one :casa_case, through: :case_contact
has_one :casa_org, through: :casa_case

# validates :other_expense_amount, presence: true
validates :other_expenses_describe, presence: {message: "Expense description cannot be blank."}
validates :other_expenses_describe, presence: true, if: :describe_required?

alias_attribute :amount, :other_expense_amount
alias_attribute :describe, :other_expenses_describe

def describe_required?
other_expense_amount&.positive?
end
end

# == Schema Information
Expand Down
3 changes: 3 additions & 0 deletions app/models/contact_topic_answer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ class ContactTopicAnswer < ApplicationRecord
belongs_to :case_contact
belongs_to :contact_topic

has_one :casa_case, through: :case_contact
has_one :casa_org, through: :casa_case

validates :selected, inclusion: [true, false]

default_scope { joins(:contact_topic).order("contact_topics.id") }
Expand Down
27 changes: 27 additions & 0 deletions app/policies/additional_expense_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class AdditionalExpensePolicy < ApplicationPolicy
class Scope < ApplicationPolicy::Scope
def resolve
case user
when CasaAdmin, Supervisor
scope.joins([:case_contact, :casa_case]).where(casa_case: {casa_org_id: user.casa_org.id})
when Volunteer
scope.where(case_contact: user.case_contacts)
else
scope.none
end
end
end

def create?
case user
when Volunteer
user.case_contacts.include?(record.case_contact)
when CasaAdmin, Supervisor
same_org?
else
false
end
end

alias_method :destroy?, :create?
end
27 changes: 27 additions & 0 deletions app/policies/contact_topic_answer_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class ContactTopicAnswerPolicy < ApplicationPolicy
class Scope < ApplicationPolicy::Scope
def resolve
case user
when CasaAdmin, Supervisor
scope.joins([:case_contact, :casa_case]).where(casa_case: {casa_org_id: user.casa_org&.id})
when Volunteer
scope.where(case_contact: user.case_contacts)
else
scope.none
end
end
end

def create?
case user
when Volunteer
user.case_contacts.include?(record.case_contact)
when CasaAdmin, Supervisor
same_org?
else
false
end
end

alias_method :destroy?, :create?
end
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
en:
activerecord:
attributes:
additional_expense:
other_expenses_amount: Amount
other_expenses_describe: Description
case_contact:
occurred_at: Date
errors:
Expand Down
6 changes: 6 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
end
end

resources :contact_topic_answers, only: %i[create destroy],
constraints: lambda { |req| req.format == :json }

resources :reports, only: %i[index]
get :export_emails, to: "reports#export_emails"

Expand Down Expand Up @@ -191,6 +194,9 @@
end
resources :case_court_orders, only: %i[destroy]

resources :additional_expenses, only: %i[create destroy],
constraints: lambda { |req| req.format == :json }

namespace :all_casa_admins do
resources :casa_orgs, only: [:new, :create, :show] do
resources :casa_admins, only: [:new, :create, :edit, :update] do
Expand Down
109 changes: 109 additions & 0 deletions spec/policies/additional_expense_policy_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
require "rails_helper"

RSpec.describe AdditionalExpensePolicy, type: :policy do
let(:casa_org) { create :casa_org }
let(:volunteer) { create :volunteer, :with_single_case, casa_org: }
let(:supervisor) { create :supervisor, casa_org: }
let(:casa_admin) { create :casa_admin, casa_org: }
let(:all_casa_admin) { create :all_casa_admin }

let(:casa_case) { volunteer.casa_cases.first }
let(:case_contact) { create :case_contact, casa_case:, creator: volunteer }
let!(:additional_expense) { create :additional_expense, case_contact: }

let(:same_org_volunteer) { create :volunteer, casa_org: }
let!(:same_org_volunteer_case_assignment) { create :case_assignment, volunteer: same_org_volunteer, casa_case: }

subject { described_class }

permissions :create?, :destroy? do
it "does not permit a nil user" do
expect(described_class).not_to permit(nil, additional_expense)
end

it "permits a volunteer assigned to the expense's case contact" do
expect(described_class).to permit(volunteer, additional_expense)
end

it "does not permit a volunteer who did not create the case contact" do
expect(same_org_volunteer.casa_cases).to include(casa_case)
expect(described_class).not_to permit(same_org_volunteer, additional_expense)
end

it "permits a supervisor" do
expect(described_class).to permit(supervisor, additional_expense)
end

it "does not permit a supervisor for a different casa org" do
other_org_supervisor = create :supervisor, casa_org: create(:casa_org)
expect(described_class).not_to permit(other_org_supervisor, additional_expense)
end

it "permits a casa admin" do
expect(described_class).to permit(casa_admin, additional_expense)
end

it "does not permit a casa admin for a different casa org" do
other_org_casa_admin = create :casa_admin, casa_org: create(:casa_org)
expect(described_class).not_to permit(other_org_casa_admin, additional_expense)
end

it "does not permit an all casa admin" do
expect(described_class).not_to permit(all_casa_admin, additional_expense)
end
end

describe "Scope#resolve" do
let(:same_org_volunteer_case_contact) { create :case_contact, casa_case:, creator: same_org_volunteer }
let!(:same_org_other_volunteer_additional_expense) do
create :additional_expense, case_contact: same_org_volunteer_case_contact
end

let(:other_volunteer_case_contact) { create :case_contact, casa_case:, creator: other_volunteer }
let!(:other_volunteer_additional_expense) { create :additional_expense, case_contact: other_org_case_contact }

let(:other_org) { create :casa_org }
let(:other_org_volunteer) { create :volunteer, casa_org: other_org }
let(:other_org_casa_case) { create :casa_case, casa_org: other_org }
let(:other_org_case_contact) { create :case_contact, casa_case: other_org_casa_case, creator: other_org_volunteer }
let!(:other_org_additional_expense) { create :additional_expense, case_contact: other_org_case_contact }

subject { described_class::Scope.new(user, AdditionalExpense.all).resolve }

context "when user is a visitor" do
let(:user) { nil }

it { is_expected.not_to include(additional_expense) }
it { is_expected.not_to include(other_org_additional_expense) }
end

context "when user is a volunteer" do
let(:user) { volunteer }

it { is_expected.to include(additional_expense) }
it { is_expected.not_to include(other_volunteer_additional_expense) }
it { is_expected.not_to include(other_org_additional_expense) }
end

context "when user is a supervisor" do
let(:user) { supervisor }

it { is_expected.to include(additional_expense) }
it { is_expected.not_to include(other_org_additional_expense) }
end

context "when user is a casa_admin" do
let(:user) { casa_admin }

it { is_expected.to include(additional_expense) }
it { is_expected.not_to include(other_org_additional_expense) }
end

context "when user is an all_casa_admin" do
let(:user) { all_casa_admin }

it { is_expected.not_to include(additional_expense) }
it { is_expected.not_to include(other_org_additional_expense) }
end
end
end
Loading

0 comments on commit fea791a

Please sign in to comment.