'vendor.demo', 'type' => 'plugin', 'title' => '演示付费插件', 'description' => '演示', 'version' => '1.0.0', 'price' => 9900, 'download_url' => 'https://example.com/vendor.demo.zip', ]; protected function setUp(): void { parent::setUp(); $this->seed(); Setting::set('pay_sandbox', '1'); $this->user = User::create([ 'name' => '买家', 'email' => 'buyer@test.com', 'password' => bcrypt('password'), ]); } private function service(): MarketPurchaseService { return app(MarketPurchaseService::class); } public function test_purchase_creates_order_with_payable_package(): void { $this->actingAs($this->user); $payment = $this->service()->purchase($this->item); $this->assertNotNull($payment); $this->assertInstanceOf(MarketPackage::class, $payment->payable); $this->assertSame('pending', $payment->payable->status); $this->assertSame(9900, $payment->amount); $this->assertSame('市场商品:演示付费插件', $payment->payable_label); } public function test_sandbox_payment_marks_package_paid(): void { $this->actingAs($this->user); $payment = $this->service()->purchase($this->item); $this->actingAs($this->user)->post('/pay/sandbox/'.$payment->order_no.'/confirm'); $package = MarketPackage::query()->first(); $this->assertTrue($package->isPaid()); $this->assertSame($payment->id, $package->payment_id); $this->assertTrue($this->service()->isPurchased('vendor.demo', 'plugin')); } public function test_purchase_returns_null_when_already_paid(): void { $this->actingAs($this->user); $this->service()->purchase($this->item); $package = MarketPackage::query()->first(); $package->markPaid($package->payment ?? Payment::first() ?? Payment::create([ 'order_no' => 'X'.uniqid(), 'user_id' => $this->user->id, 'subject' => '占位', 'amount' => 0, 'status' => 'paid', 'paid_at' => now(), ])); $this->assertNull($this->service()->purchase($this->item)); } public function test_assert_can_install_blocks_unpaid_paid_item(): void { $this->actingAs($this->user); $this->expectException(RuntimeException::class); $this->service()->assertCanInstall($this->item); } public function test_free_item_needs_no_purchase(): void { $this->actingAs($this->user); $free = ['name' => 'vendor.free', 'type' => 'plugin', 'title' => '免费插件', 'price' => 0]; $this->assertFalse($this->service()->requiresPayment($free)); $this->service()->assertCanInstall($free); // 不抛异常 $this->assertTrue(true); } public function test_purchase_requires_payment_plugin(): void { $this->actingAs($this->user); app(\App\Blog\Support\PluginManager::class)->disable('neatstudio.membership'); app(\App\Blog\Support\PluginManager::class)->disable('neatstudio.payment'); $this->expectException(RuntimeException::class); $this->service()->purchase($this->item); } }