|
|
|
|
@@ -27,7 +27,7 @@ import (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestServeExposesHealthz(t *testing.T) {
|
|
|
|
|
server := NewServer("127.0.0.1:0", NewAPIHandler("admin-token", ActionSet{}), nil)
|
|
|
|
|
server := NewServer("127.0.0.1:0", NewAPIHandler("admin-token", ActionSet{}, ""), nil)
|
|
|
|
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("net.Listen() error = %v", err)
|
|
|
|
|
@@ -66,7 +66,7 @@ func TestRunReturnsAfterContextCancellation(t *testing.T) {
|
|
|
|
|
t.Fatalf("net.Listen() error = %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
server := NewServer("127.0.0.1:0", NewAPIHandler("admin-token", ActionSet{}), func(string, string) (net.Listener, error) {
|
|
|
|
|
server := NewServer("127.0.0.1:0", NewAPIHandler("admin-token", ActionSet{}, ""), func(string, string) (net.Listener, error) {
|
|
|
|
|
return listener, nil
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
@@ -93,7 +93,7 @@ func TestRunReturnsAfterContextCancellation(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
func TestRunReturnsListenError(t *testing.T) {
|
|
|
|
|
wantErr := errors.New("listen failed")
|
|
|
|
|
server := NewServer("127.0.0.1:0", NewAPIHandler("admin-token", ActionSet{}), func(string, string) (net.Listener, error) {
|
|
|
|
|
server := NewServer("127.0.0.1:0", NewAPIHandler("admin-token", ActionSet{}, ""), func(string, string) (net.Listener, error) {
|
|
|
|
|
return nil, wantErr
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
@@ -104,7 +104,7 @@ func TestRunReturnsListenError(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestServeReturnsListenerError(t *testing.T) {
|
|
|
|
|
server := NewServer("127.0.0.1:0", NewAPIHandler("admin-token", ActionSet{}), nil)
|
|
|
|
|
server := NewServer("127.0.0.1:0", NewAPIHandler("admin-token", ActionSet{}, ""), nil)
|
|
|
|
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("net.Listen() error = %v", err)
|
|
|
|
|
@@ -121,7 +121,7 @@ func TestServeReturnsListenerError(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAPIRejectsMissingAdminToken(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("secret-token", ActionSet{})
|
|
|
|
|
handler := NewAPIHandler("secret-token", ActionSet{}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/packs/install", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/pack.zip"}, "")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusUnauthorized)
|
|
|
|
|
@@ -141,7 +141,7 @@ func TestAPIAdminSessionLoginSetsCookieAndAuthorizesSubsequentRequest(t *testing
|
|
|
|
|
ListPacks: func(context.Context) ([]PackInfo, error) {
|
|
|
|
|
return []PackInfo{{PackID: "openai-cn-pack", Version: "1.1.6"}}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
|
|
|
|
|
loginRequest := httptestRequest(t, http.MethodPost, "/api/admin/session/login", map[string]any{
|
|
|
|
|
"username": "admin",
|
|
|
|
|
@@ -177,7 +177,7 @@ func TestAPIAdminSessionRejectsInvalidPassword(t *testing.T) {
|
|
|
|
|
Token: "secret-token",
|
|
|
|
|
Username: "admin",
|
|
|
|
|
Password: "pass-123",
|
|
|
|
|
}, ActionSet{})
|
|
|
|
|
}, ActionSet{}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/admin/session/login", map[string]any{
|
|
|
|
|
"username": "admin",
|
|
|
|
|
"password": "wrong",
|
|
|
|
|
@@ -192,7 +192,7 @@ func TestAPIAdminSessionLogoutClearsCookie(t *testing.T) {
|
|
|
|
|
Token: "secret-token",
|
|
|
|
|
Username: "admin",
|
|
|
|
|
Password: "pass-123",
|
|
|
|
|
}, ActionSet{})
|
|
|
|
|
}, ActionSet{}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/admin/session/logout", nil, "")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusNoContent)
|
|
|
|
|
@@ -219,7 +219,7 @@ func TestAPIAdminSessionMeReportsAuthenticationState(t *testing.T) {
|
|
|
|
|
Now: func() time.Time {
|
|
|
|
|
return now
|
|
|
|
|
},
|
|
|
|
|
}, ActionSet{})
|
|
|
|
|
}, ActionSet{}, "")
|
|
|
|
|
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/admin/session", nil, "")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
@@ -253,7 +253,7 @@ func TestAPIInstallPackReturnsSummary(t *testing.T) {
|
|
|
|
|
Providers: []sqlite.Provider{{ProviderID: "deepseek", DisplayName: "DeepSeek"}},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/packs/install", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/openai-pack.zip"}, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -275,7 +275,7 @@ func TestAPIPreviewProviderReturnsSummary(t *testing.T) {
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/providers/deepseek/preview-import", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/openai-pack.zip", "keys": []string{"k1", "k2"}, "mode": "partial"}, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -301,7 +301,7 @@ func TestAPICreateProviderDraftReturnsCreated(t *testing.T) {
|
|
|
|
|
Manifest: map[string]any{"provider_id": req.ProviderID},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/provider-drafts", map[string]any{
|
|
|
|
|
"pack_id": "openai-cn-pack",
|
|
|
|
|
"provider_id": "openai-zhongzhuan",
|
|
|
|
|
@@ -332,7 +332,7 @@ func TestAPIListProviderDraftsReturnsCollection(t *testing.T) {
|
|
|
|
|
SourceHostID: "remote43-current-host",
|
|
|
|
|
}}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/provider-drafts?pack_id=openai-cn-pack", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -369,7 +369,7 @@ func TestAPIGetProviderDraftReturnsItem(t *testing.T) {
|
|
|
|
|
SourceHostID: "remote43-current-host",
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/provider-drafts/draft_001", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -393,7 +393,7 @@ func TestAPIUpdateProviderDraftReturnsUpdatedItem(t *testing.T) {
|
|
|
|
|
SourceHostID: req.SourceHostID,
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPut, "/api/provider-drafts/draft_001", map[string]any{
|
|
|
|
|
"pack_id": "openai-cn-pack",
|
|
|
|
|
"provider_id": "openai-zhongzhuan",
|
|
|
|
|
@@ -414,7 +414,7 @@ func TestAPIDeleteProviderDraftReturnsNoContent(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodDelete, "/api/provider-drafts/draft_001", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusNoContent)
|
|
|
|
|
@@ -439,7 +439,7 @@ func TestAPIPublishProviderDraftReturnsSummary(t *testing.T) {
|
|
|
|
|
RepoRoot: "/srv/sub2api-cn-relay-manager",
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/provider-drafts/draft_001/publish", map[string]any{
|
|
|
|
|
"commit_message": "feat(pack): publish provider draft openai-zhongzhuan",
|
|
|
|
|
}, "secret-token")
|
|
|
|
|
@@ -463,7 +463,7 @@ func TestAPIImportProviderReturnsConflictWithBatchStatus(t *testing.T) {
|
|
|
|
|
},
|
|
|
|
|
}, errors.New("strict import failed")
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/providers/deepseek/import", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/openai-pack.zip", "keys": []string{"k1"}, "mode": "strict", "access_mode": "self_service", "access_api_key": "user-key"}, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusConflict)
|
|
|
|
|
@@ -479,7 +479,7 @@ func TestAPIBatchDetailReturnsSummary(t *testing.T) {
|
|
|
|
|
Items: []sqlite.ImportBatchItem{{ID: 1, KeyFingerprint: "sha256:abc", AccountStatus: "passed"}},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/import-batches/7", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -510,7 +510,7 @@ func TestAPIProviderStatusReturnsSummary(t *testing.T) {
|
|
|
|
|
ReconcileRuns: []sqlite.ReconcileRun{{}},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/providers/deepseek/status?pack_id=openai-cn-pack", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -534,7 +534,7 @@ func TestAPIProviderAccessStatusReturnsSummary(t *testing.T) {
|
|
|
|
|
AccessClosures: []sqlite.AccessClosureRecord{{ID: 2, ClosureType: provision.AccessModeSelfService, Status: provision.AccessStatusSelfServiceReady, DetailsJSON: `{"ok":true}`}},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/providers/deepseek/access/status", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -561,7 +561,7 @@ func TestAPIListPackProvidersReturnsProviderMetadata(t *testing.T) {
|
|
|
|
|
SupportedModels: []string{"deepseek-chat", "deepseek-reasoner"},
|
|
|
|
|
}}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/packs/openai-cn-pack/providers", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -605,7 +605,7 @@ func TestAPIProviderResourcesReturnsSummary(t *testing.T) {
|
|
|
|
|
ReconcileRuns: []sqlite.ReconcileRun{{ID: 3, Status: "active", SummaryJSON: `{"missing_count":0}`}},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/providers/deepseek/resources", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -627,7 +627,7 @@ func TestAPIRollbackProviderReturnsSummary(t *testing.T) {
|
|
|
|
|
RollbackProvider: func(context.Context, RollbackProviderRequest) (provision.RollbackReport, error) {
|
|
|
|
|
return provision.RollbackReport{AccountsDeleted: 2, PlansDeleted: 1, ChannelsDeleted: 1, GroupsDeleted: 1}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/providers/deepseek/rollback", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/openai-pack.zip"}, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -643,7 +643,7 @@ func TestAPIReconcileProviderReturnsSummary(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
return reconcile.Result{BatchID: 7, Status: "drifted", MissingCount: 1, ExtraCount: 2, StaleNoiseCount: 3, ProbeFailureCount: 1, AccessStatus: provision.AccessStatusBroken, Summary: map[string]any{"probe_failures": 1, "stale_noise_count": 3}}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/providers/deepseek/reconcile", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/openai-pack.zip", "access_api_key": "user-key"}, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusOK)
|
|
|
|
|
@@ -925,7 +925,7 @@ func TestFindProvider(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAPIRequiresConfiguredAdminToken(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("", ActionSet{})
|
|
|
|
|
handler := NewAPIHandler("", ActionSet{}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/packs/install", map[string]any{"host_base_url": "https://sub2api.example.com"}, "any-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusInternalServerError)
|
|
|
|
|
@@ -936,7 +936,7 @@ func TestAPIBatchDetailRejectsInvalidBatchID(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("secret-token", ActionSet{BatchDetail: func(context.Context, BatchDetailRequest) (provision.BatchDetailResult, error) {
|
|
|
|
|
t.Fatal("BatchDetail should not be called for invalid batch id")
|
|
|
|
|
return provision.BatchDetailResult{}, nil
|
|
|
|
|
}})
|
|
|
|
|
}}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodGet, "/api/import-batches/not-a-number", nil, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusBadRequest)
|
|
|
|
|
@@ -948,7 +948,7 @@ func TestAPIInstallPackRejectsInvalidJSON(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("secret-token", ActionSet{InstallPack: func(context.Context, InstallPackRequest) (provision.PackInstallResult, error) {
|
|
|
|
|
t.Fatal("InstallPack should not be called for invalid JSON")
|
|
|
|
|
return provision.PackInstallResult{}, nil
|
|
|
|
|
}})
|
|
|
|
|
}}, "")
|
|
|
|
|
request, err := http.NewRequest(http.MethodPost, "/api/packs/install", strings.NewReader(`{"host_base_url":"https://sub2api.example.com","unknown":true}`))
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("http.NewRequest() error = %v", err)
|
|
|
|
|
@@ -965,7 +965,7 @@ func TestAPIImportProviderReturnsClassifiedErrorWithoutBatch(t *testing.T) {
|
|
|
|
|
ImportProvider: func(context.Context, ImportProviderRequest) (provision.RuntimeImportResult, error) {
|
|
|
|
|
return provision.RuntimeImportResult{}, errors.New("pack path is required")
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/providers/deepseek/import", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/openai-pack.zip"}, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusBadRequest)
|
|
|
|
|
@@ -978,7 +978,7 @@ func TestAPIPreviewProviderReturnsUpstreamError(t *testing.T) {
|
|
|
|
|
PreviewProvider: func(context.Context, PreviewProviderRequest) (provision.PreviewReport, error) {
|
|
|
|
|
return provision.PreviewReport{}, &sub2api.HTTPError{Method: http.MethodPost, Path: "/preview", StatusCode: http.StatusTooManyRequests, Body: "rate limited"}
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/providers/deepseek/preview-import", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/openai-pack.zip"}, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusBadGateway)
|
|
|
|
|
@@ -991,7 +991,7 @@ func TestAPIRollbackProviderReturnsConfiguredError(t *testing.T) {
|
|
|
|
|
RollbackProvider: func(context.Context, RollbackProviderRequest) (provision.RollbackReport, error) {
|
|
|
|
|
return provision.RollbackReport{}, &httpError{StatusCode: http.StatusGone, Code: "rolled_back", Message: "already removed"}
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
request := httptestRequest(t, http.MethodPost, "/api/providers/deepseek/rollback", map[string]any{"host_base_url": "https://sub2api.example.com", "pack_path": "/tmp/openai-pack.zip"}, "secret-token")
|
|
|
|
|
response := httptestRecorder(handler, request)
|
|
|
|
|
assertStatusCode(t, response, http.StatusGone)
|
|
|
|
|
@@ -1002,7 +1002,7 @@ func TestAPIReconcileProviderRejectsTrailingNonObjectPayload(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("secret-token", ActionSet{ReconcileProvider: func(context.Context, ReconcileProviderRequest) (reconcile.Result, error) {
|
|
|
|
|
t.Fatal("ReconcileProvider should not be called for invalid JSON")
|
|
|
|
|
return reconcile.Result{}, nil
|
|
|
|
|
}})
|
|
|
|
|
}}, "")
|
|
|
|
|
request, err := http.NewRequest(http.MethodPost, "/api/providers/deepseek/reconcile", strings.NewReader(`{"host_base_url":"https://sub2api.example.com"}[]`))
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("http.NewRequest() error = %v", err)
|
|
|
|
|
@@ -1024,7 +1024,7 @@ func TestHTTPErrorError(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestProviderStatusFnNil(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{})
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{}, "")
|
|
|
|
|
req := httptestRequest(t, http.MethodGet, "/api/providers/x/status", nil, "t")
|
|
|
|
|
res := httptestRecorder(handler, req)
|
|
|
|
|
assertStatusCode(t, res, http.StatusInternalServerError)
|
|
|
|
|
@@ -1032,7 +1032,7 @@ func TestProviderStatusFnNil(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestProviderAccessStatusFnNil(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{})
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{}, "")
|
|
|
|
|
req := httptestRequest(t, http.MethodGet, "/api/providers/x/access/status", nil, "t")
|
|
|
|
|
res := httptestRecorder(handler, req)
|
|
|
|
|
assertStatusCode(t, res, http.StatusInternalServerError)
|
|
|
|
|
@@ -1040,7 +1040,7 @@ func TestProviderAccessStatusFnNil(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestProviderResourcesFnNil(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{})
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{}, "")
|
|
|
|
|
req := httptestRequest(t, http.MethodGet, "/api/providers/x/resources", nil, "t")
|
|
|
|
|
res := httptestRecorder(handler, req)
|
|
|
|
|
assertStatusCode(t, res, http.StatusInternalServerError)
|
|
|
|
|
@@ -1052,7 +1052,7 @@ func TestProviderStatusReturnsError(t *testing.T) {
|
|
|
|
|
GetProviderStatus: func(context.Context, ProviderQueryRequest) (provision.ProviderSnapshot, error) {
|
|
|
|
|
return provision.ProviderSnapshot{}, errors.New(`provider "x" not found in pack "p"`)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
req := httptestRequest(t, http.MethodGet, "/api/providers/x/status", nil, "t")
|
|
|
|
|
res := httptestRecorder(handler, req)
|
|
|
|
|
assertStatusCode(t, res, http.StatusBadRequest)
|
|
|
|
|
@@ -1074,7 +1074,7 @@ func TestPostHandlersFnNil(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{})
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{}, "")
|
|
|
|
|
req, _ := http.NewRequest(tt.method, tt.path, strings.NewReader(tt.body))
|
|
|
|
|
req.Header.Set("Authorization", "Bearer t")
|
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
@@ -1095,7 +1095,7 @@ func TestGetHandlersFnNil(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{})
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{}, "")
|
|
|
|
|
req, _ := http.NewRequest(http.MethodGet, tt.path, nil)
|
|
|
|
|
req.Header.Set("Authorization", "Bearer t")
|
|
|
|
|
res := httptestRecorder(handler, req)
|
|
|
|
|
@@ -1114,7 +1114,7 @@ func TestDeleteHandlersFnNil(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{})
|
|
|
|
|
handler := NewAPIHandler("t", ActionSet{}, "")
|
|
|
|
|
req, _ := http.NewRequest(http.MethodDelete, tt.path, nil)
|
|
|
|
|
req.Header.Set("Authorization", "Bearer t")
|
|
|
|
|
res := httptestRecorder(handler, req)
|
|
|
|
|
@@ -1248,7 +1248,7 @@ func TestHandlerErrorPaths(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
handler := NewAPIHandler("t", tt.actionSet)
|
|
|
|
|
handler := NewAPIHandler("t", tt.actionSet, "")
|
|
|
|
|
var req *http.Request
|
|
|
|
|
if tt.body != "" {
|
|
|
|
|
req, _ = http.NewRequest(tt.method, tt.path, strings.NewReader(tt.body))
|
|
|
|
|
@@ -1323,7 +1323,7 @@ func TestProviderAccessStatusMultipleClosures(t *testing.T) {
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
req := httptestRequest(t, http.MethodGet, "/api/providers/dp/access/status", nil, "t")
|
|
|
|
|
res := httptestRecorder(handler, req)
|
|
|
|
|
assertStatusCode(t, res, http.StatusOK)
|
|
|
|
|
@@ -1549,7 +1549,7 @@ func TestAPIProbeHostReturnsHostSnapshot(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
return HostInfo{HostID: req.HostID, BaseURL: "https://sub2api.example.com", HostVersion: "0.1.126", Status: "supported"}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
req := httptestRequest(t, http.MethodPost, "/api/hosts/prod-sub2api/probe", map[string]any{
|
|
|
|
|
"auth": map[string]any{"type": "bearer", "token": "probe-token"},
|
|
|
|
|
}, "secret-token")
|
|
|
|
|
@@ -1568,7 +1568,7 @@ func TestAPIListProviderImportBatchesReturnsItems(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
return []ImportBatchInfo{{BatchID: 7, BatchStatus: provision.BatchStatusSucceeded, AccessStatus: provision.AccessStatusSelfServiceReady}}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
req := httptestRequest(t, http.MethodGet, "/api/providers/deepseek/import-batches", nil, "secret-token")
|
|
|
|
|
res := httptestRecorder(handler, req)
|
|
|
|
|
assertStatusCode(t, res, http.StatusOK)
|
|
|
|
|
@@ -1589,7 +1589,7 @@ func TestAPIRollbackBatchReturnsSummary(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
return provision.RollbackReport{AccountsDeleted: 2, PlansDeleted: 1, ChannelsDeleted: 1, GroupsDeleted: 1}, nil
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}, "")
|
|
|
|
|
req := httptestRequest(t, http.MethodPost, "/api/import-batches/11/rollback", map[string]any{
|
|
|
|
|
"auth": map[string]any{"type": "apikey", "token": "admin-key"},
|
|
|
|
|
}, "secret-token")
|
|
|
|
|
|