CaiWuXiTong/tests/Feature/Installation/ConnectTeamSystemDatabaseTest.php

95 lines
5.3 KiB
PHP

<?php
namespace Tests\Feature\Installation;
use App\Utilities\SystemDatabaseConfiguration;
use App\Utilities\TeamSystemDatabaseProfile;
use Mockery;
use RuntimeException;
use Tests\TestCase;
class ConnectTeamSystemDatabaseTest extends TestCase
{
private function settings(): array
{
return ['driver'=>'mysql','host'=>'new-team.test','port'=>8444,'database'=>'shared_system',
'mirror_database'=>'caiwu_business_mirror','username'=>'team_user','password'=>'fixture-secret',
'prefix'=>'ak_','tls_required'=>true,'tls_verify_server_cert'=>false,'tls_ca'=>''];
}
private function configureProfile(): void
{
$this->app->instance(TeamSystemDatabaseProfile::class, new TeamSystemDatabaseProfile(
TeamSystemDatabaseProfile::seal($this->settings(), 'fixture-secret')
));
}
public function test_existing_password_repairs_old_endpoint_without_connecting_to_old_database(): void
{
$this->configureProfile();
$configuration=Mockery::mock(SystemDatabaseConfiguration::class);
$configuration->shouldReceive('current')->once()->andReturn(array_replace($this->settings(), ['host'=>'retired.test','mode'=>'shared']));
$configuration->shouldReceive('probe')->once()->with(Mockery::on(fn($s)=>$s['host']==='new-team.test'))->andReturn(['prefix'=>'ak_']);
$configuration->shouldReceive('persist')->once()->with($this->settings())->andReturn('private-backup');
$this->app->instance(SystemDatabaseConfiguration::class,$configuration);
$this->artisan('system-database:connect-team')->expectsOutputToContain('已备份并更新本机')->assertSuccessful();
}
public function test_first_bootstrap_without_team_password_does_not_write_or_probe(): void
{
$this->configureProfile();
$configuration=Mockery::mock(SystemDatabaseConfiguration::class);
$configuration->shouldReceive('current')->once()->andReturn(['password'=>'bootstrap-only','mode'=>'bootstrap']);
$configuration->shouldNotReceive('probe');
$configuration->shouldNotReceive('persist');
$this->app->instance(SystemDatabaseConfiguration::class,$configuration);
$this->artisan('system-database:connect-team')->expectsOutputToContain('输入一次密码')->assertExitCode(13);
}
public function test_current_team_connection_is_not_rewritten_on_every_initialization(): void
{
$this->configureProfile();
$s=$this->settings();
config(['upstreams.stored_configuration.enabled'=>true,'upstreams.local_configuration.enabled'=>false,
'database.connections.business_mirror'=>['read'=>['host'=>[$s['host']]],'write'=>['host'=>[$s['host']]],'port'=>$s['port'],
'database'=>$s['mirror_database'],'username'=>$s['username'],'password'=>$s['password'],'unix_socket'=>'']]);
$configuration=Mockery::mock(SystemDatabaseConfiguration::class);
$configuration->shouldReceive('current')->once()->andReturn($s+['mode'=>'shared']);
$configuration->shouldReceive('probe')->once()->andReturn(['prefix'=>'ak_']);
$configuration->shouldNotReceive('persist');
$this->app->instance(SystemDatabaseConfiguration::class,$configuration);
$this->artisan('system-database:connect-team')->expectsOutputToContain('已连接最新团队')->assertSuccessful();
}
public function test_failed_new_endpoint_probe_keeps_original_configuration(): void
{
$this->configureProfile();
$configuration=Mockery::mock(SystemDatabaseConfiguration::class);
$configuration->shouldReceive('current')->once()->andReturn($this->settings()+['mode'=>'shared']);
$configuration->shouldReceive('probe')->once()->andThrow(new RuntimeException('private connection details'));
$configuration->shouldNotReceive('persist');
$this->app->instance(SystemDatabaseConfiguration::class,$configuration);
$this->artisan('system-database:connect-team')->expectsOutputToContain('原配置已保留')->doesntExpectOutputToContain('private connection details')->assertFailed();
}
public function test_production_never_rewrites_its_internal_endpoint(): void
{
$this->app->detectEnvironment(fn()=>'production');
$configuration=Mockery::mock(SystemDatabaseConfiguration::class);
$configuration->shouldNotReceive('current');
$this->app->instance(SystemDatabaseConfiguration::class,$configuration);
$this->artisan('system-database:connect-team')->expectsOutputToContain('不修改生产服务器连接')->assertFailed();
}
public function test_persistence_failure_does_not_claim_connection_success(): void
{
$this->configureProfile();
$configuration=Mockery::mock(SystemDatabaseConfiguration::class);
$configuration->shouldReceive('current')->once()->andReturn(array_replace($this->settings(), ['host'=>'retired.test','mode'=>'shared']));
$configuration->shouldReceive('probe')->once()->andReturn(['prefix'=>'ak_']);
$configuration->shouldReceive('persist')->once()->andThrow(new RuntimeException('private details'));
$this->app->instance(SystemDatabaseConfiguration::class,$configuration);
$this->artisan('system-database:connect-team')->expectsOutputToContain('请核对私有配置备份')->doesntExpectOutputToContain('已备份并更新')->assertFailed();
}
}