mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Match product taxon with DFC Product type
It relies on having dfc_name populated on the given taxon. Matching is as follow: - parse the DFC product types and store in PRODUCT_TYPES if needed - match the dfc_name against PRODUCT_TYPES - call the method returned on the DFC connector
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SuppliedProductBuilder < DfcBuilder
|
||||
PRODUCT_TYPES = {} # rubocop:disable Style/MutableConstant
|
||||
|
||||
def self.supplied_product(variant)
|
||||
id = urls.enterprise_supplied_product_url(
|
||||
enterprise_id: variant.product.supplier_id,
|
||||
@@ -63,11 +65,48 @@ class SuppliedProductBuilder < DfcBuilder
|
||||
|
||||
return nil if taxon_name.nil?
|
||||
|
||||
root_product_types = DfcLoader.connector.PRODUCT_TYPES.methods(false).sort
|
||||
search = root_product_types.index(taxon_name.upcase.to_sym)
|
||||
populate_product_types if PRODUCT_TYPES.empty?
|
||||
|
||||
return nil if search.nil?
|
||||
return nil if PRODUCT_TYPES[taxon_name.to_sym].nil?
|
||||
|
||||
DfcLoader.connector.PRODUCT_TYPES.public_send(root_product_types[search])
|
||||
call_dfc_product_type(PRODUCT_TYPES[taxon_name.to_sym])
|
||||
end
|
||||
|
||||
def self.populate_product_types
|
||||
DfcLoader.connector.PRODUCT_TYPES.topConcepts.each do |product_type|
|
||||
stack = []
|
||||
record_type(stack, product_type.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
def self.record_type(stack, product_type)
|
||||
name = product_type.to_s
|
||||
current_stack = stack.dup.push(name)
|
||||
PRODUCT_TYPES[name.downcase.to_sym] = current_stack
|
||||
|
||||
type = call_dfc_product_type(current_stack)
|
||||
|
||||
# Narrower product types are defined as class method on the current product type object
|
||||
narrowers = type.methods(false).sort
|
||||
|
||||
# Leaf node
|
||||
return if narrowers.empty?
|
||||
|
||||
narrowers.each do |narrower|
|
||||
# recursive call
|
||||
record_type(current_stack, narrower)
|
||||
end
|
||||
end
|
||||
|
||||
# Callproduct type method ie: DfcLoader.connector.PRODUCT_TYPES.DRINK.SOFT_DRINK
|
||||
def self.call_dfc_product_type(product_type_path)
|
||||
type = DfcLoader.connector.PRODUCT_TYPES
|
||||
product_type_path.each do |pt|
|
||||
type = type.public_send(pt)
|
||||
end
|
||||
|
||||
type
|
||||
end
|
||||
|
||||
private_class_method :product_type, :populate_product_types, :record_type
|
||||
end
|
||||
|
||||
@@ -46,19 +46,38 @@ describe SuppliedProductBuilder do
|
||||
end
|
||||
|
||||
context "product_type mapping" do
|
||||
it "assigns a product type" do
|
||||
product = builder.supplied_product(variant)
|
||||
subject(:product) { builder.supplied_product(variant) }
|
||||
|
||||
it "assigns a top level product type" do
|
||||
drink = DfcLoader.connector.PRODUCT_TYPES.DRINK
|
||||
|
||||
expect(product.productType).to eq drink
|
||||
end
|
||||
|
||||
context "with second level product type" do
|
||||
let(:taxon) { build(:taxon, name: "Soft Drink", dfc_name: "soft_drink") }
|
||||
|
||||
it "assigns a second level product type" do
|
||||
soft_drink = DfcLoader.connector.PRODUCT_TYPES.DRINK.SOFT_DRINK
|
||||
|
||||
expect(product.productType).to eq soft_drink
|
||||
end
|
||||
end
|
||||
|
||||
context "with leaf level product type" do
|
||||
let(:taxon) { build(:taxon, name: "Lemonade", dfc_name: "lemonade") }
|
||||
|
||||
it "assigns a leaf level product type" do
|
||||
lemonade = DfcLoader.connector.PRODUCT_TYPES.DRINK.SOFT_DRINK.LEMONADE
|
||||
|
||||
expect(product.productType).to eq lemonade
|
||||
end
|
||||
end
|
||||
|
||||
context "with non existing product type" do
|
||||
let(:taxon) { build(:taxon, name: "other", dfc_name: "other") }
|
||||
|
||||
it "returns nil" do
|
||||
product = builder.supplied_product(variant)
|
||||
|
||||
expect(product.productType).to be_nil
|
||||
end
|
||||
end
|
||||
@@ -67,8 +86,6 @@ describe SuppliedProductBuilder do
|
||||
let(:taxon) { nil }
|
||||
|
||||
it "returns nil" do
|
||||
product = builder.supplied_product(variant)
|
||||
|
||||
expect(product.productType).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user