forked from chroe/gitlink-cli
159 lines
4.3 KiB
Go
159 lines
4.3 KiB
Go
package rules
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/gitlink-org/gitlink-cli/shortcuts/workflow"
|
|
)
|
|
|
|
func TestTriageRuleClassifiesByKeyword(t *testing.T) {
|
|
upstream := map[string]interface{}{
|
|
"open-issues": map[string]interface{}{
|
|
"data": []interface{}{
|
|
map[string]interface{}{"project_issues_index": "1", "title": "fix crash on startup", "body": "应用启动时崩溃"},
|
|
map[string]interface{}{"project_issues_index": "2", "title": "新增导出功能", "body": ""},
|
|
map[string]interface{}{"project_issues_index": "3", "title": "如何配置SSO", "body": "请问怎么配"},
|
|
},
|
|
},
|
|
"labels": map[string]interface{}{
|
|
"data": []interface{}{
|
|
map[string]interface{}{"id": 1, "name": "bug"},
|
|
map[string]interface{}{"id": 2, "name": "enhancement"},
|
|
map[string]interface{}{"id": 3, "name": "question"},
|
|
},
|
|
},
|
|
"members": map[string]interface{}{
|
|
"data": []interface{}{
|
|
map[string]interface{}{"login": "dev1", "name": "Dev One"},
|
|
},
|
|
},
|
|
}
|
|
|
|
resp, err := TriageRule(upstream, "triage")
|
|
if err != nil {
|
|
t.Fatalf("TriageRule failed: %v", err)
|
|
}
|
|
if resp.Analysis == nil {
|
|
t.Fatal("expected non-nil Analysis")
|
|
}
|
|
|
|
analysis, ok := resp.Analysis.(map[string]interface{})
|
|
if !ok {
|
|
t.Fatal("Analysis is not a map")
|
|
}
|
|
if v := analysis["classified"]; v.(int) != 3 {
|
|
t.Fatalf("expected 3 classified, got %v", v)
|
|
}
|
|
if len(resp.Actions) == 0 {
|
|
t.Fatal("expected actions for issue triage")
|
|
}
|
|
|
|
// Verify each action type.
|
|
for _, a := range resp.Actions {
|
|
if a.Type == "api" && a.Method != "PATCH" {
|
|
t.Errorf("unexpected API method: %s", a.Method)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTriageRuleEmptyIssues(t *testing.T) {
|
|
upstream := map[string]interface{}{
|
|
"open-issues": map[string]interface{}{"data": []interface{}{}},
|
|
"labels": map[string]interface{}{"data": []interface{}{}},
|
|
"members": map[string]interface{}{"data": []interface{}{}},
|
|
}
|
|
resp, err := TriageRule(upstream, "triage")
|
|
if err != nil {
|
|
t.Fatalf("TriageRule failed: %v", err)
|
|
}
|
|
if len(resp.Actions) != 0 {
|
|
t.Fatalf("expected 0 actions for empty issues, got %d", len(resp.Actions))
|
|
}
|
|
analysis := resp.Analysis.(map[string]interface{})
|
|
if v := analysis["classified"]; v.(int) != 0 {
|
|
t.Fatalf("expected 0 classified, got %v", v)
|
|
}
|
|
}
|
|
|
|
func TestTriageRuleGoodFirstIssue(t *testing.T) {
|
|
upstream := map[string]interface{}{
|
|
"open-issues": map[string]interface{}{
|
|
"data": []interface{}{
|
|
map[string]interface{}{"project_issues_index": "10", "title": "good first issue: add docs", "body": "easy task for beginners"},
|
|
},
|
|
},
|
|
"labels": map[string]interface{}{
|
|
"data": []interface{}{
|
|
map[string]interface{}{"id": 1, "name": "docs"},
|
|
},
|
|
},
|
|
"members": map[string]interface{}{
|
|
"data": []interface{}{
|
|
map[string]interface{}{"login": "dev1", "name": "Dev"},
|
|
},
|
|
},
|
|
}
|
|
|
|
resp, err := TriageRule(upstream, "triage")
|
|
if err != nil {
|
|
t.Fatalf("TriageRule failed: %v", err)
|
|
}
|
|
hasComment := false
|
|
for _, a := range resp.Actions {
|
|
if a.Type == "cli" && a.Module == "issue" && a.Command == "+comment" {
|
|
hasComment = true
|
|
break
|
|
}
|
|
}
|
|
if !hasComment {
|
|
t.Fatal("expected a cli comment action for good first issue")
|
|
}
|
|
}
|
|
|
|
func TestTriageRulePriority(t *testing.T) {
|
|
cases := []struct {
|
|
title string
|
|
expected int
|
|
}{
|
|
{"紧急: 安全漏洞", 4},
|
|
{"重要功能", 3},
|
|
{"普通建议", 2},
|
|
{"低优先级改进", 1},
|
|
}
|
|
for _, tc := range cases {
|
|
upstream := map[string]interface{}{
|
|
"open-issues": map[string]interface{}{
|
|
"data": []interface{}{
|
|
map[string]interface{}{"project_issues_index": "1", "title": tc.title, "body": ""},
|
|
},
|
|
},
|
|
"labels": map[string]interface{}{"data": []interface{}{}},
|
|
"members": map[string]interface{}{"data": []interface{}{}},
|
|
}
|
|
resp, err := TriageRule(upstream, "triage")
|
|
if err != nil {
|
|
t.Fatalf("TriageRule failed for %q: %v", tc.title, err)
|
|
}
|
|
if len(resp.Actions) > 0 {
|
|
body := resp.Actions[0].Body
|
|
if v, ok := body["priority_id"]; ok {
|
|
if v.(int) != tc.expected {
|
|
t.Errorf("title=%q: priority_id=%v, want %d", tc.title, v, tc.expected)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTriageRuleOutputFormat(t *testing.T) {
|
|
resp, err := TriageRule(map[string]interface{}{}, "triage")
|
|
if err != nil {
|
|
t.Fatalf("TriageRule failed: %v", err)
|
|
}
|
|
if resp == nil {
|
|
t.Fatal("expected non-nil response")
|
|
}
|
|
// Verify it's a valid workflow.AIResponse.
|
|
var _ *workflow.AIResponse = resp
|
|
}
|