Files
toolbox/tests/Unit/JenkinsClientTest.php
T
tradewindandCursor c45d68e201 #feature: Jenkins 构建入口与自动创建 release 分支
加入 crm-web/crm-opm 并可跳转 Jenkins 发布页;自动创建 release 时 commit 使用 release-版本号,并跳过本地 git hook,避免 agent-be 被拦下。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 09:14:57 +08:00

133 lines
4.7 KiB
PHP

<?php
namespace Tests\Unit;
use App\Clients\JenkinsClient;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;
class JenkinsClientTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
config([
'jenkins.host' => 'https://jenkins.example.com',
'jenkins.username' => 'test-user',
'jenkins.api_token' => 'test-token',
'jenkins.timeout' => 30,
]);
}
public function test_parameterized_build_posts_form_json_parameters_and_returns_queue_url(): void
{
Http::fake([
'https://jenkins.example.com/job/deploy/api/json' => Http::response([
'nextBuildNumber' => 42,
]),
'https://jenkins.example.com/crumbIssuer/api/json' => Http::response([
'crumbRequestField' => 'Jenkins-Crumb',
'crumb' => 'test-crumb',
]),
'https://jenkins.example.com/job/deploy/build?delay=0sec' => Http::response('', 201, [
'Location' => 'https://jenkins.example.com/queue/item/123/',
]),
]);
$result = app(JenkinsClient::class)->triggerBuild('deploy', [
'project' => 'portal',
'branchName' => 'release/1.0',
]);
$this->assertTrue($result['success']);
$this->assertSame('https://jenkins.example.com/queue/item/123/', $result['queue_url']);
$this->assertSame(42, $result['build_number']);
Http::assertSent(function ($request) {
parse_str($request->body(), $form);
$payload = json_decode((string) ($form['json'] ?? ''), true);
$parameters = collect($payload['parameter'] ?? [])->pluck('value', 'name');
return $request->method() === 'POST'
&& $request->url() === 'https://jenkins.example.com/job/deploy/build?delay=0sec'
&& $parameters['project'] === 'portal'
&& $parameters['branchName'] === 'release/1.0';
});
}
public function test_cancel_build_with_queue_url_cancels_pending_queue_item(): void
{
Http::fake([
'https://jenkins.example.com/queue/item/123/api/json' => Http::response([
'why' => 'In the quiet period',
]),
'https://jenkins.example.com/crumbIssuer/api/json' => Http::response([
'crumbRequestField' => 'Jenkins-Crumb',
'crumb' => 'test-crumb',
]),
'https://jenkins.example.com/queue/cancelItem?id=123' => Http::response('', 200),
]);
$result = app(JenkinsClient::class)->cancelBuild('deploy', 'https://jenkins.example.com/queue/item/123/');
$this->assertTrue($result['success']);
$this->assertTrue($result['cancelled_queue']);
Http::assertSent(function ($request) {
return $request->method() === 'POST'
&& $request->url() === 'https://jenkins.example.com/queue/cancelItem?id=123';
});
}
public function test_cancel_build_without_queue_url_cancels_matching_queued_job(): void
{
Http::fake([
'https://jenkins.example.com/queue/api/json' => Http::response([
'items' => [
[
'id' => 456,
'task' => [
'fullName' => 'deploy',
'name' => 'deploy',
],
],
],
]),
'https://jenkins.example.com/crumbIssuer/api/json' => Http::response([
'crumbRequestField' => 'Jenkins-Crumb',
'crumb' => 'test-crumb',
]),
'https://jenkins.example.com/queue/cancelItem?id=456' => Http::response('', 200),
]);
$result = app(JenkinsClient::class)->cancelBuild('deploy', null, 42);
$this->assertTrue($result['success']);
$this->assertTrue($result['cancelled_queue']);
Http::assertSent(function ($request) {
return $request->method() === 'POST'
&& $request->url() === 'https://jenkins.example.com/queue/cancelItem?id=456';
});
}
public function test_get_job_url_builds_job_and_build_pages(): void
{
$client = app(JenkinsClient::class);
$this->assertSame(
'https://jenkins.example.com/job/crm-dev-crm_web/',
$client->getJobUrl('crm-dev-crm_web')
);
$this->assertSame(
'https://jenkins.example.com/job/crm-dev-crm_web/42/',
$client->getJobUrl('crm-dev-crm_web', 42)
);
$this->assertSame(
'https://jenkins.example.com/job/folder/job/nested-job/',
$client->getJobUrl('folder/nested-job')
);
}
}