From 2175c59a6b30375c4540ffd180d18d0a5095276a Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 14 Sep 2023 13:28:33 +1000 Subject: [PATCH 1/7] Load spec helper not knowing Rails When the application is not preloaded then running Rspec doesn't know Rails until the spec helper is loaded. So we can't use Rails to find the path of the spec helper. This has been fixed before but the DFC Address code was developed at the same time and missed. --- engines/dfc_provider/spec/requests/addresses_spec.rb | 2 +- engines/dfc_provider/spec/services/address_builder_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/dfc_provider/spec/requests/addresses_spec.rb b/engines/dfc_provider/spec/requests/addresses_spec.rb index 9848c9244b..21032e5df9 100644 --- a/engines/dfc_provider/spec/requests/addresses_spec.rb +++ b/engines/dfc_provider/spec/requests/addresses_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require DfcProvider::Engine.root.join("spec/swagger_helper") +require_relative "../swagger_helper" describe "Addresses", type: :request, swagger_doc: "dfc.yaml", rswag_autodoc: true do let(:user) { create(:oidc_user) } diff --git a/engines/dfc_provider/spec/services/address_builder_spec.rb b/engines/dfc_provider/spec/services/address_builder_spec.rb index 72fc0f08c0..660c7781ae 100644 --- a/engines/dfc_provider/spec/services/address_builder_spec.rb +++ b/engines/dfc_provider/spec/services/address_builder_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require DfcProvider::Engine.root.join("spec/spec_helper") +require_relative "../spec_helper" describe AddressBuilder do subject(:result) { described_class.address(address) } From c42f62e09f7a23aa91163ebdcd29b3fd0dbd24d9 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 10 Aug 2023 14:55:50 +1000 Subject: [PATCH 2/7] Add custom OFN product id to DFC SuppliedProduct The Spree::Variant in OFN corresponds to a DFC SuppliedProduct. But several Spree::Variant can be grouped under one Spree::Product which wasn't exposed on the DFC API. I'm adding a custom property here which can be used internally and shouldn't break any other DFC tools. A gotcha of this first test implementation: The `ofn:` prefix has not been defined in the context. Software needs to know that this is an Open Food Network attribute or ignore it. We could define our own context and ontology and publish it on our website but I don't see any benefit of that at this point. --- .../app/services/supplied_product_builder.rb | 6 +++++- .../dfc_provider/spec/requests/catalog_items_spec.rb | 2 +- .../dfc_provider/spec/requests/enterprises_spec.rb | 2 +- .../spec/requests/supplied_products_spec.rb | 11 ++++++++++- swagger/dfc.yaml | 4 ++++ 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/engines/dfc_provider/app/services/supplied_product_builder.rb b/engines/dfc_provider/app/services/supplied_product_builder.rb index fe036dcfb1..1f9ff42df8 100644 --- a/engines/dfc_provider/app/services/supplied_product_builder.rb +++ b/engines/dfc_provider/app/services/supplied_product_builder.rb @@ -13,7 +13,11 @@ class SuppliedProductBuilder < DfcBuilder description: variant.description, productType: product_type, quantity: QuantitativeValueBuilder.quantity(variant), - ) + ).tap do |supplied_product| + supplied_product.registerSemanticProperty("ofn:spree_product_id") do + variant.product.id + end + end end def self.import(supplied_product) diff --git a/engines/dfc_provider/spec/requests/catalog_items_spec.rb b/engines/dfc_provider/spec/requests/catalog_items_spec.rb index 0d401f9090..c082630044 100644 --- a/engines/dfc_provider/spec/requests/catalog_items_spec.rb +++ b/engines/dfc_provider/spec/requests/catalog_items_spec.rb @@ -15,7 +15,7 @@ describe "CatalogItems", type: :request, swagger_doc: "dfc.yaml", let(:product) { create( :base_product, - supplier: enterprise, name: "Apple", description: "Red", + id: 90_000, supplier: enterprise, name: "Apple", description: "Red", variants: [variant], ) } diff --git a/engines/dfc_provider/spec/requests/enterprises_spec.rb b/engines/dfc_provider/spec/requests/enterprises_spec.rb index 3c3835452f..0e5f885490 100644 --- a/engines/dfc_provider/spec/requests/enterprises_spec.rb +++ b/engines/dfc_provider/spec/requests/enterprises_spec.rb @@ -22,7 +22,7 @@ describe "Enterprises", type: :request, swagger_doc: "dfc.yaml", rswag_autodoc: let!(:product) { create( :base_product, - supplier: enterprise, name: "Apple", description: "Round", + id: 90_000, supplier: enterprise, name: "Apple", description: "Round", variants: [variant], ) } diff --git a/engines/dfc_provider/spec/requests/supplied_products_spec.rb b/engines/dfc_provider/spec/requests/supplied_products_spec.rb index b310fff021..966ff2b56f 100644 --- a/engines/dfc_provider/spec/requests/supplied_products_spec.rb +++ b/engines/dfc_provider/spec/requests/supplied_products_spec.rb @@ -9,6 +9,7 @@ describe "SuppliedProducts", type: :request, swagger_doc: "dfc.yaml", let!(:product) { create( :base_product, + id: 90_000, supplier: enterprise, name: "Pesto", description: "Basil Pesto", variants: [variant], ) @@ -78,7 +79,7 @@ describe "SuppliedProducts", type: :request, swagger_doc: "dfc.yaml", example.metadata[:operation][:parameters].first[:schema][:example] end - it "creates a variant" do |example| + it "creates a product and variant" do |example| expect { submit_request(example.metadata) } .to change { enterprise.supplied_products.count }.by(1) @@ -87,16 +88,23 @@ describe "SuppliedProducts", type: :request, swagger_doc: "dfc.yaml", %r|^http://test\.host/api/dfc/enterprises/10000/supplied_products/[0-9]+$| ) + spree_product_id = json_response["ofn:spree_product_id"].to_i + variant_id = dfc_id.split("/").last.to_i variant = Spree::Variant.find(variant_id) expect(variant.name).to eq "Apple" expect(variant.unit_value).to eq 3 + expect(variant.product_id).to eq spree_product_id # Insert static value to keep documentation deterministic: response.body.gsub!( "supplied_products/#{variant_id}", "supplied_products/10001" ) + .gsub!( + "\"ofn:spree_product_id\":#{spree_product_id}", + '"ofn:spree_product_id":90000' + ) end end end @@ -116,6 +124,7 @@ describe "SuppliedProducts", type: :request, swagger_doc: "dfc.yaml", run_test! do expect(response.body).to include variant.name + expect(json_response["ofn:spree_product_id"]).to eq 90_000 end end diff --git a/swagger/dfc.yaml b/swagger/dfc.yaml index 8927ccfc1d..f08222b960 100644 --- a/swagger/dfc.yaml +++ b/swagger/dfc.yaml @@ -118,6 +118,7 @@ paths: dfc-b:lifetime: '' dfc-b:usageOrStorageCondition: '' dfc-b:totalTheoreticalStock: 0.0 + ofn:spree_product_id: 90000 - "@id": http://test.host/api/dfc/enterprises/10000/offers/10001 "@type": dfc-b:Offer dfc-b:price: 19.99 @@ -341,6 +342,7 @@ paths: dfc-b:lifetime: '' dfc-b:usageOrStorageCondition: '' dfc-b:totalTheoreticalStock: 0.0 + ofn:spree_product_id: 90000 - "@id": http://test.host/api/dfc/enterprises/10000/catalog_items/10001 "@type": dfc-b:CatalogItem dfc-b:references: http://test.host/api/dfc/enterprises/10000/supplied_products/10001 @@ -409,6 +411,7 @@ paths: dfc-b:lifetime: '' dfc-b:usageOrStorageCondition: '' dfc-b:totalTheoreticalStock: 0.0 + ofn:spree_product_id: 90000 requestBody: content: application/json: @@ -471,6 +474,7 @@ paths: dfc-b:lifetime: '' dfc-b:usageOrStorageCondition: '' dfc-b:totalTheoreticalStock: 0.0 + ofn:spree_product_id: 90000 '404': description: not found put: From fcf7b942780bac62bcc95b08c85e9a4f6efea0c1 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 11 Aug 2023 13:17:38 +1000 Subject: [PATCH 3/7] Add our own SuppliedProduct with custom property --- engines/dfc_provider/app/services/dfc_io.rb | 3 --- engines/dfc_provider/app/services/dfc_loader.rb | 2 -- .../app/services/supplied_product_builder.rb | 9 +++------ engines/dfc_provider/lib/dfc_provider.rb | 7 +++++++ .../lib/dfc_provider/supplied_product.rb | 17 +++++++++++++++++ 5 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 engines/dfc_provider/lib/dfc_provider/supplied_product.rb diff --git a/engines/dfc_provider/app/services/dfc_io.rb b/engines/dfc_provider/app/services/dfc_io.rb index 2457eb4a46..99bf63df66 100644 --- a/engines/dfc_provider/app/services/dfc_io.rb +++ b/engines/dfc_provider/app/services/dfc_io.rb @@ -1,8 +1,5 @@ # frozen_string_literal: true -# Load our monkey-patches: -require "data_food_consortium/connector/connector" - # Our interface to the DFC Connector library. module DfcIo # Serialise DFC Connector subjects as JSON-LD string. diff --git a/engines/dfc_provider/app/services/dfc_loader.rb b/engines/dfc_provider/app/services/dfc_loader.rb index d9ef128c96..1fae62f9f4 100644 --- a/engines/dfc_provider/app/services/dfc_loader.rb +++ b/engines/dfc_provider/app/services/dfc_loader.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "data_food_consortium/connector/connector" - class DfcLoader def self.connector @connector ||= load_vocabularies diff --git a/engines/dfc_provider/app/services/supplied_product_builder.rb b/engines/dfc_provider/app/services/supplied_product_builder.rb index 1f9ff42df8..53d64f5d3c 100644 --- a/engines/dfc_provider/app/services/supplied_product_builder.rb +++ b/engines/dfc_provider/app/services/supplied_product_builder.rb @@ -7,17 +7,14 @@ class SuppliedProductBuilder < DfcBuilder id: variant.id, ) - DataFoodConsortium::Connector::SuppliedProduct.new( + DfcProvider::SuppliedProduct.new( id, name: variant.name_to_display, description: variant.description, productType: product_type, quantity: QuantitativeValueBuilder.quantity(variant), - ).tap do |supplied_product| - supplied_product.registerSemanticProperty("ofn:spree_product_id") do - variant.product.id - end - end + spree_product_id: variant.product.id, + ) end def self.import(supplied_product) diff --git a/engines/dfc_provider/lib/dfc_provider.rb b/engines/dfc_provider/lib/dfc_provider.rb index b0cf98121a..d6be00d677 100644 --- a/engines/dfc_provider/lib/dfc_provider.rb +++ b/engines/dfc_provider/lib/dfc_provider.rb @@ -1,6 +1,13 @@ # frozen_string_literal: true +# Load our monkey-patches of the DFC Connector: +require "data_food_consortium/connector/connector" + +# Our Rails engine require "dfc_provider/engine" +# Custom data types +require "dfc_provider/supplied_product" + module DfcProvider end diff --git a/engines/dfc_provider/lib/dfc_provider/supplied_product.rb b/engines/dfc_provider/lib/dfc_provider/supplied_product.rb new file mode 100644 index 0000000000..06b762ba87 --- /dev/null +++ b/engines/dfc_provider/lib/dfc_provider/supplied_product.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module DfcProvider + class SuppliedProduct < DataFoodConsortium::Connector::SuppliedProduct + attr_accessor :spree_product_id + + def initialize(semantic_id, spree_product_id: nil, **properties) + super(semantic_id, **properties) + + self.spree_product_id = spree_product_id + + registerSemanticProperty("ofn:spree_product_id") do + self.spree_product_id + end + end + end +end From db5b6e5406d8e8604de70c8c0818d441c1577adf Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 11 Aug 2023 15:31:34 +1000 Subject: [PATCH 4/7] Enable DFC importer to import OFN objects --- .../connector/importer.rb | 35 +++++++++++-------- engines/dfc_provider/lib/dfc_provider.rb | 1 + .../connector/connector_spec.rb | 4 +-- .../connector/importer_spec.rb | 10 +++--- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb b/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb index e46a021d73..81c6624f11 100644 --- a/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb +++ b/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb @@ -15,21 +15,28 @@ module DataFoodConsortium ].freeze def self.type_map - @type_map ||= TYPES.each_with_object({}) do |clazz, result| - # Methods with variable arguments have a negative arity of -n-1 - # where n is the number of required arguments. - number_of_required_args = -1 * (clazz.instance_method(:initialize).arity + 1) - args = Array.new(number_of_required_args) - type_uri = clazz.new(*args).semanticType - result[type_uri] = clazz - - # Add support for the old DFC v1.7 URLs: - new_type_uri = type_uri.gsub( - "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_BusinessOntology.owl#", - "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#" - ) - result[new_type_uri] = clazz + unless @type_map + @type_map = {} + TYPES.each(&method(:register_type)) end + + @type_map + end + + def self.register_type(clazz) + # Methods with variable arguments have a negative arity of -n-1 + # where n is the number of required arguments. + number_of_required_args = -1 * (clazz.instance_method(:initialize).arity + 1) + args = Array.new(number_of_required_args) + type_uri = clazz.new(*args).semanticType + type_map[type_uri] = clazz + + # Add support for the old DFC v1.7 URLs: + new_type_uri = type_uri.gsub( + "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_BusinessOntology.owl#", + "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#" + ) + type_map[new_type_uri] = clazz end def import(json_string_or_io) diff --git a/engines/dfc_provider/lib/dfc_provider.rb b/engines/dfc_provider/lib/dfc_provider.rb index d6be00d677..4676736439 100644 --- a/engines/dfc_provider/lib/dfc_provider.rb +++ b/engines/dfc_provider/lib/dfc_provider.rb @@ -10,4 +10,5 @@ require "dfc_provider/engine" require "dfc_provider/supplied_product" module DfcProvider + DataFoodConsortium::Connector::Importer.register_type(SuppliedProduct) end diff --git a/engines/dfc_provider/spec/lib/data_food_consortium/connector/connector_spec.rb b/engines/dfc_provider/spec/lib/data_food_consortium/connector/connector_spec.rb index 48d7cbd3e6..f0bda34bf9 100644 --- a/engines/dfc_provider/spec/lib/data_food_consortium/connector/connector_spec.rb +++ b/engines/dfc_provider/spec/lib/data_food_consortium/connector/connector_spec.rb @@ -21,7 +21,7 @@ describe DataFoodConsortium::Connector::Connector, vcr: true do it "imports" do json = connector.export(product) result = connector.import(json) - expect(result.class).to eq product.class + expect(result).to be_a product.class expect(result.semanticType).to eq product.semanticType expect(result.semanticId).to eq "https://example.net/tomato" expect(result.name).to eq "Tomato" @@ -32,7 +32,7 @@ describe DataFoodConsortium::Connector::Connector, vcr: true do io = StringIO.new(json) result = connector.import(io) - expect(result.class).to eq product.class + expect(result).to be_a product.class expect(result.semanticType).to eq product.semanticType expect(result.semanticId).to eq "https://example.net/tomato" expect(result.name).to eq "Tomato" diff --git a/engines/dfc_provider/spec/lib/data_food_consortium/connector/importer_spec.rb b/engines/dfc_provider/spec/lib/data_food_consortium/connector/importer_spec.rb index e64dce16a7..04e9407ce6 100644 --- a/engines/dfc_provider/spec/lib/data_food_consortium/connector/importer_spec.rb +++ b/engines/dfc_provider/spec/lib/data_food_consortium/connector/importer_spec.rb @@ -100,7 +100,7 @@ describe DataFoodConsortium::Connector::Importer do it "imports a single object with simple properties" do result = import(product) - expect(result.class).to eq product.class + expect(result).to be_a product.class expect(result.semanticType).to eq product.semanticType expect(result.semanticId).to eq "https://example.net/tomato" expect(result.name).to eq "Tomato" @@ -111,7 +111,7 @@ describe DataFoodConsortium::Connector::Importer do it "imports an object with referenced context" do result = connector.import(product_data) - expect(result.class).to eq DataFoodConsortium::Connector::SuppliedProduct + expect(result).to be_a DataFoodConsortium::Connector::SuppliedProduct expect(result.semanticType).to eq "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_BusinessOntology.owl#SuppliedProduct" expect(result.semanticId).to eq "https://example.net/tomato" expect(result.name).to eq "Tomato" @@ -122,7 +122,7 @@ describe DataFoodConsortium::Connector::Importer do it "imports an object with included context" do result = connector.import(product_data_with_context) - expect(result.class).to eq DataFoodConsortium::Connector::SuppliedProduct + expect(result).to be_a DataFoodConsortium::Connector::SuppliedProduct expect(result.semanticType).to eq "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_BusinessOntology.owl#SuppliedProduct" expect(result.semanticId).to eq "https://example.net/tomato" expect(result.name).to eq "Tomato" @@ -133,7 +133,7 @@ describe DataFoodConsortium::Connector::Importer do it "imports an object with DFC v1.8 context" do result = connector.import(product_data_with_context_v1_8) - expect(result.class).to eq DataFoodConsortium::Connector::SuppliedProduct + expect(result).to be_a DataFoodConsortium::Connector::SuppliedProduct expect(result.semanticType).to eq "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_BusinessOntology.owl#SuppliedProduct" expect(result.semanticId).to eq "https://example.net/tomato" expect(result.name).to eq "Tomato" @@ -149,7 +149,7 @@ describe DataFoodConsortium::Connector::Importer do item, tomato = result - expect(item.class).to eq catalog_item.class + expect(item).to be_a catalog_item.class expect(item.semanticType).to eq catalog_item.semanticType expect(item.semanticId).to eq "https://example.net/tomatoItem" expect(tomato.name).to eq "Tomato" From 02f251c900711f6aea0afe1656b4b96c8f30cf5c Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 20 Sep 2023 17:02:26 +1000 Subject: [PATCH 5/7] Import DFC SuppliedProduct as new variant of existing product --- app/models/spree/product.rb | 24 +++++++++---------- .../supplied_products_controller.rb | 18 +++++++++----- .../app/services/supplied_product_builder.rb | 20 +++++++++++++++- .../connector/importer.rb | 11 +++++---- .../spec/requests/supplied_products_spec.rb | 21 ++++++++++++++++ 5 files changed, 71 insertions(+), 23 deletions(-) diff --git a/app/models/spree/product.rb b/app/models/spree/product.rb index e7bf67a3d3..be905c8ccc 100755 --- a/app/models/spree/product.rb +++ b/app/models/spree/product.rb @@ -272,18 +272,6 @@ module Spree end end - private - - def update_units - return unless saved_change_to_variant_unit? || saved_change_to_variant_unit_name? - - variants.each(&:update_units) - end - - def touch_distributors - Enterprise.distributing_products(id).each(&:touch) - end - def ensure_standard_variant return unless variants.empty? @@ -298,6 +286,18 @@ module Spree variants << variant end + private + + def update_units + return unless saved_change_to_variant_unit? || saved_change_to_variant_unit_name? + + variants.each(&:update_units) + end + + def touch_distributors + Enterprise.distributing_products(id).each(&:touch) + end + def validate_image return if image.blank? || image.valid? diff --git a/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb index e4daf3155f..21b4c4b59d 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb @@ -14,13 +14,19 @@ module DfcProvider return head :bad_request unless supplied_product - product = SuppliedProductBuilder.import(supplied_product) - product.supplier = current_enterprise - product.save! + variant = SuppliedProductBuilder.import_variant(supplied_product) + product = variant.product - supplied_product = SuppliedProductBuilder.supplied_product( - product.variants.first - ) + if product.new_record? + product.supplier = current_enterprise + product.save! + end + + if variant.new_record? + variant.save! + end + + supplied_product = SuppliedProductBuilder.supplied_product(variant) render json: DfcIo.export(supplied_product) end diff --git a/engines/dfc_provider/app/services/supplied_product_builder.rb b/engines/dfc_provider/app/services/supplied_product_builder.rb index 53d64f5d3c..a706a72eb7 100644 --- a/engines/dfc_provider/app/services/supplied_product_builder.rb +++ b/engines/dfc_provider/app/services/supplied_product_builder.rb @@ -17,7 +17,25 @@ class SuppliedProductBuilder < DfcBuilder ) end - def self.import(supplied_product) + def self.import_variant(supplied_product) + product_id = supplied_product.spree_product_id + + if product_id.present? + product = Spree::Product.find(product_id) + Spree::Variant.new( + product:, + price: 0, + ).tap do |variant| + apply(supplied_product, variant) + end + else + product = import_product(supplied_product) + product.ensure_standard_variant + product.variants.first + end + end + + def self.import_product(supplied_product) Spree::Product.new( name: supplied_product.name, description: supplied_product.description, diff --git a/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb b/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb index 81c6624f11..2876f853c4 100644 --- a/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb +++ b/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb @@ -127,11 +127,14 @@ module DataFoodConsortium end def guess_setter_name(predicate) - fragment = predicate.fragment + name = - # Some predicates are named like `hasQuantity` - # but the attribute name would be `quantity`. - name = fragment.sub(/^has/, "").camelize(:lower) + # Some predicates are named like `hasQuantity` + # but the attribute name would be `quantity`. + predicate.fragment&.sub(/^has/, "")&.camelize(:lower) || + + # And sometimes the URI looks like `ofn:spree_product_id`. + predicate.to_s.split(":").last "#{name}=" end diff --git a/engines/dfc_provider/spec/requests/supplied_products_spec.rb b/engines/dfc_provider/spec/requests/supplied_products_spec.rb index 966ff2b56f..a3e2ed2d77 100644 --- a/engines/dfc_provider/spec/requests/supplied_products_spec.rb +++ b/engines/dfc_provider/spec/requests/supplied_products_spec.rb @@ -96,6 +96,27 @@ describe "SuppliedProducts", type: :request, swagger_doc: "dfc.yaml", expect(variant.unit_value).to eq 3 expect(variant.product_id).to eq spree_product_id + # References the associated Spree::Product + product_id = json_response["ofn:spree_product_id"] + product = Spree::Product.find(product_id) + expect(product.name).to eq "Apple" + expect(product.variants).to eq [variant] + + # Creates a variant for existing product + supplied_product[:'ofn:spree_product_id'] = product_id + supplied_product[:'dfc-b:hasQuantity'][:'dfc-b:value'] = 6 + + expect { + submit_request(example.metadata) + product.variants.reload + } + .to change { product.variants.count }.by(1) + + variant_id = json_response["@id"].split("/").last.to_i + second_variant = Spree::Variant.find(variant_id) + expect(product.variants).to match_array [variant, second_variant] + expect(second_variant.unit_value).to eq 6 + # Insert static value to keep documentation deterministic: response.body.gsub!( "supplied_products/#{variant_id}", From 07ac381a97ccdd8667eca650a5bbdc55187d032b Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 21 Sep 2023 09:19:21 +1000 Subject: [PATCH 6/7] Ignore block length of response blocks In Rswag request specs, the `response` block is like `describe` and is just used to group several other blocks. It can be long and that's okay. --- .rubocop_styleguide.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.rubocop_styleguide.yml b/.rubocop_styleguide.yml index a6a2fab4f4..5459d63ebc 100644 --- a/.rubocop_styleguide.yml +++ b/.rubocop_styleguide.yml @@ -39,6 +39,7 @@ Metrics/BlockLength: "put", "resource", "resources", + "response", "scenario", "shared_examples", "shared_examples_for", From 847ddab4e633e0226a8c6b16b6c8c46434ca8e3e Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 22 Sep 2023 17:18:49 +1000 Subject: [PATCH 7/7] Improve readability of assignment without blank lines --- .../dfc_provider/lib/data_food_consortium/connector/importer.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb b/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb index 2876f853c4..b8365cdc8a 100644 --- a/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb +++ b/engines/dfc_provider/lib/data_food_consortium/connector/importer.rb @@ -128,11 +128,9 @@ module DataFoodConsortium def guess_setter_name(predicate) name = - # Some predicates are named like `hasQuantity` # but the attribute name would be `quantity`. predicate.fragment&.sub(/^has/, "")&.camelize(:lower) || - # And sometimes the URI looks like `ofn:spree_product_id`. predicate.to_s.split(":").last