testInvalidTokenRejection(); $this->testUrlTokenAllowed(); $this->testHeaderTokenAllowed(); $this->testHmacSha256SignatureAllowed(); $this->testHubSignature256Allowed(); $this->testNonPostMethodRejection(); $this->testPingEventSuccess(); $this->testIgnoredBranchSkipped(); $this->testTargetBranchTriggersDeploy(); echo "\n测试结果: {$this->passed} 通过, {$this->failed} 失败\n"; if ($this->failed > 0) { exit(1); } } private function assert($condition, $message) { if ($condition) { echo " [PASS] {$message}\n"; $this->passed++; } else { echo " [FAIL] {$message}\n"; $this->failed++; } } /** * 测试非法 Token 被拦截 */ public function testInvalidTokenRejection() { $handler = new \app\common\library\WebhookHandler('test_secret_123'); $server = ['REQUEST_METHOD' => 'POST', 'HTTP_X_GITEA_TOKEN' => 'wrong_token']; $res = $handler->handle($server, [], '{}'); $this->assert($res['code'] === 403, "非法 Token 应返回 HTTP 403"); $this->assert($res['data']['status'] === 'error', "非法 Token 应返回 error 状态"); } /** * 测试通过 URL 参数传递 Token 允许通过 */ public function testUrlTokenAllowed() { $handler = new \app\common\library\WebhookHandler('test_secret_123'); $server = ['REQUEST_METHOD' => 'POST']; $get = ['token' => 'test_secret_123']; $res = $handler->handle($server, $get, json_encode(['ref' => 'refs/heads/master'])); $this->assert($res['code'] === 200, "合法 URL Token 应返回 HTTP 200"); } /** * 测试通过 Header 传递 Token 允许通过 */ public function testHeaderTokenAllowed() { $handler = new \app\common\library\WebhookHandler('test_secret_123'); $server = ['REQUEST_METHOD' => 'POST', 'HTTP_X_GITEA_TOKEN' => 'test_secret_123']; $res = $handler->handle($server, [], json_encode(['ref' => 'refs/heads/master'])); $this->assert($res['code'] === 200, "合法 Header Token 应返回 HTTP 200"); } /** * 测试通过 Gitea HMAC-SHA256 签名校验 */ public function testHmacSha256SignatureAllowed() { $handler = new \app\common\library\WebhookHandler('test_secret_123'); $body = json_encode(['ref' => 'refs/heads/master']); $sig = hash_hmac('sha256', $body, 'test_secret_123'); $server = ['REQUEST_METHOD' => 'POST', 'HTTP_X_GITEA_SIGNATURE' => $sig]; $res = $handler->handle($server, [], $body); $this->assert($res['code'] === 200, "合法 HMAC-SHA256 签名应返回 HTTP 200"); } /** * 测试通过 GitHub/Gitea sha256= 前缀签名校验 */ public function testHubSignature256Allowed() { $handler = new \app\common\library\WebhookHandler('test_secret_123'); $body = json_encode(['ref' => 'refs/heads/master']); $sig = 'sha256=' . hash_hmac('sha256', $body, 'test_secret_123'); $server = ['REQUEST_METHOD' => 'POST', 'HTTP_X_HUB_SIGNATURE_256' => $sig]; $res = $handler->handle($server, [], $body); $this->assert($res['code'] === 200, "合法 X-Hub-Signature-256 签名应返回 HTTP 200"); } /** * 测试非 POST 请求被拒绝 */ public function testNonPostMethodRejection() { $handler = new \app\common\library\WebhookHandler('test_secret_123'); $server = ['REQUEST_METHOD' => 'GET']; $get = ['token' => 'test_secret_123']; $res = $handler->handle($server, $get, ''); $this->assert($res['code'] === 405, "非 POST 请求应返回 HTTP 405"); } /** * 测试 Gitea Ping / Test 事件直接响应成功 */ public function testPingEventSuccess() { $handler = new \app\common\library\WebhookHandler('test_secret_123'); $server = [ 'REQUEST_METHOD' => 'POST', 'HTTP_X_GITEA_EVENT' => 'ping', 'HTTP_X_GITEA_TOKEN' => 'test_secret_123' ]; $res = $handler->handle($server, [], '{}'); $this->assert($res['code'] === 200, "Ping 事件应返回 HTTP 200"); $this->assert($res['data']['message'] === 'pong', "Ping 事件应返回 pong 响应"); } /** * 测试非目标分支推送被跳过 */ public function testIgnoredBranchSkipped() { $handler = new \app\common\library\WebhookHandler('test_secret_123', 'master'); $server = ['REQUEST_METHOD' => 'POST', 'HTTP_X_GITEA_TOKEN' => 'test_secret_123']; $body = json_encode(['ref' => 'refs/heads/feature_test']); $res = $handler->handle($server, [], $body); $this->assert($res['code'] === 200, "非目标分支应返回 HTTP 200"); $this->assert($res['data']['status'] === 'skipped', "非目标分支状态应为 skipped"); } /** * 测试目标分支推送正确触发部署回调 */ public function testTargetBranchTriggersDeploy() { $triggered = false; $handler = new \app\common\library\WebhookHandler('test_secret_123', 'master', function () use (&$triggered) { $triggered = true; return "Deploy OK"; }); $server = ['REQUEST_METHOD' => 'POST', 'HTTP_X_GITEA_TOKEN' => 'test_secret_123']; $body = json_encode(['ref' => 'refs/heads/master']); $res = $handler->handle($server, [], $body); $this->assert($res['code'] === 200, "目标分支应返回 HTTP 200"); $this->assert($triggered === true, "目标分支必须触发部署回调"); $this->assert($res['data']['status'] === 'success', "部署状态应为 success"); $this->assert($res['data']['output'] === 'Deploy OK', "返回内容应包含部署输出"); } } $test = new WebhookTest(); $test->run();