Skip to content

Commit 00066ef

Browse files
committed
Add specs for adjusment csv export
1 parent a20fe8e commit 00066ef

2 files changed

Lines changed: 268 additions & 0 deletions

File tree

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
RSpec.describe AdjustmentsController, type: :controller do
2+
let(:organization) { create(:organization) }
3+
let(:user) { create(:user, organization: organization) }
4+
let(:storage_location) { create(:storage_location, organization: organization) }
5+
let(:item1) { create(:item, name: "Item One", organization: organization) }
6+
let(:item2) { create(:item, name: "Item Two", organization: organization) }
7+
8+
let!(:adjustment1) do
9+
adj = create(:adjustment,
10+
organization: organization,
11+
storage_location: storage_location,
12+
comment: "First adjustment",
13+
created_at: 1.day.ago
14+
)
15+
adj.line_items << build(:line_item, quantity: 10, item: item1, itemizable: adj)
16+
adj.line_items << build(:line_item, quantity: 5, item: item2, itemizable: adj)
17+
adj
18+
end
19+
20+
let!(:adjustment2) do
21+
adj = create(:adjustment,
22+
organization: organization,
23+
storage_location: storage_location,
24+
comment: "Second adjustment",
25+
created_at: 5.days.ago
26+
)
27+
adj.line_items << build(:line_item, quantity: -5, item: item1, itemizable: adj)
28+
adj
29+
end
30+
31+
before do
32+
sign_in(user)
33+
end
34+
35+
describe "GET #index" do
36+
context "with CSV format" do
37+
it "returns a CSV file" do
38+
get :index, format: :csv
39+
expect(response).to be_successful
40+
expect(response.header['Content-Type']).to include 'text/csv'
41+
end
42+
43+
it "includes appropriate headers for adjustments" do
44+
get :index, format: :csv
45+
expect(response.body).to include("Created")
46+
expect(response.body).to include("Storage Location")
47+
expect(response.body).to include("Comment")
48+
expect(response.body).to include("User")
49+
expect(response.body).to include("Changes")
50+
expect(response.body).to include(item1.name)
51+
expect(response.body).to include(item2.name)
52+
end
53+
54+
it "includes data from the adjustments" do
55+
get :index, format: :csv
56+
parsed_csv = CSV.parse(response.body, headers: true)
57+
58+
expect(parsed_csv.count).to eq(2)
59+
60+
expect(parsed_csv[0]["Comment"]).to eq(adjustment1.comment)
61+
expect(parsed_csv[1]["Comment"]).to eq(adjustment2.comment)
62+
63+
expect(parsed_csv[0][item1.name]).to eq("10")
64+
expect(parsed_csv[0][item2.name]).to eq("5")
65+
expect(parsed_csv[0]["Changes"]).to eq("2")
66+
67+
expect(parsed_csv[1][item1.name]).to eq("-5")
68+
expect(parsed_csv[1]["Changes"]).to eq("1")
69+
end
70+
71+
context "when filtering by date" do
72+
it "returns adjustments filtered by date range" do
73+
start_date = 3.days.ago.to_fs(:date_picker)
74+
end_date = Time.zone.today.to_fs(:date_picker)
75+
76+
get :index, params: { filters: { date_range: "#{start_date} - #{end_date}" } }, format: :csv
77+
78+
parsed_csv = CSV.parse(response.body, headers: true)
79+
expect(parsed_csv.count).to eq(1)
80+
expect(assigns(:adjustments)).to include(adjustment1)
81+
end
82+
end
83+
end
84+
end
85+
end
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
RSpec.describe Exports::ExportAdjustmentsCSVService do
2+
# Create organization after items to ensure proper associations
3+
let!(:item1) { create(:item, name: 'item1') }
4+
let!(:item2) { create(:item, name: 'item2') }
5+
let!(:item3) { create(:item, name: 'item3') }
6+
let!(:item4) { create(:item, name: 'item4') }
7+
let!(:item5) { create(:item, :inactive, name: 'item5') }
8+
9+
# Now create organization and associate items with it
10+
let(:organization) do
11+
org = create(:organization)
12+
[item1, item2, item3, item4, item5].each do |item|
13+
item.update!(organization_id: org.id)
14+
end
15+
org
16+
end
17+
18+
let(:sorted_item_names) do
19+
[item1, item2, item3, item4, item5].map(&:name).sort
20+
end
21+
22+
let(:expected_headers) do
23+
[
24+
"Created", "Storage Location",
25+
"Comment", "User", "Changes"
26+
] + sorted_item_names
27+
end
28+
29+
let(:storage_location) { create(:storage_location, organization: organization) }
30+
let(:user) { create(:user, organization: organization) }
31+
32+
describe "#generate_csv_data" do
33+
subject { described_class.new(adjustments: adjustments, organization: organization).generate_csv_data }
34+
35+
context "with multiple adjustments and items" do
36+
let(:adjustments) do
37+
[
38+
# 1st adjustment with 2 items
39+
create(:adjustment,
40+
user_id: user.id,
41+
storage_location: storage_location,
42+
organization: organization,
43+
comment: "adjustment 1",
44+
line_items_attributes: [
45+
{item_id: item1.id, quantity: 10},
46+
{item_id: item2.id, quantity: -5}
47+
]),
48+
49+
# 2nd adjustment with 1 item
50+
create(:adjustment,
51+
user_id: user.id,
52+
storage_location: storage_location,
53+
organization: organization,
54+
comment: "adjustment 2",
55+
line_items_attributes: [
56+
{item_id: item3.id, quantity: 3}
57+
]),
58+
59+
# 3rd adjustment with the :with_items trait
60+
create(:adjustment, :with_items,
61+
user_id: user.id,
62+
storage_location: storage_location,
63+
organization: organization,
64+
comment: "adjustment 3",
65+
item: item1,
66+
item_quantity: 7)
67+
]
68+
end
69+
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+
user.name,
81+
2 # Number of items changed
82+
)
83+
84+
# Check 2nd adjustment
85+
expect(subject[2]).to include(
86+
adjustments[1].created_at.strftime("%F"),
87+
storage_location.name,
88+
"adjustment 2",
89+
user.name,
90+
1 # Number of items changed
91+
)
92+
93+
# Check 3rd adjustment
94+
expect(subject[3]).to include(
95+
adjustments[2].created_at.strftime("%F"),
96+
storage_location.name,
97+
"adjustment 3",
98+
user.name,
99+
1 # Number of items changed
100+
)
101+
end
102+
103+
it "should include the correct item quantities" do
104+
# Get indexes of item quantity columns
105+
item1_idx = expected_headers.index(item1.name)
106+
item2_idx = expected_headers.index(item2.name)
107+
item3_idx = expected_headers.index(item3.name)
108+
item4_idx = expected_headers.index(item4.name)
109+
item5_idx = expected_headers.index(item5.name)
110+
111+
# Check 1st adjustment
112+
expect(subject[1][item1_idx]).to eq(10)
113+
expect(subject[1][item2_idx]).to eq(-5)
114+
expect(subject[1][item3_idx]).to eq(0)
115+
expect(subject[1][item4_idx]).to eq(0)
116+
expect(subject[1][item5_idx]).to eq(0)
117+
118+
# Check 2nd adjustment
119+
expect(subject[2][item1_idx]).to eq(0)
120+
expect(subject[2][item2_idx]).to eq(0)
121+
expect(subject[2][item3_idx]).to eq(3)
122+
expect(subject[2][item4_idx]).to eq(0)
123+
expect(subject[2][item5_idx]).to eq(0)
124+
125+
# Check 3rd adjustment
126+
expect(subject[3][item1_idx]).to eq(7)
127+
expect(subject[3][item2_idx]).to eq(0)
128+
expect(subject[3][item3_idx]).to eq(0)
129+
expect(subject[3][item4_idx]).to eq(0)
130+
expect(subject[3][item5_idx]).to eq(0)
131+
end
132+
133+
it "should correctly sum up the number of changes" do
134+
idx = expected_headers.index("Changes")
135+
expect(subject[1][idx]).to eq(2)
136+
expect(subject[2][idx]).to eq(1)
137+
expect(subject[3][idx]).to eq(1)
138+
end
139+
end
140+
141+
context "when there are no adjustments" do
142+
let(:adjustments) { [] }
143+
144+
it "returns only headers row" do
145+
expect(subject.size).to eq(1)
146+
expect(subject[0]).to eq(expected_headers)
147+
end
148+
end
149+
end
150+
151+
describe "#generate_csv" do
152+
subject { described_class.new(adjustments: adjustments, organization: organization).generate_csv }
153+
154+
let(:adjustments) do
155+
[
156+
create(:adjustment,
157+
storage_location: storage_location,
158+
organization: organization,
159+
line_items_attributes: [
160+
{item_id: item1.id, quantity: 111},
161+
{item_id: item2.id, quantity: -7}
162+
])
163+
]
164+
end
165+
166+
it "generates valid CSV data" do
167+
expect(subject).to be_a(String)
168+
parsed_csv = CSV.parse(subject, headers: true)
169+
expect(parsed_csv.headers).to include("Created",
170+
"Storage Location",
171+
"Comment",
172+
"Changes",
173+
item1.name,
174+
item2.name,
175+
item3.name,
176+
item4.name)
177+
178+
expect(parsed_csv.first["Changes"]).to eq("2")
179+
expect(parsed_csv.first[item1.name]).to eq("111")
180+
expect(parsed_csv.first[item2.name]).to eq("-7")
181+
end
182+
end
183+
end

0 commit comments

Comments
 (0)