Skip to content

Commit 7c2847e

Browse files
committed
Introduce Product Resource
The Core API supports retrieval of products by its Product ID. This PR introduces the new Product resource, along with child resources needed to build the main Product object. These child resources include Allergens, Ingredient, Dietary Tag. This change addresses the need by: * Introducing a CoreObject resource which can be used by all core (v2) objects * Introducing a Product resource
1 parent 453ce0f commit 7c2847e

13 files changed

Lines changed: 289 additions & 0 deletions

File tree

‎lib/bls/core.rb‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,20 @@
1717
require_relative "core/resources/api_error"
1818
require_relative "core/authorization/bearer"
1919
require_relative "core/resources/object"
20+
require_relative "core/resources/object_v2"
21+
require_relative "core/resources/allergen"
22+
require_relative "core/resources/dietary_tag"
23+
require_relative "core/resources/ingredient"
2024
require_relative "core/resources/inventory_level"
25+
require_relative "core/resources/nutrition_fact"
2126
require_relative "core/resources/order"
2227
require_relative "core/resources/order_item"
2328
require_relative "core/serializers/order_item_serializer"
2429
require_relative "core/resources/menu"
2530
require_relative "core/resources/menu_item"
2631
require_relative "core/serializers/menu_item_serializer"
32+
require_relative "core/resources/product"
33+
require_relative "core/resources/product_factory"
2734
require_relative "core/resources/recipient"
2835
require_relative "core/serializers/recipient_serializer"
2936
require_relative "core/version"

‎lib/bls/core/resources/allergen.rb‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
module Bls
4+
module Core
5+
class Allergen < Bls::Core::ObjectV2; end
6+
end
7+
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
module Bls
4+
module Core
5+
class DietaryTag < Bls::Core::ObjectV2; end
6+
end
7+
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
module Bls
4+
module Core
5+
class Ingredient < Bls::Core::ObjectV2; end
6+
end
7+
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
module Bls
4+
module Core
5+
class NutritionFact < Bls::Core::ObjectV2; end
6+
end
7+
end
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
module Bls
4+
module Core
5+
class ObjectV2 < Bls::Core::Object
6+
def self.build_from_array(array)
7+
array.map { |object| build(object) }
8+
end
9+
10+
def resources_path
11+
"#{api.base_url}/api/#{object_name.downcase}"
12+
end
13+
14+
def resource_path
15+
"#{api.base_url}/api/#{object_name.downcase}/#{id}"
16+
end
17+
18+
def api
19+
@api ||= Bls::Core::V2.build
20+
end
21+
end
22+
end
23+
end

‎lib/bls/core/resources/product.rb‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
module Bls
4+
module Core
5+
class Product < Bls::Core::ObjectV2
6+
def object_name
7+
"products"
8+
end
9+
10+
def self.build_from_response(data)
11+
factory = ProductFactory.new(data)
12+
factory.create
13+
end
14+
end
15+
end
16+
end
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# frozen_string_literal: true
2+
3+
module Bls
4+
module Core
5+
class ProductFactory
6+
attr_accessor :response
7+
8+
def initialize(response)
9+
@response = response
10+
end
11+
12+
def create
13+
product = Product.build(response)
14+
product.ingredients = ingredients
15+
product.allergens = allergens
16+
product.dietary_tags = dietary_tags
17+
product.nutrition_facts = nutrition_facts
18+
product
19+
end
20+
21+
protected
22+
23+
def ingredients
24+
Ingredient.build_from_array(response[:ingredients])
25+
end
26+
27+
def allergens
28+
Allergen.build_from_array(response[:allergens])
29+
end
30+
31+
def dietary_tags
32+
DietaryTag.build_from_array(response[:dietary_tags])
33+
end
34+
35+
def nutrition_facts
36+
as_packaged = NutritionFact.
37+
build_from_array(response[:nutrition_facts][:as_packaged])
38+
as_cooked = NutritionFact.
39+
build_from_array(response[:nutrition_facts].
40+
fetch(:as_cooked, []))
41+
{ as_packaged: as_packaged, as_cooked: as_cooked }
42+
end
43+
end
44+
end
45+
end

‎lib/bls/core/testing/fake.rb‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@ module Testing
66
class Fake
77
def self.configure(*); end
88

9+
class Allergen
10+
def self.create(code: "MILK", source: "ANCHOVY")
11+
OpenStruct.new(code: code, source: source)
12+
end
13+
end
14+
15+
class DietaryTag
16+
def self.create(tag: "PESCATARIAN")
17+
OpenStruct.new(tag: tag)
18+
end
19+
end
20+
21+
class Ingredient
22+
def self.create(code: "MILK", name: "ANCHOVY", quantity: 1,
23+
unit: "serving")
24+
OpenStruct.new(code: code, name: name, quantity: quantity,
25+
unit: unit)
26+
end
27+
end
28+
929
class InventoryLevel
1030
def self.create(sku: "SKU1", date: Date.today.to_s,
1131
distribution_center_name: "WEST_COAST",
@@ -56,6 +76,12 @@ def initialize(menu_item)
5676
end
5777
end
5878

79+
class NutritionFact
80+
def self.create(code: "CALORIES", amount: 0, unit: "serving")
81+
OpenStruct.new(code: code, amount: amount, unit: unit)
82+
end
83+
end
84+
5985
class Recipient
6086
def self.new(name: nil, street1: nil, street2: nil, city: nil,
6187
state: nil, zip: nil, zip4: nil, email: nil, phone: nil,
@@ -95,6 +121,15 @@ def self.new(sku:, quantity:, protein_sku:)
95121
end
96122
end
97123

124+
class Product
125+
def self.new(code:, name:, status: "DRAFT", nutrition_facts: [])
126+
OpenStruct.new(code: code, name: name, status: status,
127+
nutrition_facts: nutrition_facts,
128+
allergens: [Fake::Allergen.create],
129+
dietary_tags: [Fake::DietaryTag.create])
130+
end
131+
end
132+
98133
def self.client
99134
Fake::Client.new
100135
end
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe Bls::Core::ProductFactory do
4+
describe "#create" do
5+
it "assigns the ingredients to the Product" do
6+
response = build_product_response
7+
ingredient = Bls::Core::Ingredient.build(response[:ingredients])
8+
factory = Bls::Core::ProductFactory.new(response)
9+
10+
result = factory.create
11+
12+
expect(result.ingredients).to match_array(ingredient)
13+
end
14+
15+
it "assigns the allergens to the Product" do
16+
response = build_product_response
17+
allergen = Bls::Core::Allergen.build_from_array(response[:allergens])
18+
factory = Bls::Core::ProductFactory.new(response)
19+
20+
result = factory.create
21+
22+
expect(result.allergens).to match_array(allergen)
23+
end
24+
25+
it "assigns the dietary tags to the Product" do
26+
response = build_product_response
27+
dietary_tags = Bls::Core::Allergen.
28+
build_from_array(response[:dietary_tags])
29+
factory = Bls::Core::ProductFactory.new(response)
30+
31+
result = factory.create
32+
33+
expect(result.dietary_tags).to match_array(dietary_tags)
34+
end
35+
36+
it "assigns the nutrition facts to the Product" do
37+
response = build_product_response
38+
factory = Bls::Core::ProductFactory.new(response)
39+
product = factory.create
40+
41+
result = product.nutrition_facts
42+
43+
expect(result.keys).to match_array([:as_packaged, :as_cooked])
44+
end
45+
end
46+
end

0 commit comments

Comments
 (0)