Skip to content

Commit ffbc67d

Browse files
committed
PC-27: Add specs for quote management in active admin
1 parent 6d4bb9f commit ffbc67d

1 file changed

Lines changed: 208 additions & 0 deletions

File tree

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
require 'rails_helper'
2+
3+
RSpec.describe "Admin::Quotes", type: :request do
4+
let!(:admin_user) { create(:admin_user) }
5+
let!(:customer) { create(:customer) }
6+
let!(:user) { create(:user) }
7+
let!(:category) { create(:category) }
8+
let!(:item_fixed) { create(:item, :with_fixed_parameters, category: category, name: "Fixed Item") }
9+
let!(:item_open) { create(:item, :with_open_parameters, category: category, name: "Open Item") }
10+
let!(:item_select) { create(:item, :with_pricing_options, name: "Select Item", category: nil) }
11+
let!(:quote) { create(:quote, customer: customer, user: user) }
12+
let!(:quote_item) { create(:quote_item, quote: quote, item: item_fixed, price: 2500, discount: 10, final_price: 2250) }
13+
14+
before do
15+
sign_in admin_user
16+
end
17+
18+
describe "GET /admin/quotes (Index)" do
19+
it "renders the index page successfully" do
20+
get admin_quotes_path
21+
expect(response).to be_successful
22+
expect(response.body).to include("Quotes")
23+
expect(response.body).to include(customer.company_name)
24+
expect(response.body).to include(user.name)
25+
expect(response.body).to include(quote.total_price.to_s)
26+
end
27+
end
28+
29+
describe "GET /admin/quotes/:id (Show)" do
30+
it "renders the show page successfully" do
31+
get admin_quote_path(quote)
32+
expect(response).to be_successful
33+
expect(response.body).to include(customer.company_name)
34+
expect(response.body).to include(user.name)
35+
expect(response.body).to include("Quote Items")
36+
expect(response.body).to include(item_fixed.name)
37+
expect(response.body).to include("2500")
38+
expect(response.body).to include("10")
39+
expect(response.body).to include("2250")
40+
end
41+
end
42+
43+
describe "GET /admin/quotes/new" do
44+
it "renders the new quote form successfully" do
45+
get new_admin_quote_path
46+
expect(response).to be_successful
47+
expect(response.body).to include("New Quote")
48+
expect(response.body).to include("Customer")
49+
expect(response.body).to include("Categories")
50+
expect(response.body).to include("Items Without Category")
51+
expect(response.body).to include("Load Items")
52+
expect(response.body).to include("Quote Items")
53+
end
54+
end
55+
56+
describe "POST /admin/quotes (Create)" do
57+
let(:valid_attributes) do
58+
{
59+
customer_id: customer.id,
60+
user_id: user.id,
61+
quote_items_attributes: {
62+
"0" => {
63+
item_id: item_open.id,
64+
discount: "5",
65+
open_param_values: { "Custom" => "123" }
66+
}
67+
}
68+
}
69+
end
70+
71+
let(:invalid_attributes) do
72+
{ user_id: user.id }
73+
end
74+
75+
context "with valid parameters" do
76+
it "creates a new Quote and associated QuoteItem" do
77+
expect do
78+
post admin_quotes_path, params: { quote: valid_attributes }
79+
end.to change(Quote, :count).by(1).and change(QuoteItem, :count).by(1)
80+
81+
expect(response).to redirect_to(admin_quote_path(Quote.last))
82+
expect(flash[:notice]).to eq("Quote was successfully created.")
83+
84+
new_quote = Quote.last
85+
expect(new_quote.customer).to eq(customer)
86+
expect(new_quote.user).to eq(user)
87+
new_item = new_quote.quote_items.first
88+
expect(new_item.item).to eq(item_open)
89+
expect(new_item.discount).to eq(5)
90+
expect(new_item.pricing_parameters["Custom"]).to eq("123")
91+
end
92+
end
93+
94+
context "with invalid parameters" do
95+
it "does not create a new Quote" do
96+
expect do
97+
post admin_quotes_path, params: { quote: invalid_attributes }
98+
end.not_to change(Quote, :count)
99+
end
100+
end
101+
end
102+
103+
describe "GET /admin/quotes/:id/edit" do
104+
it "renders the edit quote form successfully" do
105+
get edit_admin_quote_path(quote)
106+
expect(response).to be_successful
107+
expect(response.body).to include("Edit Quote")
108+
expect(response.body).to include(customer.company_name)
109+
expect(response.body).to include("item-id-field")
110+
expect(response.body).to include("value=\"#{item_fixed.id}\"")
111+
end
112+
end
113+
114+
describe "PATCH /admin/quotes/:id (Update)" do
115+
let!(:quote_to_update) { create(:quote, customer: customer, user: user) }
116+
let!(:existing_item) { create(:quote_item, quote: quote_to_update, item: item_fixed, discount: 10) }
117+
let!(:item_to_delete) do
118+
create(:quote_item,
119+
quote: quote_to_update,
120+
item: item_open,
121+
discount: 5,
122+
open_param_values: { "Custom" => "100" })
123+
end
124+
125+
let(:update_attributes) do
126+
other_customer = create(:customer)
127+
{
128+
customer_id: other_customer.id,
129+
quote_items_attributes: {
130+
"0" => {
131+
id: existing_item.id,
132+
item_id: item_fixed.id,
133+
discount: "20"
134+
},
135+
"1" => {
136+
item_id: item_select.id,
137+
discount: "0",
138+
select_param_values: { "Tier" => "100" }
139+
},
140+
"2" => {
141+
id: item_to_delete.id,
142+
_destroy: "1"
143+
}
144+
}
145+
}
146+
end
147+
148+
let(:invalid_update_attributes) do
149+
{
150+
customer_id: customer.id,
151+
quote_items_attributes: {
152+
"0" => {
153+
id: existing_item.id,
154+
item_id: item_fixed.id,
155+
discount: "-5"
156+
}
157+
}
158+
}
159+
end
160+
161+
context "with valid parameters via custom controller action" do
162+
it "updates the Quote and processes QuoteItems correctly" do
163+
expect do
164+
patch admin_quote_path(quote_to_update), params: { quote: update_attributes }
165+
existing_item.reload
166+
quote_to_update.reload
167+
end.to change { quote_to_update.customer }.to(Customer.find(update_attributes[:customer_id]))
168+
.and change { existing_item.discount }.to(20)
169+
.and change { quote_to_update.quote_items.count }.by(0)
170+
171+
expect(response).to redirect_to(admin_quote_path(quote_to_update))
172+
expect(flash[:notice]).to eq("Quote updated successfully.")
173+
174+
new_item = quote_to_update.quote_items.find_by(item_id: item_select.id)
175+
expect(new_item).not_to be_nil
176+
expect(new_item.pricing_parameters["Tier"]).to eq("100")
177+
178+
expect(QuoteItem.find_by(id: item_to_delete.id)).to be_nil
179+
end
180+
end
181+
182+
context "with invalid parameters for a quote item" do
183+
it "does not update the quote and re-renders edit" do
184+
initial_discount = existing_item.discount
185+
patch admin_quote_path(quote_to_update), params: { quote: invalid_update_attributes }
186+
187+
expect(response).to have_http_status(:found)
188+
189+
existing_item.reload
190+
expect(existing_item.discount).to eq(initial_discount)
191+
end
192+
end
193+
end
194+
195+
describe "DELETE /admin/quotes/:id (Destroy)" do
196+
let!(:quote_to_destroy) { create(:quote, customer: customer, user: user) }
197+
let!(:item_in_quote) { create(:quote_item, quote: quote_to_destroy, item: item_fixed) }
198+
199+
it "destroys the requested quote and its items" do
200+
expect do
201+
delete admin_quote_path(quote_to_destroy)
202+
end.to change(Quote, :count).by(-1).and change(QuoteItem, :count).by(-1)
203+
204+
expect(response).to redirect_to(admin_quotes_path)
205+
expect(flash[:notice]).to eq("Quote was successfully destroyed.")
206+
end
207+
end
208+
end

0 commit comments

Comments
 (0)