package config import ( "encoding/hex" "strings" "testing" "git.avsdev.uk/Go/job-search/internal/cli/cmdtest" ) // fileCSRFKey returns the CSRF key in config.yaml, or "" if it has none. func fileCSRFKey(t *testing.T) string { t.Helper() key, _ := fileSettings(t, "config.yaml")[csrfKeySetting].(string) return key } // checkCSRFKey fails the test unless key is csrfKeyBytes of hex. func checkCSRFKey(t *testing.T, key string) { t.Helper() decoded, err := hex.DecodeString(key) if err != nil || len(decoded) != csrfKeyBytes { t.Fatalf("key %q is not %d bytes of hex", key, csrfKeyBytes) } } // The key is stored in the configuration file, without being printed, and // the file's other settings are kept. func TestGenerateCSRFKey(t *testing.T) { cmdtest.Setup(t, appConfig) out := mustRun(t, "config", "generate-csrf-key") cmdtest.Contains(t, out, csrfKeySetting+" set in ") key := fileCSRFKey(t) checkCSRFKey(t, key) if strings.Contains(out, key) { t.Errorf("the key was printed: %s", out) } if fileSettings(t, "config.yaml")["sources.sleeper.interval"] != "2m" { t.Errorf("other settings were changed: %v", fileSettings(t, "config.yaml")) } } // An existing key is only replaced with --force. func TestGenerateCSRFKeyExisting(t *testing.T) { cmdtest.Setup(t, appConfig) mustRun(t, "config", "generate-csrf-key") first := fileCSRFKey(t) _, err := run(t, "config", "generate-csrf-key") cmdtest.ErrContains(t, err, "already set: --force replaces it") if fileCSRFKey(t) != first { t.Fatal("the key was replaced without --force") } mustRun(t, "config", "generate-csrf-key", "--force") second := fileCSRFKey(t) checkCSRFKey(t, second) if second == first { t.Error("--force kept the same key") } } // --print only prints a key, and needs no configuration file. func TestGenerateCSRFKeyPrint(t *testing.T) { cmdtest.Setup(t, "") key := strings.TrimSpace(mustRun(t, "config", "generate-csrf-key", "--print")) checkCSRFKey(t, key) other := strings.TrimSpace(mustRun(t, "config", "generate-csrf-key", "--print")) if other == key { t.Error("two keys were the same") } } // A key in the environment variable would override the file, so none is // stored while it is set. func TestGenerateCSRFKeyEnvironment(t *testing.T) { cmdtest.Setup(t, appConfig) t.Setenv("JOBSEARCH_SERVER_CSRF_TOKENS_KEY", generateCSRFKey()) _, err := run(t, "config", "generate-csrf-key") cmdtest.ErrContains(t, err, "JOBSEARCH_SERVER_CSRF_TOKENS_KEY is set") if fileCSRFKey(t) != "" { t.Error("a key was stored") } } func TestGenerateCSRFKeyWithoutConfigFile(t *testing.T) { cmdtest.Setup(t, "") _, err := run(t, "config", "generate-csrf-key") cmdtest.ErrContains(t, err, "no configuration file exists") } func TestGenerateCSRFKeyFlags(t *testing.T) { cmdtest.Setup(t, appConfig) _, err := run(t, "config", "generate-csrf-key", "--print", "--force") cmdtest.ErrContains(t, err, "none of the others") if _, err := run(t, "config", "generate-csrf-key", "extra"); err == nil { t.Error("an argument was accepted") } }