159 lines
5.7 KiB
Go
159 lines
5.7 KiB
Go
package workflow
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestAnalyzeIssueDetectsSecurityP0(t *testing.T) {
|
|
result := AnalyzeIssue(IssueInput{
|
|
Title: "Token leaked in command output",
|
|
Body: "A secret token leaked and may allow permission escalation.",
|
|
Labels: []string{"security"},
|
|
}, "en")
|
|
|
|
if result.DetectedType != IssueTypeSecurity {
|
|
t.Fatalf("DetectedType = %q, want %q", result.DetectedType, IssueTypeSecurity)
|
|
}
|
|
if result.Priority != PriorityP0 {
|
|
t.Fatalf("Priority = %q, want %q", result.Priority, PriorityP0)
|
|
}
|
|
if !containsString(result.RiskFlags, RiskPossibleSecretLeak) && !containsString(result.RiskFlags, RiskSecuritySensitive) {
|
|
t.Fatalf("RiskFlags = %v, want security or secret leak flag", result.RiskFlags)
|
|
}
|
|
if result.Confidence < 70 {
|
|
t.Fatalf("Confidence = %d, want >= 70", result.Confidence)
|
|
}
|
|
}
|
|
|
|
func TestAnalyzeIssueDetectsBugAndMissingInfo(t *testing.T) {
|
|
result := AnalyzeIssue(IssueInput{
|
|
Title: "CLI crash with error",
|
|
Body: "It crashes.",
|
|
}, "en")
|
|
|
|
if result.DetectedType != IssueTypeBug {
|
|
t.Fatalf("DetectedType = %q, want %q", result.DetectedType, IssueTypeBug)
|
|
}
|
|
if result.Priority != PriorityP1 && result.Priority != PriorityP2 {
|
|
t.Fatalf("Priority = %q, want P1 or P2", result.Priority)
|
|
}
|
|
if len(result.MissingInformation) == 0 {
|
|
t.Fatal("MissingInformation is empty, want bug info requirements")
|
|
}
|
|
if !containsString(result.RiskFlags, RiskInsufficientInfo) {
|
|
t.Fatalf("RiskFlags = %v, want %q", result.RiskFlags, RiskInsufficientInfo)
|
|
}
|
|
}
|
|
|
|
func TestAnalyzeIssueDetectsDocs(t *testing.T) {
|
|
result := AnalyzeIssue(IssueInput{
|
|
Title: "README typo in documentation example",
|
|
Body: "The docs guide has a typo.",
|
|
}, "en")
|
|
|
|
if result.DetectedType != IssueTypeDocs {
|
|
t.Fatalf("DetectedType = %q, want %q", result.DetectedType, IssueTypeDocs)
|
|
}
|
|
if result.Priority != PriorityP3 {
|
|
t.Fatalf("Priority = %q, want %q", result.Priority, PriorityP3)
|
|
}
|
|
if result.RecommendedAction != ActionUpdateDocs {
|
|
t.Fatalf("RecommendedAction = %q, want %q", result.RecommendedAction, ActionUpdateDocs)
|
|
}
|
|
}
|
|
|
|
func TestAnalyzeIssueChinese(t *testing.T) {
|
|
result := AnalyzeIssue(IssueInput{
|
|
Title: "安装失败并且报错,无法登录",
|
|
Body: "执行登录命令后失败。",
|
|
}, "zh-CN")
|
|
|
|
if result.DetectedType != IssueTypeBug {
|
|
t.Fatalf("DetectedType = %q, want %q", result.DetectedType, IssueTypeBug)
|
|
}
|
|
if result.Priority != PriorityP1 {
|
|
t.Fatalf("Priority = %q, want %q", result.Priority, PriorityP1)
|
|
}
|
|
if result.SuggestedComment == "" {
|
|
t.Fatal("SuggestedComment is empty")
|
|
}
|
|
}
|
|
|
|
func TestAnalyzeIssueUnknownLowConfidence(t *testing.T) {
|
|
result := AnalyzeIssue(IssueInput{
|
|
Title: "General repository note",
|
|
Body: "This is a neutral note without clear maintenance signal.",
|
|
}, "en")
|
|
|
|
if result.DetectedType != IssueTypeUnknown {
|
|
t.Fatalf("DetectedType = %q, want %q", result.DetectedType, IssueTypeUnknown)
|
|
}
|
|
if result.Confidence > 40 {
|
|
t.Fatalf("Confidence = %d, want <= 40", result.Confidence)
|
|
}
|
|
}
|
|
|
|
func TestDeterminePriority(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
text string
|
|
detectedType string
|
|
wantPriority string
|
|
}{
|
|
{"security type", "something", IssueTypeSecurity, PriorityP0},
|
|
{"token leak in text", "token leak found", IssueTypeBug, PriorityP0},
|
|
{"secret leak", "a secret leak happened", IssueTypeBug, PriorityP0},
|
|
{"vulnerability", "vulnerability in parse", IssueTypeBug, PriorityP0},
|
|
{"chinese auth bypass", "认证绕过", IssueTypeBug, PriorityP0},
|
|
{"crash", "the cli crash on start", IssueTypeBug, PriorityP1},
|
|
{"panic", "panic at runtime", IssueTypeBug, PriorityP1},
|
|
{"install failed", "install failed on windows", IssueTypeBug, PriorityP1},
|
|
{"cannot login", "cannot login with token", IssueTypeBug, PriorityP1},
|
|
{"chinese install failed", "安装失败", IssueTypeBug, PriorityP1},
|
|
{"chinese login fail", "无法登录", IssueTypeBug, PriorityP1},
|
|
{"chinese crash", "崩溃", IssueTypeBug, PriorityP1},
|
|
{"bug type", "some text", IssueTypeBug, PriorityP2},
|
|
{"ci type", "ci failure", IssueTypeCI, PriorityP2},
|
|
{"performance", "slow response", IssueTypePerformance, PriorityP2},
|
|
{"feature", "new feature request", IssueTypeFeature, PriorityP2},
|
|
{"default", "random note", IssueTypeQuestion, PriorityP3},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, _ := determinePriority(tt.text, tt.detectedType)
|
|
if got != tt.wantPriority {
|
|
t.Fatalf("determinePriority = %q, want %q", got, tt.wantPriority)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRecommendedAction(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
detectedType string
|
|
priority string
|
|
riskFlags []string
|
|
missingInformation []string
|
|
want string
|
|
}{
|
|
{"security flag", IssueTypeBug, PriorityP2, []string{RiskSecuritySensitive}, nil, ActionReviewSecurity},
|
|
{"secret leak flag", IssueTypeBug, PriorityP2, []string{RiskPossibleSecretLeak}, nil, ActionReviewSecurity},
|
|
{"security type", IssueTypeSecurity, PriorityP2, nil, nil, ActionReviewSecurity},
|
|
{"p0 immediate", IssueTypeBug, PriorityP0, nil, nil, ActionPrioritizeImmediate},
|
|
{"request more info", IssueTypeBug, PriorityP1, nil, []string{"version"}, ActionRequestMoreInfo},
|
|
{"question convert", IssueTypeQuestion, PriorityP3, nil, nil, ActionConvertToDiscussion},
|
|
{"docs update", IssueTypeDocs, PriorityP3, nil, nil, ActionUpdateDocs},
|
|
{"ci investigate", IssueTypeCI, PriorityP2, nil, nil, ActionInvestigateCI},
|
|
{"default schedule fix", IssueTypeBug, PriorityP2, nil, nil, ActionScheduleFix},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := recommendedAction(tt.detectedType, tt.priority, tt.riskFlags, tt.missingInformation)
|
|
if got != tt.want {
|
|
t.Fatalf("recommendedAction = %q, want %q", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|