feat: tg/ws

This commit is contained in:
hashbro
2026-08-31 02:45:24 +08:00
parent 9176af86dd
commit 337bf45c79
47 changed files with 1725 additions and 598 deletions
+55 -25
View File
@@ -207,15 +207,21 @@ class ChannelProjectServiceTest extends TestCase
#[Test]
public function failed_database_insert_compensates_with_delete(): void
{
$this->stageFakeWeifile();
Process::fake([
'*' => Process::sequence()
->push(Process::result(output: $this->fakeBuildResult()))
->push(Process::result(output: ChannelProjectService::RESULT_MARKER.json_encode([
'status' => 'deleted',
'removed' => true,
])."\n")),
'*' => Process::result(output: $this->fakeBuildResult([
'builder_type' => 'new',
'channel_id' => self::NEW_CHANNEL_ID,
'landing_path' => '/channel/'.self::NEW_CHANNEL_ID.'/weifile/weifile.html',
'details_path' => '/channel/'.self::NEW_CHANNEL_ID.'/details/',
'channel_dir' => '/channel/'.self::NEW_CHANNEL_ID,
])),
]);
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
$channelDir = storage_path('app/channel-artifacts-test/channel/'.self::NEW_CHANNEL_ID);
if (! is_dir($channelDir) && ! mkdir($channelDir, 0775, true) && ! is_dir($channelDir)) {
$this->fail('unable to create channel dir for compensation test');
}
$originalDispatcher = Channel::getEventDispatcher();
Channel::setEventDispatcher(new Dispatcher($this->app));
@@ -224,7 +230,7 @@ class ChannelProjectServiceTest extends TestCase
try {
$this->actingAs($admin, 'admin')
->post(route('admin.channels.store'), [
'channel_id' => self::CHANNEL_ID,
'channel_id' => self::NEW_CHANNEL_ID,
'user_id' => 0,
])
->assertStatus(422)
@@ -233,11 +239,8 @@ class ChannelProjectServiceTest extends TestCase
Channel::setEventDispatcher($originalDispatcher);
}
Process::assertRan(fn ($process) => str_contains(
is_array($process->command) ? implode(' ', $process->command) : (string) $process->command,
'delete_channel_web.py'
));
$this->assertDatabaseMissing('channels', ['channel_id' => self::CHANNEL_ID]);
$this->assertDirectoryDoesNotExist($channelDir);
$this->assertDatabaseMissing('channels', ['channel_id' => self::NEW_CHANNEL_ID]);
}
#[Test]
@@ -247,19 +250,20 @@ class ChannelProjectServiceTest extends TestCase
$projects = Mockery::mock(ChannelProjectService::class);
$projects->shouldReceive('generate')->once()->andReturnUsing(function (): array {
Channel::query()->create([
'channel_id' => self::CHANNEL_ID,
'channel_id' => self::NEW_CHANNEL_ID,
'builder_type' => Channel::BUILDER_NEW,
'user_id' => 0,
'status' => 1,
]);
return [
'channel_id' => self::CHANNEL_ID,
'channel_id' => self::NEW_CHANNEL_ID,
'seeds' => ['deployment_seed' => 'a', 'reporting_seed' => 'b'],
'domains' => ['deployment' => [], 'reporting' => []],
'seeds_initialized' => false,
'sync_rebuilt' => false,
'support_path' => '/web/'.self::CHANNEL_ID.'/support.html',
'daily_path' => '/sync/daily.html',
'support_path' => '/channel/'.self::NEW_CHANNEL_ID.'/weifile/weifile.html',
'daily_path' => '/channel/'.self::NEW_CHANNEL_ID.'/details/',
];
});
$projects->shouldNotReceive('deleteWebTree');
@@ -267,7 +271,7 @@ class ChannelProjectServiceTest extends TestCase
$this->actingAs($admin, 'admin')
->post(route('admin.channels.store'), [
'channel_id' => self::CHANNEL_ID,
'channel_id' => self::NEW_CHANNEL_ID,
'user_id' => 0,
])
->assertStatus(422)
@@ -328,27 +332,54 @@ class ChannelProjectServiceTest extends TestCase
#[Test]
public function store_returns_seeds_and_domains(): void
{
$this->stageFakeWeifile();
Process::fake([
'*' => Process::result(output: $this->fakeBuildResult()),
'*' => Process::result(output: $this->fakeBuildResult([
'builder_type' => 'new',
'channel_id' => self::NEW_CHANNEL_ID,
'landing_path' => '/channel/'.self::NEW_CHANNEL_ID.'/weifile/weifile.html',
'details_path' => '/channel/'.self::NEW_CHANNEL_ID.'/details/',
'daily_path' => '/channel/'.self::NEW_CHANNEL_ID.'/details/',
'channel_dir' => '/channel/'.self::NEW_CHANNEL_ID,
])),
]);
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
$this->actingAs($admin, 'admin')
->post(route('admin.channels.store'), [
'channel_id' => self::CHANNEL_ID,
'channel_id' => self::NEW_CHANNEL_ID,
'user_id' => 0,
])
->assertOk()
->assertJsonPath('code', 0)
->assertJsonPath('data.builder_type', Channel::BUILDER_NEW)
->assertJsonPath('data.seeds.deployment_seed', '11111111111111111111111111111111')
->assertJsonPath('data.domains.deployment.0', 'www.dep.example')
->assertJsonPath('data.seeds_initialized', true)
->assertJsonPath('data.daily_path', '/sync/daily.html');
->assertJsonPath('data.daily_path', '/channel/'.self::NEW_CHANNEL_ID.'/details/');
$this->assertDatabaseHas('channels', ['channel_id' => self::CHANNEL_ID]);
$channel = Channel::query()->where('channel_id', self::CHANNEL_ID)->first();
$this->assertDatabaseHas('channels', [
'channel_id' => self::NEW_CHANNEL_ID,
'builder_type' => Channel::BUILDER_NEW,
]);
$channel = Channel::query()->where('channel_id', self::NEW_CHANNEL_ID)->first();
$this->assertSame([], $channel->domains ?? []);
$this->assertSame(Channel::BUILDER_OLD, $channel->builderType());
$this->assertSame(Channel::BUILDER_NEW, $channel->builderType());
}
#[Test]
public function store_rejects_old_builder_channel_id(): void
{
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
$this->actingAs($admin, 'admin')
->post(route('admin.channels.store'), [
'channel_id' => self::CHANNEL_ID,
'builder_type' => Channel::BUILDER_OLD,
'user_id' => 0,
])
->assertSessionHasErrors('channel_id');
$this->assertDatabaseMissing('channels', ['channel_id' => self::CHANNEL_ID]);
}
#[Test]
@@ -477,7 +508,6 @@ class ChannelProjectServiceTest extends TestCase
$response = $this->actingAs($admin, 'admin')
->post(route('admin.channels.store'), [
'channel_id' => self::NEW_CHANNEL_ID,
'builder_type' => Channel::BUILDER_NEW,
'user_id' => 0,
])
->assertOk()