button 'update cart' will only be shown if corresponding products are in cart

This commit is contained in:
Steffen Mahler 2020-01-24 07:15:49 +01:00
parent 91d6586ad8
commit a5c49e4b76
10 changed files with 215 additions and 4 deletions

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ yarn.lock
.php_cs.cache
storage/
storage/*.key
/docker-compose-collection/

View File

@ -320,6 +320,25 @@ class Cart {
return true;
}
/**
* Clear cart
* @return bool
*/
public function clear(): bool
{
if (! $cart = $this->getCart()) {
return false;
}
$this->cartRepository->delete($cart->id);
if (session()->has('cart')) {
session()->forget('cart');
}
return true;
}
/**
* This function handles when guest has some of cart products and then logs in.
*

View File

@ -130,4 +130,20 @@ class Cart extends Model implements CartContract
return false;
}
/**
* Returns true if cart contains one or many products with quantity box.
* f.e. simple, configurable, virtual
* @return bool
*/
public function hasProductsWithQuantityBox(): bool
{
$result = true;
foreach ($this->items as $item) {
if ($item->product->getTypeInstance()->showQuantityBox() === true) {
$result = false;
}
}
return $result;
}
}

View File

@ -80,9 +80,12 @@ class CartController extends Controller
try {
$result = Cart::addProduct($id, request()->all());
if (is_array($result) && isset($result['warning'])) {
if ($this->onWarningAddingToCart($result)) {
session()->flash('warning', $result['warning']);
} else {
return redirect()->back();
}
if ($result instanceof Cart) {
session()->flash('success', trans('shop::app.checkout.cart.item.success'));
if ($customer = auth()->guard('customer')->user())
@ -203,4 +206,16 @@ class CartController extends Controller
'message' => trans('shop::app.checkout.total.remove-coupon')
]);
}
/**
* Returns true, if result of adding product to cart
* is an array and contains a key "warning"
*
* @param $result
*
* @return bool
*/
private function onWarningAddingToCart($result): bool {
return is_array($result) && isset($result['warning']);
}
}

View File

@ -108,9 +108,11 @@
<a href="{{ route('shop.home.index') }}" class="link">{{ __('shop::app.checkout.cart.continue-shopping') }}</a>
<div>
<button type="submit" class="btn btn-lg btn-primary">
@if (! $cart->hasProductsWithQuantityBox())
<button type="submit" class="btn btn-lg btn-primary" id="update_cart_button">
{{ __('shop::app.checkout.cart.update-cart') }}
</button>
@endif
@if (! cart()->hasError())
<a href="{{ route('shop.checkout.onepage.index') }}" class="btn btn-lg btn-primary">

View File

@ -1,3 +1,4 @@
{
"/js/app.js": "/js/app.js"
"/js/app.js": "/js/app.js",
"/css/app.css": "/css/app.css"
}

View File

@ -1,5 +1,6 @@
<?php
use Codeception\Stub;
/**
* Inherited Methods
@ -23,4 +24,52 @@ class UnitTester extends \Codeception\Actor
/**
* Define custom actions here
*/
/**
* execute any function of a class (also private/protected) and return its return
*
* @param string|object $className name of the class (FQCN) or an instance of it
* @param string $functionName name of the function which will be executed
* @param array $methodParams params the function will be executed with
* @param array $constructParams params which will be called in constructor. Will be ignored if $className
* is already an instance of an object.
* @param array $mocks mock/stub overrides of methods and properties. Will be ignored if $className is
* already an instance of an object.
*
* @return mixed
* @throws \Exception
*/
public function executeFunction(
$className,
string $functionName,
array $methodParams = [],
array $constructParams = [],
array $mocks = []
) {
$I = $this;
$I->comment('I execute function "'
. $functionName
. '" of class "'
. (is_object($className) ? get_class($className) : $className)
. '" with '
. count($methodParams)
. ' method-params, '
. count($constructParams)
. ' constuctor-params and '
. count($mocks)
. ' mocked class-methods/params'
);
$class = new \ReflectionClass($className);
$method = $class->getMethod($functionName);
$method->setAccessible(true);
if (is_object($className)) {
$reflectedClass = $className;
} elseif (empty($constructParams)) {
$reflectedClass = Stub::make($className, $mocks);
} else {
$reflectedClass = Stub::construct($className, $constructParams, $mocks);
}
return $method->invokeArgs($reflectedClass, $methodParams);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Tests\Functional\Checkout\Cart;
use FunctionalTester;
class CartCest
{
public function _before(FunctionalTester $I)
{
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace Tests\Unit\Checkout\Cart\Controllers;
use UnitTester;
use Webkul\Checkout\Models\Cart;
use Webkul\Shop\Http\Controllers\CartController;
class CartControllerCest
{
public function _before(UnitTester $I)
{
}
public function testOnWarningAddingToCart(UnitTester $I)
{
$scenarios = [
[
'result' => ['key' => 'value', 'warning' => 'Hello World. Something went wrong.'],
'expected' => true,
],
[
'result' => ['key' => 'value'],
'expected' => false,
],
[
'result' => new Cart(),
'expected' => false,
],
];
foreach ($scenarios as $scenario) {
$I->assertEquals($scenario['expected'], $I->executeFunction(CartController::class, 'onWarningAddingToCart', [$scenario['result']]));
}
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace Tests\Unit\Checkout\Cart\Models;
use UnitTester;
use Webkul\Checkout\Models\Cart as CartModel;
use Webkul\Customer\Repositories\WishlistRepository;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Shop\Http\Controllers\CartController;
use Cart;
class CartModelCest
{
public $productWithQuantityBox;
public $productWithoutQuantityBox;
public function _before(UnitTester $I)
{
$this->productWithQuantityBox = $I->haveProduct();
$this->productWithoutQuantityBox = $I->haveProduct();
}
public function testHasProductsWithQuantityBox(UnitTester $I)
{
$this->createMixedCart();
$I->assertTrue($I->executeFunction(CartModel::class, 'hasProductsWithQuantityBox'));
$this->createCardWithProductsWithQuantityBox();
$I->assertTrue($I->executeFunction(CartModel::class, 'hasProductsWithQuantityBox'));
$this->createCardWithProductsWithQuantityBox();
$I->assertFalse($I->executeFunction(CartModel::class, 'hasProductsWithQuantityBox'));
}
private function createMixedCart()
{
$this->clearCart();
Cart::addProduct($this->productWithQuantityBox->id);
Cart::addProduct($this->productWithoutQuantityBox->id);
}
private function createCardWithProductsWithQuantityBox()
{
$this->clearCart();
Cart::addProduct($this->productWithQuantityBox->id);
}
private function createCardWithoutProductsWithQuantityBox()
{
$this->clearCart();
Cart::addProduct($this->productWithoutQuantityBox);
}
private function clearCart()
{
Cart::clear();
}
}