// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package preferences import ( "strings" "testing" "git.stormux.org/storm/cthulhu/internal/tentacle" ) func TestTentacleUpdateConfirmationDescribesPermissionChanges(t *testing.T) { entry := tentacle.Entry{Presentation: true} update := tentacle.AvailableUpdate{Name: "Example", InstalledVersion: "1.0", AvailableVersion: "1.1"} manifest := tentacle.Manifest{Capabilities: []string{"presentation", "interaction", "reader-settings"}} message := tentacleUpdateConfirmation(entry, update, manifest) for _, want := range []string{ "Update Example from version 1.0 to version 1.1?", "Current capabilities: presentation.", "Repository declares: presentation, interaction, reader-settings.", "Changes take effect immediately.", } { if !strings.Contains(message, want) { t.Fatalf("confirmation missing %q: %s", want, message) } } message = tentacleUpdateConfirmation(tentacle.Entry{}, update, tentacle.Manifest{}) if !strings.Contains(message, "Current capabilities: none. Repository declares: none.") { t.Fatalf("empty capability sets were not described: %s", message) } } func TestTentacleInstallConfirmationDescribesInteractionAndSettings(t *testing.T) { entry := tentacle.Entry{Name: "Example", Version: "1.1", Repository: "https://example.org/tentacles"} manifest := tentacle.Manifest{Capabilities: []string{"presentation", "interaction", "reader-settings"}} message := tentacleInstallConfirmation(entry, manifest, "Install and enable") for _, want := range []string{ "Install and enable Example version 1.1 from https://example.org/tentacles?", "read the focused item and clipboard when invoked", "temporarily change the reader voice configuration", "resource limits do not protect your files or network", } { if !strings.Contains(message, want) { t.Fatalf("confirmation missing %q: %s", want, message) } } message = tentacleInstallConfirmation(entry, tentacle.Manifest{}, "Install") if !strings.Contains(message, "This tentacle can register reader commands.") || strings.Contains(message, "write clipboard text") { t.Fatalf("command-only installation described incorrectly: %s", message) } } func TestRemoteGrantConfirmationExplainsDirectionAndConsent(t *testing.T) { entry := tentacle.Entry{RemoteGrants: []string{"output-observe"}} manifest := tentacle.Manifest{Capabilities: []string{"output-observe", "keyboard-inject", "remote-present", "keyboard-capture", "braille-stream", "clipboard-exchange"}} for _, message := range []string{tentacleInstallConfirmation(entry, manifest, "Install"), tentacleUpdateConfirmation(entry, tentacle.AvailableUpdate{}, manifest)} { for _, want := range []string{"share local reader output", "accept keyboard input from the remote controller", "capture local keyboard input", "present output received", "Each session requires local approval", "receive text with session permission", "Installation does not start a connection"} { if !strings.Contains(message, want) { t.Fatalf("missing %q in %s", want, message) } } } if !strings.Contains(tentacleUpdateCapabilities(entry, manifest), "Current capabilities: output-observe.") { t.Fatal("existing grants hidden") } }