Files
gpt-plus-gpt/internal/task/membership_test.go
2026-03-15 20:48:19 +08:00

126 lines
3.6 KiB
Go

package task
import (
"testing"
"gpt-plus/internal/db"
"gpt-plus/pkg/chatgpt"
)
func TestFinalMembershipStateSatisfiedByTaskType(t *testing.T) {
state := &finalMembershipState{
Personal: &chatgpt.AccountInfo{
AccountID: "personal-1",
Structure: "personal",
PlanType: "plus",
HasActiveSubscription: true,
SubscriptionID: "sub_123",
},
Workspace: &chatgpt.AccountInfo{
AccountID: "workspace-1",
Structure: "workspace",
PlanType: "team",
},
}
if !state.satisfied(TaskTypePlus) {
t.Fatal("expected plus task to be satisfied")
}
if !state.satisfied(TaskTypeTeam) {
t.Fatal("expected team task to be satisfied")
}
if !state.satisfied(TaskTypeBoth) {
t.Fatal("expected both task to be satisfied")
}
if got := state.resultPlanForTask(TaskTypePlus); got != TaskTypePlus {
t.Fatalf("plus resultPlanForTask = %q, want %q", got, TaskTypePlus)
}
if got := state.resultPlanForTask(TaskTypeTeam); got != TaskTypeTeam {
t.Fatalf("team resultPlanForTask = %q, want %q", got, TaskTypeTeam)
}
if got := state.resultPlanForTask(TaskTypeBoth); got != TaskTypeBoth {
t.Fatalf("both resultPlanForTask = %q, want %q", got, TaskTypeBoth)
}
}
func TestFinalMembershipStateFallbackToActualPlan(t *testing.T) {
state := &finalMembershipState{
Personal: &chatgpt.AccountInfo{
AccountID: "personal-1",
Structure: "personal",
PlanType: "free",
},
}
if state.satisfied(TaskTypePlus) {
t.Fatal("free personal account should not satisfy plus task")
}
if got := state.resultPlanForTask(TaskTypePlus); got != "free" {
t.Fatalf("resultPlanForTask = %q, want free", got)
}
}
func TestAccountStatusForResult(t *testing.T) {
cases := []struct {
name string
result *chatgpt.AccountResult
want string
}{
{name: "nil", result: nil, want: "active"},
{name: "free", result: &chatgpt.AccountResult{PlanType: "free"}, want: "free"},
{name: "plus", result: &chatgpt.AccountResult{PlanType: "plus"}, want: "plus"},
{name: "team", result: &chatgpt.AccountResult{PlanType: "team"}, want: "team"},
{name: "unknown", result: &chatgpt.AccountResult{PlanType: "mystery"}, want: "active"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if got := accountStatusForResult(tc.result); got != tc.want {
t.Fatalf("accountStatusForResult() = %q, want %q", got, tc.want)
}
})
}
}
func TestSaveAccountToDBUsesRealMembershipStatus(t *testing.T) {
d := setupTaskTestDB(t)
runner := &TaskRunner{taskID: "task-1", gormDB: d}
runner.saveAccountToDB(&chatgpt.AccountResult{
Email: "free@test.com",
Password: "pw",
PlanType: "free",
}, "plus", nil, "task-1")
var acct db.Account
if err := d.First(&acct, "email = ?", "free@test.com").Error; err != nil {
t.Fatalf("load account: %v", err)
}
if acct.Plan != "plus" {
t.Fatalf("plan = %q, want plus", acct.Plan)
}
if acct.Status != "free" {
t.Fatalf("status = %q, want free", acct.Status)
}
}
func TestLogResultStoresUsefulMessage(t *testing.T) {
d := setupTaskTestDB(t)
taskRow := &db.Task{ID: "task-2", Type: "plus", Status: StatusRunning, TotalCount: 1}
if err := d.Create(taskRow).Error; err != nil {
t.Fatalf("create task: %v", err)
}
runner := &TaskRunner{taskID: "task-2", gormDB: d}
runner.logResult(taskRow, 1, "a@test.com", LogStatusFailed, "free", "final membership mismatch", 3)
var logRow db.TaskLog
if err := d.First(&logRow, "task_id = ?", "task-2").Error; err != nil {
t.Fatalf("load task log: %v", err)
}
if logRow.Message != "final membership mismatch" {
t.Fatalf("message = %q, want final membership mismatch", logRow.Message)
}
}