Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve integration mapping chain resolution #526

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions dev/lib/product_taxonomy/models/integration_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,9 @@ def load_all_from_source(current_shopify_version: nil, base_path: INTEGRATIONS_P
#
# @param versions [Array<IntegrationVersion>] The versions to resolve, ordered from oldest to newest.
def resolve_to_shopify_mappings_chain(versions)
# Resolve newest version against current taxonomy
versions.last.resolve_to_shopify_mappings(nil)

# Resolve each older version against the one following it
versions.each_cons(2).reverse_each do |previous, next_version|
previous.resolve_to_shopify_mappings(next_version)
versions.reverse.each_with_object([]) do |version, resolved_versions|
version.resolve_to_shopify_mappings(resolved_versions)
resolved_versions.prepend(version)
end
end

Expand Down Expand Up @@ -177,16 +174,23 @@ def generate_distribution(output_path:, direction:)
)
end

# Resolve the output categories of to_shopify mappings to the next version of the Shopify taxonomy.
# Resolve the output categories of to_shopify mappings to the current version of the Shopify taxonomy, taking into
# any mappings from later versions.
#
# @param next_integration_version [IntegrationVersion | nil] The IntegrationVersion defining mappings to the next
# newer version of the Shopify taxonomy. If nil, the latest version of the Shopify taxonomy is used.
def resolve_to_shopify_mappings(next_integration_version)
# @param next_integration_versions [Array<IntegrationVersion>] An array of Shopify integration versions coming
# after the current version.
def resolve_to_shopify_mappings(next_integration_versions)
@to_shopify_mappings.each do |mapping|
newer_mapping = next_integration_version&.to_shopify_mappings&.find do
_1.input_category["id"] == mapping.output_category
newer_mapping = next_integration_versions.flat_map(&:to_shopify_mappings).find do |mapping_rule|
mapping_rule.input_category["id"] == mapping.output_category
end
mapping.output_category = newer_mapping&.output_category || Category.find_by(id: mapping.output_category)

next unless mapping.output_category.nil?

raise ArgumentError, "Failed to resolve Shopify mapping: " \
"\"#{mapping.input_category["id"]}\" to \"#{mapping.output_category}\" " \
"(input version: #{version})"
end
end

Expand Down
152 changes: 150 additions & 2 deletions dev/test/models/integration_version_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class IntegrationVersionTest < TestCase
integration_path: File.expand_path("integrations/shopify/2020-01", DATA_PATH),
current_shopify_version: @current_shopify_version,
)
@shopify_integration.resolve_to_shopify_mappings(nil) # Resolve against current version
@shopify_integration.resolve_to_shopify_mappings([]) # Resolve against current version
@external_integration = IntegrationVersion.load_from_source(
integration_path: File.expand_path("integrations/foocommerce/1.0.0", DATA_PATH),
current_shopify_version: @current_shopify_version,
Expand Down Expand Up @@ -236,7 +236,7 @@ class IntegrationVersionTest < TestCase
end

test "unmapped_external_category_ids returns IDs of external categories not mapped from the Shopify taxonomy" do
external_category1 = { "id" => "1", "full_name" => "External category 1" }
external_category1 = category_hash("1")
from_shopify_mappings = [
MappingRule.new(
input_category: Category.new(id: "aa", name: "aa"),
Expand All @@ -257,5 +257,153 @@ class IntegrationVersionTest < TestCase

assert_equal ["2", "3"], integration_version.unmapped_external_category_ids
end

test "resolve_to_shopify_mappings resolves mappings to the latest version of the Shopify taxonomy" do
mapping = MappingRule.new(input_category: category_hash("aa-1"), output_category: "aa-2")
integration_version = IntegrationVersion.new(
name: "shopify",
version: "2020-01",
to_shopify_mappings: [mapping],
full_names_by_id: {},
)
integration_version.resolve_to_shopify_mappings([])
assert_equal "gid://shopify/TaxonomyCategory/aa-2", mapping.output_category.gid
end

test "resolve_to_shopify_mappings raises an error if a mapping cannot be resolved" do
mapping = MappingRule.new(input_category: category_hash("aa-1"), output_category: "invalid")
integration_version = IntegrationVersion.new(
name: "shopify",
version: "2020-01",
to_shopify_mappings: [mapping],
full_names_by_id: {},
)
assert_raises(ArgumentError) { integration_version.resolve_to_shopify_mappings([]) }
end

test "IntegrationVersion.resolve_to_shopify_mappings_chain resolves mappings to the current version of the Shopify taxonomy" do
version = IntegrationVersion.new(
name: "shopify",
version: "2020-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("aa-1"), output_category: "aa-2")],
full_names_by_id: {},
)
IntegrationVersion.resolve_to_shopify_mappings_chain([version])
assert_equal "gid://shopify/TaxonomyCategory/aa-2", version.to_shopify_mappings[0].output_category.gid
end

test "IntegrationVersion.resolve_to_shopify_mappings_chain resolves mappings through two versions without chained mappings" do
versions = [
IntegrationVersion.new(
name: "shopify",
version: "2020-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("aa-1"), output_category: "aa-2")],
full_names_by_id: {},
),
IntegrationVersion.new(
name: "shopify",
version: "2021-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("bb-1"), output_category: "aa-1")],
full_names_by_id: {},
),
]
IntegrationVersion.resolve_to_shopify_mappings_chain(versions)
assert_equal "gid://shopify/TaxonomyCategory/aa-2", versions[0].to_shopify_mappings[0].output_category.gid
assert_equal "gid://shopify/TaxonomyCategory/aa-1", versions[1].to_shopify_mappings[0].output_category.gid
end

test "IntegrationVersion.resolve_to_shopify_mappings_chain resolves mappings through two versions with chained mappings" do
versions = [
IntegrationVersion.new(
name: "shopify",
version: "2020-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("aa-1"), output_category: "aa-2")],
full_names_by_id: {},
),
IntegrationVersion.new(
name: "shopify",
version: "2021-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("aa-2"), output_category: "aa-3")],
full_names_by_id: {},
),
]
IntegrationVersion.resolve_to_shopify_mappings_chain(versions)
assert_equal "gid://shopify/TaxonomyCategory/aa-3", versions[0].to_shopify_mappings[0].output_category.gid
assert_equal "gid://shopify/TaxonomyCategory/aa-3", versions[1].to_shopify_mappings[0].output_category.gid
end

test "IntegrationVersion.resolve_to_shopify_mappings_chain resolves mappings through four versions with non-consecutive chained mappings" do
versions = [
IntegrationVersion.new(
name: "shopify",
version: "2020-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("aa-1"), output_category: "aa-2")],
full_names_by_id: {},
),
IntegrationVersion.new(
name: "shopify",
version: "2021-01",
to_shopify_mappings: [],
full_names_by_id: {},
),
IntegrationVersion.new(
name: "shopify",
version: "2022-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("aa-2"), output_category: "aa-3")],
full_names_by_id: {},
),
IntegrationVersion.new(
name: "shopify",
version: "2023-01",
to_shopify_mappings: [],
full_names_by_id: {},
),
]
IntegrationVersion.resolve_to_shopify_mappings_chain(versions)
assert_equal "gid://shopify/TaxonomyCategory/aa-3", versions[0].to_shopify_mappings[0].output_category.gid
assert_equal "gid://shopify/TaxonomyCategory/aa-3", versions[2].to_shopify_mappings[0].output_category.gid
end

test "IntegrationVersion.resolve_to_shopify_mappings_chain resolves mappings through four versions with a mix of chained and non-chained mappings" do
versions = [
IntegrationVersion.new(
name: "shopify",
version: "2020-01",
to_shopify_mappings: [
MappingRule.new(input_category: category_hash("aa-1"), output_category: "aa-2"),
MappingRule.new(input_category: category_hash("bb-1"), output_category: "aa-1"),
],
full_names_by_id: {},
),
IntegrationVersion.new(
name: "shopify",
version: "2021-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("cc-1"), output_category: "aa-1")],
full_names_by_id: {},
),
IntegrationVersion.new(
name: "shopify",
version: "2022-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("aa-2"), output_category: "aa-3")],
full_names_by_id: {},
),
IntegrationVersion.new(
name: "shopify",
version: "2023-01",
to_shopify_mappings: [MappingRule.new(input_category: category_hash("dd-1"), output_category: "aa-2")],
full_names_by_id: {},
),
]
IntegrationVersion.resolve_to_shopify_mappings_chain(versions)
assert_equal "gid://shopify/TaxonomyCategory/aa-3", versions[0].to_shopify_mappings[0].output_category.gid
assert_equal "gid://shopify/TaxonomyCategory/aa-1", versions[0].to_shopify_mappings[1].output_category.gid
assert_equal "gid://shopify/TaxonomyCategory/aa-1", versions[1].to_shopify_mappings[0].output_category.gid
assert_equal "gid://shopify/TaxonomyCategory/aa-3", versions[2].to_shopify_mappings[0].output_category.gid
assert_equal "gid://shopify/TaxonomyCategory/aa-2", versions[3].to_shopify_mappings[0].output_category.gid
end

def category_hash(id)
{ "id" => id, "full_name" => "Category #{id}" }
end
end
end
Loading