diff --git a/backend/app/Controller/Api/V1/OrderItemController.php b/backend/app/Controller/Api/V1/OrderItemController.php index 6f274a1..021d520 100644 --- a/backend/app/Controller/Api/V1/OrderItemController.php +++ b/backend/app/Controller/Api/V1/OrderItemController.php @@ -57,6 +57,7 @@ class OrderItemController extends AbstractDataController 'company_id' => 'exact', 'platform_id' => 'exact', 'store_id' => 'exact', + 'order_id' => 'exact', 'platform_order_id' => 'exact', 'platform_product_id' => 'exact', 'product_sku' => 'exact', @@ -85,6 +86,7 @@ class OrderItemController extends AbstractDataController new OA\Parameter(name: 'company_id', in: 'query', required: false, description: '公司 ID 精确筛选', schema: new OA\Schema(type: 'integer')), new OA\Parameter(name: 'platform_id', in: 'query', required: false, description: '平台 ID 精确筛选', schema: new OA\Schema(type: 'integer')), new OA\Parameter(name: 'store_id', in: 'query', required: false, description: '店铺 ID 精确筛选', schema: new OA\Schema(type: 'integer')), + new OA\Parameter(name: 'order_id', in: 'query', required: false, description: '内部订单 ID 精确筛选', schema: new OA\Schema(type: 'integer')), new OA\Parameter(name: 'platform_order_id', in: 'query', required: false, description: '平台订单 ID 精确筛选', schema: new OA\Schema(type: 'string')), new OA\Parameter(name: 'platform_product_id', in: 'query', required: false, description: '平台商品 ID 精确筛选', schema: new OA\Schema(type: 'string')), new OA\Parameter(name: 'product_sku', in: 'query', required: false, description: 'SKU 编码精确筛选', schema: new OA\Schema(type: 'string')), diff --git a/backend/test/Cases/Integration/Order/OrderControllerTest.php b/backend/test/Cases/Integration/Order/OrderControllerTest.php index 5df3810..a1fff35 100644 --- a/backend/test/Cases/Integration/Order/OrderControllerTest.php +++ b/backend/test/Cases/Integration/Order/OrderControllerTest.php @@ -5,12 +5,8 @@ declare(strict_types=1); namespace HyperfTest\Cases\Integration\Order; use App\Model\Order; -use App\Model\Role; -use App\Model\User; use HyperfTest\TestCase; -use Qbhy\HyperfAuth\AuthManager; - -use function Hyperf\Support\make; +use HyperfTest\Traits\AuthenticatedTestTrait; /** * OrderController 集成测试 @@ -22,83 +18,20 @@ use function Hyperf\Support\make; */ class OrderControllerTest extends TestCase { - protected function getAdminToken(): string - { - $admin_role = $this->fetchAdminRole(); - $user = $this->fetchUser(static function ($query) use ($admin_role): void { - $query->where('status', 1)->where('role_id', $admin_role->id); - }); - if (!$user) { - $this->markTestSkipped('没有可用的 administrator 用户'); - } - - $auth = make(AuthManager::class); - return $auth->guard('jwt')->login($user); - } - - protected function fetchAdminRole(): Role - { - if (\Swoole\Coroutine::getCid() > 0) { - return Role::query()->where('name', 'administrator')->firstOrFail(); - } - - $role = null; - \Swoole\Coroutine\run(static function () use (&$role): void { - $role = Role::query()->where('name', 'administrator')->firstOrFail(); - }); - return $role; - } - - protected function fetchUser(?callable $callback = null): ?User - { - if (\Swoole\Coroutine::getCid() > 0) { - $query = User::query(); - if ($callback !== null) { - $callback($query); - } - return $query->first(); - } - - $user = null; - \Swoole\Coroutine\run(static function () use ($callback, &$user): void { - $query = User::query(); - if ($callback !== null) { - $callback($query); - } - $user = $query->first(); - }); - return $user; - } - - protected function authHeaders(): array - { - return ['Authorization' => 'Bearer ' . $this->getAdminToken()]; - } + use AuthenticatedTestTrait; protected function hasOrderData(): bool { - if (\Swoole\Coroutine::getCid() > 0) { + return $this->runInCoroutine(static function (): bool { return Order::query()->exists(); - } - - $exists = false; - \Swoole\Coroutine\run(static function () use (&$exists): void { - $exists = Order::query()->exists(); }); - return $exists; } protected function getFirstOrderId(): ?int { - if (\Swoole\Coroutine::getCid() > 0) { + return $this->runInCoroutine(static function (): ?int { return Order::query()->value('id'); - } - - $id = null; - \Swoole\Coroutine\run(static function () use (&$id): void { - $id = Order::query()->value('id'); }); - return $id; } // ========== Normal 列表接口 ========== @@ -184,14 +117,9 @@ class OrderControllerTest extends TestCase $this->markTestSkipped('没有订单数据'); } - $company_id = null; - if (\Swoole\Coroutine::getCid() > 0) { - $company_id = Order::query()->value('company_id'); - } else { - \Swoole\Coroutine\run(static function () use (&$company_id): void { - $company_id = Order::query()->value('company_id'); - }); - } + $company_id = $this->runInCoroutine(static function (): mixed { + return Order::query()->value('company_id'); + }); $response = $this->get('/api/v1/orders', ['company_id' => $company_id], $this->authHeaders()); @@ -209,14 +137,9 @@ class OrderControllerTest extends TestCase $this->markTestSkipped('没有订单数据'); } - $status_id = null; - if (\Swoole\Coroutine::getCid() > 0) { - $status_id = Order::query()->value('order_status_id'); - } else { - \Swoole\Coroutine\run(static function () use (&$status_id): void { - $status_id = Order::query()->value('order_status_id'); - }); - } + $status_id = $this->runInCoroutine(static function (): mixed { + return Order::query()->value('order_status_id'); + }); $response = $this->get('/api/v1/orders', ['order_status_id' => $status_id], $this->authHeaders()); diff --git a/backend/test/Cases/Integration/Order/OrderItemControllerTest.php b/backend/test/Cases/Integration/Order/OrderItemControllerTest.php index 56ec977..2ac7109 100644 --- a/backend/test/Cases/Integration/Order/OrderItemControllerTest.php +++ b/backend/test/Cases/Integration/Order/OrderItemControllerTest.php @@ -5,12 +5,8 @@ declare(strict_types=1); namespace HyperfTest\Cases\Integration\Order; use App\Model\OrderItem; -use App\Model\Role; -use App\Model\User; use HyperfTest\TestCase; -use Qbhy\HyperfAuth\AuthManager; - -use function Hyperf\Support\make; +use HyperfTest\Traits\AuthenticatedTestTrait; /** * OrderItemController 集成测试 @@ -22,83 +18,20 @@ use function Hyperf\Support\make; */ class OrderItemControllerTest extends TestCase { - protected function getAdminToken(): string - { - $admin_role = $this->fetchAdminRole(); - $user = $this->fetchUser(static function ($query) use ($admin_role): void { - $query->where('status', 1)->where('role_id', $admin_role->id); - }); - if (!$user) { - $this->markTestSkipped('没有可用的 administrator 用户'); - } - - $auth = make(AuthManager::class); - return $auth->guard('jwt')->login($user); - } - - protected function fetchAdminRole(): Role - { - if (\Swoole\Coroutine::getCid() > 0) { - return Role::query()->where('name', 'administrator')->firstOrFail(); - } - - $role = null; - \Swoole\Coroutine\run(static function () use (&$role): void { - $role = Role::query()->where('name', 'administrator')->firstOrFail(); - }); - return $role; - } - - protected function fetchUser(?callable $callback = null): ?User - { - if (\Swoole\Coroutine::getCid() > 0) { - $query = User::query(); - if ($callback !== null) { - $callback($query); - } - return $query->first(); - } - - $user = null; - \Swoole\Coroutine\run(static function () use ($callback, &$user): void { - $query = User::query(); - if ($callback !== null) { - $callback($query); - } - $user = $query->first(); - }); - return $user; - } - - protected function authHeaders(): array - { - return ['Authorization' => 'Bearer ' . $this->getAdminToken()]; - } + use AuthenticatedTestTrait; protected function hasOrderItemData(): bool { - if (\Swoole\Coroutine::getCid() > 0) { + return $this->runInCoroutine(static function (): bool { return OrderItem::query()->exists(); - } - - $exists = false; - \Swoole\Coroutine\run(static function () use (&$exists): void { - $exists = OrderItem::query()->exists(); }); - return $exists; } protected function getFirstOrderItemId(): ?int { - if (\Swoole\Coroutine::getCid() > 0) { + return $this->runInCoroutine(static function (): ?int { return OrderItem::query()->value('id'); - } - - $id = null; - \Swoole\Coroutine\run(static function () use (&$id): void { - $id = OrderItem::query()->value('id'); }); - return $id; } // ========== 列表接口 ========== @@ -187,14 +120,9 @@ class OrderItemControllerTest extends TestCase $this->markTestSkipped('没有订单项数据'); } - $company_id = null; - if (\Swoole\Coroutine::getCid() > 0) { - $company_id = OrderItem::query()->value('company_id'); - } else { - \Swoole\Coroutine\run(static function () use (&$company_id): void { - $company_id = OrderItem::query()->value('company_id'); - }); - } + $company_id = $this->runInCoroutine(static function (): mixed { + return OrderItem::query()->value('company_id'); + }); $response = $this->get('/api/v1/order-items', ['company_id' => $company_id], $this->authHeaders()); @@ -206,20 +134,35 @@ class OrderItemControllerTest extends TestCase } } + public function test_list_filter_by_order_id(): void + { + if (!$this->hasOrderItemData()) { + $this->markTestSkipped('没有订单项数据'); + } + + $order_id = $this->runInCoroutine(static function (): mixed { + return OrderItem::query()->value('order_id'); + }); + + $response = $this->get('/api/v1/order-items', ['order_id' => $order_id], $this->authHeaders()); + + $response->assertStatus(200); + $body = json_decode($response->getContent(), true); + + foreach ($body['data']['items'] as $item) { + $this->assertSame($order_id, $item['order_id']); + } + } + public function test_list_filter_by_platform_order_id(): void { if (!$this->hasOrderItemData()) { $this->markTestSkipped('没有订单项数据'); } - $platform_order_id = null; - if (\Swoole\Coroutine::getCid() > 0) { - $platform_order_id = OrderItem::query()->value('platform_order_id'); - } else { - \Swoole\Coroutine\run(static function () use (&$platform_order_id): void { - $platform_order_id = OrderItem::query()->value('platform_order_id'); - }); - } + $platform_order_id = $this->runInCoroutine(static function (): mixed { + return OrderItem::query()->value('platform_order_id'); + }); $response = $this->get('/api/v1/order-items', ['platform_order_id' => $platform_order_id], $this->authHeaders()); @@ -237,14 +180,9 @@ class OrderItemControllerTest extends TestCase $this->markTestSkipped('没有订单项数据'); } - $platform_product_id = null; - if (\Swoole\Coroutine::getCid() > 0) { - $platform_product_id = OrderItem::query()->value('platform_product_id'); - } else { - \Swoole\Coroutine\run(static function () use (&$platform_product_id): void { - $platform_product_id = OrderItem::query()->value('platform_product_id'); - }); - } + $platform_product_id = $this->runInCoroutine(static function (): mixed { + return OrderItem::query()->value('platform_product_id'); + }); $response = $this->get('/api/v1/order-items', ['platform_product_id' => $platform_product_id], $this->authHeaders()); @@ -262,14 +200,9 @@ class OrderItemControllerTest extends TestCase $this->markTestSkipped('没有订单项数据'); } - $product_sku = null; - if (\Swoole\Coroutine::getCid() > 0) { - $product_sku = OrderItem::query()->whereNotNull('product_sku')->where('product_sku', '!=', '')->value('product_sku'); - } else { - \Swoole\Coroutine\run(static function () use (&$product_sku): void { - $product_sku = OrderItem::query()->whereNotNull('product_sku')->where('product_sku', '!=', '')->value('product_sku'); - }); - } + $product_sku = $this->runInCoroutine(static function (): mixed { + return OrderItem::query()->whereNotNull('product_sku')->where('product_sku', '!=', '')->value('product_sku'); + }); if (!$product_sku) { $this->markTestSkipped('没有有 SKU 的订单项数据'); diff --git a/backend/test/Cases/Integration/Product/ProductControllerTest.php b/backend/test/Cases/Integration/Product/ProductControllerTest.php index 3224f36..7b7b002 100644 --- a/backend/test/Cases/Integration/Product/ProductControllerTest.php +++ b/backend/test/Cases/Integration/Product/ProductControllerTest.php @@ -5,12 +5,8 @@ declare(strict_types=1); namespace HyperfTest\Cases\Integration\Product; use App\Model\Product; -use App\Model\Role; -use App\Model\User; use HyperfTest\TestCase; -use Qbhy\HyperfAuth\AuthManager; - -use function Hyperf\Support\make; +use HyperfTest\Traits\AuthenticatedTestTrait; /** * ProductController 集成测试 @@ -22,83 +18,20 @@ use function Hyperf\Support\make; */ class ProductControllerTest extends TestCase { - protected function getAdminToken(): string - { - $admin_role = $this->fetchAdminRole(); - $user = $this->fetchUser(static function ($query) use ($admin_role): void { - $query->where('status', 1)->where('role_id', $admin_role->id); - }); - if (!$user) { - $this->markTestSkipped('没有可用的 administrator 用户'); - } - - $auth = make(AuthManager::class); - return $auth->guard('jwt')->login($user); - } - - protected function fetchAdminRole(): Role - { - if (\Swoole\Coroutine::getCid() > 0) { - return Role::query()->where('name', 'administrator')->firstOrFail(); - } - - $role = null; - \Swoole\Coroutine\run(static function () use (&$role): void { - $role = Role::query()->where('name', 'administrator')->firstOrFail(); - }); - return $role; - } - - protected function fetchUser(?callable $callback = null): ?User - { - if (\Swoole\Coroutine::getCid() > 0) { - $query = User::query(); - if ($callback !== null) { - $callback($query); - } - return $query->first(); - } - - $user = null; - \Swoole\Coroutine\run(static function () use ($callback, &$user): void { - $query = User::query(); - if ($callback !== null) { - $callback($query); - } - $user = $query->first(); - }); - return $user; - } - - protected function authHeaders(): array - { - return ['Authorization' => 'Bearer ' . $this->getAdminToken()]; - } + use AuthenticatedTestTrait; protected function hasProductData(): bool { - if (\Swoole\Coroutine::getCid() > 0) { + return $this->runInCoroutine(static function (): bool { return Product::query()->exists(); - } - - $exists = false; - \Swoole\Coroutine\run(static function () use (&$exists): void { - $exists = Product::query()->exists(); }); - return $exists; } protected function getFirstProductId(): ?int { - if (\Swoole\Coroutine::getCid() > 0) { + return $this->runInCoroutine(static function (): ?int { return Product::query()->value('id'); - } - - $id = null; - \Swoole\Coroutine\run(static function () use (&$id): void { - $id = Product::query()->value('id'); }); - return $id; } // ========== Normal 列表接口 ========== @@ -180,15 +113,9 @@ class ProductControllerTest extends TestCase $this->markTestSkipped('没有产品数据'); } - // 获取一个已知的 company_id - $company_id = null; - if (\Swoole\Coroutine::getCid() > 0) { - $company_id = Product::query()->value('company_id'); - } else { - \Swoole\Coroutine\run(static function () use (&$company_id): void { - $company_id = Product::query()->value('company_id'); - }); - } + $company_id = $this->runInCoroutine(static function (): mixed { + return Product::query()->value('company_id'); + }); $response = $this->get('/api/v1/products', ['company_id' => $company_id], $this->authHeaders()); diff --git a/backend/test/Traits/AuthenticatedTestTrait.php b/backend/test/Traits/AuthenticatedTestTrait.php new file mode 100644 index 0000000..961f3fb --- /dev/null +++ b/backend/test/Traits/AuthenticatedTestTrait.php @@ -0,0 +1,73 @@ +fetchAdminRole(); + $user = $this->fetchUser(static function ($query) use ($admin_role): void { + $query->where('status', 1)->where('role_id', $admin_role->id); + }); + if (!$user) { + $this->markTestSkipped('没有可用的 administrator 用户'); + } + + $auth = make(AuthManager::class); + return $auth->guard('jwt')->login($user); + } + + protected function fetchAdminRole(): Role + { + return $this->runInCoroutine(static function (): Role { + return Role::query()->where('name', 'administrator')->firstOrFail(); + }); + } + + protected function fetchUser(?callable $callback = null): ?User + { + return $this->runInCoroutine(static function () use ($callback): ?User { + $query = User::query(); + if ($callback !== null) { + $callback($query); + } + return $query->first(); + }); + } + + protected function authHeaders(): array + { + return ['Authorization' => 'Bearer ' . $this->getAdminToken()]; + } + + /** + * 在协程环境中执行回调,自动处理 Swoole 协程包装 + */ + protected function runInCoroutine(callable $callback): mixed + { + if (\Swoole\Coroutine::getCid() > 0) { + return $callback(); + } + + $result = null; + \Swoole\Coroutine\run(static function () use ($callback, &$result): void { + $result = $callback(); + }); + return $result; + } +}