test(project): achieve ≥70% package coverage across all internal packages
- store/sqlite: 75.4% (repos + db coverage) - host/sub2api: 80.8% (httptest mock server, pure function tests) - app: 74.2% (handler error paths, NewActionSet closures) - pack: 72.4% - provision: 75.2% - access: 77.3% - config: 94.7% (lookup mock tests) All tests pass: build, vet, race, coverage gates.
This commit is contained in:
80
internal/access/closure.go
Normal file
80
internal/access/closure.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package access
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"sub2api-cn-relay-manager/internal/host/sub2api"
|
||||
)
|
||||
|
||||
const (
|
||||
ModeSubscription = "subscription"
|
||||
ModeSelfService = "self_service"
|
||||
)
|
||||
|
||||
type SubscriptionTarget struct {
|
||||
UserID string
|
||||
DurationDays int
|
||||
}
|
||||
|
||||
type ClosureRequest struct {
|
||||
Mode string
|
||||
ProbeAPIKey string
|
||||
Subscriptions []SubscriptionTarget
|
||||
GroupID string
|
||||
ExpectedModel string
|
||||
}
|
||||
|
||||
type Host interface {
|
||||
AssignSubscription(ctx context.Context, req sub2api.AssignSubscriptionRequest) (sub2api.SubscriptionRef, error)
|
||||
CheckGatewayAccess(ctx context.Context, req sub2api.GatewayAccessCheckRequest) (sub2api.GatewayAccessResult, error)
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
host Host
|
||||
}
|
||||
|
||||
func NewService(host Host) *Service {
|
||||
return &Service{host: host}
|
||||
}
|
||||
|
||||
func Validate(req ClosureRequest) error {
|
||||
switch strings.TrimSpace(req.Mode) {
|
||||
case ModeSubscription:
|
||||
if len(req.Subscriptions) == 0 {
|
||||
return fmt.Errorf("subscription access requires at least one subscription target")
|
||||
}
|
||||
case ModeSelfService:
|
||||
if strings.TrimSpace(req.ProbeAPIKey) == "" {
|
||||
return fmt.Errorf("self_service access requires probe api key")
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unsupported access mode %q", req.Mode)
|
||||
}
|
||||
if strings.TrimSpace(req.ProbeAPIKey) == "" {
|
||||
return fmt.Errorf("access probe api key is required to verify gateway closure")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) Close(ctx context.Context, req ClosureRequest) (sub2api.GatewayAccessResult, error) {
|
||||
if s == nil || s.host == nil {
|
||||
return sub2api.GatewayAccessResult{}, fmt.Errorf("access host is required")
|
||||
}
|
||||
if err := Validate(req); err != nil {
|
||||
return sub2api.GatewayAccessResult{}, err
|
||||
}
|
||||
if strings.TrimSpace(req.Mode) == ModeSubscription {
|
||||
for _, target := range req.Subscriptions {
|
||||
if _, err := s.host.AssignSubscription(ctx, sub2api.AssignSubscriptionRequest{UserID: target.UserID, GroupID: req.GroupID, DurationDays: target.DurationDays}); err != nil {
|
||||
return sub2api.GatewayAccessResult{}, fmt.Errorf("assign subscription for %s: %w", target.UserID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
result, err := s.host.CheckGatewayAccess(ctx, sub2api.GatewayAccessCheckRequest{APIKey: req.ProbeAPIKey, ExpectedModel: req.ExpectedModel})
|
||||
if err != nil {
|
||||
return sub2api.GatewayAccessResult{}, fmt.Errorf("check gateway access: %w", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user