Skip to content

Commit 2ead900

Browse files
committed
Adapt adjustments specs to test csv export text and use module method
1 parent 08c98e0 commit 2ead900

4 files changed

Lines changed: 71 additions & 176 deletions

File tree

app/models/adjustment.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@ def split_difference
3737
def self.generate_csv(adjustments)
3838
return nil if adjustments.empty?
3939

40-
Exports::ExportAdjustmentsCSVService.new(
41-
adjustments: adjustments,
42-
organization: adjustments.first.organization
43-
).generate_csv
40+
Exports::ExportAdjustmentsCSVService
41+
.generate_csv(adjustments, adjustments.first.organization)
4442
end
4543

4644
private
Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,48 @@
11
module Exports
2-
class ExportAdjustmentsCSVService
3-
def initialize(adjustments:, organization:)
4-
@adjustments = adjustments
5-
@organization = organization
6-
end
7-
8-
def generate_csv
9-
CSV.generate(headers: true) do |csv|
10-
generate_csv_data.each { |row| csv << row }
2+
module ExportAdjustmentsCSVService
3+
class << self
4+
def generate_csv(adjustments, organization)
5+
CSV.generate(headers: true) do |csv|
6+
generate_csv_data(adjustments, organization).each { |row| csv << row }
7+
end
118
end
12-
end
139

14-
def generate_csv_data
15-
[headers] + @adjustments.map { |adjustment| build_row(adjustment) }
16-
end
10+
def generate_csv_data(adjustments, organization)
11+
item_names = get_item_names(organization)
12+
headers = [
13+
"Created date", "Storage Area",
14+
"Comment", "# of changes"
15+
] + item_names
1716

18-
private
17+
[headers] + adjustments.map { |adjustment| build_row(adjustment, item_names) }
18+
end
1919

20-
def headers
21-
[
22-
"Created date", "Storage Area",
23-
"Comment", "# of changes"
24-
] + item_names
25-
end
20+
private
2621

27-
def item_names
28-
@organization.items.order(:name).pluck(:name).uniq
29-
end
22+
def get_item_names(organization)
23+
organization.items.order(:name).pluck(:name).uniq
24+
end
3025

31-
def build_row(adjustment)
32-
row = [
33-
adjustment.created_at.strftime("%F"),
34-
adjustment.storage_location.name,
35-
adjustment.comment,
36-
adjustment.line_items.count { |item| !item.quantity.eql?(0) }
37-
]
26+
def build_row(adjustment, item_names)
27+
row = [
28+
adjustment.created_at.strftime("%F"),
29+
adjustment.storage_location.name,
30+
adjustment.comment,
31+
adjustment.line_items.count { |item| !item.quantity.eql?(0) }
32+
]
3833

39-
item_quantities = Hash.new(0)
34+
item_quantities = Hash.new(0)
4035

41-
adjustment.line_items.each do |line_item|
42-
item_quantities[line_item.item.name] += line_item.quantity
43-
end
36+
adjustment.line_items.each do |line_item|
37+
item_quantities[line_item.item.name] += line_item.quantity
38+
end
4439

45-
item_names.each do |item_name|
46-
row << item_quantities[item_name]
47-
end
40+
item_names.each do |item_name|
41+
row << item_quantities[item_name]
42+
end
4843

49-
row
44+
row
45+
end
5046
end
5147
end
5248
end

spec/requests/adjustments_requests_spec.rb

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
RSpec.describe "Adjustments", :wip, type: :request do
1+
RSpec.describe "Adjustments", type: :request do
22
let(:organization) { create(:organization) }
33
let(:user) { create(:user, organization: organization) }
44

@@ -104,29 +104,14 @@
104104
expect(response.header['Content-Type']).to include 'text/csv'
105105
end
106106

107-
it "includes appropriate headers for adjustments" do
108-
expect(response.body).to include("Created date")
109-
expect(response.body).to include("Storage Area")
110-
expect(response.body).to include("Comment")
111-
expect(response.body).to include("# of changes")
112-
expect(response.body).to include(item1.name)
113-
expect(response.body).to include(item2.name)
114-
end
115-
116-
it "includes data from the adjustments" do
117-
parsed_csv = CSV.parse(response.body, headers: true)
118-
119-
expect(parsed_csv.count).to eq(2)
107+
it "includes appropriate headers and data" do
108+
csv = <<~CSV
109+
Created date,Storage Area,Comment,# of changes,#{item1.name},#{item2.name}
110+
2019-06-30,Smithsonian Conservation Center,First adjustment,2,10,5
111+
2019-06-26,Smithsonian Conservation Center,Second adjustment,1,-5,0
112+
CSV
120113

121-
expect(parsed_csv[0]["Comment"]).to eq(adjustment1.comment)
122-
expect(parsed_csv[1]["Comment"]).to eq(adjustment2.comment)
123-
124-
expect(parsed_csv[0][item1.name]).to eq("10")
125-
expect(parsed_csv[0][item2.name]).to eq("5")
126-
expect(parsed_csv[0]["# of changes"]).to eq("2")
127-
128-
expect(parsed_csv[1][item1.name]).to eq("-5")
129-
expect(parsed_csv[1]["# of changes"]).to eq("1")
114+
expect(response.body).to eq(csv)
130115
end
131116

132117
context "when filtering by date" do
@@ -136,9 +121,12 @@
136121

137122
get adjustments_path, params: { filters: { date_range: "#{start_date} - #{end_date}" }, format: 'csv' }
138123

139-
parsed_csv = CSV.parse(response.body, headers: true)
140-
expect(parsed_csv.count).to eq(1)
141-
expect(parsed_csv[0]["Comment"]).to eq(adjustment1.comment)
124+
csv = <<~CSV
125+
Created date,Storage Area,Comment,# of changes,#{item1.name},#{item2.name}
126+
2019-06-30,Smithsonian Conservation Center,First adjustment,2,10,5
127+
CSV
128+
129+
expect(response.body).to eq(csv)
142130
end
143131
end
144132
end
Lines changed: 21 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
RSpec.describe Exports::ExportAdjustmentsCSVService, :wip do
1+
RSpec.describe Exports::ExportAdjustmentsCSVService do
22
# Create organization after items to ensure proper associations
33
let!(:item1) { create(:item, name: "item1") }
44
let!(:item2) { create(:item, name: "item2") }
@@ -19,18 +19,17 @@
1919
[item1, item2, item3, item4, item5].map(&:name).sort
2020
end
2121

22-
let(:expected_headers) do
23-
[
24-
"Created date", "Storage Area",
25-
"Comment", "# of changes"
26-
] + sorted_item_names
27-
end
28-
2922
let(:storage_location) { create(:storage_location, organization: organization) }
3023
let(:user) { create(:user, organization: organization) }
3124

25+
around do |example|
26+
travel_to Time.zone.local(2024, 12, 25)
27+
example.run
28+
travel_back
29+
end
30+
3231
describe "#generate_csv_data" do
33-
subject { described_class.new(adjustments: adjustments, organization: organization).generate_csv_data }
32+
subject { described_class.generate_csv(adjustments, organization) }
3433

3534
context "with multiple adjustments and items" do
3635
let(:adjustments) do
@@ -67,114 +66,28 @@
6766
]
6867
end
6968

70-
it "should have the expected headers" do
71-
expect(subject[0]).to eq(expected_headers)
72-
end
73-
74-
it "should include the adjustment data in the rows" do
75-
# Check 1st adjustment
76-
expect(subject[1]).to include(
77-
adjustments[0].created_at.strftime("%F"),
78-
storage_location.name,
79-
"adjustment 1",
80-
2 # Number of items changed
81-
)
82-
83-
# Check 2nd adjustment
84-
expect(subject[2]).to include(
85-
adjustments[1].created_at.strftime("%F"),
86-
storage_location.name,
87-
"adjustment 2",
88-
1 # Number of items changed
89-
)
90-
91-
# Check 3rd adjustment
92-
expect(subject[3]).to include(
93-
adjustments[2].created_at.strftime("%F"),
94-
storage_location.name,
95-
"adjustment 3",
96-
1 # Number of items changed
97-
)
98-
end
99-
100-
it "should include the correct item quantities" do
101-
# Get indexes of item quantity columns
102-
item1_idx = expected_headers.index(item1.name)
103-
item2_idx = expected_headers.index(item2.name)
104-
item3_idx = expected_headers.index(item3.name)
105-
item4_idx = expected_headers.index(item4.name)
106-
item5_idx = expected_headers.index(item5.name)
107-
108-
# Check 1st adjustment
109-
expect(subject[1][item1_idx]).to eq(10)
110-
expect(subject[1][item2_idx]).to eq(-5)
111-
expect(subject[1][item3_idx]).to eq(0)
112-
expect(subject[1][item4_idx]).to eq(0)
113-
expect(subject[1][item5_idx]).to eq(0)
69+
it "should include the correct adjustment data" do
70+
csv = <<~CSV
71+
Created date,Storage Area,Comment,# of changes,item1,item2,item3,item4,item5
72+
2024-12-25,Smithsonian Conservation Center,adjustment 1,2,10,-5,0,0,0
73+
2024-12-25,Smithsonian Conservation Center,adjustment 2,1,0,0,3,0,0
74+
2024-12-25,Smithsonian Conservation Center,adjustment 3,1,7,0,0,0,0
75+
CSV
11476

115-
# Check 2nd adjustment
116-
expect(subject[2][item1_idx]).to eq(0)
117-
expect(subject[2][item2_idx]).to eq(0)
118-
expect(subject[2][item3_idx]).to eq(3)
119-
expect(subject[2][item4_idx]).to eq(0)
120-
expect(subject[2][item5_idx]).to eq(0)
121-
122-
# Check 3rd adjustment
123-
expect(subject[3][item1_idx]).to eq(7)
124-
expect(subject[3][item2_idx]).to eq(0)
125-
expect(subject[3][item3_idx]).to eq(0)
126-
expect(subject[3][item4_idx]).to eq(0)
127-
expect(subject[3][item5_idx]).to eq(0)
128-
end
129-
130-
it "should correctly sum up the number of changes" do
131-
idx = expected_headers.index("# of changes")
132-
expect(subject[1][idx]).to eq(2)
133-
expect(subject[2][idx]).to eq(1)
134-
expect(subject[3][idx]).to eq(1)
77+
expect(subject).to eq(csv)
13578
end
13679
end
13780

13881
context "when there are no adjustments" do
13982
let(:adjustments) { [] }
14083

14184
it "returns only headers row" do
142-
expect(subject.size).to eq(1)
143-
expect(subject[0]).to eq(expected_headers)
144-
end
145-
end
146-
end
85+
csv = <<~CSV
86+
Created date,Storage Area,Comment,# of changes,item1,item2,item3,item4,item5
87+
CSV
14788

148-
describe "#generate_csv" do
149-
subject { described_class.new(adjustments: adjustments, organization: organization).generate_csv }
150-
151-
let(:adjustments) do
152-
[
153-
create(:adjustment,
154-
storage_location: storage_location,
155-
organization: organization,
156-
line_items_attributes: [
157-
{item_id: item1.id, quantity: 111},
158-
{item_id: item2.id, quantity: -7}
159-
])
160-
]
161-
end
162-
163-
it "generates valid CSV data" do
164-
expect(subject).to be_a(String)
165-
parsed_csv = CSV.parse(subject, headers: true)
166-
expect(parsed_csv.headers).to include("Created date",
167-
"Storage Area",
168-
"Comment",
169-
"# of changes",
170-
item1.name,
171-
item2.name,
172-
item3.name,
173-
item4.name)
174-
175-
expect(parsed_csv.first["# of changes"]).to eq("2")
176-
expect(parsed_csv.first[item1.name]).to eq("111")
177-
expect(parsed_csv.first[item2.name]).to eq("-7")
89+
expect(subject).to eq(csv)
90+
end
17891
end
17992
end
18093
end

0 commit comments

Comments
 (0)