mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-04 22:16:08 +00:00
Merge pull request #8756 from jibees/8075-take-into-account-the-inherits_properties-attribute
Product that don't inherits from "producer"/"enterprise" properties should be filtered out by user on shop page
This commit is contained in:
@@ -67,7 +67,7 @@ angular.module('Darkswarm').controller "ProductsCtrl", ($scope, $sce, $filter, $
|
||||
page: page || $scope.page,
|
||||
per_page: $scope.per_page,
|
||||
'q[name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont]': $scope.query,
|
||||
'q[properties_id_or_supplier_properties_id_in_any][]': $scope.activeProperties,
|
||||
'q[with_properties][]': $scope.activeProperties,
|
||||
'q[primary_taxon_id_in_any][]': $scope.activeTaxons
|
||||
}
|
||||
|
||||
|
||||
@@ -81,8 +81,7 @@ module Api
|
||||
|
||||
def permitted_ransack_params
|
||||
[:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont,
|
||||
:properties_id_or_supplier_properties_id_in_any,
|
||||
:primary_taxon_id_in_any]
|
||||
:with_properties, :primary_taxon_id_in_any]
|
||||
end
|
||||
|
||||
def distributor
|
||||
|
||||
@@ -31,7 +31,7 @@ module Spree
|
||||
|
||||
searchable_attributes :supplier_id, :primary_taxon_id, :meta_keywords
|
||||
searchable_associations :supplier, :properties, :primary_taxon, :variants, :master
|
||||
searchable_scopes :active
|
||||
searchable_scopes :active, :with_properties
|
||||
|
||||
has_many :product_option_types, dependent: :destroy
|
||||
# We have an after_destroy callback on Spree::ProductOptionType. However, if we
|
||||
@@ -69,6 +69,19 @@ module Spree
|
||||
|
||||
has_many :stock_items, through: :variants
|
||||
|
||||
has_many :supplier_properties, through: :supplier, source: :properties
|
||||
|
||||
scope :with_properties, ->(*property_ids) {
|
||||
left_outer_joins(:product_properties).
|
||||
left_outer_joins(:supplier_properties).
|
||||
where(inherits_properties: true).
|
||||
where(producer_properties: { property_id: property_ids }).
|
||||
or(
|
||||
where(spree_product_properties: { property_id: property_ids })
|
||||
).
|
||||
distinct
|
||||
}
|
||||
|
||||
delegate_belongs_to :master, :sku, :price, :currency, :display_amount, :display_price, :weight,
|
||||
:height, :width, :depth, :is_master, :cost_currency,
|
||||
:price_in, :amount_in, :unit_value, :unit_description
|
||||
|
||||
@@ -65,11 +65,32 @@ module Api
|
||||
context "with property filters" do
|
||||
it "filters by product property" do
|
||||
api_get :products, id: order_cycle.id, distributor: distributor.id,
|
||||
q: { properties_id_or_supplier_properties_id_in_any: [property1.id, property2.id] }
|
||||
q: { with_properties: [property1.id, property2.id] }
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(product_ids).to include product1.id, product2.id
|
||||
expect(product_ids).to_not include product3.id
|
||||
end
|
||||
|
||||
context "with supplier properties" do
|
||||
let!(:supplier_property) { create(:property, presentation: 'Certified Organic') }
|
||||
let!(:supplier) { create(:supplier_enterprise, properties: [supplier_property]) }
|
||||
|
||||
before do
|
||||
product1.update!(supplier: supplier)
|
||||
product2.update!(supplier: supplier)
|
||||
product3.update!(supplier: supplier, inherits_properties: false)
|
||||
end
|
||||
|
||||
it "filter out the product that don't inherits from supplier properties" do
|
||||
api_get :products, id: order_cycle.id, distributor: distributor.id,
|
||||
q: { with_properties: [supplier_property.id] }
|
||||
|
||||
expect(response.status).to eq 200
|
||||
expect(product_ids).to include product1.id, product2.id
|
||||
expect(product_ids).to_not include product3.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with taxon filters" do
|
||||
|
||||
@@ -199,6 +199,51 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
describe "supplier properties" do
|
||||
subject { create(:product) }
|
||||
|
||||
it "has no supplier properties to start with" do
|
||||
expect(subject.supplier_properties).to eq []
|
||||
end
|
||||
|
||||
it "doesn't include product properties" do
|
||||
subject.set_property("certified", "organic")
|
||||
expect(subject.supplier_properties).to eq []
|
||||
end
|
||||
|
||||
it "includes the supplier's properties" do
|
||||
subject.supplier.set_producer_property("certified", "yes")
|
||||
expect(subject.supplier_properties.map(&:presentation)).to eq ["certified"]
|
||||
end
|
||||
end
|
||||
|
||||
describe ".with_properties scope" do
|
||||
let!(:product_without_wanted_property_on_supplier) { create(:product, supplier: supplier_without_wanted_property) }
|
||||
let!(:product_with_wanted_property_on_supplier) { create(:product, supplier: supplier_with_wanted_property) }
|
||||
let!(:product_with_wanted_property) { create(:product, properties: [wanted_property]) }
|
||||
let!(:product_without_wanted_property_property) { create(:product, properties: [unwanted_property]) }
|
||||
let!(:product_with_wanted_property_and_on_supplier) { create(:product, properties: [wanted_property], supplier: supplier_with_wanted_property) }
|
||||
let!(:product_ignoring_property) { create(:product, supplier: supplier_with_wanted_property, inherits_properties: false) }
|
||||
let(:supplier_with_wanted_property) { create(:supplier_enterprise, properties: [wanted_property]) }
|
||||
let(:supplier_without_wanted_property) { create(:supplier_enterprise, properties: [unwanted_property]) }
|
||||
let(:wanted_property) { create(:property, presentation: 'Certified Organic') }
|
||||
let(:unwanted_property) { create(:property, presentation: 'Latest Hype') }
|
||||
|
||||
it "returns no products without a property id" do
|
||||
expect(Spree::Product.with_properties([])).to eq []
|
||||
end
|
||||
|
||||
it "returns only products with the wanted property set both on supplier and on the product itself" do
|
||||
expect(
|
||||
Spree::Product.with_properties([wanted_property.id])
|
||||
).to match_array [
|
||||
product_with_wanted_property_on_supplier,
|
||||
product_with_wanted_property,
|
||||
product_with_wanted_property_and_on_supplier
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
# Regression tests for Spree #2352
|
||||
context "classifications and taxons" do
|
||||
it "is joined through classifications" do
|
||||
|
||||
@@ -242,6 +242,30 @@ describe "As a consumer I want to shop with a distributor", js: true do
|
||||
expect(page).not_to have_content product.name
|
||||
end
|
||||
|
||||
context "when supplier uses property" do
|
||||
let(:product3) { create(:simple_product, supplier: supplier, inherits_properties: false) }
|
||||
|
||||
before do
|
||||
add_variant_to_order_cycle(exchange, product3.variants.first)
|
||||
property = create(:property, presentation: 'certified')
|
||||
supplier.update!(properties: [property])
|
||||
end
|
||||
|
||||
it "filters product by properties" do
|
||||
visit shop_path
|
||||
|
||||
expect(page).to have_content product2.name
|
||||
expect(page).to have_content product3.name
|
||||
|
||||
expect(page).to have_selector ".sticky-shop-filters-container .property-selectors span", text: "certified"
|
||||
find(".sticky-shop-filters-container .property-selectors span", text: 'certified').click
|
||||
expect(page).to have_content "Results for certified"
|
||||
|
||||
expect(page).to have_content product2.name
|
||||
expect(page).not_to have_content product3.name
|
||||
end
|
||||
end
|
||||
|
||||
it "returns search results for products where the search term matches one of the product's variant names" do
|
||||
visit shop_path
|
||||
fill_in "search", with: "Badg" # For variant with display_name "Badgers"
|
||||
|
||||
Reference in New Issue
Block a user