Compare commits
2 Commits
b5529eb9d4
...
800096542b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
800096542b | ||
|
|
cbfaf4a28b |
@@ -1886,3 +1886,48 @@
|
|||||||
- 这轮已经把测试能力从“人工执行命令”提升到“统一脚本 + 覆盖率配置 + 非回归报告”
|
- 这轮已经把测试能力从“人工执行命令”提升到“统一脚本 + 覆盖率配置 + 非回归报告”
|
||||||
- 后续提测前的推荐入口应优先改为:
|
- 后续提测前的推荐入口应优先改为:
|
||||||
- `bash ./scripts/test/verify_quality_gates.sh`
|
- `bash ./scripts/test/verify_quality_gates.sh`
|
||||||
|
|
||||||
|
## 2026-05-30 已补齐 internal/app 无监听 handler 测试并抬过 70%
|
||||||
|
|
||||||
|
**目标**:优先补 `internal/app` 中不依赖本地监听端口的 handler 级测试,把 `watch` 包里最关键的 `internal/app` 稳定抬过 `70%`
|
||||||
|
|
||||||
|
**本次补测范围**:
|
||||||
|
|
||||||
|
- `internal/app/logical_groups_api_test.go`
|
||||||
|
- 新增覆盖:
|
||||||
|
- `GET /api/logical-groups`
|
||||||
|
- `PUT /api/logical-groups/{groupID}`
|
||||||
|
- `DELETE /api/logical-groups/{groupID}`
|
||||||
|
- `POST /api/logical-groups/{groupID}/models`
|
||||||
|
- `GET /api/logical-groups/{groupID}/models`
|
||||||
|
- `DELETE /api/logical-groups/{groupID}/models/{model}`
|
||||||
|
- `GET /api/logical-groups/{groupID}/routes`
|
||||||
|
- `PUT /api/logical-groups/{groupID}/routes/{routeID}`
|
||||||
|
- `DELETE /api/logical-groups/{groupID}/routes/{routeID}`
|
||||||
|
- `GET /api/logical-groups/{groupID}/routes/{routeID}/models`
|
||||||
|
- `internal/app/provider_accounts_api_test.go`
|
||||||
|
- 新增覆盖:
|
||||||
|
- `POST /api/provider-accounts/{accountID}/enable`
|
||||||
|
- `POST /api/provider-accounts/{accountID}/retire`
|
||||||
|
|
||||||
|
**本地验证结果**:
|
||||||
|
|
||||||
|
- `go test ./internal/app -count=1` => `ok`
|
||||||
|
- `go test -coverprofile=/tmp/internal-app.cover ./internal/app` => `coverage: 71.5% of statements`
|
||||||
|
- `gofmt -l .` => clean
|
||||||
|
- `go vet ./...` => `ok`
|
||||||
|
- `go test -cover ./internal/...` => `ok`
|
||||||
|
- `go test ./tests/integration/... -count=1` => `ok`
|
||||||
|
|
||||||
|
**覆盖率变化**:
|
||||||
|
|
||||||
|
- `internal/app`
|
||||||
|
- 本轮前:`69.9%`
|
||||||
|
- 本轮后:`71.5%`
|
||||||
|
- 由此 `internal/app` 已越过 `70%`,可作为后续把 `watch` 包逐步升级为 `core` 的第一批候选
|
||||||
|
|
||||||
|
**结论**:
|
||||||
|
|
||||||
|
- 这轮没有继续加新测试脚本,而是直接补最短路径的 handler 级测试缺口
|
||||||
|
- `internal/app` 已不再卡在 `70%` 以下
|
||||||
|
- 下一步测试治理可以开始从“抬单包覆盖率”转向“按包把 `watch` 升级为 `core`”
|
||||||
|
|||||||
@@ -114,6 +114,153 @@ func TestAPIGetLogicalGroupReturnsAggregatedItem(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPIListLogicalGroupsReturnsRows(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
ListLogicalGroups: func(_ context.Context) ([]LogicalGroupInfo, error) {
|
||||||
|
return []LogicalGroupInfo{{
|
||||||
|
LogicalGroupID: "gpt-shared",
|
||||||
|
DisplayName: "GPT Shared",
|
||||||
|
Status: "active",
|
||||||
|
UsageScenario: "适合统一 GPT 产品入口",
|
||||||
|
VisibilityScope: "login_required",
|
||||||
|
PackageTier: "pro",
|
||||||
|
PurchaseCTALabel: "升级到 Pro",
|
||||||
|
PurchaseCTAURL: "https://sub.tksea.top/portal/upgrade/pro",
|
||||||
|
}}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodGet, "/api/logical-groups", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusOK)
|
||||||
|
var payload struct {
|
||||||
|
LogicalGroups []LogicalGroupInfo `json:"logical_groups"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(response.Body().Bytes(), &payload); err != nil {
|
||||||
|
t.Fatalf("json.Unmarshal() error = %v", err)
|
||||||
|
}
|
||||||
|
if len(payload.LogicalGroups) != 1 || payload.LogicalGroups[0].LogicalGroupID != "gpt-shared" {
|
||||||
|
t.Fatalf("logical_groups = %+v, want one row gpt-shared", payload.LogicalGroups)
|
||||||
|
}
|
||||||
|
if payload.LogicalGroups[0].VisibilityScope != "login_required" {
|
||||||
|
t.Fatalf("logical_groups[0].visibility_scope = %q, want login_required", payload.LogicalGroups[0].VisibilityScope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIUpdateLogicalGroupUsesPathID(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
UpdateLogicalGroup: func(_ context.Context, req UpdateLogicalGroupRequest) (LogicalGroupInfo, error) {
|
||||||
|
if req.LogicalGroupID != "gpt-shared" {
|
||||||
|
t.Fatalf("LogicalGroupID = %q, want gpt-shared", req.LogicalGroupID)
|
||||||
|
}
|
||||||
|
if req.DisplayName != "GPT Shared Updated" || req.Status != "paused" {
|
||||||
|
t.Fatalf("request = %+v, want updated display name and status", req)
|
||||||
|
}
|
||||||
|
return LogicalGroupInfo{
|
||||||
|
LogicalGroupID: req.LogicalGroupID,
|
||||||
|
DisplayName: req.DisplayName,
|
||||||
|
Status: req.Status,
|
||||||
|
Recommendation: req.Recommendation,
|
||||||
|
VisibilityScope: req.VisibilityScope,
|
||||||
|
PackageTier: req.PackageTier,
|
||||||
|
PurchaseCTALabel: req.PurchaseCTALabel,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodPut, "/api/logical-groups/gpt-shared", map[string]any{
|
||||||
|
"display_name": "GPT Shared Updated",
|
||||||
|
"status": "paused",
|
||||||
|
"recommendation": "先验证高质量推理链路",
|
||||||
|
"visibility_scope": "entitled_only",
|
||||||
|
"package_tier": "enterprise",
|
||||||
|
"purchase_cta_label": "联系销售升级",
|
||||||
|
}, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusOK)
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "logical_group.logical_group_id", "gpt-shared")
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "logical_group.package_tier", "enterprise")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIDeleteLogicalGroupUsesPathID(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
DeleteLogicalGroup: func(_ context.Context, groupID string) error {
|
||||||
|
if groupID != "gpt-shared" {
|
||||||
|
t.Fatalf("groupID = %q, want gpt-shared", groupID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodDelete, "/api/logical-groups/gpt-shared", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPICreateLogicalGroupModelUsesPathGroupID(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
CreateLogicalGroupModel: func(_ context.Context, req CreateLogicalGroupModelRequest) (LogicalGroupModelInfo, error) {
|
||||||
|
if req.LogicalGroupID != "gpt-shared" {
|
||||||
|
t.Fatalf("LogicalGroupID = %q, want gpt-shared", req.LogicalGroupID)
|
||||||
|
}
|
||||||
|
if req.PublicModel != "gpt-5.4" || req.Status != "active" {
|
||||||
|
t.Fatalf("request = %+v, want public_model gpt-5.4 active", req)
|
||||||
|
}
|
||||||
|
return LogicalGroupModelInfo{
|
||||||
|
PublicModel: req.PublicModel,
|
||||||
|
Status: req.Status,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodPost, "/api/logical-groups/gpt-shared/models", map[string]any{
|
||||||
|
"public_model": "gpt-5.4",
|
||||||
|
"status": "active",
|
||||||
|
}, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusCreated)
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "logical_group_model.public_model", "gpt-5.4")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIListLogicalGroupModelsUsesPathGroupID(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
ListLogicalGroupModels: func(_ context.Context, groupID string) ([]LogicalGroupModelInfo, error) {
|
||||||
|
if groupID != "gpt-shared" {
|
||||||
|
t.Fatalf("groupID = %q, want gpt-shared", groupID)
|
||||||
|
}
|
||||||
|
return []LogicalGroupModelInfo{{PublicModel: "gpt-5.4", Status: "active"}}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodGet, "/api/logical-groups/gpt-shared/models", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusOK)
|
||||||
|
var payload struct {
|
||||||
|
Models []LogicalGroupModelInfo `json:"models"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(response.Body().Bytes(), &payload); err != nil {
|
||||||
|
t.Fatalf("json.Unmarshal() error = %v", err)
|
||||||
|
}
|
||||||
|
if len(payload.Models) != 1 || payload.Models[0].PublicModel != "gpt-5.4" {
|
||||||
|
t.Fatalf("models = %+v, want one row gpt-5.4", payload.Models)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIDeleteLogicalGroupModelUsesPathValues(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
DeleteLogicalGroupModel: func(_ context.Context, req DeleteLogicalGroupModelRequest) error {
|
||||||
|
if req.LogicalGroupID != "gpt-shared" || req.PublicModel != "gpt-5.4" {
|
||||||
|
t.Fatalf("request = %+v, want gpt-shared/gpt-5.4", req)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodDelete, "/api/logical-groups/gpt-shared/models/gpt-5.4", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPICreateLogicalGroupRouteUsesPathGroupID(t *testing.T) {
|
func TestAPICreateLogicalGroupRouteUsesPathGroupID(t *testing.T) {
|
||||||
handler := NewAPIHandler("secret-token", ActionSet{
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
CreateLogicalGroupRoute: func(_ context.Context, req CreateLogicalGroupRouteRequest) (LogicalGroupRouteInfo, error) {
|
CreateLogicalGroupRoute: func(_ context.Context, req CreateLogicalGroupRouteRequest) (LogicalGroupRouteInfo, error) {
|
||||||
@@ -143,6 +290,89 @@ func TestAPICreateLogicalGroupRouteUsesPathGroupID(t *testing.T) {
|
|||||||
assertJSONContains(t, response.Body().Bytes(), "route.route_id", "asxs")
|
assertJSONContains(t, response.Body().Bytes(), "route.route_id", "asxs")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPIListLogicalGroupRoutesUsesPathGroupID(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
ListLogicalGroupRoutes: func(_ context.Context, groupID string) ([]LogicalGroupRouteInfo, error) {
|
||||||
|
if groupID != "gpt-shared" {
|
||||||
|
t.Fatalf("groupID = %q, want gpt-shared", groupID)
|
||||||
|
}
|
||||||
|
return []LogicalGroupRouteInfo{{
|
||||||
|
RouteID: "asxs",
|
||||||
|
LogicalGroupID: groupID,
|
||||||
|
Name: "ASXS",
|
||||||
|
Status: "active",
|
||||||
|
ShadowGroupID: "gpt-shared__asxs",
|
||||||
|
ShadowHostID: "remote43",
|
||||||
|
}}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodGet, "/api/logical-groups/gpt-shared/routes", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusOK)
|
||||||
|
var payload struct {
|
||||||
|
Routes []LogicalGroupRouteInfo `json:"routes"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(response.Body().Bytes(), &payload); err != nil {
|
||||||
|
t.Fatalf("json.Unmarshal() error = %v", err)
|
||||||
|
}
|
||||||
|
if len(payload.Routes) != 1 || payload.Routes[0].RouteID != "asxs" {
|
||||||
|
t.Fatalf("routes = %+v, want one row asxs", payload.Routes)
|
||||||
|
}
|
||||||
|
if payload.Routes[0].ShadowHostID != "remote43" {
|
||||||
|
t.Fatalf("routes[0].shadow_host_id = %q, want remote43", payload.Routes[0].ShadowHostID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIUpdateLogicalGroupRouteUsesPathValues(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
UpdateLogicalGroupRoute: func(_ context.Context, req UpdateLogicalGroupRouteRequest) (LogicalGroupRouteInfo, error) {
|
||||||
|
if req.LogicalGroupID != "gpt-shared" || req.RouteID != "asxs" {
|
||||||
|
t.Fatalf("request = %+v, want gpt-shared/asxs", req)
|
||||||
|
}
|
||||||
|
if req.Priority != 20 || req.Status != "degraded" {
|
||||||
|
t.Fatalf("request = %+v, want priority 20 degraded", req)
|
||||||
|
}
|
||||||
|
return LogicalGroupRouteInfo{
|
||||||
|
RouteID: req.RouteID,
|
||||||
|
LogicalGroupID: req.LogicalGroupID,
|
||||||
|
Name: req.Name,
|
||||||
|
Status: req.Status,
|
||||||
|
Priority: req.Priority,
|
||||||
|
ShadowGroupID: req.ShadowGroupID,
|
||||||
|
ShadowHostID: req.ShadowHostID,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodPut, "/api/logical-groups/gpt-shared/routes/asxs", map[string]any{
|
||||||
|
"name": "ASXS Updated",
|
||||||
|
"status": "degraded",
|
||||||
|
"priority": 20,
|
||||||
|
"shadow_group_id": "gpt-shared__asxs",
|
||||||
|
"shadow_host_id": "remote43",
|
||||||
|
}, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusOK)
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "route.route_id", "asxs")
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "route.status", "degraded")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIDeleteLogicalGroupRouteUsesPathValues(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
DeleteLogicalGroupRoute: func(_ context.Context, req DeleteLogicalGroupRouteRequest) error {
|
||||||
|
if req.LogicalGroupID != "gpt-shared" || req.RouteID != "asxs" {
|
||||||
|
t.Fatalf("request = %+v, want gpt-shared/asxs", req)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodDelete, "/api/logical-groups/gpt-shared/routes/asxs", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPICreateLogicalGroupRouteModelUsesPathValues(t *testing.T) {
|
func TestAPICreateLogicalGroupRouteModelUsesPathValues(t *testing.T) {
|
||||||
handler := NewAPIHandler("secret-token", ActionSet{
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
CreateLogicalGroupRouteModel: func(_ context.Context, req CreateLogicalGroupRouteModelRequest) (LogicalGroupRouteModelInfo, error) {
|
CreateLogicalGroupRouteModel: func(_ context.Context, req CreateLogicalGroupRouteModelRequest) (LogicalGroupRouteModelInfo, error) {
|
||||||
@@ -170,6 +400,37 @@ func TestAPICreateLogicalGroupRouteModelUsesPathValues(t *testing.T) {
|
|||||||
assertJSONContains(t, response.Body().Bytes(), "route_model.public_model", "gpt-5.4")
|
assertJSONContains(t, response.Body().Bytes(), "route_model.public_model", "gpt-5.4")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPIListLogicalGroupRouteModelsUsesPathValues(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
ListLogicalGroupRouteModels: func(_ context.Context, req ListLogicalGroupRouteModelsRequest) ([]LogicalGroupRouteModelInfo, error) {
|
||||||
|
if req.LogicalGroupID != "gpt-shared" || req.RouteID != "asxs" {
|
||||||
|
t.Fatalf("request = %+v, want gpt-shared/asxs", req)
|
||||||
|
}
|
||||||
|
return []LogicalGroupRouteModelInfo{{
|
||||||
|
PublicModel: "gpt-5.4",
|
||||||
|
ShadowModel: "gpt-5.4",
|
||||||
|
Status: "active",
|
||||||
|
}}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, http.MethodGet, "/api/logical-groups/gpt-shared/routes/asxs/models", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, http.StatusOK)
|
||||||
|
var payload struct {
|
||||||
|
RouteModels []LogicalGroupRouteModelInfo `json:"route_models"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(response.Body().Bytes(), &payload); err != nil {
|
||||||
|
t.Fatalf("json.Unmarshal() error = %v", err)
|
||||||
|
}
|
||||||
|
if len(payload.RouteModels) != 1 || payload.RouteModels[0].PublicModel != "gpt-5.4" {
|
||||||
|
t.Fatalf("route_models = %+v, want one row gpt-5.4", payload.RouteModels)
|
||||||
|
}
|
||||||
|
if payload.RouteModels[0].ShadowModel != "gpt-5.4" {
|
||||||
|
t.Fatalf("route_models[0].shadow_model = %q, want gpt-5.4", payload.RouteModels[0].ShadowModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNewActionSetLogicalGroupCRUDFlow(t *testing.T) {
|
func TestNewActionSetLogicalGroupCRUDFlow(t *testing.T) {
|
||||||
dbPath := filepath.Join(t.TempDir(), "logical-groups.db")
|
dbPath := filepath.Join(t.TempDir(), "logical-groups.db")
|
||||||
dsn := "file:" + filepath.ToSlash(dbPath) + "?_busy_timeout=5000"
|
dsn := "file:" + filepath.ToSlash(dbPath) + "?_busy_timeout=5000"
|
||||||
|
|||||||
@@ -132,6 +132,46 @@ func TestAPIDisableProviderAccountUsesPathID(t *testing.T) {
|
|||||||
assertJSONContains(t, response.Body().Bytes(), "provider_account.account_status", "disabled")
|
assertJSONContains(t, response.Body().Bytes(), "provider_account.account_status", "disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPIEnableProviderAccountUsesPathID(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
EnableProviderAccount: func(_ context.Context, req UpdateProviderAccountStatusRequest) (ProviderAccountInfo, error) {
|
||||||
|
if req.AccountID != 42 {
|
||||||
|
t.Fatalf("AccountID = %d, want 42", req.AccountID)
|
||||||
|
}
|
||||||
|
if req.AccountStatus != sqlite.ProviderAccountStatusActive {
|
||||||
|
t.Fatalf("AccountStatus = %q, want active", req.AccountStatus)
|
||||||
|
}
|
||||||
|
return ProviderAccountInfo{ID: req.AccountID, AccountStatus: req.AccountStatus}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, "POST", "/api/provider-accounts/42/enable", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, 200)
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "provider_account.id", float64(42))
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "provider_account.account_status", sqlite.ProviderAccountStatusActive)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIRetireProviderAccountUsesPathID(t *testing.T) {
|
||||||
|
handler := NewAPIHandler("secret-token", ActionSet{
|
||||||
|
RetireProviderAccount: func(_ context.Context, req UpdateProviderAccountStatusRequest) (ProviderAccountInfo, error) {
|
||||||
|
if req.AccountID != 42 {
|
||||||
|
t.Fatalf("AccountID = %d, want 42", req.AccountID)
|
||||||
|
}
|
||||||
|
if req.AccountStatus != sqlite.ProviderAccountStatusDeprecated {
|
||||||
|
t.Fatalf("AccountStatus = %q, want deprecated", req.AccountStatus)
|
||||||
|
}
|
||||||
|
return ProviderAccountInfo{ID: req.AccountID, AccountStatus: req.AccountStatus}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request := httptestRequest(t, "POST", "/api/provider-accounts/42/retire", nil, "secret-token")
|
||||||
|
response := httptestRecorder(handler, request)
|
||||||
|
assertStatusCode(t, response, 200)
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "provider_account.id", float64(42))
|
||||||
|
assertJSONContains(t, response.Body().Bytes(), "provider_account.account_status", sqlite.ProviderAccountStatusDeprecated)
|
||||||
|
}
|
||||||
|
|
||||||
func TestNewActionSetProviderAccountListAndStatusFlow(t *testing.T) {
|
func TestNewActionSetProviderAccountListAndStatusFlow(t *testing.T) {
|
||||||
dbPath := filepath.Join(t.TempDir(), "provider-accounts.db")
|
dbPath := filepath.Join(t.TempDir(), "provider-accounts.db")
|
||||||
dsn := "file:" + filepath.ToSlash(dbPath) + "?_busy_timeout=5000"
|
dsn := "file:" + filepath.ToSlash(dbPath) + "?_busy_timeout=5000"
|
||||||
|
|||||||
Reference in New Issue
Block a user