add specs

This commit is contained in:
Ahmed Ejaz
2025-03-03 05:52:26 +05:00
parent b803e18f42
commit bf6934db94
7 changed files with 434 additions and 154 deletions

View File

@@ -28,8 +28,7 @@ class SearchOrders
end
def search_query
base_query = ::Permissions::Order.new(current_user).editable_orders.not_empty
.or(::Permissions::Order.new(current_user).editable_orders.finalized)
base_query = ::Permissions::Order.new(current_user).editable_orders.not_empty.or(::Permissions::Order.new(current_user).editable_orders.finalized)
return base_query if params[:shipping_method_id].blank?

View File

@@ -3,7 +3,7 @@
- content_for :minimal_js, true
- if can?(:create, Spree::Order)
- if can?(:create, Spree::Order) && spree_current_user.can_manage_orders?
- content_for :page_actions do
%li
= button_link_to t('.new_order'), spree.new_admin_order_url, icon: 'icon-plus', id: 'admin_new_order'

View File

@@ -190,6 +190,22 @@ RSpec.describe OpenFoodNetwork::ScopeVariantsForSearch do
to eq(["Product 1", "Product a", "Product b", "Product c"])
end
end
context "when search is done by the producer allowing to edit orders" do
let(:params) { { q: "product" } }
let(:producer) { create(:supplier_enterprise) }
let(:spree_current_user) { instance_double('Spree::User', enterprises: Enterprise.where(id: producer.id), can_manage_line_items_in_orders_only?: true) }
it "returns all products distributed through distributors allowing producers to edit orders" do
v1.supplier_id = producer.id
v2.supplier_id = producer.id
v1.save!
v2.save!
expect(result).to include v1, v2
expect(result).not_to include v3, v4
end
end
end
private

View File

@@ -1012,6 +1012,29 @@ RSpec.describe Enterprise do
expect(expected).to include(sender)
end
end
describe "#is_producer" do
context "when enterprise is_primary_producer and sells none" do
it "returns true" do
enterprise = build(:supplier_enterprise)
expect(enterprise.is_producer).to be true
end
end
context "when enterprise is_primary_producer and sells any" do
it "returns false" do
enterprise = build(:enterprise, is_primary_producer: true, sells: "any")
expect(enterprise.is_producer).to be false
end
end
context "when enterprise is_primary_producer and sells own" do
it "returns false" do
enterprise = build(:enterprise, is_primary_producer: true, sells: "own")
expect(enterprise.is_producer).to be false
end
end
end
end
def enterprise_name_error(owner_email)

View File

@@ -298,4 +298,39 @@ RSpec.describe Spree::User do
end
end
end
describe "#can_manage_line_items_in_orders_only?" do
let(:producer) { create(:supplier_enterprise) }
let(:order) { create(:order, distributor: distributor) }
subject { user.can_manage_line_items_in_orders_only? }
context "when user has producer" do
let(:user) { create(:user, enterprises: [producer]) }
context "order containing their product" do
before do
order.line_items << create(:line_item, product: create(:product, supplier_id: producer.id))
end
context "order distributor allow producer to edit orders" do
let(:distributor) do
create(:distributor_enterprise, enable_producers_to_edit_orders: true)
end
it { is_expected.to be_truthy }
end
context "order distributor doesn't allow producer to edit orders" do
let(:distributor) { create(:distributor_enterprise) }
it { is_expected.to be_falsey }
end
end
end
context "no order containing their product" do
let(:user) { create(:user, enterprises: [create(:distributor_enterprise)]) }
it { is_expected.to be_falsey }
end
end
end

View File

@@ -4,7 +4,6 @@ require 'spec_helper'
module Permissions
RSpec.describe Order do
let(:user) { double(:user, can_manage_line_items_in_orders_only?: false) }
let(:permissions) { Permissions::Order.new(user) }
let!(:basic_permissions) { OpenFoodNetwork::Permissions.new(user) }
let(:distributor) { create(:distributor_enterprise) }
@@ -28,68 +27,24 @@ module Permissions
before { allow(OpenFoodNetwork::Permissions).to receive(:new) { basic_permissions } }
describe "finding orders that are visible in reports" do
let(:random_enterprise) { create(:distributor_enterprise) }
let(:order) { create(:order, order_cycle:, distributor: ) }
let!(:line_item) { create(:line_item, order:) }
let!(:producer) { create(:supplier_enterprise) }
context "with user cannot only manage line_items in orders" do
let(:user) { instance_double('Spree::User', can_manage_line_items_in_orders_only?: false) }
before do
allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") }
end
describe "finding orders that are visible in reports" do
let(:random_enterprise) { create(:distributor_enterprise) }
let(:order) { create(:order, order_cycle:, distributor: ) }
let!(:line_item) { create(:line_item, order:) }
let!(:producer) { create(:supplier_enterprise) }
context "as the hub through which the order was placed" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: distributor)
}
allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") }
end
it "should let me see the order" do
expect(permissions.visible_orders).to include order
end
end
context "as the coordinator of the order cycle through which the order was placed" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: coordinator)
}
allow(basic_permissions).to receive(:coordinated_order_cycles) {
OrderCycle.where(id: order_cycle)
}
end
it "should let me see the order" do
expect(permissions.visible_orders).to include order
end
context "with search params" do
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
let(:permissions) { Permissions::Order.new(user, search_params) }
it "only returns completed, non-cancelled orders within search filter range" do
expect(permissions.visible_orders).to include order_completed
expect(permissions.visible_orders).not_to include order_cancelled
expect(permissions.visible_orders).not_to include order_cart
expect(permissions.visible_orders).not_to include order_from_last_year
end
end
end
context "as a producer which has granted P-OC to the distributor of an order" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: producer)
}
create(:enterprise_relationship, parent: producer, child: distributor,
permissions_list: [:add_to_order_cycle])
end
context "which contains my products" do
context "as the hub through which the order was placed" do
before do
line_item.variant.supplier = producer
line_item.variant.save
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: distributor)
}
end
it "should let me see the order" do
@@ -97,118 +52,206 @@ module Permissions
end
end
context "which does not contain my products" do
context "as the coordinator of the order cycle through which the order was placed" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: coordinator)
}
allow(basic_permissions).to receive(:coordinated_order_cycles) {
OrderCycle.where(id: order_cycle)
}
end
it "should let me see the order" do
expect(permissions.visible_orders).to include order
end
context "with search params" do
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
let(:permissions) { Permissions::Order.new(user, search_params) }
it "only returns completed, non-cancelled orders within search filter range" do
expect(permissions.visible_orders).to include order_completed
expect(permissions.visible_orders).not_to include order_cancelled
expect(permissions.visible_orders).not_to include order_cart
expect(permissions.visible_orders).not_to include order_from_last_year
end
end
end
context "as a producer which has granted P-OC to the distributor of an order" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: producer)
}
create(:enterprise_relationship, parent: producer, child: distributor,
permissions_list: [:add_to_order_cycle])
end
context "which contains my products" do
before do
line_item.variant.supplier = producer
line_item.variant.save
end
it "should let me see the order" do
expect(permissions.visible_orders).to include order
end
end
context "which does not contain my products" do
it "should not let me see the order" do
expect(permissions.visible_orders).not_to include order
end
end
end
context "as an enterprise that is a distributor in the order cycle, " \
"but not the distributor of the order" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: random_enterprise)
}
end
it "should not let me see the order" do
expect(permissions.visible_orders).not_to include order
end
end
end
context "as an enterprise that is a distributor in the order cycle, " \
"but not the distributor of the order" do
describe "finding line items that are visible in reports" do
let(:random_enterprise) { create(:distributor_enterprise) }
let(:order) { create(:order, order_cycle:, distributor: ) }
let!(:line_item1) { create(:line_item, order:) }
let!(:line_item2) { create(:line_item, order:) }
let!(:producer) { create(:supplier_enterprise) }
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: random_enterprise)
}
allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") }
end
it "should not let me see the order" do
expect(permissions.visible_orders).not_to include order
context "as the hub through which the parent order was placed" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: distributor)
}
end
it "should let me see the line_items" do
expect(permissions.visible_line_items).to include line_item1, line_item2
end
end
context "as the coordinator of the order cycle through which the parent order was placed" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: coordinator)
}
allow(basic_permissions).to receive(:coordinated_order_cycles) {
OrderCycle.where(id: order_cycle)
}
end
it "should let me see the line_items" do
expect(permissions.visible_line_items).to include line_item1, line_item2
end
end
context "as the manager producer which has granted P-OC to the distributor " \
"of the parent order" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: producer)
}
create(:enterprise_relationship, parent: producer, child: distributor,
permissions_list: [:add_to_order_cycle])
line_item1.variant.supplier = producer
line_item1.variant.save
end
it "should let me see the line_items pertaining to variants I produce" do
ps = permissions.visible_line_items
expect(ps).to include line_item1
expect(ps).not_to include line_item2
end
end
context "as an enterprise that is a distributor in the order cycle, " \
"but not the distributor of the parent order" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: random_enterprise)
}
end
it "should not let me see the line_items" do
expect(permissions.visible_line_items).not_to include line_item1, line_item2
end
end
context "with search params" do
let!(:line_item3) { create(:line_item, order: order_completed) }
let!(:line_item4) { create(:line_item, order: order_cancelled) }
let!(:line_item5) { create(:line_item, order: order_cart) }
let!(:line_item6) { create(:line_item, order: order_from_last_year) }
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
let(:permissions) { Permissions::Order.new(user, search_params) }
before do
allow(user).to receive(:admin?) { "admin" }
end
it "only returns line items from completed, " \
"non-cancelled orders within search filter range" do
expect(permissions.visible_line_items).to include order_completed.line_items.first
expect(permissions.visible_line_items).not_to include order_cancelled.line_items.first
expect(permissions.visible_line_items).not_to include order_cart.line_items.first
expect(permissions.visible_line_items)
.not_to include order_from_last_year.line_items.first
end
end
end
end
describe "finding line items that are visible in reports" do
let(:random_enterprise) { create(:distributor_enterprise) }
let(:order) { create(:order, order_cycle:, distributor: ) }
let!(:line_item1) { create(:line_item, order:) }
let!(:line_item2) { create(:line_item, order:) }
let!(:producer) { create(:supplier_enterprise) }
before do
allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") }
context "with user can only manage line_items in orders" do
let(:producer) { create(:supplier_enterprise) }
let(:user) do
create(:user, enterprises: [producer])
end
let!(:order_by_distributor_allow_edits) do
order = create(
:order_with_line_items,
distributor: create(
:distributor_enterprise,
enable_producers_to_edit_orders: true
),
line_items_count: 1
)
order.line_items.first.variant.update_attribute(:supplier_id, producer.id)
context "as the hub through which the parent order was placed" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: distributor)
}
end
it "should let me see the line_items" do
expect(permissions.visible_line_items).to include line_item1, line_item2
order
end
let!(:order_by_distributor_disallow_edits) do
create(
:order_with_line_items,
distributor: create(:distributor_enterprise),
line_items_count: 1
)
end
describe "#editable_orders" do
it "returns orders where the distributor allows producers to edit" do
expect(permissions.editable_orders.count).to eq 1
expect(permissions.editable_orders).to include order_by_distributor_allow_edits
end
end
context "as the coordinator of the order cycle through which the parent order was placed" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: coordinator)
}
allow(basic_permissions).to receive(:coordinated_order_cycles) {
OrderCycle.where(id: order_cycle)
}
end
it "should let me see the line_items" do
expect(permissions.visible_line_items).to include line_item1, line_item2
end
end
context "as the manager producer which has granted P-OC to the distributor " \
"of the parent order" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: producer)
}
create(:enterprise_relationship, parent: producer, child: distributor,
permissions_list: [:add_to_order_cycle])
line_item1.variant.supplier = producer
line_item1.variant.save
end
it "should let me see the line_items pertaining to variants I produce" do
ps = permissions.visible_line_items
expect(ps).to include line_item1
expect(ps).not_to include line_item2
end
end
context "as an enterprise that is a distributor in the order cycle, " \
"but not the distributor of the parent order" do
before do
allow(basic_permissions).to receive(:managed_enterprises) {
Enterprise.where(id: random_enterprise)
}
end
it "should not let me see the line_items" do
expect(permissions.visible_line_items).not_to include line_item1, line_item2
end
end
context "with search params" do
let!(:line_item3) { create(:line_item, order: order_completed) }
let!(:line_item4) { create(:line_item, order: order_cancelled) }
let!(:line_item5) { create(:line_item, order: order_cart) }
let!(:line_item6) { create(:line_item, order: order_from_last_year) }
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
let(:permissions) { Permissions::Order.new(user, search_params) }
before do
allow(user).to receive(:admin?) { "admin" }
end
it "only returns line items from completed, " \
"non-cancelled orders within search filter range" do
expect(permissions.visible_line_items).to include order_completed.line_items.first
expect(permissions.visible_line_items).not_to include order_cancelled.line_items.first
expect(permissions.visible_line_items).not_to include order_cart.line_items.first
expect(permissions.visible_line_items)
.not_to include order_from_last_year.line_items.first
describe "#editable_line_items" do
it "returns line items from orders where the distributor allows producers to edit" do
expect(permissions.editable_line_items.count).to eq 1
expect(permissions.editable_line_items.first.order).to eq order_by_distributor_allow_edits
end
end
end

View File

@@ -0,0 +1,164 @@
# frozen_string_literal: true
require 'system_helper'
RSpec.describe 'As a producer who have the ability to update orders' do
include AdminHelper
include AuthenticationHelper
include WebHelper
let!(:supplier1) { create(:supplier_enterprise, name: 'My supplier1') }
let!(:supplier2) { create(:supplier_enterprise, name: 'My supplier2') }
let!(:supplier1_v1) { create(:variant, supplier_id: supplier1.id) }
let!(:supplier1_v2) { create(:variant, supplier_id: supplier1.id) }
let!(:supplier2_v1) { create(:variant, supplier_id: supplier2.id) }
let(:order_cycle) do
create(:simple_order_cycle, distributors: [distributor], variants: [supplier1_v1, supplier1_v2])
end
let!(:order_containing_supplier1_products) do
o = create(
:completed_order_with_totals,
distributor:, order_cycle:,
user: supplier1_ent_user, line_items_count: 1
)
o.line_items.first.update_columns(variant_id: supplier1_v1.id)
o
end
let!(:order_containing_supplier2_v1_products) do
o = create(
:completed_order_with_totals,
distributor:, order_cycle:,
user: supplier2_ent_user, line_items_count: 1
)
o.line_items.first.update_columns(variant_id: supplier2_v1.id)
o
end
let(:supplier1_ent_user) { create(:user, enterprises: [supplier1]) }
let(:supplier2_ent_user) { create(:user, enterprises: [supplier2]) }
context "As supplier1 enterprise user" do
before { login_as(supplier1_ent_user) }
let(:order) { order_containing_supplier1_products }
let(:user) { supplier1_ent_user }
describe 'orders index page' do
before { visit spree.admin_orders_path }
context "when no distributor allow the producer to edit orders" do
let(:distributor) { create(:distributor_enterprise) }
it "should not allow producer to view orders page" do
expect(page).to have_content 'Unauthorized'
end
end
context "when distributor allows the producer to edit orders" do
let(:distributor) { create(:distributor_enterprise, enable_producers_to_edit_orders: true) }
it "should not allow to add new orders" do
expect(page).not_to have_link('New Order')
end
context "when distributor doesn't allow to view customer details" do
it "should allow producer to view orders page with HIDDEN customer details" do
within('#listing_orders tbody') do
expect(page).to have_selector('tr', count: 1) # Only one order
# One for Email, one for Name
expect(page).to have_selector('td', text: 'HIDDEN', count: 2)
end
end
end
context "when distributor allows to view customer details" do
let(:distributor) do
create(
:distributor_enterprise,
enable_producers_to_edit_orders: true,
show_customer_names_to_suppliers: true
)
end
it "should allow producer to view orders page with customer details" do
within('#listing_orders tbody') do
name = order.bill_address&.full_name_for_sorting
email = order.email
expect(page).to have_selector('tr', count: 1) # Only one order
expect(page).to have_selector('td', text: name, count: 1)
expect(page).to have_selector('td', text: email, count: 1)
end
end
end
end
end
describe 'orders edit page' do
before { visit spree.edit_admin_order_path(order) }
context "when no distributor allow the producer to edit orders" do
let(:distributor) { create(:distributor_enterprise) }
it "should not allow producer to view orders page" do
expect(page).to have_content 'Unauthorized'
end
end
context "when distributor allows to edit orders" do
let(:distributor) { create(:distributor_enterprise, enable_producers_to_edit_orders: true) }
let(:product) { supplier1_v2.product }
it "should allow me to manage my products in the order" do
expect(page).to have_content 'Add Product'
# Add my product
add_product(product)
expect_product_change(product, :add)
# Edit my product
edit_product(product)
expect_product_change(product, :update, 2)
# Delete my product
delete_product(product)
expect_product_change(product, :remove)
end
end
def expect_product_change(product, action, expected_qty = 0)
within('table.index') do
# JS for this page sometimes take more than 2 seconds (default timeout for cappybara)
timeout = 5
item_name_selector = 'tbody tr td.item-name'
quantity_selector = 'tbody tr td.item-qty-show'
case action
when :add
expect(page).to have_selector item_name_selector, text: product.name, wait: timeout
when :update
expect(page).to have_selector quantity_selector, text: expected_qty, wait: timeout
when :remove
expect(page).not_to have_selector item_name_selector, text: product.name, wait: timeout
else
raise 'Invalid action'
end
end
end
def add_product(product)
select2_select product.name, from: 'add_variant_id', search: true
find('button.add_variant').click
end
def edit_product(product)
find('a.edit-item.icon_link.icon-edit.no-text.with-tip').click
fill_in 'quantity', with: 2
find("a[data-variant-id='#{product.variants.last.id}'][data-action='save']").click
end
def delete_product(product)
find("a[data-variant-id='#{product.variants.last.id}'][data-action='remove']").click
click_button 'OK'
end
end
end
end