From e08ce62aa4c06b0f52e6388091b3df1517ddcbec Mon Sep 17 00:00:00 2001
From: Matt Glaman <nmd.matt@gmail.com>
Date: Mon, 15 Feb 2016 14:55:08 -0600
Subject: [PATCH] Issue #2652768 by vasike, mglaman: AddToCartForm tests

---
 modules/product/src/Tests/AddToCartFormTest.php | 231 ++++++++++++++++++++++++
 1 file changed, 231 insertions(+)
 create mode 100644 modules/product/src/Tests/AddToCartFormTest.php

diff --git a/modules/product/src/Tests/AddToCartFormTest.php b/modules/product/src/Tests/AddToCartFormTest.php
new file mode 100644
index 0000000..5fef190
--- /dev/null
+++ b/modules/product/src/Tests/AddToCartFormTest.php
@@ -0,0 +1,231 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\commerce_product\Tests\AddToCartFormTest.
+ */
+
+namespace Drupal\commerce_product\Tests;
+
+use Drupal\commerce_order\Entity\Order;
+use Drupal\commerce_order\Tests\OrderTestBase;
+use Drupal\commerce_product\Entity\Product;
+use Drupal\commerce_product\Entity\ProductInterface;
+use Drupal\commerce_product\Entity\ProductVariation;
+use Drupal\commerce_product\Entity\ProductVariationType;
+use Drupal\commerce_product\Entity\ProductVariationTypeInterface;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\taxonomy\Entity\Term;
+use Drupal\taxonomy\Entity\Vocabulary;
+
+/**
+ * Functional tests for the add to cart form.
+ *
+ * @group commerce
+ */
+class AddToCartFormTest extends OrderTestBase {
+
+
+
+  /**
+   * The cart order to test against.
+   *
+   * @var \Drupal\commerce_order\Entity\Order
+   */
+  protected $cart;
+
+  /**
+   * The cart manager for test cart operations.
+   *
+   * @var \Drupal\commerce_cart\CartManager
+   */
+  protected $cartManager;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'commerce_cart',
+    'node',
+    'taxonomy',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getAdministratorPermissions() {
+    return array_merge([
+      'administer products',
+      'access content',
+    ], parent::getAdministratorPermissions());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->cart = \Drupal::service('commerce_cart.cart_provider')->createCart('default', $this->store);
+    $this->cartManager = \Drupal::service('commerce_cart.cart_manager');
+  }
+
+  /**
+   * Test adding a product to the cart.
+   */
+//  public function testProductAddToCartForm() {
+//    // Get the existing product page and submit Add to cart form.
+//    $this->postAddToCart($this->variation->getProduct());
+//
+//    // Check if the quantity was increased for the existing line item.
+//    $this->cart = Order::load($this->cart->id());
+//    $line_items = $this->cart->getLineItems();
+//    /** @var \Drupal\commerce_order\Entity\LineItemInterface $line_item */
+//    $line_item = $line_items[0];
+//    $this->assertEqual($line_item->getTitle(), $this->variation->getLineItemTitle());
+//    $this->assertTrue(($line_item->getQuantity() == 1), t('The product @product has been added to cart.', ['@product' => $line_item->getTitle()]));
+//  }
+
+  /**
+   * Tests adding a product to the cart when there are multiple variations.
+   */
+  public function testMultipleVariationsAddToCartForm() {
+    /** @var \Drupal\commerce_product\Entity\ProductVariationTypeInterface $variation_type */
+    $variation_type = ProductVariationType::load($this->variation->bundle());
+    $attribute_name = 'test_variation';
+    $this->createAttributeField($variation_type, $attribute_name);
+
+    // Reload the variation since we have a new field.
+    $this->variation = ProductVariation::load($this->variation->id());
+    $product = $this->variation->getProduct();
+
+    // Update first variation to have the attribute's value.
+    $attribute = $this->createAttributeOption($attribute_name, $this->randomMachineName());
+    $this->variation->set($attribute_name, $attribute->id());
+    $this->variation->save();
+
+    $attribute = $this->createAttributeOption($attribute_name, $this->randomMachineName());
+    $variation2 = $this->createEntity('commerce_product_variation', [
+      'type' => $variation_type->id(),
+      'sku' => $this->randomMachineName(),
+      'price' => [
+        'amount' => 999,
+        'currency_code' => 'USD',
+      ],
+      $attribute_name => $attribute->id(),
+    ]);
+    $variation2->save();
+
+    $attribute = $this->createAttributeOption($attribute_name, $this->randomMachineName());
+    $variation3 = $this->createEntity('commerce_product_variation', [
+      'type' => $variation_type->id(),
+      'sku' => $this->randomMachineName(),
+      'price' => [
+        'amount' => 999,
+        'currency_code' => 'USD',
+      ],
+      $attribute_name => $attribute->id(),
+    ]);
+    $variation3->save();
+
+    $product->{'variations'}->appendItem($variation2);
+    $product->{'variations'}->appendItem($variation3);
+    $product->save();
+
+    // Run the original add to cart test, ensure base variation is added.
+    // Get the existing product page and submit Add to cart form.
+    $this->postAddToCart($product);
+    $this->assertEqual($variation3->{$attribute_name}->target_id, $attribute->id());
+    $this->postAddToCart($product, [
+      'attributes[test_variation]' => $variation3->{$attribute_name}->target_id,
+    ]);
+
+    // Check if the quantity was increased for the existing line item.
+    $this->cart = Order::load($this->cart->id());
+    $line_items = $this->cart->getLineItems();
+    /** @var \Drupal\commerce_order\Entity\LineItemInterface $line_item */
+    $line_item = $line_items[0];
+    $this->assertEqual($line_item->getTitle(), $this->variation->getLineItemTitle());
+    $this->assertTrue(($line_item->getQuantity() == 1), t('The product @product has been added to cart.', ['@product' => $line_item->getTitle()]));
+    $line_item = $line_items[1];
+    $this->assertEqual($line_item->getTitle(), $variation3->getLineItemTitle());
+    $this->assertTrue(($line_item->getQuantity() == 1), t('The product @product has been added to cart.', ['@product' => $line_item->getTitle()]));
+  }
+
+  /**
+   * Helper method to create an attribute field on a variation type.
+   *
+   * @param \Drupal\commerce_product\Entity\ProductVariationTypeInterface $variation_type
+   *   The variation type.
+   * @param string $field_name
+   *   The field name.
+   */
+  protected function createAttributeField(ProductVariationTypeInterface $variation_type, $field_name) {
+    $attribute_vocabulary = Vocabulary::create([
+      'name' => $field_name,
+      'vid' => $field_name,
+    ]);
+    $attribute_vocabulary->save();
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => $field_name,
+      'entity_type' => 'commerce_product_variation',
+      'type' => 'entity_reference',
+      'cardinality' => 1,
+      'settings' => [
+        'target_type' => 'taxonomy_term',
+      ],
+    ]);
+    $field_storage->save();
+    $field = FieldConfig::create([
+      'field_storage' => $field_storage,
+      'bundle' => $variation_type->id(),
+      'label' => $field_name,
+      'settings' => [
+        'handler' => 'default:taxonomy_term',
+        'handler_settings' => [
+          'target_bundles' => [$attribute_vocabulary->id() => $attribute_vocabulary->id()],
+          'auto_create' => TRUE,
+        ],
+      ],
+      'translatable' => FALSE,
+    ]);
+    $field->setThirdPartySetting('commerce_product', 'attribute_widget_title', '');
+    $field->setThirdPartySetting('commerce_product', 'attribute_widget', 'select');
+    $field->setThirdPartySetting('commerce_product', 'attribute_field', TRUE);
+    $field->save();
+  }
+
+  /**
+   * Creates an attribute.
+   *
+   * @param string $bundle
+   * @param string $name
+   *
+   * @return \Drupal\taxonomy\Entity\Term
+   */
+  protected function createAttributeOption($bundle, $name) {
+    $attribute = $this->createEntity('taxonomy_term', [
+      'vid' => $bundle,
+      'name' => $name,
+    ]);
+    $attribute->save();
+    return $attribute;
+  }
+
+  /**
+   * Posts the add to cart form for a product.
+   *
+   * @param \Drupal\commerce_product\Entity\ProductInterface $product
+   * @param array $edit
+   *
+   * @throws \Exception
+   */
+  protected function postAddToCart(ProductInterface $product, array $edit = []) {
+    $this->drupalGet('product/' . $product->id());
+    $this->assertField('edit-submit', t('Add to cart button exists.'));
+    $this->drupalPostForm(NULL, $edit, t('Add to cart'));
+  }
+}
