Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `@phpstan-type` shape aliases (unsealed, with enum literals for status/stock/discount values) for the high-arity `overrides`/`criteria` params on `ProductMethods::haveProductInDatabase`/`haveManyProductsInDatabase`, `CouponMethods::haveCouponInDatabase` and its percentage/fixed-cart/fixed-product/free-shipping wrappers, and `OrderMethods::haveOrderInDatabase`/`haveManyOrdersInDatabase`/`haveOrderAddressInDatabase`/`seeOrderAddressInDatabase`/`haveOrderItemInDatabase` — so PHPStan (already at level max over `src` and `tests`) flags hallucinated keys/values in any Cest ([#37](https://github.com/aztecweb/aztecweb-wp-browser/issues/37)).

## [0.1.0] - 2026-06-09

### Added
Expand Down
72 changes: 47 additions & 25 deletions src/WooCommerce/Method/CouponMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,36 @@

use lucatume\WPBrowser\Module\WPDb;

/**
* @phpstan-type CouponStatus 'publish'|'draft'|'pending'|'private'|'trash'
* @phpstan-type CouponDiscountType 'percent'|'fixed_cart'|'fixed_product'
* @phpstan-type CouponYesNo 'yes'|'no'
* @phpstan-type CouponMeta array{
* discount_type?: CouponDiscountType,
* coupon_amount?: string|float,
* free_shipping?: CouponYesNo,
* minimum_amount?: string,
* usage_limit?: string|int,
* usage_limit_per_user?: string|int,
* limit_usage_to_x_items?: string|int,
* product_ids?: string,
* exclude_product_ids?: string,
* product_categories?: string,
* exclude_product_categories?: string,
* individual_use?: CouponYesNo,
* usage_count?: string|int,
* ...
* }
* @phpstan-type CouponOverrides array{
* code?: string,
* post_type?: string,
* post_status?: CouponStatus,
* post_title?: string,
* post_name?: string,
* meta?: CouponMeta,
* ...
* }
*/
trait CouponMethods
{
abstract protected function wpDb(): WPDb;
Expand All @@ -24,13 +54,13 @@ abstract protected function wpDb(): WPDb;
* ]);
* ```
*
* @param array<string, mixed> $overrides Post and meta data overrides. Meta is passed under the 'meta' key.
* @param CouponOverrides $overrides Post and meta data overrides. Meta is passed under the 'meta' key.
*
* @return int The coupon post ID.
*/
public function haveCouponInDatabase(array $overrides = []): int
{
$meta = isset($overrides['meta']) && is_array($overrides['meta']) ? $overrides['meta'] : [];
$meta = $overrides['meta'] ?? [];
unset($overrides['meta']);

$couponData = array_merge([
Expand Down Expand Up @@ -79,18 +109,16 @@ public function haveCouponInDatabase(array $overrides = []): int
* ]);
* ```
*
* @param string $code The coupon code.
* @param float $percentage The discount percentage (0-100).
* @param array<string, mixed> $overrides Post and meta data overrides.
* @param string $code The coupon code.
* @param float $percentage The discount percentage (0-100).
* @param CouponOverrides $overrides Post and meta data overrides.
*
* @return int The coupon post ID.
*/
public function havePercentageCouponInDatabase(string $code, float $percentage, array $overrides = []): int
{
$overrides['code'] = $code;
if (!isset($overrides['meta']) || !is_array($overrides['meta'])) {
$overrides['meta'] = [];
}
$overrides['meta'] ??= [];
$overrides['meta']['discount_type'] = 'percent';
$overrides['meta']['coupon_amount'] = $percentage;

Expand All @@ -105,18 +133,16 @@ public function havePercentageCouponInDatabase(string $code, float $percentage,
* $couponId = $I->haveFixedCartCouponInDatabase('FIXED5', 5.00);
* ```
*
* @param string $code The coupon code.
* @param float $amount The discount amount in shop currency.
* @param array<string, mixed> $overrides Post and meta data overrides.
* @param string $code The coupon code.
* @param float $amount The discount amount in shop currency.
* @param CouponOverrides $overrides Post and meta data overrides.
*
* @return int The coupon post ID.
*/
public function haveFixedCartCouponInDatabase(string $code, float $amount, array $overrides = []): int
{
$overrides['code'] = $code;
if (!isset($overrides['meta']) || !is_array($overrides['meta'])) {
$overrides['meta'] = [];
}
$overrides['meta'] ??= [];
$overrides['meta']['discount_type'] = 'fixed_cart';
$overrides['meta']['coupon_amount'] = $amount;

Expand All @@ -131,18 +157,16 @@ public function haveFixedCartCouponInDatabase(string $code, float $amount, array
* $couponId = $I->haveFixedProductCouponInDatabase('PROD10', 10.00);
* ```
*
* @param string $code The coupon code.
* @param float $amount The discount amount in shop currency.
* @param array<string, mixed> $overrides Post and meta data overrides.
* @param string $code The coupon code.
* @param float $amount The discount amount in shop currency.
* @param CouponOverrides $overrides Post and meta data overrides.
*
* @return int The coupon post ID.
*/
public function haveFixedProductCouponInDatabase(string $code, float $amount, array $overrides = []): int
{
$overrides['code'] = $code;
if (!isset($overrides['meta']) || !is_array($overrides['meta'])) {
$overrides['meta'] = [];
}
$overrides['meta'] ??= [];
$overrides['meta']['discount_type'] = 'fixed_product';
$overrides['meta']['coupon_amount'] = $amount;

Expand All @@ -157,17 +181,15 @@ public function haveFixedProductCouponInDatabase(string $code, float $amount, ar
* $couponId = $I->haveFreeShippingCouponInDatabase('FREESHIPPING');
* ```
*
* @param string $code The coupon code.
* @param array<string, mixed> $overrides Post and meta data overrides.
* @param string $code The coupon code.
* @param CouponOverrides $overrides Post and meta data overrides.
*
* @return int The coupon post ID.
*/
public function haveFreeShippingCouponInDatabase(string $code, array $overrides = []): int
{
$overrides['code'] = $code;
if (!isset($overrides['meta']) || !is_array($overrides['meta'])) {
$overrides['meta'] = [];
}
$overrides['meta'] ??= [];
$overrides['meta']['discount_type'] = 'fixed_cart';
$overrides['meta']['free_shipping'] = 'yes';

Expand Down
62 changes: 52 additions & 10 deletions src/WooCommerce/Method/OrderMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,48 @@
use Aztec\WPBrowser\WooCommerce\OrderStorage\OrderStorageInterface;
use lucatume\WPBrowser\Module\WPDb;

/**
* @phpstan-type OrderStatus 'wc-pending'|'wc-processing'|'wc-on-hold'|'wc-completed'|'wc-cancelled'|'wc-refunded'|'wc-failed'|'wc-checkout-draft'
* @phpstan-type OrderAddressType 'billing'|'shipping'
* @phpstan-type OrderAddress array{
* first_name?: string,
* last_name?: string,
* company?: string,
* address_1?: string,
* address_2?: string,
* city?: string,
* state?: string,
* postcode?: string,
* country?: string,
* email?: string,
* phone?: string,
* ...
* }
* @phpstan-type OrderItemType 'line_item'|'fee'|'shipping'|'coupon'|'tax'
* @phpstan-type OrderItemOverrides array{
* order_item_name?: string,
* order_item_type?: OrderItemType,
* meta?: array<string, mixed>,
* ...
* }
* @phpstan-type OrderOverrides array{
* status?: OrderStatus,
* customer_id?: int,
* currency?: string,
* total_amount?: string,
* tax_amount?: string,
* billing_email?: string,
* payment_method?: string,
* payment_method_title?: string,
* transaction_id?: string,
* customer_note?: string,
* parent_order_id?: int,
* address?: array{billing?: OrderAddress, shipping?: OrderAddress},
* items?: list<OrderItemOverrides>,
* meta?: array<string, mixed>,
* ...
* }
*/
trait OrderMethods
{
abstract protected function wpDb(): WPDb;
Expand All @@ -24,7 +66,7 @@ abstract protected function orderStorage(): OrderStorageInterface;
* $I->seeOrderInDatabase(['id' => $orderId, 'status' => 'processing']);
* ```
*
* @param array<string, mixed> $overrides Order data overrides (status, customer_id, etc.). Behavior depends on storage mode (HPOS or Legacy)
* @param OrderOverrides $overrides Order data overrides (status, customer_id, etc.). Behavior depends on storage mode (HPOS or Legacy)
*
* @return int The created order ID
*/
Expand Down Expand Up @@ -149,9 +191,9 @@ public function haveOrderStatus(int $orderId, string $newStatus): void
* $I->assertGreaterThan(0, $addressId);
* ```
*
* @param int $orderId Order ID
* @param string $addressType Address type ('billing' or 'shipping')
* @param array<string, mixed> $overrides Address fields (first_name, last_name, company, address_1, address_2, city, state, postcode, country, email, phone)
* @param int $orderId Order ID
* @param OrderAddressType $addressType Address type ('billing' or 'shipping')
* @param OrderAddress $overrides Address fields (first_name, last_name, company, address_1, address_2, city, state, postcode, country, email, phone)
*
* @return int Address ID
*/
Expand All @@ -174,8 +216,8 @@ public function haveOrderAddressInDatabase(int $orderId, string $addressType, ar
* $I->assertGreaterThan(0, $itemId);
* ```
*
* @param int $orderId Order ID
* @param array<string, mixed> $overrides Line item data (order_item_name, order_item_type, meta array for item meta)
* @param int $orderId Order ID
* @param OrderItemOverrides $overrides Line item data (order_item_name, order_item_type, meta array for item meta)
*
* @return int Order item ID
*/
Expand Down Expand Up @@ -404,8 +446,8 @@ public function dontSeeOrderItemMetaInDatabase(array $criteria): void
* $I->seeOrderAddressInDatabase('billing', ['first_name' => 'John']);
* ```
*
* @param string $type Address type ('billing' or 'shipping')
* @param array<string, mixed> $criteria Database query criteria for address fields
* @param OrderAddressType $type Address type ('billing' or 'shipping')
* @param OrderAddress $criteria Database query criteria for address fields
*
* @return void
*/
Expand Down Expand Up @@ -442,8 +484,8 @@ public function grabOrderItemsTableName(): string
* }
* ```
*
* @param int $count Number of orders to create
* @param array<string, mixed> $overrides Order data overrides applied to each order
* @param int $count Number of orders to create
* @param OrderOverrides $overrides Order data overrides applied to each order
*
* @return array<int, int> Array of created order IDs
*/
Expand Down
39 changes: 34 additions & 5 deletions src/WooCommerce/Method/ProductMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,36 @@

use lucatume\WPBrowser\Module\WPDb;

/**
* @phpstan-type ProductStatus 'publish'|'draft'|'pending'|'private'|'trash'
* @phpstan-type ProductStockStatus 'instock'|'outofstock'|'onbackorder'
* @phpstan-type ProductTaxStatus 'taxable'|'shipping'|'none'
* @phpstan-type ProductYesNo 'yes'|'no'
* @phpstan-type ProductBackorders 'no'|'notify'|'yes'
* @phpstan-type ProductMeta array{
* _price?: string,
* _regular_price?: string,
* _sale_price?: string,
* _sku?: string,
* _stock_status?: ProductStockStatus,
* _tax_status?: ProductTaxStatus,
* _tax_class?: string,
* _manage_stock?: ProductYesNo,
* _backorders?: ProductBackorders,
* _sold_individually?: ProductYesNo,
* _virtual?: ProductYesNo,
* _downloadable?: ProductYesNo,
* ...
* }
* @phpstan-type ProductOverrides array{
* post_type?: string,
* post_status?: ProductStatus,
* post_title?: string,
* post_name?: string,
* meta?: ProductMeta,
* ...
* }
*/
trait ProductMethods
{
abstract protected function wpDb(): WPDb;
Expand Down Expand Up @@ -78,7 +108,7 @@ public function haveProductCategoryRelationshipInDatabase(int $productId, int $c
* ]);
* ```
*
* @param array<string, mixed> $overrides Post and meta data overrides. Meta is passed under the 'meta' key.
* @param ProductOverrides $overrides Post and meta data overrides. Meta is passed under the 'meta' key.
*
* @return int The created product post ID.
*/
Expand Down Expand Up @@ -387,16 +417,15 @@ public function dontSeeProductMetaInDatabase(array $criteria): void
* ]);
* ```
*
* @param int $count The number of products to create.
* @param array<string, mixed> $overrides Post and meta data overrides.
* @param int $count The number of products to create.
* @param ProductOverrides $overrides Post and meta data overrides.
*
* @return array<int, int> Array of created product post IDs.
*/
public function haveManyProductsInDatabase(int $count, array $overrides = []): array
{
$createdIds = [];
$baseTitleValue = $overrides['post_title'] ?? 'Product';
$baseTitle = is_string($baseTitleValue) ? $baseTitleValue : 'Product';
$baseTitle = $overrides['post_title'] ?? 'Product';

for ($i = 1; $i <= $count; $i++) {
$productData = array_merge($overrides, [
Expand Down
Loading