package plugins import ( "encoding/json" "os" "path/filepath" "runtime" "strings" "testing" ) func TestQwenCommandsBlockAndForwardNativePayloadByteForByte(t *testing.T) { fixture := prepareQwenFixture(t, qwenFixtureOptions{}) installQwenFixture(t, fixture) capturePath := filepath.Join(t.TempDir(), "captured-event.json") encodedPath, err := json.Marshal(capturePath) if err != nil { t.Fatalf("marshal capture path: %v", err) } guardScript := "const fs = require('node:fs');\n" + "fs.readFileSync(0);\n" + "process.stderr.write('Agent is frozen by Elydora.');\n" + "process.exit(2);\n" if err := os.WriteFile(fixture.guardPath, []byte(guardScript), 0700); err != nil { t.Fatalf("write blocking guard runtime: %v", err) } captureScript := "const fs = require('node:fs');\n" + "fs.writeFileSync(" + string(encodedPath) + ", fs.readFileSync(0));\n" if err := os.WriteFile(fixture.hookPath, []byte(captureScript), 0700); err != nil { t.Fatalf("write capture audit runtime: %v", err) } settings := readQwenTestObject(t, fixture.configPath) prePayload := `{"session_id":"session-1","cwd":"C:/workspace","hook_event_name":"PreToolUse","timestamp":"2026-07-19T00:00:00.000Z","tool_name":"run_shell_command","tool_input":{"command":"echo test"}}` + "\n" guard := qwenManagedHandler(t, settings, "PreToolUse", fixture.guardPath) guardResult := runQwenHandler(t, guard, fixture.homeDir, prePayload) if guardResult.exitCode != 2 || guardResult.stdout != "" || !strings.Contains(guardResult.stderr, "Agent is frozen by Elydora") { t.Fatalf("guard result = %#v", guardResult) } for _, event := range []string{"PostToolUse", "PostToolUseFailure"} { payload := strings.Replace(prePayload, "PreToolUse", event, 1) handler := qwenManagedHandler(t, settings, event, fixture.hookPath) result := runQwenHandler(t, handler, fixture.homeDir, payload) if result.exitCode != 0 || result.stdout != "" || result.stderr != "" { t.Fatalf("%s result = %#v", event, result) } if readQwenTestFile(t, capturePath) != payload { t.Fatalf("%s changed the native Qwen Code payload", event) } } } func TestQwenPowerShellCommandPropagatesNodeExitCode(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("PowerShell command contract is Windows-specific") } fixture := prepareQwenFixture(t, qwenFixtureOptions{}) installQwenFixture(t, fixture) handler := qwenManagedHandler( t, readQwenTestObject(t, fixture.configPath), "PreToolUse", fixture.guardPath, ) command := handler["command"].(string) if !strings.HasPrefix(command, "& '") || !strings.HasSuffix(command, "; exit $LASTEXITCODE") { t.Fatalf("PowerShell command = %q", command) } } func TestQwenStatusRequiresEnabledExactTripleAndRuntimeFiles(t *testing.T) { fixture := prepareQwenFixture(t, qwenFixtureOptions{}) installQwenFixture(t, fixture) status, err := fixture.plugin.Status() if err != nil || !status.Installed || !status.HookConfigured || !status.HookScriptExists { t.Fatalf("installed status = %#v, %v", status, err) } settings := readQwenTestObject(t, fixture.configPath) hooks := requireQwenObject(t, settings["hooks"]) failureGroups := requireQwenArray(t, hooks["PostToolUseFailure"]) hooks["PostToolUseFailure"] = append(failureGroups, failureGroups[len(failureGroups)-1]) writeQwenTestObject(t, fixture.configPath, settings) status, err = fixture.plugin.Status() if err != nil || status.HookConfigured || status.Installed { t.Fatalf("duplicate status = %#v, %v", status, err) } installQwenFixture(t, fixture) settings = readQwenTestObject(t, fixture.configPath) hooks = requireQwenObject(t, settings["hooks"]) delete(hooks, "PostToolUseFailure") writeQwenTestObject(t, fixture.configPath, settings) status, err = fixture.plugin.Status() if err != nil || status.HookConfigured || status.Installed { t.Fatalf("incomplete status = %#v, %v", status, err) } installQwenFixture(t, fixture) writeOptionalQwenFile( t, fixture.systemConfig, qwenJSON(map[string]any{"disableAllHooks": true}), ) status, err = fixture.plugin.Status() if err != nil || status.HookConfigured || status.Installed { t.Fatalf("disabled status = %#v, %v", status, err) } if err := os.Remove(fixture.systemConfig); err != nil { t.Fatalf("remove system settings: %v", err) } if err := os.Remove(fixture.guardPath); err != nil { t.Fatalf("remove guard runtime: %v", err) } status, err = fixture.plugin.Status() if err != nil || !status.HookConfigured || status.HookScriptExists || status.Installed { t.Fatalf("missing runtime status = %#v, %v", status, err) } } func TestQwenStatusRequiresCanonicalRuntimeContents(t *testing.T) { tests := []struct { name string mutate func(*testing.T, *qwenFixture) wantErr string }{ { "guard content", func(t *testing.T, f *qwenFixture) { if err := os.WriteFile(f.guardPath, []byte("tampered\n"), 0700); err != nil { t.Fatalf("tamper guard: %v", err) } }, "", }, { "audit content", func(t *testing.T, f *qwenFixture) { if err := os.WriteFile(f.hookPath, []byte("tampered\n"), 0700); err != nil { t.Fatalf("tamper audit: %v", err) } }, "", }, { "private key", func(t *testing.T, f *qwenFixture) { if err := os.WriteFile(f.privateKey, []byte("invalid"), 0600); err != nil { t.Fatalf("tamper private key: %v", err) } }, "private key", }, { "extra config field", func(t *testing.T, f *qwenFixture) { config := readQwenTestObject(t, f.runtimeConfig) config["extra"] = true writeQwenTestObject(t, f.runtimeConfig, config) }, "unsupported field", }, { "runtime identity", func(t *testing.T, f *qwenFixture) { config := readQwenTestObject(t, f.runtimeConfig) config["agent_id"] = "other-agent" writeQwenTestObject(t, f.runtimeConfig, config) }, "identity does not match", }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { fixture := prepareQwenFixture(t, qwenFixtureOptions{}) installQwenFixture(t, fixture) test.mutate(t, fixture) status, err := fixture.plugin.Status() if test.wantErr == "" { if err != nil || status.Installed || status.HookScriptExists { t.Fatalf("status = %#v, %v", status, err) } return } if err == nil || !strings.Contains(err.Error(), test.wantErr) || status.Installed || status.HookScriptExists { t.Fatalf("status = %#v, %v", status, err) } }) } }