Skip to content

Commit

Permalink
feat: add timing metadata for case contacts (#5919)
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticspoon authored Jul 17, 2024
1 parent 4ff3d5c commit ed7b83f
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 2 deletions.
3 changes: 2 additions & 1 deletion app/controllers/case_contacts/form_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def update
params[:case_contact][:status] = step.to_s if !@case_contact.active?
remove_unwanted_contact_types
remove_nil_draft_ids
if @case_contact.update(case_contact_params)

if CaseContactUpdateService.new(@case_contact).update_attrs(case_contact_params)
respond_to do |format|
format.html {
if step == steps.last
Expand Down
1 change: 1 addition & 0 deletions app/models/case_contact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ def casa_org_any_expenses_enabled?
# draft_case_ids :integer default([]), is an Array
# duration_minutes :integer
# medium_type :string
# metadata :jsonb
# miles_driven :integer default(0), not null
# notes :string
# occurred_at :datetime
Expand Down
28 changes: 28 additions & 0 deletions app/services/case_contact_update_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class CaseContactUpdateService
attr_reader :case_contact

def initialize(case_contact)
@case_contact = case_contact
end

def update_attrs(new_attrs)
old_attrs = case_contact.as_json

result = case_contact.update(new_attrs)
update_status_metadata(old_attrs, new_attrs) if result

result
end

private

def update_status_metadata(old_attrs, new_attrs)
return if old_attrs[:status] == new_attrs[:status]

metadata = case_contact.metadata
metadata["status"] ||= {}
metadata["status"][new_attrs[:status]] = Time.zone.now

case_contact.update(metadata: metadata)
end
end
5 changes: 5 additions & 0 deletions db/migrate/20240716194609_add_metadata_to_case_contacts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddMetadataToCaseContacts < ActiveRecord::Migration[7.1]
def change
add_column :case_contacts, :metadata, :jsonb, default: {}
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_06_22_020203) do
ActiveRecord::Schema[7.1].define(version: 2024_07_16_194609) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -203,6 +203,7 @@
t.string "status", default: "started"
t.integer "draft_case_ids", default: [], array: true
t.string "volunteer_address"
t.jsonb "metadata", default: {}
t.index ["casa_case_id"], name: "index_case_contacts_on_casa_case_id"
t.index ["creator_id"], name: "index_case_contacts_on_creator_id"
t.index ["deleted_at"], name: "index_case_contacts_on_deleted_at"
Expand Down
203 changes: 203 additions & 0 deletions spec/services/case_contact_update_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
require "rails_helper"

RSpec.describe CaseContactUpdateService do
let(:updater) { described_class.new(case_contact) }
let(:case_contact) { create(:case_contact) }

let!(:now) { Time.zone.now }
let!(:one_day_ago) { 1.day.ago }
let!(:two_days_ago) { 2.days.ago }

before { travel_to one_day_ago }
after { travel_back }

describe "#update_attributes" do
context "case is in details status" do
let!(:case_contact) { create(:case_contact, status: "details", created_at: two_days_ago) }

context "status is not updated" do
before { updater.update_attrs({notes: "stuff"}) }

it { expect(case_contact.metadata).to eq({}) }
it { expect(updater.update_attrs({notes: "stuff"})).to be true }
end

it "does not update metadata if attrs are invalid" do
result = updater.update_attrs({occurred_at: 50.years.ago})
expect(case_contact.metadata).to eq({})
expect(result).to be false
end

context "gets updated to details" do
before { updater.update_attrs({status: "details"}) }

it "updates details metadata to current date" do
date = case_contact.metadata.dig("status", "details")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("details") }
end

context "gets updated to expenses" do
before { updater.update_attrs({status: "expenses"}) }

it "updates expenses metadata to current date" do
date = case_contact.metadata.dig("status", "expenses")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("expenses") }
end

context "gets updated to active" do
before { updater.update_attrs({status: "active"}) }

it "updates active metadata to current date" do
date = case_contact.metadata.dig("status", "active")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("active") }
end
end

context "case is in expenses status" do
let!(:case_contact) { create(:case_contact, status: "expenses", created_at: two_days_ago) }

context "status is not updated" do
before { updater.update_attrs({notes: "stuff"}) }

it { expect(case_contact.metadata).to eq({}) }
it { expect(updater.update_attrs({notes: "stuff"})).to be true }
end

it "does not update metadata if attrs are invalid" do
result = updater.update_attrs({occurred_at: 50.years.ago})
expect(case_contact.metadata).to eq({})
expect(result).to be false
end

context "gets updated to details" do
before { updater.update_attrs({status: "details"}) }

it "updates details metadata to current date" do
date = case_contact.metadata.dig("status", "details")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("details") }
end

context "gets updated to expenses" do
before { updater.update_attrs({status: "expenses"}) }

it "updates expenses metadata to current date" do
date = case_contact.metadata.dig("status", "expenses")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("expenses") }
end

context "gets updated to active" do
before { updater.update_attrs({status: "active"}) }

it "updates active metadata to current date" do
date = case_contact.metadata.dig("status", "active")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("active") }
end
end

context "case is in active status" do
let!(:case_contact) { create(:case_contact, status: "active", created_at: two_days_ago) }

context "status is not updated" do
before { updater.update_attrs({notes: "stuff"}) }

it { expect(case_contact.metadata).to eq({}) }
it { expect(updater.update_attrs({notes: "stuff"})).to be true }
end

it "does not update metadata if attrs are invalid" do
result = updater.update_attrs({occurred_at: 50.years.ago})
expect(case_contact.metadata).to eq({})
expect(result).to be false
end

context "gets updated to details" do
before { updater.update_attrs({status: "details"}) }

it "updates details metadata to current date" do
date = case_contact.metadata.dig("status", "details")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("details") }
end

context "gets updated to expenses" do
before { updater.update_attrs({status: "expenses"}) }

it "updates expenses metadata to current date" do
date = case_contact.metadata.dig("status", "expenses")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("expenses") }
end

context "gets updated to active" do
before { updater.update_attrs({status: "active"}) }

it "updates active metadata to current date" do
date = case_contact.metadata.dig("status", "active")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("active") }
end
end

context "case is in started status" do
let!(:case_contact) { create(:case_contact, status: "started", created_at: two_days_ago) }

context "status is not updated" do
before { updater.update_attrs({notes: "stuff"}) }

it { expect(case_contact.metadata).to eq({}) }
it { expect(updater.update_attrs({notes: "stuff"})).to be true }
end

it "does not update metadata if attrs are invalid" do
result = updater.update_attrs({occurred_at: 50.years.ago})
expect(case_contact.metadata).to eq({})
expect(result).to be false
end

context "gets updated to details" do
before { updater.update_attrs({status: "details"}) }

it "updates details metadata to current date" do
date = case_contact.metadata.dig("status", "details")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("details") }
end

context "gets updated to expenses" do
before { updater.update_attrs({status: "expenses"}) }

it "updates expenses metadata to current date" do
date = case_contact.metadata.dig("status", "expenses")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("expenses") }
end

context "gets updated to active" do
before { updater.update_attrs({status: "active"}) }

it "updates active metadata to current date" do
date = case_contact.metadata.dig("status", "active")
expect(DateTime.parse(date)).to eq(Time.zone.now)
end
it { expect(case_contact.status).to eq("active") }
end
end
end
end

0 comments on commit ed7b83f

Please sign in to comment.