You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wx.sstbc.com/tests/Feature/VerifyQccEnterprisePackInfo...

113 lines
5.1 KiB

<?php
namespace Tests\Feature;
use App\Exceptions\YuanhePackInfoException;
use App\Repositories\YuanheRepository;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Mockery;
use Tests\TestCase;
class VerifyQccEnterprisePackInfoTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
config(['database.default' => 'sqlite', 'database.connections.sqlite.database' => ':memory:', 'audit.enabled' => false]);
DB::purge('sqlite');
Schema::create('companies', function (Blueprint $t) {
$t->id(); $t->string('company_name'); $t->string('credit_code')->nullable(); $t->timestamps(); $t->softDeletes();
});
Schema::create('company_qcc_accounts', function (Blueprint $t) {
$t->id(); $t->unsignedBigInteger('company_id'); $t->string('status'); $t->timestamps();
$t->dateTime('first_success_at')->nullable(); $t->string('first_success_source')->nullable();
$t->string('first_success_ref')->nullable(); $t->text('unknown_note')->nullable();
});
}
protected function tearDown(): void
{
DB::disconnect('sqlite');
parent::tearDown();
}
private function company(string $status): void
{
DB::table('companies')->insert(['id' => 333, 'company_name' => '测试企业', 'credit_code' => 'test-credit']);
DB::table('company_qcc_accounts')->insert([
'company_id' => 333, 'status' => $status, 'first_success_ref' => 'original-ref',
'updated_at' => '2026-01-01 00:00:00', 'unknown_note' => '原有诊断备注',
]);
}
/** @dataProvider responseCases */
public function test_response_and_timeout_without_database_writes(string $status, array $response, array $options, int $timeout, int $exit): void
{
$this->company($status);
$before = DB::table('company_qcc_accounts')->get()->toJson();
$companies = DB::table('companies')->get()->toJson();
$mock = Mockery::mock(YuanheRepository::class);
$mock->shouldReceive('enterprisePackInfo')->once()
->with(['creditCode' => 'test-credit', 'enterpriseName' => '测试企业'], $timeout)->andReturn($response);
$this->app->instance(YuanheRepository::class, $mock);
$this->assertSame($exit, Artisan::call('qcc:verify-pack-info', ['company_id' => 333] + $options));
$this->assertSame($response, json_decode(Artisan::output(), true));
$this->assertSame($before, DB::table('company_qcc_accounts')->get()->toJson());
$this->assertSame($companies, DB::table('companies')->get()->toJson());
}
public static function responseCases(): array
{
return [
['selected', ['code' => 200, 'data' => ['news' => [['Title' => '<info>标题</info>']]]], [], 60, 0],
['occupied', ['code' => '200', 'data' => []], ['--timeout' => '120', '--raw' => true], 120, 0],
['unknown', ['code' => 200, 'data' => ['news' => []]], [], 60, 0],
['unknown', ['code' => 500], ['--timeout' => '120'], 120, 1],
['selected', ['code' => 0], [], 60, 1],
['occupied', ['code' => 500, 'msg' => '失败'], [], 60, 1],
['selected', ['data' => []], [], 60, 1],
];
}
/** @dataProvider exceptionCases */
public function test_exception_leaves_account_unchanged(string $status, ?string $raw): void
{
$this->company($status);
$before = DB::table('company_qcc_accounts')->get()->toJson();
$mock = Mockery::mock(YuanheRepository::class);
$mock->shouldReceive('enterprisePackInfo')->once()->andThrow(new YuanhePackInfoException('请求超时', null, null, $raw));
$this->app->instance(YuanheRepository::class, $mock);
$this->assertSame(1, Artisan::call('qcc:verify-pack-info', ['company_id' => 333]));
$this->assertSame(($raw ?? '请求超时').PHP_EOL, Artisan::output());
$this->assertSame($before, DB::table('company_qcc_accounts')->get()->toJson());
}
public static function exceptionCases(): array
{
return [['selected', null], ['selected', '<html>Bad Gateway</html>'], ['unknown', null], ['unknown', '<html>Bad Gateway</html>']];
}
/** @dataProvider rejectedCases */
public function test_invalid_input_does_not_call_api(string $status, array $options): void
{
$this->company($status);
$mock = Mockery::mock(YuanheRepository::class);
$mock->shouldNotReceive('enterprisePackInfo');
$this->app->instance(YuanheRepository::class, $mock);
$this->assertSame(1, Artisan::call('qcc:verify-pack-info', ['company_id' => 333] + $options));
$this->assertSame($status, DB::table('company_qcc_accounts')->value('status'));
}
public static function rejectedCases(): array
{
return [
['none', []], ['non_occupying', []], ['selected', ['--timeout' => '0']],
['selected', ['--timeout' => '-1']], ['selected', ['--timeout' => '1.5']],
['selected', ['--timeout' => 'abc']],
];
}
}