code: def test_node_evaluator_with_multihop_joined_spec(  # noqa: D
      consistent_id_object_repository: ConsistentIdObjectRepository,
      multi_hop_join_semantic_manifest_lookup: SemanticManifestLookup,
  ) -> None:
      """Tests the case where multiple nodes need to be joined to get all linkable specs."""
      txn_source = (
          consistent_id_object_repository.multihop_model_read_nodes[
              "account_month_txns"
          ]
      )
  
      linkable_specs = [
          DimensionSpec(
              element_name="customer_name",
              entity_links=(
                  EntityReference(element_name="account_id"),
                  EntityReference(element_name="customer_id"),
              ),
          ),
      ]
  
      multihop_node_evaluator = make_multihop_node_evaluator(
          model_source_nodes=consistent_id_object_repository.multihop_model_source_nodes,
          semantic_manifest_lookup_with_multihop_links=multi_hop_join_semantic_manifest_lookup,
          desired_linkable_specs=linkable_specs,
      )
  
      evaluation = multihop_node_evaluator.evaluate_node(
          required_linkable_specs=linkable_specs,
          start_node=txn_source,
          default_join_type=SqlJoinType.LEFT_OUTER,
      )
  
      assert evaluation == LinkableInstanceSatisfiabilityEvaluation(
          local_linkable_specs=(),
          joinable_linkable_specs=(
              DimensionSpec(
                  element_name="customer_name",
                  entity_links=(
                      EntityReference(element_name="account_id"),
                      EntityReference(element_name="customer_id"),
                  ),
              ),
          ),
          join_recipes=(
              JoinLinkableInstancesRecipe(
                  node_to_join=evaluation.join_recipes[0].node_to_join,
                  join_on_entity=LinklessEntitySpec.from_element_name(
                      "account_id"
                  ),
                  satisfiable_linkable_specs=[
                      DimensionSpec(
                          element_name="customer_name",
                          entity_links=(
                              EntityReference(
                                  element_name="account_id"
                              ),
                              EntityReference(
                                  element_name="customer_id"
                              ),
                          ),
                      ),
                  ],
                  join_on_partition_dimensions=(),
                  join_on_partition_time_dimensions=(
                      PartitionTimeDimensionJoinDescription(
                          start_node_time_dimension_spec=TimeDimensionSpec(
                              element_name="ds_partitioned",
                              entity_links=(),
                              time_granularity=TimeGranularity.DAY,
                          ),
                          node_to_join_time_dimension_spec=TimeDimensionSpec(
                              element_name="ds_partitioned",
                              entity_links=(),
                              time_granularity=TimeGranularity.DAY,
                          ),
                      ),
                  ),
                  join_type=SqlJoinType.LEFT_OUTER,
              ),
          ),
          unjoinable_linkable_specs=(),
      )
  
imports: from __future__ import annotations
  import logging
  from typing import Sequence
  import pytest
  from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity
  from metricflow.dataflow.builder.dataflow_plan_builder import DataflowPlanBuilder
  from metricflow.dataflow.builder.node_data_set import DataflowPlanNodeOutputDataSetResolver
  from metricflow.dataflow.builder.node_evaluator import JoinLinkableInstancesRecipe, LinkableInstanceSatisfiabilityEvaluation, NodeEvaluatorForLinkableInstances
  from metricflow.dataflow.builder.partitions import PartitionTimeDimensionJoinDescription
  from metricflow.dataflow.dataflow_plan import BaseOutput, ValidityWindowJoinDescription
  from metricflow.dataset.dataset import DataSet
  from metricflow.model.semantic_manifest_lookup import SemanticManifestLookup
  from metricflow.plan_conversion.column_resolver import DunderColumnAssociationResolver
  from metricflow.plan_conversion.node_processor import PreJoinNodeProcessor
  from metricflow.specs.specs import DimensionSpec, EntityReference, EntitySpec, LinkableInstanceSpec, LinklessEntitySpec, TimeDimensionSpec
  from metricflow.sql.sql_plan import SqlJoinType
  from metricflow.test.fixtures.model_fixtures import ConsistentIdObjectRepository
label_desc: Use image node_id 10 for calling a global function with example usage: test_node_evaluator_with_multihop_joined_spec(consistent_id_object_repository, multi_hop_join_semantic_manifest_lookup) without return types