postJson('/api/v1/client/register', [ 'site_url' => 'https://demo.example.com/', 'site_name' => 'Demo Blog', 'typecho_version' => '1.3.0', 'php_version' => '8.2.16', 'plugin_version' => '1.0.0', 'user_count' => 3, ]); $register->assertOk() ->assertJsonPath('code', 0) ->assertJsonPath('data.site_url', 'https://demo.example.com') ->assertJsonPath('data.user_count', 3); $token = (string) $register->json('data.access_token'); $heartbeat = $this->withToken($token)->postJson('/api/v1/client/heartbeat', [ 'site_name' => 'Demo Blog', 'user_count' => 5, 'plugin_version' => '1.0.1', ]); $heartbeat->assertOk() ->assertJsonPath('code', 0) ->assertJsonPath('data.user_count', 5) ->assertJsonPath('data.plugin_version', '1.0.1') ->assertJsonPath('data.stats.registered_sites', 1) ->assertJsonPath('data.stats.tracked_users', 5); $this->withToken($token)->getJson('/api/v1/client/status') ->assertOk() ->assertJsonPath('code', 0) ->assertJsonPath('data.site_url', 'https://demo.example.com') ->assertJsonMissingPath('data.access_token'); $client = StoreClient::query()->where('site_url', 'https://demo.example.com')->firstOrFail(); $previousSeenAt = $client->last_seen_at; sleep(1); $this->withToken($token)->getJson('/api/v1/client/status') ->assertOk() ->assertJsonPath('code', 0); $client->refresh(); $this->assertNotNull($client->last_seen_at); $this->assertTrue($client->last_seen_at->gt($previousSeenAt)); $this->assertSame('online', $client->status); } public function test_download_endpoint_accepts_registered_client_token(): void { config(['app.url' => 'http://127.0.0.1:8000']); $package = Package::query()->create([ 'type' => 'plugin', 'slug' => 'DemoPlugin', 'name' => 'Demo Plugin', 'summary' => 'Summary', 'description' => 'Description', 'author' => 'Author', 'homepage' => '', 'icon_url' => '', 'license' => '', 'status' => 'published', 'is_featured' => false, 'sort_order' => 0, 'download_count' => 0, 'latest_version' => '1.2.3', ]); Version::query()->create([ 'package_id' => $package->id, 'version' => '1.2.3', 'changelog' => 'Initial release', 'typecho_min' => '1.2.0', 'typecho_max' => '', 'php_min' => '8.0', 'php_max' => '', 'php_extensions' => '[]', 'package_url' => 'https://cdn.example.com/DemoPlugin-1.2.3.zip', 'package_size' => 1234, 'sha256' => str_repeat('a', 64), 'is_stable' => true, 'is_latest' => true, 'download_count' => 0, 'published_at' => now(), ]); $this->getJson('/api/v1/repo/download/plugin/DemoPlugin/latest') ->assertStatus(403) ->assertJsonPath('message', 'client token required'); $register = $this->postJson('/api/v1/client/register', [ 'site_url' => 'https://demo.example.com', 'site_name' => 'Demo Blog', 'user_count' => 2, ]); $token = (string) $register->json('data.access_token'); $this->withToken($token) ->getJson('https://store.typecho.team/api/v1/repo/download/plugin/DemoPlugin/latest') ->assertOk() ->assertJsonPath('code', 0) ->assertJsonPath('data.package.sha256', str_repeat('a', 64)) ->assertJsonPath('data.version', '1.2.3') ->assertJsonPath('data.package.download_url', 'https://store.typecho.team/api/v1/repo/download/plugin/DemoPlugin/1.2.3?redirect=1'); } public function test_check_updates_returns_request_host_download_url_when_app_url_is_local(): void { config(['app.url' => 'http://127.0.0.1:8000']); $package = Package::query()->create([ 'type' => 'plugin', 'slug' => 'DemoPlugin', 'name' => 'Demo Plugin', 'summary' => 'Summary', 'description' => 'Description', 'author' => 'Author', 'homepage' => '', 'icon_url' => '', 'license' => '', 'status' => 'published', 'is_featured' => false, 'sort_order' => 0, 'download_count' => 0, 'latest_version' => '1.2.3', ]); Version::query()->create([ 'package_id' => $package->id, 'version' => '1.2.3', 'changelog' => 'Initial release', 'typecho_min' => '1.2.0', 'typecho_max' => '', 'php_min' => '8.0', 'php_max' => '', 'php_extensions' => '[]', 'package_url' => 'http://127.0.0.1:8000/api/v1/repo/download/plugin/DemoPlugin/1.2.3?redirect=1', 'package_size' => 1234, 'sha256' => str_repeat('a', 64), 'is_stable' => true, 'is_latest' => true, 'download_count' => 0, 'published_at' => now(), ]); $response = $this->postJson('https://store.typecho.team/api/v1/repo/updates/check', [ 'installed' => [ [ 'type' => 'plugin', 'slug' => 'DemoPlugin', 'version' => '1.0.0', ], ], 'typecho_version' => '1.3.0', 'php_version' => '8.2.16', ]); $response->assertOk() ->assertJsonPath('code', 0) ->assertJsonCount(1, 'data.updates') ->assertJsonPath('data.updates.0.package.download_url', 'https://store.typecho.team/api/v1/repo/download/plugin/DemoPlugin/1.2.3?redirect=1'); } }