// Copyright (c) 2026 Storm Dragon // SPDX-License-Identifier: GPL-3.0-or-later package preferences import ( "path/filepath" "reflect" "testing" "git.stormux.org/storm/fenrir/internal/config" "git.stormux.org/storm/fenrir/internal/interaction" ) func focus_modifier(t *testing.T, s *interaction.Session, id string) { t.Helper() for range 40 { if control, ok := s.Focused_control(); ok && control.ID == id { return } s.Handle(interaction.Key{Name: "tab"}) } t.Fatal("could not focus", id) } func TestModifierCheckboxesRejectConflictAndSaveSelections(t *testing.T) { for _, key := range []string{"KEY_KP0", "KEY_INSERT", "KEY_CAPSLOCK", "KEY_META"} { base := config.Defaults() base.Keyboard.Devices = []string{} base.Keyboard.FenrirKeys = []string{key} base.General.ScriptKeys = []string{"KEY_COMPOSE", "KEY_F9"} session, err := New_session(base, []string{"keyboard"}) if err != nil { t.Fatal(err) } for _, role := range []string{"fenrir_key.", "script_key."} { control := session.Values()["keyboard."+role+key] if control.Kind != interaction.CheckBox || control.Checked != (role == "fenrir_key.") { t.Fatal(control) } } focus_modifier(t, session, "script_key."+key) session.Handle(interaction.Key{Name: "space"}) if _, err := Settings(session, base); err == nil { t.Fatal("overlapping checkbox roles saved", key) } focus_modifier(t, session, "fenrir_key."+key) session.Handle(interaction.Key{Name: "space"}) if _, err := Settings(session, base); err == nil { t.Fatal("all reader keys unchecked accepted") } replacement := "KEY_INSERT" if key == replacement { replacement = "KEY_CAPSLOCK" } focus_modifier(t, session, "fenrir_key."+replacement) session.Handle(interaction.Key{Name: "space"}) draft, err := Settings(session, base) if err != nil || !modifier_checked(draft.General.ScriptKeys, key) || !modifier_checked(draft.Keyboard.FenrirKeys, replacement) || modifier_checked(draft.Keyboard.FenrirKeys, key) { t.Fatal(draft.Keyboard, draft.General, err) } if !reflect.DeepEqual(base.Keyboard.FenrirKeys, []string{key}) || len(base.General.ScriptKeys) != 2 { t.Fatal("draft changed original") } path := filepath.Join(t.TempDir(), "settings.toml") doc, err := config.Open_document(path, base) if err != nil { t.Fatal(err) } if err := doc.Save(draft); err != nil { t.Fatal(err) } saved, _, err := config.Load(path, nil) if err != nil || !reflect.DeepEqual(saved.Keyboard.FenrirKeys, draft.Keyboard.FenrirKeys) || !reflect.DeepEqual(saved.General.ScriptKeys, draft.General.ScriptKeys) { t.Fatal(saved.Keyboard, saved.General, err) } if !modifier_checked(saved.General.ScriptKeys, "KEY_F9") { t.Fatal("custom script key lost") } } } func TestModifierCheckboxesPreserveSideSpecificSuperAndDefaults(t *testing.T) { base := config.Defaults() base.Keyboard.Devices = []string{} base.Keyboard.FenrirKeys = []string{"KEY_RIGHTMETA"} base.General.ScriptKeys = []string{"KEY_LEFTMETA"} session, err := New_session(base, []string{"keyboard"}) if err != nil { t.Fatal(err) } unchanged, err := Settings(session, base) if err != nil || !reflect.DeepEqual(unchanged, base) { t.Fatal(unchanged, err) } base = config.Defaults() base.Keyboard.Devices = []string{} base.General.ScriptKeys = []string{"KEY_META", "KEY_COMPOSE"} session, err = New_session(base, []string{"keyboard"}) if err != nil { t.Fatal(err) } if session.Values()["keyboard.fenrir_key.KEY_META"].Checked || !session.Values()["keyboard.script_key.KEY_META"].Checked { t.Fatal("defaults claimed existing script key") } unchanged, err = Settings(session, base) if err != nil || !reflect.DeepEqual(unchanged, base) { t.Fatal(unchanged, err) } }