Merge pull request #12502 from dacook/specs

Break up large spec files
This commit is contained in:
Maikel
2024-05-22 13:39:02 +10:00
committed by GitHub
5 changed files with 665 additions and 556 deletions

View File

@@ -65,7 +65,7 @@ jobs:
- name: Set up database
run: |
bundle exec rake db:create db:schema:load
bin/rake db:create db:schema:load
- name: Run tests
env:
@@ -83,7 +83,7 @@ jobs:
KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/controllers/**/*_spec.rb}"
run: |
git show --no-patch # the commit being tested (which is often a merge due to actions/checkout@v3)
bundle exec rake knapsack_pro:rspec
bin/rake knapsack_pro:rspec
models:
runs-on: ubuntu-22.04
@@ -106,10 +106,10 @@ jobs:
# [n] - where the n is a number of parallel jobs you want to run your tests on.
# Use a higher number if you have slow tests to split them between more parallel jobs.
# Remember to update the value of the `ci_node_index` below to (0..n-1).
ci_node_total: [5]
ci_node_total: [4]
# Indexes for parallel jobs (starting from zero).
# E.g. use [0, 1] for 2 parallel jobs, [0, 1, 2] for 3 parallel jobs, etc.
ci_node_index: [0, 1, 2, 3, 4]
ci_node_index: [0, 1, 2, 3]
steps:
- uses: actions/checkout@v3
@@ -125,7 +125,7 @@ jobs:
- name: Set up database
run: |
bundle exec rake db:create db:schema:load
bin/rake db:create db:schema:load
- name: Run tests
env:
@@ -142,7 +142,7 @@ jobs:
#KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES: true
KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/models/**/*_spec.rb}"
run: |
bundle exec rake knapsack_pro:rspec
bin/rake knapsack_pro:rspec
system_admin:
runs-on: ubuntu-22.04
@@ -165,10 +165,10 @@ jobs:
# [n] - where the n is a number of parallel jobs you want to run your tests on.
# Use a higher number if you have slow tests to split them between more parallel jobs.
# Remember to update the value of the `ci_node_index` below to (0..n-1).
ci_node_total: [13]
ci_node_total: [14]
# Indexes for parallel jobs (starting from zero).
# E.g. use [0, 1] for 2 parallel jobs, [0, 1, 2] for 3 parallel jobs, etc.
ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
steps:
- uses: actions/checkout@v3
@@ -191,7 +191,7 @@ jobs:
- name: Set up database
run: |
bundle exec rake db:create db:schema:load
bin/rake db:create db:schema:load
- name: Run tests
@@ -210,7 +210,7 @@ jobs:
KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/system/admin/**/*_spec.rb}"
run: |
bundle exec rake knapsack_pro:queue:rspec
bin/rake knapsack_pro:queue:rspec
- name: Archive failed tests screenshots
if: failure()
@@ -268,7 +268,7 @@ jobs:
- name: Set up database
run: |
bundle exec rake db:create db:schema:load
bin/rake db:create db:schema:load
- name: Run tests
@@ -287,7 +287,7 @@ jobs:
KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/system/consumer/**/*_spec.rb}"
run: |
bundle exec rake knapsack_pro:queue:rspec
bin/rake knapsack_pro:queue:rspec
- name: Archive failed tests screenshots
if: failure()
@@ -346,7 +346,7 @@ jobs:
- name: Set up database
run: |
bundle exec rake db:create db:schema:load
bin/rake db:create db:schema:load
- name: Run tests
@@ -365,7 +365,7 @@ jobs:
KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/lib/**/*_spec.rb,spec/migrations/**/*_spec.rb,spec/serializers/**/*_spec.rb,engines/**/*_spec.rb}"
run: |
bundle exec rake knapsack_pro:rspec
bin/rake knapsack_pro:rspec
- name: Archive failed tests screenshots
if: failure()
@@ -424,7 +424,7 @@ jobs:
- name: Set up database
run: |
bundle exec rake db:create db:schema:load
bin/rake db:create db:schema:load
- name: Run tests
env:
@@ -441,7 +441,7 @@ jobs:
#KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES: true
KNAPSACK_PRO_TEST_FILE_EXCLUDE_PATTERN: "{engines/**/*_spec.rb,spec/models/**/*_spec.rb,spec/controllers/**/*_spec.rb,spec/serializers/**/*_spec.rb,spec/lib/**/*_spec.rb,spec/migrations/**/*_spec.rb,spec/system/**/*_spec.rb}"
run: |
bundle exec rake knapsack_pro:rspec
bin/rake knapsack_pro:rspec
non_knapsack_jest_karma:
runs-on: ubuntu-22.04
@@ -475,7 +475,7 @@ jobs:
run: yarn install --frozen-lockfile
- name: Run JS tests
run: bundle exec rake karma:run
run: bin/rake karma:run
- name: Run jest tests
run: yarn jest

View File

@@ -1140,165 +1140,4 @@ RSpec.describe '
end
end
end
describe "Legal Invoices", feature: :invoices do
before do
login_as user
end
describe "for order states" do
context "complete" do
let!(:order1) {
create(:order_with_totals_and_distribution, user:, distributor:,
order_cycle:, state: 'complete',
payment_state: 'balance_due',
customer_id: customer.id)
}
context "editing the order" do
before do
visit spree.edit_admin_order_path(order1)
end
it "displays the invoice tab" do
expect(page).to have_content "Complete".upcase
expect(page).to have_content "Invoices".upcase
end
end
context "visiting the invoices tab" do
let!(:table_header) {
[
"Date/Time",
"Invoice Number",
"Amount",
"Status",
"File",
].join(" ").upcase
}
let(:invoice_number){ "#{order.distributor_id}-1" }
let(:table_contents) {
[
Invoice.first.created_at.strftime('%B %d, %Y').to_s,
invoice_number,
"0.0",
"Active",
"Download"
].join(" ")
}
let(:download_href) {
"#{spree.print_admin_order_path(order1)}?invoice_id=#{Invoice.last.id}"
}
before do
Spree::Config[:enterprise_number_required_on_invoices?] = false
visit spree.admin_order_invoices_path(order1)
end
it "displays the invoices table" do
# with no invoices, only the table header is displayed
expect(page).to have_css "table.index"
expect(page).to have_content "#{customer.first_name} #{customer.last_name} -"
expect(page.find("table").text).to have_content(table_header)
# the New invoice button + the warning should be visible
expect(page).to have_link "Create or Update Invoice"
expect(page).to have_content "The order has changed since the last invoice update."
click_link "Create or Update Invoice"
# and disappear after clicking
expect(page).not_to have_link "Create or Update Invoice"
expect(page).not_to have_content "The order has changed since the last invoice update."
# creating an invoice, displays a second row
expect(page.find("table").text).to have_content(table_contents)
# with a valid invoice download link
expect(page).to have_link("Download",
href: download_href)
end
context "the Create or Update Invoice button" do
context "when an ABN number is mandatory for invoices but not present" do
before do
Spree::Config[:enterprise_number_required_on_invoices?] = true
end
it "displays a warning that an ABN is required when it's clicked" do
visit spree.admin_order_invoices_path(order1)
message = accept_prompt { click_link "Create or Update Invoice" }
distributor = order1.distributor
expect(message)
.to eq "#{distributor.name} must have a valid ABN before invoices can be used."
end
end
end
end
end
context "resumed" do
let!(:order2) {
create(:order_with_totals_and_distribution, user:, distributor:,
order_cycle:, state: 'resumed',
payment_state: 'balance_due')
}
before do
visit spree.edit_admin_order_path(order2)
end
it "displays the invoice tab" do
expect(page).to have_content "Resumed".upcase
expect(page).to have_content "Invoices".upcase
end
end
context "canceled" do
let!(:order3) {
create(:order_with_totals_and_distribution, user:, distributor:,
order_cycle:, state: 'canceled',
payment_state: 'balance_due')
}
before do
visit spree.edit_admin_order_path(order3)
end
it "displays the invoice tab" do
expect(page).to have_content "Cancelled".upcase
expect(page).to have_content "Invoices".upcase
end
end
context "cart" do
let!(:order_empty) {
create(:order_with_line_items, user:, distributor:, order_cycle:,
line_items_count: 0)
}
before do
visit spree.edit_admin_order_path(order_empty)
end
it "should not display the invoice tab" do
expect(page).to have_content "Cart".upcase
expect(page).not_to have_content "Invoices".upcase
end
end
context "payment" do
let!(:order4) do
create(:order_ready_for_payment, user:, distributor:,
order_cycle:,
payment_state: 'balance_due')
end
before do
visit spree.edit_admin_order_path(order4)
end
it "should not display the invoice tab" do
expect(page).to have_content "Payment".upcase
expect(page).not_to have_content "Invoices".upcase
end
end
end
end
end

View File

@@ -0,0 +1,473 @@
# frozen_string_literal: true
require "system_helper"
RSpec.describe '
As an administrator
I want to perform bulk order actions
' do
include AuthenticationHelper
include WebHelper
let(:owner) { create(:user) }
let(:owner2) { create(:user) }
let(:customer) { create(:user) }
let(:customer2) { create(:user) }
let(:customer3) { create(:user) }
let(:customer4) { create(:user) }
let(:customer5) { create(:user) }
let(:billing_address) { create(:address, :randomized) }
let(:billing_address2) { create(:address, :randomized) }
let(:billing_address3) { create(:address, :randomized) }
let(:billing_address4) { create(:address, :randomized) }
let(:billing_address5) { create(:address, :randomized) }
let(:product) { create(:simple_product) }
let(:distributor) {
create(:distributor_enterprise, owner:, with_payment_and_shipping: true,
charges_sales_tax: true)
}
let(:distributor2) { create(:distributor_enterprise_with_tax, owner:) }
let(:distributor3) {
create(:distributor_enterprise, owner:, with_payment_and_shipping: true,
charges_sales_tax: true)
}
let(:distributor4) {
create(:distributor_enterprise, owner:, with_payment_and_shipping: true,
charges_sales_tax: true)
}
let(:distributor5) { create(:distributor_enterprise, owner: owner2, charges_sales_tax: true) }
let!(:shipping_method) {
create(:shipping_method_with, :pickup, name: "pick_up",
distributors: [distributor, distributor2, distributor3])
}
let!(:shipping_method2) {
create(:shipping_method_with, :pickup, name: "delivery",
distributors: [distributor4, distributor5])
}
let(:order_cycle) do
create(:simple_order_cycle, name: 'One', distributors: [distributor, distributor2,
distributor3, distributor4],
variants: [product.variants.first])
end
context "with a complete order" do
let(:order) do
create(:order_with_totals_and_distribution, user: customer, distributor:,
order_cycle:,
state: 'complete', payment_state: 'balance_due',
bill_address_id: billing_address.id)
end
let!(:order_cycle2) {
create(:simple_order_cycle, name: 'Two', orders_close_at: 2.weeks.from_now)
}
let!(:order_cycle3) {
create(:simple_order_cycle, name: 'Three', orders_close_at: 3.weeks.from_now)
}
let!(:order_cycle4) {
create(:simple_order_cycle, name: 'Four', orders_close_at: 4.weeks.from_now)
}
let!(:order_cycle5) do
create(:simple_order_cycle, name: 'Five', coordinator: distributor5,
distributors: [distributor5], variants: [product.variants.first])
end
let!(:order2) {
create(:order_ready_to_ship, user: customer2, distributor: distributor2,
order_cycle: order_cycle2, completed_at: 2.days.ago,
bill_address_id: billing_address2.id)
}
let!(:order3) {
create(:order_with_credit_payment, user: customer3, distributor: distributor3,
order_cycle: order_cycle3,
bill_address_id: billing_address3.id)
}
let!(:order4) {
create(:order_with_credit_payment, user: customer4, distributor: distributor4,
order_cycle: order_cycle4,
bill_address_id: billing_address4.id)
}
let!(:order5) {
create(:order_ready_to_ship, user: customer5, distributor: distributor5,
order_cycle: order_cycle5,
bill_address_id: billing_address5.id)
}
context "as a super admin" do
before do
login_as_admin
visit spree.admin_orders_path
end
context "can bulk send invoices per email" do
before do
Spree::Config[:enable_invoices?] = true
Spree::Config[:enterprise_number_required_on_invoices?] = false
end
context "with multiple orders with differents states" do
before do
order2.update(state: "complete")
order3.update(state: "resumed")
order4.update(state: "canceled")
order5.update(state: "payment")
end
it "can bulk send invoices per email, but only for the 'complete' or 'resumed' ones" do
within "#listing_orders" do
page.find("input[name='bulk_ids[]'][value='#{order2.id}']").click
page.find("input[name='bulk_ids[]'][value='#{order3.id}']").click
page.find("input[name='bulk_ids[]'][value='#{order4.id}']").click
page.find("input[name='bulk_ids[]'][value='#{order5.id}']").click
end
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Send Invoices").click
end
expect(page).to have_content "This will email customer invoices " \
"for all selected complete orders."
expect(page).to have_content "Are you sure you want to proceed?"
within ".reveal-modal" do
expect {
find_button("Confirm").click
}.to enqueue_job(ActionMailer::MailDeliveryJob).exactly(:twice)
end
expect(page).to have_content "Invoice emails sent for 2 orders."
end
end
it "can bulk send confirmation email from 2 orders" do
page.find("#listing_orders tbody tr:nth-child(1) input[name='bulk_ids[]']").click
page.find("#listing_orders tbody tr:nth-child(2) input[name='bulk_ids[]']").click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Resend Confirmation").click
end
expect(page).to have_content "Are you sure you want to proceed?"
within ".reveal-modal" do
expect {
find_button("Confirm").click
}.to enqueue_job(ActionMailer::MailDeliveryJob).exactly(:twice)
end
expect(page).to have_content "Confirmation emails sent for 2 orders."
end
end
context "can bulk print invoices" do
let(:order4_selector){ "#order_#{order4.id} input[name='bulk_ids[]']" }
let(:order5_selector){ "#order_#{order5.id} input[name='bulk_ids[]']" }
shared_examples "can bulk print invoices from 2 orders" do
it "bulk prints invoices in pdf format" do
page.find(order4_selector).click
page.find(order5_selector).click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
expect {
page.find("span", text: "Print Invoices").click # Prints invoices in bulk
}.to enqueue_job(BulkInvoiceJob).exactly(:once)
end
expect(page).to have_content "Compiling Invoices"
expect(page).to have_content "Please wait until the PDF is ready " \
"before closing this modal."
# we don't run Sidekiq in test environment, so we need to manually run enqueued jobs
# to generate PDF files, and change the modal accordingly
perform_enqueued_jobs(only: BulkInvoiceJob)
expect(page).to have_content "Bulk Invoice created"
within ".modal-content" do
expect(page).to have_link(class: "button", text: "VIEW FILE", href: /invoices/)
invoice_content = extract_pdf_content
expect(invoice_content).to have_content("TAX INVOICE", count: 2)
expect(invoice_content).to have_content(order4.number.to_s)
expect(invoice_content).to have_content(order5.number.to_s)
expect(invoice_content).to have_content(distributor4.name.to_s)
expect(invoice_content).to have_content(distributor5.name.to_s)
expect(invoice_content).to have_content(order_cycle4.name.to_s)
expect(invoice_content).to have_content(order_cycle5.name.to_s)
end
end
end
shared_examples "should ignore the non invoiceable order" do
it "bulk prints invoices in pdf format" do
page.find(order4_selector).click
page.find(order5_selector).click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
expect {
page.find("span", text: "Print Invoices").click # Prints invoices in bulk
}.to enqueue_job(BulkInvoiceJob).exactly(:once)
end
expect(page).to have_content "Compiling Invoices"
expect(page).to have_content "Please wait until the PDF is ready " \
"before closing this modal."
perform_enqueued_jobs(only: BulkInvoiceJob)
expect(page).to have_content "Bulk Invoice created"
within ".modal-content" do
expect(page).to have_link(class: "button", text: "VIEW FILE",
href: /invoices/)
invoice_content = extract_pdf_content
expect(invoice_content).to have_content("TAX INVOICE", count: 1)
expect(invoice_content).not_to have_content(order4.number.to_s)
expect(invoice_content).to have_content(order5.number.to_s)
expect(invoice_content).not_to have_content(distributor4.name.to_s)
expect(invoice_content).to have_content(distributor5.name.to_s)
expect(invoice_content).not_to have_content(order_cycle4.name.to_s)
expect(invoice_content).to have_content(order_cycle5.name.to_s)
end
end
end
context "ABN is not required" do
before do
allow(Spree::Config).to receive(:enterprise_number_required_on_invoices?)
.and_return false
end
it_behaves_like "can bulk print invoices from 2 orders"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "can bulk print invoices from 2 orders"
end
context "one of the two orders is not invoiceable" do
before do
order4.cancel!
end
it_behaves_like "should ignore the non invoiceable order"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "should ignore the non invoiceable order"
end
end
context "ordering by customer name" do
context "ascending" do
let!(:surnames) {
[order2.name.gsub(/.* /, ""), order3.name.gsub(/.* /, ""),
order4.name.gsub(/.* /, ""), order5.name.gsub(/.* /, "")].sort
}
it "orders by customer name ascending" do
page.find('a', text: "NAME").click # orders alphabetically (asc)
sleep(0.5) # waits for column sorting
page.find("#selectAll").click
print_all_invoices
invoice_content = extract_pdf_content
expect(
invoice_content.join
).to match(/#{surnames[0]}.*#{surnames[1]}.*#{surnames[2]}.*#{surnames[3]}/m)
end
end
context "descending" do
let!(:surnames) {
[order2.name.gsub(/.* /, ""), order3.name.gsub(/.* /, ""),
order4.name.gsub(/.* /, ""), order5.name.gsub(/.* /, "")].sort.reverse
}
it "order by customer name descending" do
page.find('a', text: "NAME").click # orders alphabetically (asc)
sleep(0.5) # waits for column sorting
page.find('a', text: "NAME").click # orders alphabetically (desc)
sleep(0.5) # waits for column sorting
page.find("#selectAll").click
print_all_invoices
invoice_content = extract_pdf_content
expect(
invoice_content.join
).to match(/#{surnames[0]}.*#{surnames[1]}.*#{surnames[2]}.*#{surnames[3]}/m)
end
end
end
end
context "ABN is required" do
before do
allow(Spree::Config).to receive(:enterprise_number_required_on_invoices?)
.and_return true
end
context "All the distributors setup the ABN" do
before do
order4.distributor.update(abn: "123456789")
order5.distributor.update(abn: "987654321")
end
context "all the orders are invoiceable (completed/resumed)" do
it_behaves_like "can bulk print invoices from 2 orders"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "can bulk print invoices from 2 orders"
end
end
context "one of the two orders is not invoiceable" do
before do
order4.cancel!
end
it_behaves_like "should ignore the non invoiceable order"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "should ignore the non invoiceable order"
end
end
end
context "the distributor of one of the order didn't set the ABN" do
before do
order4.distributor.update(abn: "123456789")
order5.distributor.update(abn: nil)
end
shared_examples "should not print the invoice" do
it "should render a warning message" do
page.find(order4_selector).click
page.find(order5_selector).click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
expect {
page.find("span", text: "Print Invoices").click # Prints invoices in bulk
}.not_to enqueue_job(BulkInvoiceJob)
end
expect(page).not_to have_content "Compiling Invoices"
expect(page).not_to have_content "Please wait until the PDF is ready " \
"before closing this modal."
expect(page).to have_content "#{
order5.distributor.name
} must have a valid ABN before invoices can be used."
end
end
it_behaves_like "should not print the invoice"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "should not print the invoice"
end
end
end
end
it "can bulk cancel 2 orders" do
page.find("#listing_orders tbody tr:nth-child(1) input[name='bulk_ids[]']").click
page.find("#listing_orders tbody tr:nth-child(2) input[name='bulk_ids[]']").click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Cancel Orders").click
end
expect(page).to have_content "Are you sure you want to proceed?"
expect(page).to have_content "This will cancel the current order."
within ".reveal-modal" do
uncheck "Send a cancellation email to the customer"
expect {
find_button("Cancel").click # Cancels the cancel action
}.not_to enqueue_job(ActionMailer::MailDeliveryJob).exactly(:twice)
end
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Cancel Orders").click
end
within ".reveal-modal" do
expect {
find_button("Confirm").click # Confirms the cancel action
}.not_to enqueue_job(ActionMailer::MailDeliveryJob).exactly(:twice)
end
expect(page).to have_content("CANCELLED", count: 2)
end
end
context "for a hub manager" do
before do
login_as owner2
visit spree.admin_orders_path
end
it "displays the orders for the respective distributor" do
expect(page).to have_content order5.number # displays the only order for distributor5
expect(page).not_to have_content order.number
expect(page).not_to have_content order2.number
expect(page).not_to have_content order3.number
expect(page).not_to have_content order4.number
end
it "cannot send emails to orders if permission have been revoked in the meantime" do
page.find("#listing_orders tbody tr:nth-child(1) input[name='bulk_ids[]']").click
# Find the clicked order
order = Spree::Order.find_by(
id: page.find("#listing_orders tbody tr:nth-child(1) input[name='bulk_ids[]']").value
)
# Revoke permission for the current user on that specific order by changing its owners
order.update_attribute(:distributor, distributor)
order.update_attribute(:order_cycle, order_cycle)
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Resend Confirmation").click
end
expect(page).to have_content "Are you sure you want to proceed?"
within ".reveal-modal" do
expect {
find_button("Confirm").click
}.not_to enqueue_job(ActionMailer::MailDeliveryJob)
end
end
end
end
def extract_pdf_content
# Extract last part of invoice URL
link = page.find(class: "button", text: "VIEW FILE")
filename = link[:href].match %r{/invoices/.*}
# Load invoice temp file directly instead of downloading
reader = PDF::Reader.new("tmp/#{filename}.pdf")
reader.pages.map(&:text)
end
def print_all_invoices
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
expect {
page.find("span", text: "Print Invoices").click # Prints invoices in bulk
}.to enqueue_job(BulkInvoiceJob).exactly(:once)
end
expect(page).to have_content "Compiling Invoices"
expect(page).to have_content "Please wait until the PDF is ready " \
"before closing this modal."
perform_enqueued_jobs(only: BulkInvoiceJob)
expect(page).to have_content "Bulk Invoice created"
end
end

View File

@@ -211,3 +211,178 @@ RSpec.describe '
end
end
end
RSpec.describe "Invoice order states", feature: :invoices do
let(:user) { create(:user) }
let(:product) { create(:simple_product) }
let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) }
let(:order_cycle) do
create(:simple_order_cycle, name: 'One', distributors: [distributor],
variants: [product.variants.first])
end
let(:order) do
create(:order_with_totals_and_distribution, user:, distributor:,
order_cycle:, state: 'complete',
payment_state: 'balance_due')
end
let(:customer) { order.customer }
before do
order.finalize!
login_as user
end
context "complete" do
let!(:order1) {
create(:order_with_totals_and_distribution, user:, distributor:,
order_cycle:, state: 'complete',
payment_state: 'balance_due',
customer_id: customer.id)
}
context "editing the order" do
before do
visit spree.edit_admin_order_path(order1)
end
it "displays the invoice tab" do
expect(page).to have_content "Complete".upcase
expect(page).to have_content "Invoices".upcase
end
end
context "visiting the invoices tab" do
let!(:table_header) {
[
"Date/Time",
"Invoice Number",
"Amount",
"Status",
"File",
].join(" ").upcase
}
let(:invoice_number){ "#{order.distributor_id}-1" }
let(:table_contents) {
[
Invoice.first.created_at.strftime('%B %d, %Y').to_s,
invoice_number,
"0.0",
"Active",
"Download"
].join(" ")
}
let(:download_href) {
"#{spree.print_admin_order_path(order1)}?invoice_id=#{Invoice.last.id}"
}
before do
Spree::Config[:enterprise_number_required_on_invoices?] = false
visit spree.admin_order_invoices_path(order1)
end
it "displays the invoices table" do
# with no invoices, only the table header is displayed
expect(page).to have_css "table.index"
expect(page).to have_content "#{customer.first_name} #{customer.last_name} -"
expect(page.find("table").text).to have_content(table_header)
# the New invoice button + the warning should be visible
expect(page).to have_link "Create or Update Invoice"
expect(page).to have_content "The order has changed since the last invoice update."
click_link "Create or Update Invoice"
# and disappear after clicking
expect(page).not_to have_link "Create or Update Invoice"
expect(page).not_to have_content "The order has changed since the last invoice update."
# creating an invoice, displays a second row
expect(page.find("table").text).to have_content(table_contents)
# with a valid invoice download link
expect(page).to have_link("Download",
href: download_href)
end
context "the Create or Update Invoice button" do
context "when an ABN number is mandatory for invoices but not present" do
before do
Spree::Config[:enterprise_number_required_on_invoices?] = true
end
it "displays a warning that an ABN is required when it's clicked" do
visit spree.admin_order_invoices_path(order1)
message = accept_prompt { click_link "Create or Update Invoice" }
distributor = order1.distributor
expect(message)
.to eq "#{distributor.name} must have a valid ABN before invoices can be used."
end
end
end
end
end
context "resumed" do
let!(:order2) {
create(:order_with_totals_and_distribution, user:, distributor:,
order_cycle:, state: 'resumed',
payment_state: 'balance_due')
}
before do
visit spree.edit_admin_order_path(order2)
end
it "displays the invoice tab" do
expect(page).to have_content "Resumed".upcase
expect(page).to have_content "Invoices".upcase
end
end
context "canceled" do
let!(:order3) {
create(:order_with_totals_and_distribution, user:, distributor:,
order_cycle:, state: 'canceled',
payment_state: 'balance_due')
}
before do
visit spree.edit_admin_order_path(order3)
end
it "displays the invoice tab" do
expect(page).to have_content "Cancelled".upcase
expect(page).to have_content "Invoices".upcase
end
end
context "cart" do
let!(:order_empty) {
create(:order_with_line_items, user:, distributor:, order_cycle:,
line_items_count: 0)
}
before do
visit spree.edit_admin_order_path(order_empty)
end
it "should not display the invoice tab" do
expect(page).to have_content "Cart".upcase
expect(page).not_to have_content "Invoices".upcase
end
end
context "payment" do
let!(:order4) do
create(:order_ready_for_payment, user:, distributor:,
order_cycle:,
payment_state: 'balance_due')
end
before do
visit spree.edit_admin_order_path(order4)
end
it "should not display the invoice tab" do
expect(page).to have_content "Payment".upcase
expect(page).not_to have_content "Invoices".upcase
end
end
end

View File

@@ -504,358 +504,6 @@ RSpec.describe '
end
end
context "bulk actions" do
context "as a super admin" do
before do
login_as_admin
visit spree.admin_orders_path
end
context "can bulk send invoices per email" do
before do
Spree::Config[:enable_invoices?] = true
Spree::Config[:enterprise_number_required_on_invoices?] = false
end
context "with multiple orders with differents states" do
before do
order2.update(state: "complete")
order3.update(state: "resumed")
order4.update(state: "canceled")
order5.update(state: "payment")
end
it "can bulk send invoices per email, but only for the 'complete' or 'resumed' ones" do
within "#listing_orders" do
page.find("input[name='bulk_ids[]'][value='#{order2.id}']").click
page.find("input[name='bulk_ids[]'][value='#{order3.id}']").click
page.find("input[name='bulk_ids[]'][value='#{order4.id}']").click
page.find("input[name='bulk_ids[]'][value='#{order5.id}']").click
end
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Send Invoices").click
end
expect(page).to have_content "This will email customer invoices " \
"for all selected complete orders."
expect(page).to have_content "Are you sure you want to proceed?"
within ".reveal-modal" do
expect {
find_button("Confirm").click
}.to enqueue_job(ActionMailer::MailDeliveryJob).exactly(:twice)
end
expect(page).to have_content "Invoice emails sent for 2 orders."
end
end
it "can bulk send confirmation email from 2 orders" do
page.find("#listing_orders tbody tr:nth-child(1) input[name='bulk_ids[]']").click
page.find("#listing_orders tbody tr:nth-child(2) input[name='bulk_ids[]']").click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Resend Confirmation").click
end
expect(page).to have_content "Are you sure you want to proceed?"
within ".reveal-modal" do
expect {
find_button("Confirm").click
}.to enqueue_job(ActionMailer::MailDeliveryJob).exactly(:twice)
end
expect(page).to have_content "Confirmation emails sent for 2 orders."
end
end
context "can bulk print invoices" do
let(:order4_selector){ "#order_#{order4.id} input[name='bulk_ids[]']" }
let(:order5_selector){ "#order_#{order5.id} input[name='bulk_ids[]']" }
shared_examples "can bulk print invoices from 2 orders" do
it "bulk prints invoices in pdf format" do
page.find(order4_selector).click
page.find(order5_selector).click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
expect {
page.find("span", text: "Print Invoices").click # Prints invoices in bulk
}.to enqueue_job(BulkInvoiceJob).exactly(:once)
end
expect(page).to have_content "Compiling Invoices"
expect(page).to have_content "Please wait until the PDF is ready " \
"before closing this modal."
# we don't run Sidekiq in test environment, so we need to manually run enqueued jobs
# to generate PDF files, and change the modal accordingly
perform_enqueued_jobs(only: BulkInvoiceJob)
expect(page).to have_content "Bulk Invoice created"
within ".modal-content" do
expect(page).to have_link(class: "button", text: "VIEW FILE", href: /invoices/)
invoice_content = extract_pdf_content
expect(invoice_content).to have_content("TAX INVOICE", count: 2)
expect(invoice_content).to have_content(order4.number.to_s)
expect(invoice_content).to have_content(order5.number.to_s)
expect(invoice_content).to have_content(distributor4.name.to_s)
expect(invoice_content).to have_content(distributor5.name.to_s)
expect(invoice_content).to have_content(order_cycle4.name.to_s)
expect(invoice_content).to have_content(order_cycle5.name.to_s)
end
end
end
shared_examples "should ignore the non invoiceable order" do
it "bulk prints invoices in pdf format" do
page.find(order4_selector).click
page.find(order5_selector).click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
expect {
page.find("span", text: "Print Invoices").click # Prints invoices in bulk
}.to enqueue_job(BulkInvoiceJob).exactly(:once)
end
expect(page).to have_content "Compiling Invoices"
expect(page).to have_content "Please wait until the PDF is ready " \
"before closing this modal."
perform_enqueued_jobs(only: BulkInvoiceJob)
expect(page).to have_content "Bulk Invoice created"
within ".modal-content" do
expect(page).to have_link(class: "button", text: "VIEW FILE",
href: /invoices/)
invoice_content = extract_pdf_content
expect(invoice_content).to have_content("TAX INVOICE", count: 1)
expect(invoice_content).not_to have_content(order4.number.to_s)
expect(invoice_content).to have_content(order5.number.to_s)
expect(invoice_content).not_to have_content(distributor4.name.to_s)
expect(invoice_content).to have_content(distributor5.name.to_s)
expect(invoice_content).not_to have_content(order_cycle4.name.to_s)
expect(invoice_content).to have_content(order_cycle5.name.to_s)
end
end
end
context "ABN is not required" do
before do
allow(Spree::Config).to receive(:enterprise_number_required_on_invoices?)
.and_return false
end
it_behaves_like "can bulk print invoices from 2 orders"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "can bulk print invoices from 2 orders"
end
context "one of the two orders is not invoiceable" do
before do
order4.cancel!
end
it_behaves_like "should ignore the non invoiceable order"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "should ignore the non invoiceable order"
end
end
context "ordering by customer name" do
context "ascending" do
let!(:surnames) {
[order2.name.gsub(/.* /, ""), order3.name.gsub(/.* /, ""),
order4.name.gsub(/.* /, ""), order5.name.gsub(/.* /, "")].sort
}
it "orders by customer name ascending" do
page.find('a', text: "NAME").click # orders alphabetically (asc)
sleep(0.5) # waits for column sorting
page.find("#selectAll").click
print_all_invoices
invoice_content = extract_pdf_content
expect(
invoice_content.join
).to match(/#{surnames[0]}.*#{surnames[1]}.*#{surnames[2]}.*#{surnames[3]}/m)
end
end
context "descending" do
let!(:surnames) {
[order2.name.gsub(/.* /, ""), order3.name.gsub(/.* /, ""),
order4.name.gsub(/.* /, ""), order5.name.gsub(/.* /, "")].sort.reverse
}
it "order by customer name descending" do
page.find('a', text: "NAME").click # orders alphabetically (asc)
sleep(0.5) # waits for column sorting
page.find('a', text: "NAME").click # orders alphabetically (desc)
sleep(0.5) # waits for column sorting
page.find("#selectAll").click
print_all_invoices
invoice_content = extract_pdf_content
expect(
invoice_content.join
).to match(/#{surnames[0]}.*#{surnames[1]}.*#{surnames[2]}.*#{surnames[3]}/m)
end
end
end
end
context "ABN is required" do
before do
allow(Spree::Config).to receive(:enterprise_number_required_on_invoices?)
.and_return true
end
context "All the distributors setup the ABN" do
before do
order4.distributor.update(abn: "123456789")
order5.distributor.update(abn: "987654321")
end
context "all the orders are invoiceable (completed/resumed)" do
it_behaves_like "can bulk print invoices from 2 orders"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "can bulk print invoices from 2 orders"
end
end
context "one of the two orders is not invoiceable" do
before do
order4.cancel!
end
it_behaves_like "should ignore the non invoiceable order"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "should ignore the non invoiceable order"
end
end
end
context "the distributor of one of the order didn't set the ABN" do
before do
order4.distributor.update(abn: "123456789")
order5.distributor.update(abn: nil)
end
shared_examples "should not print the invoice" do
it "should render a warning message" do
page.find(order4_selector).click
page.find(order5_selector).click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
expect {
page.find("span", text: "Print Invoices").click # Prints invoices in bulk
}.not_to enqueue_job(BulkInvoiceJob)
end
expect(page).not_to have_content "Compiling Invoices"
expect(page).not_to have_content "Please wait until the PDF is ready " \
"before closing this modal."
expect(page).to have_content "#{
order5.distributor.name
} must have a valid ABN before invoices can be used."
end
end
it_behaves_like "should not print the invoice"
context "with legal invoices feature", feature: :invoices do
it_behaves_like "should not print the invoice"
end
end
end
end
it "can bulk cancel 2 orders" do
page.find("#listing_orders tbody tr:nth-child(1) input[name='bulk_ids[]']").click
page.find("#listing_orders tbody tr:nth-child(2) input[name='bulk_ids[]']").click
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Cancel Orders").click
end
expect(page).to have_content "Are you sure you want to proceed?"
expect(page).to have_content "This will cancel the current order."
within ".reveal-modal" do
uncheck "Send a cancellation email to the customer"
expect {
find_button("Cancel").click # Cancels the cancel action
}.not_to enqueue_job(ActionMailer::MailDeliveryJob).exactly(:twice)
end
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Cancel Orders").click
end
within ".reveal-modal" do
expect {
find_button("Confirm").click # Confirms the cancel action
}.not_to enqueue_job(ActionMailer::MailDeliveryJob).exactly(:twice)
end
expect(page).to have_content("CANCELLED", count: 2)
end
end
context "for a hub manager" do
before do
login_as owner2
visit spree.admin_orders_path
end
it "displays the orders for the respective distributor" do
expect(page).to have_content order5.number # displays the only order for distributor5
expect(page).not_to have_content order.number
expect(page).not_to have_content order2.number
expect(page).not_to have_content order3.number
expect(page).not_to have_content order4.number
end
it "cannot send emails to orders if permission have been revoked in the meantime" do
page.find("#listing_orders tbody tr:nth-child(1) input[name='bulk_ids[]']").click
# Find the clicked order
order = Spree::Order.find_by(
id: page.find("#listing_orders tbody tr:nth-child(1) input[name='bulk_ids[]']").value
)
# Revoke permission for the current user on that specific order by changing its owners
order.update_attribute(:distributor, distributor)
order.update_attribute(:order_cycle, order_cycle)
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
page.find("span", text: "Resend Confirmation").click
end
expect(page).to have_content "Are you sure you want to proceed?"
within ".reveal-modal" do
expect {
find_button("Confirm").click
}.not_to enqueue_job(ActionMailer::MailDeliveryJob)
end
end
end
end
context "pagination" do
before do
login_as_admin
@@ -1131,30 +779,4 @@ RSpec.describe '
expect(find("input.datepicker").value).to be_empty
end
end
def extract_pdf_content
# Extract last part of invoice URL
link = page.find(class: "button", text: "VIEW FILE")
filename = link[:href].match %r{/invoices/.*}
# Load invoice temp file directly instead of downloading
reader = PDF::Reader.new("tmp/#{filename}.pdf")
reader.pages.map(&:text)
end
def print_all_invoices
page.find("span.icon-reorder", text: "ACTIONS").click
within ".ofn-drop-down .menu" do
expect {
page.find("span", text: "Print Invoices").click # Prints invoices in bulk
}.to enqueue_job(BulkInvoiceJob).exactly(:once)
end
expect(page).to have_content "Compiling Invoices"
expect(page).to have_content "Please wait until the PDF is ready " \
"before closing this modal."
perform_enqueued_jobs(only: BulkInvoiceJob)
expect(page).to have_content "Bulk Invoice created"
end
end