commerce-8.x-2.8/modules/cart/tests/src/Functional/AddToCartFormTest.php
modules/cart/tests/src/Functional/AddToCartFormTest.php
<?php
namespace Drupal\Tests\commerce_cart\Functional;
use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_product\Entity\ProductAttribute;
use Drupal\commerce_product\Entity\ProductVariation;
use Drupal\commerce_product\Entity\ProductVariationType;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\field\Entity\FieldConfig;
/**
* Tests the add to cart form.
*
* @group commerce
*/
class AddToCartFormTest extends CartBrowserTestBase {
/**
* Test adding a product to the cart.
*/
public function testProductAddToCartForm() {
// Confirm that the initial add to cart submit works.
$this->postAddToCart($this->variation->getProduct());
$this->cart = Order::load($this->cart->id());
$order_items = $this->cart->getItems();
$this->assertOrderItemInOrder($this->variation, $order_items[0]);
// Confirm that the second add to cart submit increments the quantity
// of the first order item..
$this->postAddToCart($this->variation->getProduct());
\Drupal::entityTypeManager()->getStorage('commerce_order')->resetCache();
\Drupal::entityTypeManager()->getStorage('commerce_order_item')->resetCache();
$this->cart = Order::load($this->cart->id());
$order_items = $this->cart->getItems();
$this->assertNotEmpty(count($order_items) == 1, 'No additional order items were created');
$this->assertOrderItemInOrder($this->variation, $order_items[0], 2);
}
/**
* Test assigning an anonymous cart to a logged in user.
*/
public function testCartAssignment() {
$this->drupalLogout();
$this->postAddToCart($this->variation->getProduct());
// Find the newly created anonymous cart.
$query = \Drupal::entityQuery('commerce_order')
->condition('cart', TRUE)
->condition('uid', 0);
$result = $query->execute();
$cart_id = reset($result);
$cart = Order::load($cart_id);
$this->assertEquals(0, $cart->getCustomerId());
$this->assertNotEmpty($cart->hasItems());
$this->drupalLogin($this->adminUser);
\Drupal::entityTypeManager()->getStorage('commerce_order')->resetCache();
$cart = Order::load($cart->id());
$this->assertEquals($this->adminUser->id(), $cart->getCustomerId());
}
/**
* Test adding a product to the cart, via the variant's canonical link.
*/
public function testVariationCanonicalLinkAddToCartForm() {
/** @var \Drupal\commerce_product\Entity\ProductVariationTypeInterface $variation_type */
$variation_type = ProductVariationType::load($this->variation->bundle());
$color_attribute_values = $this->createAttributeSet($variation_type, 'color', [
'cyan' => 'Cyan',
'magenta' => 'Magenta',
]);
$variation1 = $this->createEntity('commerce_product_variation', [
'type' => 'default',
'sku' => 'not-canonical',
'price' => [
'number' => '5.00',
'currency_code' => 'USD',
],
'attribute_color' => $color_attribute_values['cyan'],
]);
$variation2 = $this->createEntity('commerce_product_variation', [
'type' => 'default',
'sku' => 'canonical-test',
'price' => [
'number' => '9.99',
'currency_code' => 'USD',
],
'attribute_color' => $color_attribute_values['magenta'],
]);
$this->createEntity('commerce_product', [
'type' => 'default',
'title' => $this->randomMachineName(),
'stores' => [$this->store],
'variations' => [$variation1, $variation2],
]);
$this->drupalGet($variation2->toUrl());
$this->assertSession()->pageTextContains('$9.99');
$this->submitForm([], 'Add to cart');
$this->cart = Order::load($this->cart->id());
$order_items = $this->cart->getItems();
$this->assertEquals($variation2->getSku(), $order_items[0]->getPurchasedEntity()->getSku());
}
/**
* Tests ability to expose order item fields on the add to cart form.
*/
public function testExposedOrderItemFields() {
/** @var \Drupal\Core\Entity\Entity\EntityFormDisplay $order_item_form_display */
$order_item_form_display = EntityFormDisplay::load('commerce_order_item.default.add_to_cart');
$order_item_form_display->setComponent('quantity', [
'type' => 'commerce_quantity',
]);
$order_item_form_display->save();
// Confirm that the given quantity was accepted and saved.
$this->postAddToCart($this->variation->getProduct(), [
'quantity[0][value]' => 3,
]);
$this->cart = Order::load($this->cart->id());
$order_items = $this->cart->getItems();
$this->assertOrderItemInOrder($this->variation, $order_items[0], 3);
// Confirm that a zero quantity isn't accepted.
$this->postAddToCart($this->variation->getProduct(), [
'quantity[0][value]' => 0,
]);
$this->assertSession()->pageTextContains('Quantity must be higher than or equal to 1.');
}
/**
* Tests that an attribute field is disabled if there's only one value.
*/
public function testProductAttributeDisabledIfOne() {
/** @var \Drupal\commerce_product\Entity\ProductVariationTypeInterface $variation_type */
$variation_type = ProductVariationType::load($this->variation->bundle());
$size_attributes = $this->createAttributeSet($variation_type, 'size', [
'small' => 'Small',
'medium' => 'Medium',
'large' => 'Large',
]);
$color_attributes = $this->createAttributeSet($variation_type, 'color', [
'red' => 'Red',
]);
// Reload the variation since we have new fields.
$this->variation = ProductVariation::load($this->variation->id());
$product = $this->variation->getProduct();
// Update first variation to have the attribute's value.
$this->variation->attribute_size = $size_attributes['small']->id();
$this->variation->attribute_color = $color_attributes['red']->id();
$this->variation->save();
$attribute_values_matrix = [
['medium', 'red'],
['large', 'red'],
];
$variations = [
$this->variation,
];
// Generate variations off of the attributes values matrix.
foreach ($attribute_values_matrix as $key => $value) {
$variation = $this->createEntity('commerce_product_variation', [
'type' => $variation_type->id(),
'sku' => $this->randomMachineName(),
'price' => [
'number' => 999,
'currency_code' => 'USD',
],
'attribute_size' => $size_attributes[$value[0]]->id(),
'attribute_color' => $color_attributes[$value[1]]->id(),
]);
$variations[] = $variation;
$product->variations->appendItem($variation);
}
$product->save();
$this->drupalGet($product->toUrl());
$this->assertSession()->elementExists('xpath', '//select[@id="edit-purchased-entity-0-attributes-attribute-color" and @disabled]');
}
/**
* Tests that the add to cart form renders an attribute entity.
*/
public function testRenderedAttributeElement() {
/** @var \Drupal\commerce_product\Entity\ProductVariationTypeInterface $variation_type */
$variation_type = ProductVariationType::load($this->variation->bundle());
$color_attribute_values = $this->createAttributeSet($variation_type, 'color', [
'cyan' => 'Cyan',
'magenta' => 'Magenta',
], TRUE);
$color_attribute_values['cyan']->set('rendered_test', 'Cyan (Rendered)')->save();
$color_attribute_values['cyan']->save();
$color_attribute_values['magenta']->set('rendered_test', 'Magenta (Rendered)')->save();
$color_attribute_values['magenta']->save();
$color_attribute = ProductAttribute::load($color_attribute_values['cyan']->getAttributeId());
$variation1 = $this->createEntity('commerce_product_variation', [
'type' => 'default',
'sku' => $this->randomMachineName(),
'price' => [
'number' => 999,
'currency_code' => 'USD',
],
'attribute_color' => $color_attribute_values['cyan'],
]);
$variation2 = $this->createEntity('commerce_product_variation', [
'type' => 'default',
'sku' => $this->randomMachineName(),
'price' => [
'number' => 999,
'currency_code' => 'USD',
],
'attribute_color' => $color_attribute_values['magenta'],
]);
$product = $this->createEntity('commerce_product', [
'type' => 'default',
'title' => $this->randomMachineName(),
'stores' => [$this->store],
'variations' => [$variation1, $variation2],
]);
$this->drupalGet($product->toUrl());
$this->assertAttributeExists('purchased_entity[0][attributes][attribute_color]', $color_attribute_values['cyan']->id());
$color_attribute->set('elementType', 'commerce_product_rendered_attribute')->save();
$this->drupalGet($product->toUrl());
$this->assertSession()->pageTextContains('Cyan (Rendered)');
$this->assertSession()->pageTextContains('Magenta (Rendered)');
}
/**
* Tests the behavior of optional product attributes.
*/
public function testOptionalProductAttribute() {
/** @var \Drupal\commerce_product\Entity\ProductVariationTypeInterface $variation_type */
$variation_type = ProductVariationType::load($this->variation->bundle());
$size_attributes = $this->createAttributeSet($variation_type, 'size', [
'small' => 'Small',
'medium' => 'Medium',
'large' => 'Large',
]);
$color_attributes = $this->createAttributeSet($variation_type, 'color', [
'red' => 'Red',
]);
// Make the color attribute optional.
$color_field = FieldConfig::loadByName('commerce_product_variation', 'default', 'attribute_color');
$color_field->setRequired(TRUE);
$color_field->save();
// Reload the variation since we have new fields.
$this->variation = ProductVariation::load($this->variation->id());
$product = $this->variation->getProduct();
// Update the first variation to have the attribute values.
$this->variation->attribute_size = $size_attributes['small']->id();
$this->variation->attribute_color = $color_attributes['red']->id();
$this->variation->save();
$attribute_values_matrix = [
['medium', 'red'],
['large', 'red'],
];
$variations = [
$this->variation,
];
// Generate variations off of the attributes values matrix.
foreach ($attribute_values_matrix as $key => $value) {
$variation = $this->createEntity('commerce_product_variation', [
'type' => $variation_type->id(),
'sku' => $this->randomMachineName(),
'price' => [
'number' => 999,
'currency_code' => 'USD',
],
'attribute_size' => $size_attributes[$value[0]]->id(),
'attribute_color' => $color_attributes[$value[1]]->id(),
]);
$variations[] = $variation;
$product->variations->appendItem($variation);
}
$product->save();
// The color element should be required because each variation has a color.
$this->drupalGet($product->toUrl());
$this->assertSession()->fieldExists('purchased_entity[0][attributes][attribute_size]');
$this->assertSession()->elementExists('xpath', '//select[@id="edit-purchased-entity-0-attributes-attribute-color" and @required]');
// Remove the color value from all variations.
// The color element should now be hidden.
foreach ($variations as $variation) {
$variation->attribute_color = NULL;
$this->variation->save();
}
$this->drupalGet($product->toUrl());
$this->assertSession()->fieldExists('purchased_entity[0][attributes][attribute_size]');
$this->assertSession()->fieldNotExists('purchased_entity[0][attributes][attribute_color]');
}
}
