You are here

public function ProductVariationAttributeMapperTest::testThreeAttributesSixVariations in Commerce Core 8.2

Tests having three attributes and six variations.

@covers ::selectVariation @covers ::prepareAttributes

File

modules/product/tests/src/Kernel/ProductVariationAttributeMapperTest.php, line 446

Class

ProductVariationAttributeMapperTest
Tests the product variation attribute mapper.

Namespace

Drupal\Tests\commerce_product\Kernel

Code

public function testThreeAttributesSixVariations() {
  $variation_type = ProductVariationType::load('default');
  $pack = $this
    ->createAttributeSet($variation_type, 'pack', [
    'one' => '1',
    'twenty' => '20',
    'hundred' => '100',
    'twohundred' => '200',
  ]);
  $product = Product::create([
    'type' => 'default',
    'title' => $this
      ->randomMachineName(),
    'stores' => [
      $this->store,
    ],
    'variations' => [],
  ]);
  $product
    ->save();

  // The Size attribute needs a lighter weight than Color for this scenario.
  // @todo This is an undocumented item, where the order of the attributes on
  // the form display correlate to how they display in the widget / returned
  // values.
  $form_display = commerce_get_entity_display('commerce_product_variation', $variation_type
    ->id(), 'form');
  $form_display
    ->setComponent('attribute_size', [
    'weight' => 0,
  ] + $form_display
    ->getComponent('attribute_size'));
  $form_display
    ->setComponent('attribute_color', [
    'weight' => 1,
  ] + $form_display
    ->getComponent('attribute_color'));
  $form_display
    ->setComponent('attribute_pack', [
    'weight' => 2,
  ] + $form_display
    ->getComponent('attribute_pack'));
  $form_display
    ->save();
  $attribute_values_matrix = [
    [
      'small',
      'black',
      'one',
    ],
    [
      'small',
      'blue',
      'twenty',
    ],
    [
      'medium',
      'green',
      'hundred',
    ],
    [
      'medium',
      'red',
      'twohundred',
    ],
    [
      'large',
      'white',
      'hundred',
    ],
    [
      'large',
      'yellow',
      'twenty',
    ],
  ];
  $variations = [];
  foreach ($attribute_values_matrix as $key => $value) {
    $variation = ProductVariation::create([
      'type' => 'default',
      'sku' => $this
        ->randomMachineName(),
      'price' => [
        'number' => 999,
        'currency_code' => 'USD',
      ],
      'attribute_size' => $this->sizeAttributes[$value[0]],
      'attribute_color' => $this->colorAttributes[$value[1]],
      'attribute_pack' => $pack[$value[2]],
    ]);
    $variation
      ->save();
    $variations[] = $variation;
    $product
      ->addVariation($variation);
  }
  $product
    ->save();

  // Verify available attribute selections for the default variation.
  $selected_variation = $product
    ->getDefaultVariation();
  $attributes = $this->mapper
    ->prepareAttributes($selected_variation, $product
    ->getVariations());
  $size_attribute = $attributes['attribute_size'];
  $this
    ->assertEquals([
    '7' => 'Small',
    '8' => 'Medium',
    '9' => 'Large',
  ], $size_attribute
    ->getValues());
  $color_attribute = $attributes['attribute_color'];
  $this
    ->assertEquals([
    '2' => 'Blue',
    '1' => 'Black',
  ], $color_attribute
    ->getValues());
  $pack_attribute = $attributes['attribute_pack'];

  // The resolved variation is Small -> Black -> 1, cannot choose 20 for the
  // pack size, since that is Small -> Blue -> 20.
  $this
    ->assertEquals([
    '20' => '1',
  ], $pack_attribute
    ->getValues());
  $selected_variation = $this->mapper
    ->selectVariation($variations, [
    'attribute_size' => $this->sizeAttributes['small']
      ->id(),
    'attribute_color' => $this->colorAttributes['blue']
      ->id(),
  ]);
  $this
    ->assertEquals($variations[1]
    ->id(), $selected_variation
    ->id());

  // Medium only has Green & Red as color, so selecting this size should
  // cause the color to reset.
  $selected_variation = $this->mapper
    ->selectVariation($variations, [
    'attribute_size' => $this->sizeAttributes['medium']
      ->id(),
    'attribute_color' => $this->colorAttributes['blue']
      ->id(),
  ]);
  $this
    ->assertEquals($variations[2]
    ->id(), $selected_variation
    ->id());
  $this
    ->assertEquals('Medium', $selected_variation
    ->getAttributeValue('attribute_size')
    ->label());
  $this
    ->assertEquals('Green', $selected_variation
    ->getAttributeValue('attribute_color')
    ->label());
  $this
    ->assertEquals('100', $selected_variation
    ->getAttributeValue('attribute_pack')
    ->label());

  // Verify available attribute selections.
  $attributes = $this->mapper
    ->prepareAttributes($selected_variation, $product
    ->getVariations());
  $size_attribute = $attributes['attribute_size'];
  $this
    ->assertEquals([
    '7' => 'Small',
    '8' => 'Medium',
    '9' => 'Large',
  ], $size_attribute
    ->getValues());
  $color_attribute = $attributes['attribute_color'];
  $this
    ->assertEquals([
    '3' => 'Green',
    '4' => 'Red',
  ], $color_attribute
    ->getValues());
  $pack_attribute = $attributes['attribute_pack'];

  // The resolved variation is Medium -> Green -> 100, cannot choose 200 for
  // the pack size, since that is Medium -> Red -> 200.
  $this
    ->assertEquals([
    '22' => '100',
  ], $pack_attribute
    ->getValues());
}