# 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