Files
openfoodnetwork/spec/system/admin/subscriptions/crud_spec.rb
2024-07-03 11:15:10 +10:00

605 lines
25 KiB
Ruby

# frozen_string_literal: true
require 'system_helper'
RSpec.describe 'Subscriptions' do
include AdminHelper
include AuthenticationHelper
include WebHelper
include SubscriptionHelper
context "as an enterprise user" do
let!(:user) { create(:user) }
let!(:shop) { create(:distributor_enterprise, owner: user, enable_subscriptions: true) }
let!(:shop2) { create(:distributor_enterprise, owner: user, enable_subscriptions: true) }
let!(:shop_unmanaged) { create(:distributor_enterprise, enable_subscriptions: true) }
before { login_as user }
context 'listing subscriptions' do
let!(:subscription) {
create(:subscription, shop:, with_items: true, with_proxy_orders: true)
}
let!(:customer) { create(:customer, first_name: "Timmy", last_name: "Test") }
let!(:other_subscription) {
create(:subscription, shop:, customer:, with_items: true,
with_proxy_orders: true)
}
let!(:subscription2) {
create(:subscription, shop: shop2, with_items: true, with_proxy_orders: true)
}
let!(:subscription_unmanaged) {
create(:subscription, shop: shop_unmanaged, with_items: true, with_proxy_orders: true)
}
before do
subscription.update(shipping_fee_estimate: 3.5)
subscription.subscription_line_items.each do |sli|
sli.update(price_estimate: 5)
end
visit admin_subscriptions_path
end
context "for pre-existing subscriptions" do
it "passes the smoke test" do
expect(page).to have_select2 "shop_id", with_options: [shop.name, shop2.name],
without_options: [shop_unmanaged.name]
select2_select shop2.name, from: "shop_id"
# Loads the right subscriptions
expect(page).to have_selector "tr#so_#{subscription2.id}"
expect(page).not_to have_selector "tr#so_#{subscription.id}"
expect(page).not_to have_selector "tr#so_#{subscription_unmanaged.id}"
within "tr#so_#{subscription2.id}" do
expect(page).to have_selector "td.customer", text: subscription2.customer.email
end
# Changing Shops
select2_select shop.name, from: "shop_id"
# Loads the right subscriptions
expect(page).to have_selector "tr#so_#{subscription.id}"
expect(page).not_to have_selector "tr#so_#{subscription2.id}"
expect(page).not_to have_selector "tr#so_#{subscription_unmanaged.id}"
within "tr#so_#{subscription.id}" do
expect(page).to have_selector "td.customer", text: subscription.customer.email
end
# Using the Quick Search
expect(page).to have_selector "tr#so_#{subscription.id}"
expect(page).to have_selector "tr#so_#{other_subscription.id}"
# Using the Quick Search: no result
fill_in 'query', with: 'blah blah blah'
expect(page).not_to have_selector "tr#so_#{subscription.id}"
expect(page).not_to have_selector "tr#so_#{other_subscription.id}"
# Using the Quick Search: filter by email
fill_in 'query', with: other_subscription.customer.email
expect(page).to have_selector "tr#so_#{other_subscription.id}"
expect(page).not_to have_selector "tr#so_#{subscription.id}"
# Using the Quick Search: filter by first_name
fill_in 'query', with: other_subscription.customer.first_name
expect(page).to have_selector "tr#so_#{other_subscription.id}"
expect(page).not_to have_selector "tr#so_#{subscription.id}"
# Using the Quick Search: filter by last_name
fill_in 'query', with: other_subscription.customer.last_name
expect(page).to have_selector "tr#so_#{other_subscription.id}"
expect(page).not_to have_selector "tr#so_#{subscription.id}"
# Using the Quick Search: reset filter
fill_in 'query', with: ''
expect(page).to have_selector "tr#so_#{subscription.id}"
expect(page).to have_selector "tr#so_#{other_subscription.id}"
# Toggling columns
expect(page).to have_selector "th.customer"
expect(page).to have_content subscription.customer.email
toggle_columns "Customer"
expect(page).not_to have_selector "th.customer"
expect(page).not_to have_content subscription.customer.email
# Viewing Products
open_subscription_products_panel
within "#subscription-line-items" do
expect(page).to have_selector "span#order_subtotal", text: "$15.00" # 3 x $5 items
expect(page).to have_selector "span#order_fees", text: "$3.50" # $3.5 shipping
# 3 x $5 items + $3.5 shipping
expect(page).to have_selector "span#order_form_total", text: "$18.50"
end
# Viewing Orders
within "tr#so_#{subscription.id}" do
expect(page).to have_selector "td.orders.panel-toggle", text: 1
page.find("td.orders.panel-toggle").click
end
within ".subscription-orders" do
expect(page).to have_selector "tr.proxy_order", count: 1
expect(page).to have_content "$18.50" # 3 x $5 items + $3.5 shipping
proxy_order = subscription.proxy_orders.first
within "tr#po_#{proxy_order.id}" do
expect(page).not_to have_content 'CANCELLED'
accept_alert 'Are you sure?' do
find("a.cancel-order").click
end
expect(page).to have_content 'CANCELLED'
expect(proxy_order.reload.canceled_at).to be_within(5.seconds).of Time.zone.now
# Resuming an order
accept_alert 'Are you sure?' do
find("a.resume-order").click
end
# Note: the order itself was not complete when 'cancelled', so state remained as cart
expect(page).to have_content 'PENDING'
expect(proxy_order.reload.canceled_at).to be nil
end
end
# Pausing a subscription
within "tr#so_#{subscription.id}" do
find("a.pause-subscription").click
end
click_button "Yes, I'm sure"
within "tr#so_#{subscription.id}" do
expect(page).to have_selector ".state.paused", text: "PAUSED"
expect(subscription.reload.paused_at).to be_within(5.seconds).of Time.zone.now
end
# Unpausing a subscription
within "tr#so_#{subscription.id}" do
find("a.unpause-subscription").click
end
click_button "Yes, I'm sure"
within "tr#so_#{subscription.id}" do
expect(page).to have_selector ".state.active", text: "ACTIVE"
expect(subscription.reload.paused_at).to be nil
end
# Cancelling a subscription
within "tr#so_#{subscription.id}" do
find("a.cancel-subscription").click
end
click_button "Yes, I'm sure"
within "tr#so_#{subscription.id}" do
expect(page).to have_selector ".state.canceled", text: "CANCELLED"
expect(subscription.reload.canceled_at).to be_within(5.seconds).of Time.zone.now
end
end
end
context "editing subscription products quantity" do
it "updates quantity" do
select2_select shop.name, from: "shop_id"
open_subscription_products_panel
within "#sli_0" do
fill_in 'quantity', with: "5"
end
page.find("a.button.update").click
expect(page).to have_content 'SAVED'
end
end
def open_subscription_products_panel
within "tr#so_#{subscription.id}" do
expect(page).to have_selector "td.items.panel-toggle", text: 3
page.find("td.items.panel-toggle").click
end
end
end
context 'when creating a new subscription' do
let(:address) { create(:address) }
let!(:customer_user) { create(:user) }
let!(:credit_card1) {
create(:stored_credit_card, user: customer_user, cc_type: 'visa', last_digits: 1111,
month: 10, year: 2030)
}
let!(:customer) {
create(:customer, enterprise: shop, bill_address: address, user: customer_user,
allow_charges: true)
}
let!(:test_product) { create(:product) }
let!(:test_variant) {
create(:variant, product: test_product, unit_value: "100", price: 12.00, supplier: shop)
}
let!(:shop_product) { create(:product) }
let!(:shop_variant) {
create(:variant, product: shop_product, unit_value: "1000", price: 6.00, supplier: shop)
}
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
let!(:order_cycle) {
create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.from_now,
orders_close_at: 7.days.from_now)
}
let!(:outgoing_exchange) {
order_cycle.exchanges.create(sender: shop, receiver: shop,
variants: [test_variant, shop_variant],
enterprise_fees: [enterprise_fee])
}
let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) }
let!(:payment_method) {
create(:stripe_sca_payment_method, name: 'Credit Card', distributors: [shop])
}
let!(:shipping_method) { create(:shipping_method, distributors: [shop]) }
before do
visit admin_subscriptions_path
page.find("#new-subscription").click
tomselect_select shop.name, from: "subscription[shop_id]"
click_button "Continue"
end
context 'on first page' do
before do
select2_select customer.email, from: 'customer_id'
select2_select schedule.name, from: 'schedule_id'
select2_select payment_method.name, from: 'payment_method_id'
select2_select shipping_method.name, from: 'shipping_method_id'
end
context 'and date field is not filled' do
it 'counts a can not be blank content once' do
click_button('Next')
expect(page).to have_content 'can\'t be blank', count: 1
expect(page).to have_content 'Oops! Please fill in all of the required fields...'
end
end
context 'and date field is filled' do
it 'goes to the next page and preload customer bill address' do
find_field('begins_at').click
choose_today_from_datepicker
click_button('Next')
expect(page).to have_content 'Billing Address'
# Customer bill address has been pre-loaded
expect(page).to have_input "bill_address_firstname", with: address.firstname
expect(page).to have_input "bill_address_lastname", with: address.lastname
expect(page).to have_input "bill_address_address1", with: address.address1
end
end
end
context 'on second page' do
before do
select2_select customer.email, from: 'customer_id'
select2_select schedule.name, from: 'schedule_id'
select2_select payment_method.name, from: 'payment_method_id'
select2_select shipping_method.name, from: 'shipping_method_id'
find_field('begins_at').click
choose_today_from_datepicker
click_button('Next')
end
context 'when clearing some elements of bill address' do
before do
# Clear some elements of bill address
fill_in "bill_address_firstname", with: ''
fill_in "bill_address_lastname", with: ''
fill_in "bill_address_address1", with: ''
fill_in "bill_address_city", with: ''
fill_in "bill_address_zipcode", with: ''
fill_in "bill_address_phone", with: ''
end
it 'counts 6 can not be blank messages' do
click_button('Next')
expect(page).to have_content 'can\'t be blank', count: 6
end
context 'and re-setting the billing address' do
before do
fill_in "bill_address_firstname", with: 'Freda'
fill_in "bill_address_lastname", with: 'Figapple'
fill_in "bill_address_address1", with: '7 Tempany Lane'
fill_in "bill_address_city", with: 'Natte Yallock'
fill_in "bill_address_zipcode", with: '3465'
fill_in "bill_address_phone", with: '0400 123 456'
select2_select "Australia", from: "bill_address_country_id"
select2_select "Victoria", from: "bill_address_state_id"
end
context 'and using copy button to fill in ship address' do
before { click_link "Copy" }
it 'has input with ship address values' do
expect(page).to have_input "ship_address_firstname", with: 'Freda'
expect(page).to have_input "ship_address_lastname", with: 'Figapple'
expect(page).to have_input "ship_address_address1", with: '7 Tempany Lane'
end
end
end
end
end
context 'on third page' do
before do
select2_select customer.email, from: 'customer_id'
select2_select schedule.name, from: 'schedule_id'
select2_select payment_method.name, from: 'payment_method_id'
select2_select shipping_method.name, from: 'shipping_method_id'
find_field('begins_at').click
choose_today_from_datepicker
click_button('Next')
click_button('Next')
end
it 'has content NAME OR SKU' do
expect(page).to have_content 'NAME OR SKU'
end
context 'and click next button without adding at least one product' do
before { click_button('Next') }
it 'has content Please add at least one product' do
expect(page).to have_content 'Please add at least one product'
end
end
context 'with a product' do
before { add_variant_to_subscription test_variant, 2 }
it 'has description, price estimates, quantity and total' do
within 'table#subscription-line-items tr.item', match: :first do
expect(page).to have_selector '.description',
text: "#{test_product.name} - #{test_variant.full_name}"
expect(page).to have_selector 'td.price', text: "$13.75"
expect(page).to have_input 'quantity', with: "2"
expect(page).to have_selector 'td.total', text: "$27.50"
end
end
context 'and deleting the existing product' do
before do
within 'table#subscription-line-items tr.item', match: :first do
find("a.delete-item").click
end
end
it 'has content Please add at least one product and subscription does not change' do
click_button('Next')
expect{
click_button('Create Subscription')
expect(page).to have_content 'Please add at least one product'
}.not_to change { Subscription.count }
end
context 'and adding a new product' do
before do
click_button('Next')
click_button('edit-products')
add_variant_to_subscription shop_variant, 3
end
it 'has selectors for description, price, quantity and total' do
description = "#{shop_product.name} - #{shop_variant.full_name}"
within 'table#subscription-line-items tr.item', match: :first do
expect(page).to have_selector '.description',
text: description
expect(page).to have_selector 'td.price', text: "$7.75"
expect(page).to have_input 'quantity', with: "3"
expect(page).to have_selector 'td.total', text: "$23.25"
end
end
context 'and click next button' do
before { click_button('Next') }
it 'has current path as admin_subscriptions_path and counts by one subscription' do
expect{
click_button('Create Subscription')
expect(page).to have_current_path admin_subscriptions_path
}.to change { Subscription.count }.by(1)
end
context 'and click Create Subscription button' do
before do
click_button('Create Subscription')
select2_select shop.name, from: "shop_id"
end
it 'has selector td.items.panel-toggle' do
expect(page).to have_selector "td.items.panel-toggle"
end
it 'has selector for price, input for quantity and selector for total price' do
description = "#{shop_product.name} - #{shop_variant.full_name}"
subscription = Subscription.last
subscription_line_item = subscription.subscription_line_items.first
first("td.items.panel-toggle").click
within 'table#subscription-line-items tr.item', match: :first do
expect(page).to have_selector '.description',
text: description
expect(page).to have_selector 'td.price', text: "$7.75"
expect(page).to have_input 'quantity', with: "3"
expect(page).to have_selector 'td.total', text: "$23.25"
end
expect(subscription.customer).to eq customer
expect(subscription.schedule).to eq schedule
expect(subscription.payment_method).to eq payment_method
expect(subscription.shipping_method).to eq shipping_method
expect(subscription.bill_address.firstname).to eq 'John'
expect(subscription.ship_address.firstname).to eq 'John'
expect(subscription.subscription_line_items.count).to eq 1
expect(subscription_line_item.variant).to eq shop_variant
expect(subscription_line_item.quantity).to eq 3
end
end
end
end
end
end
end
end
context 'editing an existing subscription' do
let!(:customer) { create(:customer, enterprise: shop) }
let!(:product1) { create(:product) }
let!(:product2) { create(:product) }
let!(:product3) { create(:product) }
let!(:variant1) {
create(:variant, product: product1, unit_value: '100', price: 12.00, supplier: shop)
}
let!(:variant2) {
create(:variant, product: product2, unit_value: '1000', price: 6.00, supplier: shop)
}
let!(:variant3) {
create(:variant, product: product3, unit_value: '10000', price: 22.00, supplier: shop)
}
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
let!(:order_cycle) {
create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.from_now,
orders_close_at: 7.days.from_now)
}
let!(:outgoing_exchange) {
order_cycle.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2],
enterprise_fees: [enterprise_fee])
}
let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) }
let!(:variant3_oc) {
create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.from_now,
orders_close_at: 7.days.from_now)
}
let!(:variant3_ex) {
variant3_oc.exchanges.create(sender: shop, receiver: shop, variants: [variant3])
}
let!(:payment_method) { create(:payment_method, distributors: [shop]) }
let!(:stripe_payment_method) {
create(:stripe_sca_payment_method, name: 'Credit Card', distributors: [shop])
}
let!(:shipping_method) { create(:shipping_method, distributors: [shop]) }
let!(:subscription) {
create(:subscription,
shop:,
customer:,
schedule:,
payment_method:,
shipping_method:,
subscription_line_items: [create(:subscription_line_item, variant: variant1,
quantity: 2,
price_estimate: 13.75)],
with_proxy_orders: true)
}
it "passes the smoke test" do
visit edit_admin_subscription_path(subscription)
# Customer and Schedule cannot be edited
click_button 'edit-details'
expect(page).to have_selector '#s2id_customer_id.select2-container-disabled'
expect(page).to have_selector '#s2id_schedule_id.select2-container-disabled'
# Can't use a Stripe payment method because customer does not allow it
select2_select stripe_payment_method.name, from: 'payment_method_id'
expect(page).to have_content 'Charges are not allowed by this customer'
click_button 'Save Changes'
expect(page).to have_content 'Credit card charges are not allowed by this customer'
select2_select payment_method.name, from: 'payment_method_id'
click_button 'Review'
# Existing products should be visible
click_button 'edit-products'
within "#sli_0" do
expect(page).to have_selector '.description',
text: "#{product1.name} - #{variant1.full_name}"
expect(page).to have_selector 'td.price', text: "$13.75"
expect(page).to have_input 'quantity', with: "2"
expect(page).to have_selector 'td.total', text: "$27.50"
# Remove variant1 from the subscription
find("a.delete-item").click
end
# Attempting to submit without a product
click_button 'Save Changes'
expect(page).to have_content 'Please add at least one product'
# Add variant2 to the subscription
add_variant_to_subscription(variant2, 1)
within "#sli_0" do
expect(page).to have_selector '.description',
text: "#{product2.name} - #{variant2.full_name}"
expect(page).to have_selector 'td.price', text: "$7.75"
expect(page).to have_input 'quantity', with: "1"
expect(page).to have_selector 'td.total', text: "$7.75"
end
# Total should be $7.75
expect(page).to have_selector '#order_form_total', text: "$7.75"
# Add variant3 to the subscription (even though it is not available)
add_variant_to_subscription(variant3, 1)
within "#sli_1" do
expect(page).to have_selector '.description',
text: "#{product3.name} - #{variant3.full_name}"
expect(page).to have_selector 'td.price', text: "$22.00"
expect(page).to have_input 'quantity', with: "1"
expect(page).to have_selector 'td.total', text: "$22.00"
end
# Total should be $29.75
expect(page).to have_selector '#order_form_total', text: "$29.75"
# Remove variant3 from the subscription
within '#sli_1' do
find("a.delete-item").click
end
click_button 'Save Changes'
expect(page).to have_current_path admin_subscriptions_path
select2_select shop.name, from: "shop_id"
expect(page).to have_selector "td.items.panel-toggle"
first("td.items.panel-toggle").click
# Total should be $7.75
expect(page).to have_selector '#order_form_total', text: "$7.75"
expect(page).to have_selector 'tr.item', count: 1
expect(subscription.reload.subscription_line_items.length).to eq 1
expect(subscription.subscription_line_items.first.variant).to eq variant2
end
context "with initialised order that has been changed" do
let(:proxy_order) { subscription.proxy_orders.first }
let(:order) { proxy_order.initialise_order! }
let(:line_item) { order.line_items.first }
before { line_item.update(quantity: 3) }
it "reports issues encountered during the update" do
visit edit_admin_subscription_path(subscription)
click_button 'edit-products'
within "#sli_0" do
fill_in 'quantity', with: "1"
end
click_button 'Save Changes'
expect(page).to have_content 'Saved'
expect(page).to have_selector "#order_update_issues_dialog .message",
text: 'Some orders could not be automatically updated, ' \
'this is most likely because they have been ' \
'manually edited. Please review the issues listed ' \
'below and make any adjustments to individual ' \
'orders if required.'
end
end
end
end
end