fix(provision): reconcile channel pricing and hosted access

This commit is contained in:
phamnazage-jpg
2026-05-20 22:09:40 +08:00
parent 83ee216a4d
commit ca1d448cc0
27 changed files with 1344 additions and 154 deletions

View File

@@ -22,14 +22,28 @@ func TestValidateRejectsMissingSubscriptionsForSubscriptionMode(t *testing.T) {
}
}
func TestValidateAllowsManagedSubscriptionProbeWithoutExplicitAPIKey(t *testing.T) {
err := Validate(ClosureRequest{
Mode: "subscription",
GroupID: "group-1",
ExpectedModel: "deepseek-chat",
Subscriptions: []SubscriptionTarget{{UserID: "crm-user-42", DurationDays: 30}},
})
if err != nil {
t.Fatalf("Validate() error = %v, want nil for managed subscription probe", err)
}
}
func TestServiceCloseAssignsSubscriptionsAndProbesGateway(t *testing.T) {
host := &fakeClosureHost{
gatewayResult: sub2api.GatewayAccessResult{OK: true, StatusCode: 200, HasExpectedModel: true, Models: []string{"deepseek-chat"}},
managedAccess: map[string]sub2api.SubscriptionAccessRef{
"user-1": {UserID: "host-user-1", APIKey: "managed-user-key"},
},
}
service := NewService(host)
result, err := service.Close(context.Background(), ClosureRequest{
Mode: "subscription",
ProbeAPIKey: "user-key",
GroupID: "group-1",
ExpectedModel: "deepseek-chat",
Subscriptions: []SubscriptionTarget{{UserID: "user-1", DurationDays: 30}},
@@ -40,7 +54,10 @@ func TestServiceCloseAssignsSubscriptionsAndProbesGateway(t *testing.T) {
if len(host.assigned) != 1 {
t.Fatalf("assigned subscriptions = %d, want 1", len(host.assigned))
}
if host.gatewayProbe.APIKey != "user-key" || host.gatewayProbe.ExpectedModel != "deepseek-chat" {
if host.assigned[0].UserID != "host-user-1" {
t.Fatalf("assigned subscription user = %q, want host-user-1", host.assigned[0].UserID)
}
if host.gatewayProbe.APIKey != "managed-user-key" || host.gatewayProbe.ExpectedModel != "deepseek-chat" {
t.Fatalf("gateway probe = %+v, want api key + expected model", host.gatewayProbe)
}
if !result.OK || !result.HasExpectedModel {
@@ -68,12 +85,20 @@ func TestServiceCloseReturnsSubscriptionErrorBeforeGatewayProbe(t *testing.T) {
type fakeClosureHost struct {
assigned []sub2api.AssignSubscriptionRequest
managedAccess map[string]sub2api.SubscriptionAccessRef
assignErr error
gatewayProbe sub2api.GatewayAccessCheckRequest
gatewayResult sub2api.GatewayAccessResult
gatewayErr error
}
func (f *fakeClosureHost) EnsureSubscriptionAccess(_ context.Context, req sub2api.EnsureSubscriptionAccessRequest) (sub2api.SubscriptionAccessRef, error) {
if ref, ok := f.managedAccess[req.UserSelector]; ok {
return ref, nil
}
return sub2api.SubscriptionAccessRef{}, errors.New("missing managed access")
}
func (f *fakeClosureHost) AssignSubscription(_ context.Context, req sub2api.AssignSubscriptionRequest) (sub2api.SubscriptionRef, error) {
if f.assignErr != nil {
return sub2api.SubscriptionRef{}, f.assignErr