Files
toolbox/tests/Unit/JiraServiceTest.php
T

382 lines
13 KiB
PHP

<?php
namespace Tests\Unit;
use App\Services\JiraService;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Tests\TestCase;
class JiraServiceTest extends TestCase
{
private JiraService $jiraService;
protected function setUp(): void
{
parent::setUp();
// 设置测试配置
config([
'jira.host' => 'https://test-jira.example.com',
'jira.username' => 'test-user',
'jira.password' => 'test-password',
'jira.default_user' => 'test-user',
]);
$this->jiraService = app(JiraService::class);
}
protected function tearDown(): void
{
Carbon::setTestNow();
parent::tearDown();
}
public function test_is_task_completed_returns_false_for_incomplete_statuses()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('isTaskCompleted');
// 测试不完成的状态
$incompleteStatuses = [
'开发中',
'需求已排期',
'需求已评审',
'In Progress',
'To Do',
'Open',
];
foreach ($incompleteStatuses as $status) {
$this->assertFalse(
$method->invoke($this->jiraService, $status),
"状态 '{$status}' 应该返回 false"
);
}
}
public function test_is_task_completed_returns_true_for_complete_statuses()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('isTaskCompleted');
// 测试完成的状态
$completeStatuses = [
'Done',
'Closed',
'Resolved',
'已完成',
'Complete',
];
foreach ($completeStatuses as $status) {
$this->assertTrue(
$method->invoke($this->jiraService, $status),
"状态 '{$status}' 应该返回 true"
);
}
}
public function test_organize_tasks_for_report_handles_empty_collection()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('organizeTasksForReport');
$emptyWorkLogs = collect();
$result = $method->invoke($this->jiraService, $emptyWorkLogs, 'test-user');
$this->assertInstanceOf(Collection::class, $result);
$this->assertTrue($result->has('sprints'));
$this->assertTrue($result->has('stories'));
$this->assertTrue($result->has('tasks'));
$this->assertTrue($result->has('bugs'));
}
public function test_organize_tasks_for_report_categorizes_by_sprint()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('organizeTasksForReport');
$workLogs = collect([
[
'issue_key' => 'WP-1234',
'issue_summary' => '测试需求',
'issue_url' => 'https://test-jira.example.com/browse/WP-1234',
'issue_status' => 'Done',
'issue_type' => 'Story',
'sprint' => '十月中需求',
'bug_stage' => null,
'bug_type' => null,
'parent_task' => null,
],
]);
$result = $method->invoke($this->jiraService, $workLogs, 'test-user');
$this->assertTrue($result['sprints']->has('十月中需求'));
$this->assertCount(1, $result['sprints']['十月中需求']);
}
public function test_organize_tasks_for_report_categorizes_bugs_by_stage()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('organizeTasksForReport');
$workLogs = collect([
[
'issue_key' => 'WP-5678',
'issue_summary' => '测试Bug',
'issue_url' => 'https://test-jira.example.com/browse/WP-5678',
'issue_status' => 'Done',
'issue_type' => 'Bug',
'sprint' => null,
'bug_stage' => 'SIT环境BUG',
'bug_type' => '需求未说明',
'bug_description' => null,
'parent_task' => null,
'assignee' => 'test-user',
'developer' => null,
'actual_fixer' => null,
],
]);
$result = $method->invoke($this->jiraService, $workLogs, 'test-user');
$this->assertTrue($result['bugs']->has('SIT环境BUG'));
$this->assertCount(1, $result['bugs']['SIT环境BUG']);
$this->assertEquals('需求未说明', $result['bugs']['SIT环境BUG'][0]['bug_type']);
}
public function test_resolve_weekly_report_range_for_last_week()
{
Carbon::setTestNow('2026-04-02 10:00:00');
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('resolveWeeklyReportRange');
$result = $method->invoke($this->jiraService, 'last_week');
$this->assertEquals('2026-03-23 00:00:00', $result['start']->format('Y-m-d H:i:s'));
$this->assertEquals('2026-03-29 23:59:59', $result['end']->format('Y-m-d H:i:s'));
$this->assertEquals('上周完成的任务', $result['title']);
}
public function test_resolve_weekly_report_range_for_this_week()
{
Carbon::setTestNow('2026-04-02 10:00:00');
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('resolveWeeklyReportRange');
$result = $method->invoke($this->jiraService, 'this_week');
$this->assertEquals('2026-03-30 00:00:00', $result['start']->format('Y-m-d H:i:s'));
$this->assertEquals('2026-04-02 23:59:59', $result['end']->format('Y-m-d H:i:s'));
$this->assertEquals('本周完成的任务', $result['title']);
}
public function test_extract_sprint_info_from_string()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractSprintInfo');
$issue = (object) [
'fields' => (object) [
'customFields' => [
'customfield_10004' => [
'com.atlassian.greenhopper.service.sprint.Sprint@xxx[name=十月中需求,state=ACTIVE]',
],
],
],
];
$result = $method->invoke($this->jiraService, $issue);
$this->assertEquals('十月中需求', $result);
}
public function test_resolve_test_mail_sprint_period_normalizes_sprint_name()
{
$result = $this->jiraService->resolveTestMailSprintPeriod('CRM2603中迭代');
$this->assertEquals('Sprint2603月中', $result);
}
public function test_resolve_test_mail_sprint_period_uses_issue_sprint_name()
{
$issues = collect([
['sprint' => 'CRM2605底迭代'],
]);
$result = $this->jiraService->resolveTestMailSprintPeriod('2324', $issues);
$this->assertEquals('Sprint2605月底', $result);
}
public function test_resolve_test_mail_sprint_period_handles_year_month_name()
{
$result = $this->jiraService->resolveTestMailSprintPeriod('2026年5月中需求');
$this->assertEquals('Sprint2605月中', $result);
}
public function test_estimated_test_at_field_name_does_not_match_actual_test_at()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('isEstimatedTestAtFieldName');
$this->assertFalse($method->invoke($this->jiraService, '实际提测时间'));
$this->assertTrue($method->invoke($this->jiraService, '预计提测时间'));
}
public function test_next_test_mail_version_increments_second_segment()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('nextTestMailVersion');
$this->assertEquals('2.70.0.0', $method->invoke($this->jiraService, '2.69.0.0'));
}
public function test_test_mail_template_defaults_use_next_versions()
{
$defaults = $this->jiraService->getTestMailTemplateDefaults();
$this->assertEquals('2.70.0.0', $defaults['container_groups']['agent']['default_version']);
$this->assertEquals('2.65.0.0', $defaults['container_groups']['portal']['default_version']);
$this->assertEquals('1.43.0.0', $defaults['container_groups']['portal-ticket']['default_version']);
}
public function test_extract_bug_stage_from_labels()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractBugStage');
$issue = (object) [
'fields' => (object) [
'labels' => ['SIT', 'bug'],
],
];
$result = $method->invoke($this->jiraService, $issue);
$this->assertEquals('SIT环境BUG', $result);
}
public function test_extract_bug_type_from_labels()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractBugType');
$issue = (object) [
'fields' => (object) [
'labels' => ['需求未说明', 'bug'],
],
];
$result = $method->invoke($this->jiraService, $issue);
$this->assertEquals('需求未说明', $result);
}
public function test_extract_developer_from_user_object()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractDeveloper');
$issue = (object) [
'fields' => (object) [
'customFields' => [
'customfield_11000' => (object) [
'name' => 'zhangsan',
'displayName' => '张三',
'emailAddress' => 'zhangsan@example.com',
],
],
],
];
$this->assertEquals('zhangsan', $method->invoke($this->jiraService, $issue));
}
public function test_extract_developer_from_associative_array()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractDeveloper');
$issue = (object) [
'fields' => (object) [
'customFields' => [
'customfield_11000' => [
'name' => 'lisi',
'displayName' => '李四',
],
],
],
];
$this->assertEquals('lisi', $method->invoke($this->jiraService, $issue));
}
public function test_extract_actual_fixer_from_user_object()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractActualFixer');
$issue = (object) [
'fields' => (object) [
'customFields' => [
'customfield_11301' => (object) [
'name' => 'wangwu',
'displayName' => '王五',
],
],
],
];
$this->assertEquals('wangwu', $method->invoke($this->jiraService, $issue));
}
public function test_extract_developer_returns_null_when_field_missing()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractDeveloper');
$issue = (object) [
'fields' => (object) [
'customFields' => [],
],
];
$this->assertNull($method->invoke($this->jiraService, $issue));
}
public function test_organize_tasks_for_report_includes_bug_when_user_is_developer_only()
{
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('organizeTasksForReport');
// 模拟 WP-7158 场景:经办人是测试同学,开发人才是当前用户
$workLogs = collect([
[
'issue_key' => 'WP-7158',
'issue_summary' => '生产 Bug 修复',
'issue_url' => 'https://test-jira.example.com/browse/WP-7158',
'issue_status' => 'Done',
'issue_type' => 'Bug',
'sprint' => null,
'bug_stage' => '生产环境BUG',
'bug_type' => '代码错误',
'bug_description' => null,
'parent_task' => null,
'assignee' => 'tester-user',
'developer' => 'test-user',
'actual_fixer' => null,
],
]);
$result = $method->invoke($this->jiraService, $workLogs, 'test-user');
$this->assertTrue($result['bugs']->has('生产环境BUG'));
$this->assertCount(1, $result['bugs']['生产环境BUG']);
$this->assertEquals('WP-7158', $result['bugs']['生产环境BUG'][0]['key']);
}
}