Skip to content

Commit a8b05cd

Browse files
stefannibrasilcompwron
authored andcommitted
Add coverage for CaseContactsExportCsvService
Close #6835 `CaseContactsExportCsvService` is the primary reporting export but only has a pending placeholder spec. This adds coverage to it to prevent unexpected errors.
1 parent c6d337a commit a8b05cd

2 files changed

Lines changed: 143 additions & 2 deletions

File tree

app/services/case_contacts_export_csv_service.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require "csv"
24

35
class CaseContactsExportCsvService
Lines changed: 141 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,146 @@
1+
# frozen_string_literal: true
2+
13
require "rails_helper"
24

35
RSpec.describe CaseContactsExportCsvService, type: :service do
4-
# TODO: Add tests for CaseContactsExportCsvService
6+
describe "#perform" do
7+
it "exports the case contacts without the court topics header by default" do
8+
casa_case = create(:casa_case)
9+
create(:case_contact, casa_case: casa_case, medium_type: "text/email", occurred_at: Date.new(2026, 1, 8))
10+
case_contacts = casa_case.decorate.case_contacts_ordered_by_occurred_at
11+
12+
csv = CaseContactsExportCsvService.new(case_contacts, filtered_columns).perform
13+
14+
parsed_csv = CSV.parse(csv, headers: true)
15+
expect(parsed_csv.count).to eq(1)
16+
expect(parsed_csv.headers).to eq(expected_headers)
17+
expect(csv).to match(%r{text/email})
18+
expect(csv).to match(/January 8, 2026/)
19+
expect(parsed_csv.headers).not_to include("Court Topics")
20+
end
21+
22+
context "when there are no case contacts" do
23+
it "exports only the headers" do
24+
casa_case = build(:casa_case)
25+
case_contacts = casa_case.decorate.case_contacts_ordered_by_occurred_at
26+
27+
csv = CaseContactsExportCsvService.new(case_contacts, filtered_columns).perform
28+
29+
parsed_csv = CSV.parse(csv, headers: true)
30+
expect(parsed_csv.count).to eq(0)
31+
expect(parsed_csv.headers).to eq(expected_headers)
32+
end
33+
end
34+
35+
context "when the filtered columns includes court topics" do
36+
it "exports the case contacts with the CaseContactReport::COLUMNS with the contact topics" do
37+
casa_case = create(:casa_case)
38+
case_contact = build(:case_contact, casa_case:, medium_type: "text/email", occurred_at: Date.new(2026, 1, 8))
39+
create(:case_contact, casa_case:, medium_type: "in-person", occurred_at: Date.new(2026, 3, 16))
40+
contact_topic = build(:contact_topic, question: "A Topic")
41+
create(:contact_topic_answer, case_contact:, contact_topic:, value: "An answer")
42+
case_contacts = casa_case.decorate.case_contacts_ordered_by_occurred_at
43+
44+
csv = CaseContactsExportCsvService.new(case_contacts, filtered_columns).perform
45+
46+
parsed_csv = CSV.parse(csv, headers: true)
47+
expect(parsed_csv.count).to eq(2)
48+
expect(parsed_csv.headers).to eq(expected_headers + ["A Topic"])
49+
expect(csv).to match(/in-person/)
50+
expect(csv).to match(/March 16, 2026/)
51+
expect(csv).to match(%r{text/email})
52+
expect(csv).to match(/January 8, 2026/)
53+
expect(csv).to match(/a topic/i)
54+
expect(csv).to match(/an answer/i)
55+
end
56+
57+
it "does not include topics that don't have any answers" do
58+
casa_case = create(:casa_case)
59+
case_contact = build(:case_contact, casa_case: casa_case, medium_type: "text/email", occurred_at: Date.new(2026, 1, 8))
60+
contact_topic = build(:contact_topic, question: "A Topic with an Answer")
61+
create(:contact_topic_answer, contact_topic:, case_contact:, value: "An answer")
62+
build(:contact_topic, question: "Nothing to show")
63+
case_contacts = casa_case.decorate.case_contacts_ordered_by_occurred_at
64+
65+
csv = CaseContactsExportCsvService.new(case_contacts, filtered_columns).perform
66+
67+
parsed_csv = CSV.parse(csv, headers: true)
68+
expect(parsed_csv.count).to eq(1)
69+
expect(parsed_csv.headers).to eq(expected_headers + ["A Topic with an Answer"])
70+
expect(csv).to match(%r{text/email})
71+
expect(csv).to match(/January 8, 2026/)
72+
expect(csv).to include("An answer")
73+
expect(csv).not_to include("Nothing to show")
74+
end
75+
76+
context "when there are multiple answers to a case contact's court topic" do
77+
it "exports the case contact including only the latest contact topic answer" do
78+
casa_case = create(:casa_case)
79+
case_contact = build(:case_contact, casa_case: casa_case, medium_type: "text/email", occurred_at: Date.new(2026, 1, 8))
80+
contact_topic = build(:contact_topic, question: "A Topic")
81+
create(:contact_topic_answer, case_contact:, contact_topic:, value: "First answer")
82+
create(:contact_topic_answer, case_contact:, contact_topic:, value: "Second answer")
83+
case_contacts = casa_case.decorate.case_contacts_ordered_by_occurred_at
84+
85+
csv = CaseContactsExportCsvService.new(case_contacts, filtered_columns).perform
86+
87+
parsed_csv = CSV.parse(csv, headers: true)
88+
expect(parsed_csv.count).to eq(1)
89+
expect(parsed_csv.headers).to eq(expected_headers + ["A Topic"])
90+
expect(csv).to match(%r{text/email})
91+
expect(csv).to match(/January 8, 2026/)
92+
expect(csv).to match(/a topic/i)
93+
expect(csv).to include("Second answer")
94+
expect(csv).not_to include("First answer")
95+
end
96+
end
97+
end
98+
99+
context "when court topics are filtered out" do
100+
it "exports the case contacts with the CaseContactReport::COLUMNS without the Court topics entries" do
101+
casa_case = create(:casa_case)
102+
case_contact = build(:case_contact, casa_case:, medium_type: "text/email", occurred_at: Date.new(2026, 1, 8))
103+
create(:case_contact, casa_case:, medium_type: "in-person", occurred_at: Date.new(2026, 3, 16))
104+
contact_topic = build(:contact_topic, question: "Another Topic")
105+
create(:contact_topic_answer, case_contact:, contact_topic:, value: "Another answer")
106+
case_contacts = casa_case.decorate.case_contacts_ordered_by_occurred_at
107+
filtered_columns = CaseContactReport::COLUMNS - [:court_topics]
108+
109+
csv = CaseContactsExportCsvService.new(case_contacts, filtered_columns).perform
110+
111+
parsed_csv = CSV.parse(csv, headers: true)
112+
expect(parsed_csv.count).to eq(2)
113+
expect(parsed_csv.headers).to eq(expected_headers - ["A Topic"])
114+
expect(csv).to match(/in-person/)
115+
expect(csv).to match(/March 16, 2026/)
116+
expect(csv).to match(%r{text/email})
117+
expect(csv).to match(/January 8, 2026/)
118+
expect(csv).not_to include("Another Topic")
119+
expect(csv).not_to include("Another answer")
120+
end
121+
end
122+
end
123+
124+
def filtered_columns
125+
CaseContactReport::COLUMNS
126+
end
5127

6-
pending "add some tests for CaseContactsExportCsvService"
128+
def expected_headers
129+
[
130+
"Internal Contact Number",
131+
"Duration Minutes",
132+
"Contact Types",
133+
"Contact Made",
134+
"Contact Medium",
135+
"Occurred At",
136+
"Added To System At",
137+
"Miles Driven",
138+
"Wants Driving Reimbursement",
139+
"Casa Case Number",
140+
"Creator Email",
141+
"Creator Name",
142+
"Supervisor Name",
143+
"Case Contact Notes"
144+
]
145+
end
7146
end

0 commit comments

Comments
 (0)