176 lines
4.8 KiB
Go
176 lines
4.8 KiB
Go
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")
|
|
}
|