a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
103 lines
3.9 KiB
Go
103 lines
3.9 KiB
Go
package mcp
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/zzet/gortex/internal/profiles"
|
|
)
|
|
|
|
// TestMain pins the instruction-profile env override to the default
|
|
// profile for the whole package: a developer machine that ran
|
|
// `gortex instructions switch` must not change the behavior of
|
|
// unrelated internal/mcp tests. Tests that exercise the profile path
|
|
// stub activeInstructionPreset directly.
|
|
func TestMain(m *testing.M) {
|
|
os.Setenv(profiles.ActiveEnv, profiles.DefaultName)
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
// stubActiveProfilePreset swaps the machine-state reader for the test.
|
|
func stubActiveProfilePreset(t *testing.T, preset string) {
|
|
t.Helper()
|
|
prev := activeInstructionPreset
|
|
activeInstructionPreset = func() string { return preset }
|
|
t.Cleanup(func() { activeInstructionPreset = prev })
|
|
}
|
|
|
|
func TestInstructionProfilePolicy_AppliesOnDefaultConfig(t *testing.T) {
|
|
srv := setupPresetServer(t, ToolPolicyConfig{Preset: "core", Mode: "defer"})
|
|
stubActiveProfilePreset(t, "localization")
|
|
|
|
p := srv.instructionProfilePolicy()
|
|
require.NotNil(t, p, "shipped-default config must let the active profile refine the surface")
|
|
require.Equal(t, "localization", p.preset)
|
|
require.True(t, p.deferMode(), "profile policy inherits the server's defer mode")
|
|
require.True(t, p.allows("search_symbols"))
|
|
require.True(t, p.allows("smart_context"))
|
|
require.False(t, p.allows("edit_file"), "the localization surface is read-only")
|
|
|
|
// Session resolution: the profile beats the client-aware default…
|
|
sp := srv.resolveSessionPolicy("", "", "claude-code")
|
|
require.NotNil(t, sp)
|
|
require.Equal(t, "localization", sp.preset)
|
|
|
|
// …but a forwarded spec beats the profile.
|
|
sp = srv.resolveSessionPolicy("edit", "", "claude-code")
|
|
require.NotNil(t, sp)
|
|
require.Equal(t, "edit", sp.preset)
|
|
}
|
|
|
|
func TestInstructionProfilePolicy_DefaultProfileIsNoOp(t *testing.T) {
|
|
srv := setupPresetServer(t, ToolPolicyConfig{Preset: "core", Mode: "defer"})
|
|
stubActiveProfilePreset(t, "")
|
|
require.Nil(t, srv.instructionProfilePolicy(),
|
|
"the core profile carries no preset and must resolve exactly as before")
|
|
}
|
|
|
|
func TestInstructionProfilePolicy_OperatorPinWins(t *testing.T) {
|
|
srv := setupPresetServer(t, ToolPolicyConfig{Preset: "agent", Mode: "defer"})
|
|
stubActiveProfilePreset(t, "localization")
|
|
require.Nil(t, srv.instructionProfilePolicy(),
|
|
"an operator-pinned mcp.tools config must not be overridden by the profile")
|
|
}
|
|
|
|
func TestOperatorPinnedToolPolicy(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
cfg ToolPolicyConfig
|
|
want bool
|
|
}{
|
|
{"zero config", ToolPolicyConfig{}, false},
|
|
{"shipped default", ToolPolicyConfig{Preset: "core", Mode: "defer"}, false},
|
|
{"default alias", ToolPolicyConfig{Preset: "default", Mode: "defer"}, false},
|
|
{"core in hide mode", ToolPolicyConfig{Preset: "core", Mode: "hide"}, true},
|
|
{"named preset", ToolPolicyConfig{Preset: "agent", Mode: "defer"}, true},
|
|
{"allow delta", ToolPolicyConfig{Preset: "core", Mode: "defer", Allow: []string{"analyze"}}, true},
|
|
{"deny delta", ToolPolicyConfig{Deny: []string{"edit_file"}}, true},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
require.Equal(t, tc.want, operatorPinnedToolPolicy(tc.cfg))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOperatorPinnedToolPolicy_EnvPins(t *testing.T) {
|
|
t.Setenv(toolPresetEnv, "nav")
|
|
require.True(t, operatorPinnedToolPolicy(ToolPolicyConfig{Preset: "core", Mode: "defer"}))
|
|
}
|
|
|
|
// TestLocalizationPresetMatchesProfileTable is the cross-package
|
|
// no-drift gate: the preset registered here must be exactly the eager
|
|
// list the instruction-profile table declares.
|
|
func TestLocalizationPresetMatchesProfileTable(t *testing.T) {
|
|
require.Equal(t, profiles.LocalizationEagerTools(), localizationPresetTools)
|
|
set, denyMutating, known := builtinToolPresetSet("localization")
|
|
require.True(t, known)
|
|
require.False(t, denyMutating)
|
|
require.Equal(t, toToolSet(profiles.LocalizationEagerTools()), set)
|
|
}
|