#feature: update SQL generator

This commit is contained in:
2026-05-19 14:57:11 +08:00
parent 53bca7d609
commit 3c628eb391
10 changed files with 1043 additions and 165 deletions
+133
View File
@@ -0,0 +1,133 @@
<?php
namespace Tests\Feature;
use Illuminate\Support\Facades\DB;
use Mockery;
use Tests\TestCase;
class SqlGeneratorTest extends TestCase
{
public function test_check_production_countries_requires_production_codes(): void
{
$response = $this->postJson('/api/sql-generator/production-countries/check', []);
$response->assertStatus(422);
$response->assertJson([
'success' => false,
'message' => '请求参数验证失败',
]);
}
public function test_check_production_countries_returns_country_codes_from_crm(): void
{
$connection = Mockery::mock();
DB::shouldReceive('connection')
->times(2)
->with('crmslave')
->andReturn($connection);
$productionBuilder = Mockery::mock();
$productionBuilder->shouldReceive('join')
->once()
->with('ea_production_cstm as epc', 'ep.id', '=', 'epc.id_c')
->andReturnSelf();
$productionBuilder->shouldReceive('where')
->once()
->with('ep.deleted', 0)
->andReturnSelf();
$productionBuilder->shouldReceive('whereIn')
->once()
->with('ep.name', ['M20260508006905'])
->andReturnSelf();
$productionBuilder->shouldReceive('select')
->once()
->with([
'ep.name as production_code',
'epc.ea_case_id_c',
'epc.ea_businessorder_id_c',
'epc.ea_salesorder_id_c',
])
->andReturnSelf();
$productionBuilder->shouldReceive('get')
->once()
->andReturn(collect([
(object) [
'production_code' => 'M20260508006905',
'ea_case_id_c' => '',
'ea_businessorder_id_c' => '',
'ea_salesorder_id_c' => 'sales-order-1',
],
]));
$salesOrderBuilder = Mockery::mock();
$salesOrderBuilder->shouldReceive('join')
->once()
->with('accounts_ea_salesorder_1_c as aes1c', Mockery::type('Closure'))
->andReturnSelf();
$salesOrderBuilder->shouldReceive('join')
->once()
->with('accounts as a_base', 'a_base.id', '=', 'aes1c.accounts_ea_salesorder_1accounts_ida')
->andReturnSelf();
$salesOrderBuilder->shouldReceive('join')
->once()
->with('accounts_cstm as ac', 'ac.id_c', '=', 'aes1c.accounts_ea_salesorder_1accounts_ida')
->andReturnSelf();
$salesOrderBuilder->shouldReceive('where')
->once()
->with('es.deleted', 0)
->andReturnSelf();
$salesOrderBuilder->shouldReceive('where')
->once()
->with('a_base.deleted', 0)
->andReturnSelf();
$salesOrderBuilder->shouldReceive('whereIn')
->once()
->with('es.id', ['sales-order-1'])
->andReturnSelf();
$salesOrderBuilder->shouldReceive('whereNotNull')
->once()
->with('ac.country_c')
->andReturnSelf();
$salesOrderBuilder->shouldReceive('select')
->once()
->with([
'es.id as entity_id',
'ac.country_c as country',
'ac.province_c as province',
])
->andReturnSelf();
$salesOrderBuilder->shouldReceive('get')
->once()
->andReturn(collect([
(object) [
'entity_id' => 'sales-order-1',
'country' => '840',
'province' => '',
],
]));
$connection->shouldReceive('table')
->once()
->with('ea_production as ep')
->andReturn($productionBuilder);
$connection->shouldReceive('table')
->once()
->with('ea_salesorder as es')
->andReturn($salesOrderBuilder);
$response = $this->postJson('/api/sql-generator/production-countries/check', [
'production_codes' => ['M20260508006905'],
]);
$response->assertStatus(200);
$response->assertJson([
'success' => true,
'data' => [
'production_countries' => [
'M20260508006905' => ['US'],
],
],
]);
}
}
+169 -23
View File
@@ -2,9 +2,10 @@
namespace Tests\Unit;
use Tests\TestCase;
use App\Services\JiraService;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Tests\TestCase;
class JiraServiceTest extends TestCase
{
@@ -19,12 +20,19 @@ class JiraServiceTest extends TestCase
'jira.host' => 'https://test-jira.example.com',
'jira.username' => 'test-user',
'jira.password' => 'test-password',
'jira.default_user' => 'test-user'
'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);
@@ -37,7 +45,7 @@ class JiraServiceTest extends TestCase
'需求已评审',
'In Progress',
'To Do',
'Open'
'Open',
];
foreach ($incompleteStatuses as $status) {
@@ -59,7 +67,7 @@ class JiraServiceTest extends TestCase
'Closed',
'Resolved',
'已完成',
'Complete'
'Complete',
];
foreach ($completeStatuses as $status) {
@@ -76,10 +84,11 @@ class JiraServiceTest extends TestCase
$method = $reflection->getMethod('organizeTasksForReport');
$emptyWorkLogs = collect();
$result = $method->invoke($this->jiraService, $emptyWorkLogs);
$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'));
}
@@ -100,10 +109,10 @@ class JiraServiceTest extends TestCase
'bug_stage' => null,
'bug_type' => null,
'parent_task' => null,
]
],
]);
$result = $method->invoke($this->jiraService, $workLogs);
$result = $method->invoke($this->jiraService, $workLogs, 'test-user');
$this->assertTrue($result['sprints']->has('十月中需求'));
$this->assertCount(1, $result['sprints']['十月中需求']);
@@ -124,28 +133,62 @@ class JiraServiceTest extends TestCase
'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);
$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)[
'customfield_10020' => [
'com.atlassian.greenhopper.service.sprint.Sprint@xxx[name=十月中需求,state=ACTIVE]'
]
]
$issue = (object) [
'fields' => (object) [
'customFields' => [
'customfield_10004' => [
'com.atlassian.greenhopper.service.sprint.Sprint@xxx[name=十月中需求,state=ACTIVE]',
],
],
],
];
$result = $method->invoke($this->jiraService, $issue);
@@ -157,10 +200,10 @@ class JiraServiceTest extends TestCase
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractBugStage');
$issue = (object)[
'fields' => (object)[
'labels' => ['SIT', 'bug']
]
$issue = (object) [
'fields' => (object) [
'labels' => ['SIT', 'bug'],
],
];
$result = $method->invoke($this->jiraService, $issue);
@@ -172,13 +215,116 @@ class JiraServiceTest extends TestCase
$reflection = new \ReflectionClass($this->jiraService);
$method = $reflection->getMethod('extractBugType');
$issue = (object)[
'fields' => (object)[
'labels' => ['需求未说明', 'bug']
]
$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']);
}
}