package settings import ( "io" "log/slog" "os" "path/filepath" "strings" "testing" ) func TestReadYMLSettingsRejectsUnknownField(t *testing.T) { tmpDir := t.TempDir() settingsPath := filepath.Join(tmpDir, "vctp.yml") content := `settings: log_level: "info" unknown_field: true ` if err := os.WriteFile(settingsPath, []byte(content), 0o600); err != nil { t.Fatalf("failed to write settings file: %v", err) } logger := slog.New(slog.NewTextHandler(io.Discard, nil)) s := New(logger, settingsPath) err := s.ReadYMLSettings() if err == nil { t.Fatal("expected unknown field decode error") } if !strings.Contains(strings.ToLower(err.Error()), "unknown_field") { t.Fatalf("expected error to mention unknown field, got: %v", err) } } func TestSecureSettingsFileMode(t *testing.T) { cases := []struct { name string in os.FileMode want os.FileMode }{ {name: "already strict", in: 0o600, want: 0o600}, {name: "group read allowed", in: 0o640, want: 0o640}, {name: "too open world", in: 0o666, want: 0o660}, {name: "exec bits stripped", in: 0o755, want: 0o640}, {name: "no perms gets owner rw", in: 0o000, want: 0o600}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { got := secureSettingsFileMode(tc.in) if got != tc.want { t.Fatalf("unexpected mode conversion: in=%#o got=%#o want=%#o", tc.in, got, tc.want) } }) } }