Commit 6563e2a8 authored by tonytheferg's avatar tonytheferg
Browse files

Issue #3248103 by tonytheferg: create discount test

parent d14721e6
Loading
Loading
Loading
Loading
+379 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\commerce_vado\Functional;

use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Tests\commerce_cart\Functional\CartBrowserTestBase;
use Drupal\Tests\commerce_vado\Traits\VadoCreationTrait;

/**
 * Tests commerce_vado bundle discount field.
 *
 * @group commerce_vado
 */
class VadoDiscountsTest extends CartBrowserTestBase {

  use VadoCreationTrait;

  /**
   * The order storage.
   *
   * @var \Drupal\commerce_order\OrderStorage
   */
  protected $orderStorage;

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = [
    'commerce_vado',
  ];

  /**
   * {@inheritdoc}
   */
  protected function getAdministratorPermissions() {
    return array_merge([
      'access vado administration pages',
      'administer commerce_vado_group',
    ], parent::getAdministratorPermissions());
  }

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    /** @var \Drupal\commerce_vado\VadoFieldManagerInterface $vado_field_manager */
    $vado_field_manager = \Drupal::service('commerce_vado.field_manager');

    $vado_field_manager->installField('child_variations', 'default');
    $vado_field_manager->installField('variation_groups', 'default');
    $vado_field_manager->installField('bundle_discount', 'default');
    $vado_field_manager->installField('include_parent', 'default');
    // Test that the actual fields now exist on the variation type.
    $this->assertTrue($vado_field_manager->hasField('child_variations', 'default'));
    $this->assertTrue($vado_field_manager->hasField('variation_groups', 'default'));
    $this->assertTrue($vado_field_manager->hasField('bundle_discount', 'default'));
    $this->assertTrue($vado_field_manager->hasField('include_parent', 'default'));

    // Set the view display for the price to calculated.
    $variation_view_display = EntityViewDisplay::load('commerce_product_variation.default.default');
    if (!$variation_view_display) {
      $variation_view_display = EntityViewDisplay::create([
        'targetEntityType' => 'commerce_product_variation',
        'bundle' => 'default',
        'mode' => 'default',
        'status' => TRUE,
      ]);
    }
    $variation_view_display->setComponent('price', [
      'type' => 'commerce_price_calculated',
      'region' => 'content',
      'settings' => [
        'adjustment_types' => [
          'vado_discount' => 'vado_discount',
        ],
      ],
    ]);
    $variation_view_display->save();

    /** @var \Drupal\commerce_product\Entity\Product $parent_product */
    $this->parent_product = $this->createProductWithVariations(1, [
      'title' => 'Parent Product',
      'variations' => [
        [
          'sku' => 'PARENT',
          'price' => ['number' => '100.00'],
        ],
      ],
    ]);
    /** @var \Drupal\commerce_product\Entity\Product $child_product */
    $this->child_product = $this->createProductWithVariations(1, [
      'title' => 'Child Product',
      'variations' => [
        [
          'title' => 'Child Product 1',
          'sku' => 'CHILD',
          'price' => ['number' => '75.99'],
        ],
      ],
    ]);
    $this->child_product_1 = $this->createProductWithVariations(1, [
      'title' => 'Child Product 1',
      'variations' => [
        [
          'sku' => 'CHILD-1',
          'price' => ['number' => '110.00'],
        ],
      ],
    ]);
    $this->child_product_2 = $this->createProductWithVariations(1, [
      'title' => 'Child Product 2',
      'variations' => [
        [
          'sku' => 'CHILD-2',
          'price' => ['number' => '210.00'],
        ],
      ],
    ]);
    $this->child_product_3 = $this->createProductWithVariations(1, [
      'title' => 'Child Product 3',
      'variations' => [
        [
          'sku' => 'CHILD-3',
          'price' => ['number' => '310.00'],
        ],
      ],
    ]);
    $this->child_product_4 = $this->createProductWithVariations(1, [
      'title' => 'Child Product 4',
      'variations' => [
        [
          'sku' => 'CHILD-4',
          'price' => ['number' => '410.00'],
        ],
      ],
    ]);
    /** @var \Drupal\commerce_product\Entity\ProductVariation $this->parent_variation */
    $this->parent_variation = $this->parent_product->getDefaultVariation();
    /** @var \Drupal\commerce_product\Entity\ProductVariation $chid_product_variation */
    $this->child_variation = $this->child_product->getDefaultVariation();

    /** @var \Drupal\commerce_vado\Entity\VadoGroup $group */
    $this->group_1 = $this->createVadoGroupWithGroupItems(4, [
      'group_id' => 1,
      'title' => 'Group 1',
      'group_discount' => 20,
      'group_items' => [
        [
          'title' => 'Group Item 1',
          'variation' => $this->child_product_1->getDefaultVariation(),
          'group_item_discount' => 10,
        ],
        [
          'title' => $this->child_product_2->getDefaultVariation()->getTitle(),
          'variation' => $this->child_product_2->getDefaultVariation(),
          'group_item_discount' => 0,
        ],
        [
          'title' => $this->child_product_3->getDefaultVariation()->getTitle(),
          'variation' => $this->child_product_3->getDefaultVariation(),
          'group_item_discount' => -10,
        ],
        [
          'title' => $this->child_product_4->getDefaultVariation()->getTitle(),
          'variation' => $this->child_product_4->getDefaultVariation(),
          'group_item_discount' => '',
        ],
      ],
    ]);
    $this->orderStorage = $this->container->get('entity_type.manager')->getStorage('commerce_order');

  }

  /**
   * Tests the created VADO group items are in the inline form.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function testVadoGroupItemInlineForm() {
    $this->drupalGet('/admin/commerce/vado-groups');
    // Check group title and group widget.
    $this->assertSession()->pageTextContains('Group 1');
    $this->assertSession()->pageTextContains('Static List');

    $this->drupalGet('/admin/commerce/vado-groups/1/edit');
    // Check group title.
    $this->assertSession()->pageTextContains('Group 1');
    // Check overwritten group item title.
    $this->assertSession()->pageTextContains('Group Item 1');
    // Check original variation title is being passed.
    // @todo Test is not depending upon our populateTitle feature.
    $this->assertSession()->pageTextContains('Child Product 2');
    $this->assertSession()->pageTextContains('Child Product 3');
    $this->assertSession()->pageTextContains('Child Product 4');
    // Check child variation prices.
    $this->assertSession()->pageTextContains('$110.00');
    $this->assertSession()->pageTextContains('$210.00');
    $this->assertSession()->pageTextContains('$310.00');
    $this->assertSession()->pageTextContains('$410.00');
    // Check the discount labels.
    $this->assertSession()->pageTextContains('10% (Discount)');
    $this->assertSession()->pageTextContains('0% (Excluded)');
    $this->assertSession()->pageTextContains('10% (Markup)');
    // Check child variation skus.
    $this->assertSession()->pageTextContains('CHILD-1');
    $this->assertSession()->pageTextContains('CHILD-2');
    $this->assertSession()->pageTextContains('CHILD-3');
    $this->assertSession()->pageTextContains('CHILD-4');
  }

  /**
   * Tests VADO bundle discount.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function testBundleDiscount() {
    // Attach the child to the parent and ensure the bundle discount is NULL.
    $this->parent_variation->set('child_variations', $this->child_variation->id());
    $this->parent_variation->set('bundle_discount', NULL);
    $this->parent_variation->set('include_parent', FALSE);
    $this->parent_variation->save();
    // Test that the order processor is combining the price of parent and child.
    $this->drupalGet($this->parent_product->toUrl());
    $this->assertSession()->pageTextContains('Price');
    $this->assertSession()->pageTextContains('$175.99');
    // Test that the event subscriber did not apply a discount.
    $this->submitForm([], 'Add to cart');
    $this->orderStorage->resetCache([$this->cart->id()]);
    $this->cart = $this->orderStorage->load($this->cart->id());
    $this->assertCount(2, $this->cart->getItems());
    $this->drupalGet('cart');
    $this->assertSession()->pageTextContains('Parent Product');
    $this->assertSession()->pageTextContains('Child Product');
    $this->assertSession()->pageTextContains('$100.00');
    $this->assertSession()->pageTextContains('$75.99');
    // Test the subtotal.
    $this->assertSession()->pageTextContains('$175.99');
    $this->cartManager->emptyCart($this->cart);

    // Attach the child to the parent and ensure the bundle discount is NULL.
    $this->parent_variation->set('child_variations', $this->child_variation->id());
    $this->parent_variation->set('bundle_discount', 5);
    $this->parent_variation->set('include_parent', TRUE);
    $this->parent_variation->save();
    // Test that the order processor is combining the price of parent and child.
    $this->drupalGet($this->parent_product->toUrl());
    $this->assertSession()->pageTextContains('Price');
    $this->assertSession()->pageTextContains('$167.19');
    // Test that the event subscriber does apply a discount.
    $this->submitForm([], 'Add to cart');
    $this->orderStorage->resetCache([$this->cart->id()]);
    $this->cart = $this->orderStorage->load($this->cart->id());
    $this->assertCount(2, $this->cart->getItems());
    $this->drupalGet('cart');
    $this->assertSession()->pageTextContains('Parent Product');
    $this->assertSession()->pageTextContains('Child Product');
    $this->assertSession()->pageTextContains('$95.00');
    $this->assertSession()->pageTextContains('$72.19');
    // Test the subtotal.
    $this->assertSession()->pageTextContains('$167.19');
    $this->cartManager->emptyCart($this->cart);
  }

  /**
   * Tests VADO group and group item discounts.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function testGroupDiscounts() {
    // Switch to the Group add to cart form.
    /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $product_view_display */
    $product_view_display = EntityViewDisplay::load('commerce_product.default.default');
    if (!$product_view_display) {
      $product_view_display = EntityViewDisplay::create([
        'targetEntityType' => 'commerce_product',
        'bundle' => 'default',
        'mode' => 'default',
        'status' => TRUE,
      ]);
    }
    $product_view_display->setComponent('variations', [
      'type' => 'commerce_vado_group_add_to_cart',
      'region' => 'content',
      'label' => 'hidden',
      'settings' => [
        'combine' => TRUE,
      ],
    ]);
    $product_view_display->save();
    // Create the vado add to cart form display.
    $order_item_form_display = EntityFormDisplay::load('commerce_order_item.default.vado_group_add_to_cart');
    if (!$order_item_form_display) {
      $order_item_form_display = EntityFormDisplay::create([
        'targetEntityType' => 'commerce_order_item',
        'bundle' => 'default',
        'mode' => 'vado_group_add_to_cart',
        'status' => TRUE,
      ]);
    }
    // Use the variation title for the vado add to cart form.
    $order_item_form_display->setComponent('purchased_entity', [
      'type' => 'commerce_product_variation_title',
    ]);
    $order_item_form_display->save();

    // Attach the child to the parent and ensure the bundle discount is NULL.
    $this->parent_variation->set('child_variations', $this->child_variation->id());
    $this->parent_variation->set('bundle_discount', NULL);
    $this->parent_variation->set('include_parent', FALSE);
    $this->parent_variation->save();
    // Attach the group to the parent.
    $this->parent_variation->set('variation_groups', $this->group_1->id());
    $this->parent_variation->save();
    // Test that the order processor is calculating the price.
    $this->drupalGet($this->parent_product->toUrl());
    $this->assertSession()->pageTextContains('$1,153.99');
    // Test that the event subscriber is calculating the prices.
    $this->submitForm([], 'Add to cart');
    $this->orderStorage->resetCache([$this->cart->id()]);
    $this->cart = $this->orderStorage->load($this->cart->id());
    $this->assertCount(6, $this->cart->getItems());
    $this->drupalGet('cart');
    $this->assertSession()->pageTextContains('Parent Product');
    $this->assertSession()->pageTextContains('Child Product');
    $this->assertSession()->pageTextContains('Child Product 1');
    $this->assertSession()->pageTextContains('Child Product 2');
    $this->assertSession()->pageTextContains('Child Product 3');
    $this->assertSession()->pageTextContains('Child Product 4');
    $this->assertSession()->pageTextContains('$100.00');
    $this->assertSession()->pageTextContains('$75.99');
    // Test the group item 1 discount of 10%.
    $this->assertSession()->pageTextContains('$99.00');
    // Test the group item 2 discount EXCLUSION of 0%.
    $this->assertSession()->pageTextContains('$210.00');
    // Test the group item 3 markup of 10%.
    $this->assertSession()->pageTextContains('$341.00');
    // Test the group discount of 20% passed to group item 4.
    $this->assertSession()->pageTextContains('$328.00');
    // Test the subtotal.
    $this->assertSession()->pageTextContains('$1,153.99');
    $this->cartManager->emptyCart($this->cart);

    // Change the group discount to empty.
    $this->group_1->set('group_discount', '');
    $this->group_1->save();
    // Set the bundle discount, and include the parent.
    $this->parent_variation->set('bundle_discount', 5);
    $this->parent_variation->set('include_parent', TRUE);
    $this->parent_variation->save();
    // Test that the order processor is calculating the price.
    $this->drupalGet($this->parent_product->toUrl());
    $this->assertSession()->pageTextContains('$1,206.69');
    // Test that the event subscriber is calculating the prices.
    $this->submitForm([], 'Add to cart');
    $this->orderStorage->resetCache([$this->cart->id()]);
    $this->cart = $this->orderStorage->load($this->cart->id());
    $this->assertCount(6, $this->cart->getItems());
    $this->drupalGet('cart');
    // Test the include parent bundle discount of 5%.
    $this->assertSession()->pageTextContains('$95.00');
    // Test the bundle discount of 5% gets passed to the child.
    $this->assertSession()->pageTextContains('$72.19');
    // Test the group item 1 discount of 10%.
    $this->assertSession()->pageTextContains('$99.00');
    // Test the group item 2 discount EXCLUSION of 0%.
    $this->assertSession()->pageTextContains('$210.00');
    // Test the group item 3 markup of 10%.
    $this->assertSession()->pageTextContains('$341.00');
    // Test the bundle discount of 5% passed to group item 4.
    $this->assertSession()->pageTextContains('$389.50');
    // Test the subtotal.
    $this->assertSession()->pageTextContains('$1,206.69');
  }

}