Files
wc-composable-product/tests/Unit/CartHandlerTest.php
magdev a7d6a57f01
Some checks failed
Create Release Package / PHP Lint (push) Successful in 47s
Create Release Package / test (push) Failing after 53s
Create Release Package / build-release (push) Has been skipped
Add PHPUnit test suite, PSR-4 refactor, lint+test CI jobs (v1.3.1)
- 57 unit tests covering ProductType, StockManager, CartHandler, Plugin,
  Admin/ProductData, Admin/Settings using Brain Monkey + Mockery
- WooCommerce class stubs for testing without WP installation
- PHP lint and test jobs in release workflow (test gate blocks release)
- PSR-4 namespace change: WC_Composable_Product -> Magdev\WcComposableProduct
- PascalCase filenames for all classes under includes/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:08:22 +01:00

185 lines
6.4 KiB
PHP

<?php
/**
* CartHandler Tests
*
* @package Magdev\WcComposableProduct\Tests
*/
namespace Magdev\WcComposableProduct\Tests\Unit;
use Magdev\WcComposableProduct\Tests\TestCase;
use Magdev\WcComposableProduct\CartHandler;
use Brain\Monkey\Functions;
use Brain\Monkey\Actions;
use Brain\Monkey\Filters;
class CartHandlerTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
// Clean up POST superglobal between tests
$_POST = [];
}
protected function tearDown(): void
{
$_POST = [];
parent::tearDown();
}
public function testConstructor_RegistersExpectedHooks(): void
{
$handler = new CartHandler();
self::assertNotFalse(has_filter('woocommerce_add_to_cart_validation', 'Magdev\WcComposableProduct\CartHandler->validate_add_to_cart()'));
self::assertNotFalse(has_filter('woocommerce_add_cart_item_data', 'Magdev\WcComposableProduct\CartHandler->add_cart_item_data()'));
self::assertNotFalse(has_filter('woocommerce_get_cart_item_from_session', 'Magdev\WcComposableProduct\CartHandler->get_cart_item_from_session()'));
self::assertNotFalse(has_filter('woocommerce_get_item_data', 'Magdev\WcComposableProduct\CartHandler->display_cart_item_data()'));
self::assertNotFalse(has_action('woocommerce_before_calculate_totals', 'Magdev\WcComposableProduct\CartHandler->calculate_cart_item_price()'));
self::assertNotFalse(has_action('woocommerce_single_product_summary', 'Magdev\WcComposableProduct\CartHandler->render_product_selector()'));
self::assertNotFalse(has_filter('woocommerce_is_purchasable', 'Magdev\WcComposableProduct\CartHandler->hide_default_add_to_cart()'));
}
public function testHideDefaultAddToCart_ReturnsFalseForComposable(): void
{
$handler = new CartHandler();
$product = $this->createProductMock(['get_type' => 'composable']);
$result = $handler->hide_default_add_to_cart(true, $product);
$this->assertFalse($result);
}
public function testHideDefaultAddToCart_PassesThroughForSimple(): void
{
$handler = new CartHandler();
$product = $this->createProductMock(['get_type' => 'simple']);
$result = $handler->hide_default_add_to_cart(true, $product);
$this->assertTrue($result);
}
public function testValidateAddToCart_PassesThroughForNonComposable(): void
{
$product = $this->createProductMock(['get_type' => 'simple']);
Functions\expect('wc_get_product')->with(1)->andReturn($product);
$handler = new CartHandler();
$result = $handler->validate_add_to_cart(true, 1, 1);
$this->assertTrue($result);
}
public function testValidateAddToCart_ReturnsFalseWhenNoProductsSelected(): void
{
$product = $this->createProductMock(['get_type' => 'composable']);
Functions\expect('wc_get_product')->with(1)->andReturn($product);
Functions\expect('wc_add_notice')->once();
$_POST['composable_products'] = [];
$handler = new CartHandler();
$result = $handler->validate_add_to_cart(true, 1, 1);
$this->assertFalse($result);
}
public function testValidateAddToCart_ReturnsFalseWhenNoPostData(): void
{
$product = $this->createProductMock(['get_type' => 'composable']);
Functions\expect('wc_get_product')->with(1)->andReturn($product);
Functions\expect('wc_add_notice')->once();
// No $_POST['composable_products'] at all
$handler = new CartHandler();
$result = $handler->validate_add_to_cart(true, 1, 1);
$this->assertFalse($result);
}
public function testAddCartItemData_AddsSelectionsForComposable(): void
{
$product = $this->createProductMock(['get_type' => 'composable']);
Functions\expect('wc_get_product')->with(1)->andReturn($product);
Functions\expect('absint')->andReturnUsing(function ($val) {
return abs((int) $val);
});
$_POST['composable_products'] = ['101', '102'];
$handler = new CartHandler();
$result = $handler->add_cart_item_data([], 1);
$this->assertArrayHasKey('composable_products', $result);
$this->assertSame([101, 102], $result['composable_products']);
$this->assertArrayHasKey('unique_key', $result);
}
public function testAddCartItemData_PassesThroughForNonComposable(): void
{
$product = $this->createProductMock(['get_type' => 'simple']);
Functions\expect('wc_get_product')->with(1)->andReturn($product);
$handler = new CartHandler();
$result = $handler->add_cart_item_data(['existing' => 'data'], 1);
$this->assertSame(['existing' => 'data'], $result);
}
public function testGetCartItemFromSession_RestoresComposableProducts(): void
{
$handler = new CartHandler();
$result = $handler->get_cart_item_from_session(
['data' => 'test'],
['composable_products' => [101, 102]]
);
$this->assertSame([101, 102], $result['composable_products']);
}
public function testGetCartItemFromSession_PassesThroughWithoutComposableData(): void
{
$handler = new CartHandler();
$result = $handler->get_cart_item_from_session(
['data' => 'test'],
[]
);
$this->assertArrayNotHasKey('composable_products', $result);
}
public function testDisplayCartItemData_FormatsProductNames(): void
{
$mock1 = $this->createProductMock(['get_name' => 'Product A']);
$mock2 = $this->createProductMock(['get_name' => 'Product B']);
Functions\expect('wc_get_product')
->andReturnUsing(function ($id) use ($mock1, $mock2) {
return match ($id) {
101 => $mock1,
102 => $mock2,
default => false,
};
});
$handler = new CartHandler();
$result = $handler->display_cart_item_data(
[],
['composable_products' => [101, 102]]
);
$this->assertCount(1, $result);
$this->assertStringContainsString('Product A', $result[0]['value']);
$this->assertStringContainsString('Product B', $result[0]['value']);
}
public function testDisplayCartItemData_ReturnsEmptyForNonComposable(): void
{
$handler = new CartHandler();
$result = $handler->display_cart_item_data([], []);
$this->assertSame([], $result);
}
}