133 lines
5.0 KiB
Go
133 lines
5.0 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
package app
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"git.stormux.org/storm/cthulhu/internal/config"
|
|
"git.stormux.org/storm/cthulhu/internal/input"
|
|
"git.stormux.org/storm/cthulhu/internal/preferences"
|
|
"log/slog"
|
|
"path/filepath"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
type bindingRecorder struct {
|
|
values []input.BindingOverride
|
|
calls int
|
|
err error
|
|
}
|
|
|
|
func (recorder *bindingRecorder) SetKeyBindings(_ context.Context, values []input.BindingOverride) error {
|
|
recorder.calls++
|
|
if recorder.err != nil {
|
|
return recorder.err
|
|
}
|
|
recorder.values = input.CloneBindingOverrides(values)
|
|
return nil
|
|
}
|
|
|
|
func TestPreferencesKeyBindingsApplySaveResetAndFailure(t *testing.T) {
|
|
settings := config.DefaultSettings()
|
|
settings.Path = filepath.Join(t.TempDir(), "settings.toml")
|
|
worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil)
|
|
recorder := &bindingRecorder{}
|
|
worker.bindings = recorder
|
|
values := preferences.FromSettings(settings)
|
|
values.KeyBindings = []input.BindingOverride{{Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"Cthulhu+F8"}}}
|
|
recorder.err = errors.New("grab conflict")
|
|
response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true})
|
|
if response.Accepted || len(worker.settings.KeyBindings) != 0 {
|
|
t.Fatal("failed update committed")
|
|
}
|
|
recorder.err = nil
|
|
response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true})
|
|
if !response.Accepted || !reflect.DeepEqual(values.KeyBindings, recorder.values) {
|
|
t.Fatalf("apply: %+v", response)
|
|
}
|
|
loaded, err := config.Load(settings.Path)
|
|
if err != nil || !reflect.DeepEqual(values.KeyBindings, loaded.KeyBindings) {
|
|
t.Fatalf("save: %v", err)
|
|
}
|
|
calls := recorder.calls
|
|
values.KeyBindings[0].Keys = []string{"Cthulhu+q"}
|
|
response = worker.apply(context.Background(), preferences.Request{Values: values})
|
|
if response.Accepted || recorder.calls != calls {
|
|
t.Fatal("invalid bindings reached backend")
|
|
}
|
|
values.KeyBindings[0].Keys = []string{"Cthulhu+F9"}
|
|
rate := 70.0
|
|
values.Rate = &rate
|
|
response = worker.apply(context.Background(), preferences.Request{Values: values})
|
|
if response.Accepted || recorder.values[0].Keys[0] != "Cthulhu+F8" {
|
|
t.Fatal("later backend failure did not restore keys")
|
|
}
|
|
values.Rate = nil
|
|
values.KeyBindings = nil
|
|
response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true})
|
|
if !response.Accepted || len(recorder.values) != 0 {
|
|
t.Fatal("reset was not applied")
|
|
}
|
|
}
|
|
|
|
type keyboardRecorder struct {
|
|
bindingRecorder
|
|
layout input.KeyboardLayout
|
|
modifiers []string
|
|
}
|
|
|
|
func (recorder *keyboardRecorder) SetKeyboardConfiguration(ctx context.Context, layout input.KeyboardLayout, modifiers []string, overrides []input.BindingOverride) error {
|
|
if err := recorder.SetKeyBindings(ctx, overrides); err != nil {
|
|
return err
|
|
}
|
|
recorder.layout = layout
|
|
recorder.modifiers = append([]string(nil), modifiers...)
|
|
return nil
|
|
}
|
|
|
|
func TestPreferencesKeyboardConfigurationApplySaveRollback(t *testing.T) {
|
|
settings := config.DefaultSettings()
|
|
settings.Path = filepath.Join(t.TempDir(), "settings.toml")
|
|
worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil)
|
|
recorder := &keyboardRecorder{}
|
|
worker.bindings = recorder
|
|
values := preferences.FromSettings(settings)
|
|
values.KeyboardLayout = 2
|
|
values.CthulhuModifierKeys = []string{"Caps_Lock"}
|
|
recorder.err = errors.New("modifier grab conflict")
|
|
response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true})
|
|
if response.Accepted || worker.settings.KeyboardLayout != 1 {
|
|
t.Fatal("failed modifier update committed")
|
|
}
|
|
recorder.err = nil
|
|
response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true})
|
|
if !response.Accepted || recorder.layout != input.LaptopKeyboardLayout || !reflect.DeepEqual(recorder.modifiers, values.CthulhuModifierKeys) {
|
|
t.Fatalf("apply: %+v", response)
|
|
}
|
|
loaded, err := config.Load(settings.Path)
|
|
if err != nil || loaded.KeyboardLayout != 2 || !reflect.DeepEqual(loaded.CthulhuModifierKeys, values.CthulhuModifierKeys) {
|
|
t.Fatalf("save keyboard: %v", err)
|
|
}
|
|
values.KeyboardLayout = 1
|
|
values.CthulhuModifierKeys = []string{"KP_Insert"}
|
|
rate := 70.0
|
|
values.Rate = &rate
|
|
response = worker.apply(context.Background(), preferences.Request{Values: values})
|
|
if response.Accepted || recorder.layout != input.LaptopKeyboardLayout || !reflect.DeepEqual(recorder.modifiers, []string{"Caps_Lock"}) {
|
|
t.Fatal("later backend failure did not restore keyboard configuration")
|
|
}
|
|
values.Rate = nil
|
|
values.CthulhuModifierKeys = []string{}
|
|
response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true})
|
|
if !response.Accepted || len(recorder.modifiers) != 0 {
|
|
t.Fatalf("all unchecked: %+v", response)
|
|
}
|
|
loaded, err = config.Load(settings.Path)
|
|
if err != nil || len(loaded.CthulhuModifierKeys) != 0 {
|
|
t.Fatalf("reload all unchecked: %v", err)
|
|
}
|
|
}
|