fix(provision): reconcile channel pricing and hosted access
This commit is contained in:
@@ -152,7 +152,7 @@ func TestImportReusesExistingGroup(t *testing.T) {
|
||||
},
|
||||
gatewayResult: sub2api.GatewayAccessResult{OK: true, StatusCode: 200, HasExpectedModel: true, Models: []string{"deepseek-chat"}},
|
||||
managedSnapshot: sub2api.ManagedResourceSnapshot{
|
||||
Groups: []sub2api.NamedResource{{ID: "group_existing", Name: "DeepSeek 默认分组"}},
|
||||
Groups: []sub2api.NamedResource{{ID: "group_existing", Name: "DeepSeek 默认分组-self-service"}},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -198,8 +198,8 @@ func TestImportCreatesChannelWithManifestModelMapping(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Import() error = %v", err)
|
||||
}
|
||||
if host.createChannelReq.Name != "DeepSeek 默认渠道" {
|
||||
t.Fatalf("CreateChannel().Name = %q, want DeepSeek 默认渠道", host.createChannelReq.Name)
|
||||
if host.createChannelReq.Name != "DeepSeek 默认渠道-self-service" {
|
||||
t.Fatalf("CreateChannel().Name = %q, want DeepSeek 默认渠道-self-service", host.createChannelReq.Name)
|
||||
}
|
||||
if len(host.createChannelReq.GroupIDs) != 1 || host.createChannelReq.GroupIDs[0] != "group_1" {
|
||||
t.Fatalf("CreateChannel().GroupIDs = %v, want [group_1]", host.createChannelReq.GroupIDs)
|
||||
@@ -213,6 +213,31 @@ func TestImportCreatesChannelWithManifestModelMapping(t *testing.T) {
|
||||
if host.createChannelReq.BillingModelSource != "channel_mapped" {
|
||||
t.Fatalf("CreateChannel().BillingModelSource = %q, want channel_mapped", host.createChannelReq.BillingModelSource)
|
||||
}
|
||||
if len(host.createChannelReq.ModelPricing) != 1 {
|
||||
t.Fatalf("CreateChannel().ModelPricing len = %d, want 1", len(host.createChannelReq.ModelPricing))
|
||||
}
|
||||
if len(host.createChannelReq.ModelPricing[0].Models) != 2 {
|
||||
t.Fatalf("CreateChannel().ModelPricing[0].Models = %v, want default model coverage", host.createChannelReq.ModelPricing[0].Models)
|
||||
}
|
||||
if host.createChannelReq.ModelPricing[0].BillingMode != "token" {
|
||||
t.Fatalf("CreateChannel().ModelPricing[0].BillingMode = %q, want token", host.createChannelReq.ModelPricing[0].BillingMode)
|
||||
}
|
||||
if len(host.batchCreateReq.Accounts) != 1 {
|
||||
t.Fatalf("BatchCreateAccounts().Accounts len = %d, want 1", len(host.batchCreateReq.Accounts))
|
||||
}
|
||||
credentials := host.batchCreateReq.Accounts[0].Credentials
|
||||
switch rawMapping := credentials["model_mapping"].(type) {
|
||||
case map[string]string:
|
||||
if got := rawMapping["deepseek-chat"]; got != "deepseek-chat" {
|
||||
t.Fatalf("BatchCreateAccounts().Credentials.model_mapping = %+v, want deepseek-chat passthrough", rawMapping)
|
||||
}
|
||||
case map[string]any:
|
||||
if got, _ := rawMapping["deepseek-chat"].(string); got != "deepseek-chat" {
|
||||
t.Fatalf("BatchCreateAccounts().Credentials.model_mapping = %+v, want deepseek-chat passthrough", rawMapping)
|
||||
}
|
||||
default:
|
||||
t.Fatalf("BatchCreateAccounts().Credentials = %+v, want model_mapping map", credentials)
|
||||
}
|
||||
}
|
||||
|
||||
func sampleProviderManifest() pack.ProviderManifest {
|
||||
@@ -230,8 +255,48 @@ func sampleProviderManifest() pack.ProviderManifest {
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportReconcilesExistingChannelConfiguration(t *testing.T) {
|
||||
host := &fakeHostAdapter{
|
||||
batchAccounts: []sub2api.AccountRef{{ID: "account_1", Name: "deepseek-01"}},
|
||||
testResults: map[string]sub2api.ProbeResult{
|
||||
"account_1": {OK: true, Status: "ready"},
|
||||
},
|
||||
models: map[string][]sub2api.AccountModel{
|
||||
"account_1": {{ID: "deepseek-chat"}},
|
||||
},
|
||||
gatewayResult: sub2api.GatewayAccessResult{OK: true, StatusCode: 200, HasExpectedModel: true, Models: []string{"deepseek-chat"}},
|
||||
managedSnapshot: sub2api.ManagedResourceSnapshot{
|
||||
Groups: []sub2api.NamedResource{{ID: "group_existing", Name: "DeepSeek 默认分组-self-service"}},
|
||||
Channels: []sub2api.NamedResource{{ID: "channel_existing", Name: "DeepSeek 默认渠道-self-service"}},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := NewImportService(host).Import(context.Background(), ImportRequest{
|
||||
Provider: sampleProviderManifest(),
|
||||
Mode: ImportModePartial,
|
||||
Access: AccessRequest{Mode: AccessModeSelfService, ProbeAPIKey: "user-key"},
|
||||
Keys: []string{"key-1"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Import() error = %v", err)
|
||||
}
|
||||
if host.createChannelCalls != 0 {
|
||||
t.Fatalf("CreateChannel() calls = %d, want 0 when channel already exists", host.createChannelCalls)
|
||||
}
|
||||
if host.updateChannelCalls != 1 {
|
||||
t.Fatalf("UpdateChannel() calls = %d, want 1", host.updateChannelCalls)
|
||||
}
|
||||
if host.updateChannelID != "channel_existing" {
|
||||
t.Fatalf("UpdateChannel() id = %q, want channel_existing", host.updateChannelID)
|
||||
}
|
||||
if len(host.updateChannelReq.ModelPricing) != 1 {
|
||||
t.Fatalf("UpdateChannel().ModelPricing len = %d, want 1", len(host.updateChannelReq.ModelPricing))
|
||||
}
|
||||
}
|
||||
|
||||
type fakeHostAdapter struct {
|
||||
batchAccounts []sub2api.AccountRef
|
||||
batchCreateReq sub2api.BatchCreateAccountsRequest
|
||||
testResults map[string]sub2api.ProbeResult
|
||||
models map[string][]sub2api.AccountModel
|
||||
gatewayResult sub2api.GatewayAccessResult
|
||||
@@ -246,9 +311,12 @@ type fakeHostAdapter struct {
|
||||
listManagedReq sub2api.ListManagedResourcesRequest
|
||||
createGroupCalls int
|
||||
createChannelCalls int
|
||||
updateChannelCalls int
|
||||
createPlanCalls int
|
||||
createGroupReq sub2api.CreateGroupRequest
|
||||
createChannelReq sub2api.CreateChannelRequest
|
||||
updateChannelID string
|
||||
updateChannelReq sub2api.CreateChannelRequest
|
||||
}
|
||||
|
||||
func (f *fakeHostAdapter) GetHostVersion(context.Context) (string, error) {
|
||||
@@ -274,6 +342,12 @@ func (f *fakeHostAdapter) CreateChannel(_ context.Context, req sub2api.CreateCha
|
||||
f.createChannelReq = req
|
||||
return sub2api.ChannelRef{ID: "channel_1", Name: "c"}, nil
|
||||
}
|
||||
func (f *fakeHostAdapter) UpdateChannel(_ context.Context, channelID string, req sub2api.CreateChannelRequest) error {
|
||||
f.updateChannelCalls++
|
||||
f.updateChannelID = channelID
|
||||
f.updateChannelReq = req
|
||||
return nil
|
||||
}
|
||||
func (f *fakeHostAdapter) DeleteChannel(_ context.Context, channelID string) error {
|
||||
f.deletedResources = append(f.deletedResources, "channel:"+channelID)
|
||||
return nil
|
||||
@@ -289,7 +363,8 @@ func (f *fakeHostAdapter) DeletePlan(_ context.Context, planID string) error {
|
||||
func (f *fakeHostAdapter) CreateAccount(context.Context, sub2api.CreateAccountRequest) (sub2api.AccountRef, error) {
|
||||
return sub2api.AccountRef{}, errors.New("unused")
|
||||
}
|
||||
func (f *fakeHostAdapter) BatchCreateAccounts(_ context.Context, _ sub2api.BatchCreateAccountsRequest) ([]sub2api.AccountRef, error) {
|
||||
func (f *fakeHostAdapter) BatchCreateAccounts(_ context.Context, req sub2api.BatchCreateAccountsRequest) ([]sub2api.AccountRef, error) {
|
||||
f.batchCreateReq = req
|
||||
if f.batchCreateErr != nil {
|
||||
return nil, f.batchCreateErr
|
||||
}
|
||||
@@ -313,6 +388,9 @@ func (f *fakeHostAdapter) GetAccountModels(_ context.Context, accountID string)
|
||||
}
|
||||
return models, nil
|
||||
}
|
||||
func (f *fakeHostAdapter) EnsureSubscriptionAccess(_ context.Context, req sub2api.EnsureSubscriptionAccessRequest) (sub2api.SubscriptionAccessRef, error) {
|
||||
return sub2api.SubscriptionAccessRef{UserID: req.UserSelector, APIKey: "managed-subscription-key"}, nil
|
||||
}
|
||||
func (f *fakeHostAdapter) AssignSubscription(_ context.Context, req sub2api.AssignSubscriptionRequest) (sub2api.SubscriptionRef, error) {
|
||||
if f.assignErr != nil {
|
||||
return sub2api.SubscriptionRef{}, f.assignErr
|
||||
|
||||
Reference in New Issue
Block a user