package http import ( "context" "testing" ghcontext "github.com/github/github-mcp-server/pkg/context" "github.com/github/github-mcp-server/pkg/github" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestCreateHTTPFeatureChecker(t *testing.T) { tests := []struct { name string staticFeatures []string staticInsiders bool flagName string headerFeatures []string insidersMode bool wantEnabled bool }{ { name: "allowed issues_granular flag accepted from header", flagName: github.FeatureFlagIssuesGranular, headerFeatures: []string{github.FeatureFlagIssuesGranular}, wantEnabled: true, }, { name: "allowed pull_requests_granular flag accepted from header", flagName: github.FeatureFlagPullRequestsGranular, headerFeatures: []string{github.FeatureFlagPullRequestsGranular}, wantEnabled: true, }, { name: "MCP Apps flag accepted from header", flagName: github.MCPAppsFeatureFlag, headerFeatures: []string{github.MCPAppsFeatureFlag}, wantEnabled: true, }, { name: "unknown flag in header is ignored", flagName: "unknown_flag", headerFeatures: []string{"unknown_flag"}, wantEnabled: false, }, { name: "allowed flag not in header returns false", flagName: github.FeatureFlagIssuesGranular, headerFeatures: nil, wantEnabled: false, }, { name: "allowed flag with different flag in header returns false", flagName: github.FeatureFlagIssuesGranular, headerFeatures: []string{github.FeatureFlagPullRequestsGranular}, wantEnabled: false, }, { name: "multiple allowed flags in header", flagName: github.FeatureFlagIssuesGranular, headerFeatures: []string{github.FeatureFlagIssuesGranular, github.FeatureFlagPullRequestsGranular}, wantEnabled: true, }, { name: "empty header features", flagName: github.FeatureFlagIssuesGranular, headerFeatures: []string{}, wantEnabled: false, }, { name: "insiders mode enables MCP Apps without header", flagName: github.MCPAppsFeatureFlag, insidersMode: true, wantEnabled: true, }, { name: "static feature is enabled without header", staticFeatures: []string{github.FeatureFlagCSVOutput}, flagName: github.FeatureFlagCSVOutput, wantEnabled: true, }, { name: "static features combine with header features", staticFeatures: []string{github.FeatureFlagCSVOutput}, flagName: github.FeatureFlagIssuesGranular, headerFeatures: []string{github.FeatureFlagIssuesGranular}, wantEnabled: true, }, { name: "static insiders enables insiders flags without route context", staticInsiders: true, flagName: github.FeatureFlagCSVOutput, wantEnabled: true, }, { name: "insiders mode does not auto-enable ifc labels", flagName: github.FeatureFlagIFCLabels, insidersMode: true, wantEnabled: false, }, { name: "insiders mode does not enable granular flags", flagName: github.FeatureFlagIssuesGranular, insidersMode: true, wantEnabled: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { checker := createHTTPFeatureChecker(tt.staticFeatures, tt.staticInsiders) ctx := context.Background() if len(tt.headerFeatures) > 0 { ctx = ghcontext.WithHeaderFeatures(ctx, tt.headerFeatures) } if tt.insidersMode { ctx = ghcontext.WithInsidersMode(ctx, true) } enabled, err := checker(ctx, tt.flagName) require.NoError(t, err) assert.Equal(t, tt.wantEnabled, enabled) }) } } func TestResolveListenAddress(t *testing.T) { tests := []struct { name string host string port int want string }{ { name: "empty host falls back to :port", host: "", port: 8082, want: ":8082", }, { name: "ipv4 host is joined with port", host: "127.0.0.1", port: 9090, want: "127.0.0.1:9090", }, { name: "ipv6 host is bracketed and joined with port", host: "::1", port: 9090, want: "[::1]:9090", }, { name: "hostname is joined with port", host: "localhost", port: 8082, want: "localhost:8082", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := resolveListenAddress(tt.host, tt.port) assert.Equal(t, tt.want, got) }) } } func TestHeaderAllowedFeatureFlagsMatchesAllowed(t *testing.T) { // Ensure HeaderAllowedFeatureFlags delegates to AllowedFeatureFlags allowed := github.HeaderAllowedFeatureFlags() assert.Equal(t, github.AllowedFeatureFlags, allowed, "HeaderAllowedFeatureFlags() should match AllowedFeatureFlags") assert.NotEmpty(t, allowed, "AllowedFeatureFlags should not be empty") }