diff options
| author | Gab Virebent <gabriel1@virebent.art> | 2026-08-24 17:34:45 +0200 |
|---|---|---|
| committer | Gab Virebent <gabriel1@virebent.art> | 2026-08-24 17:34:45 +0200 |
| commit | e9fbbe3373eb66a345f5e3829e2563b94dc92051 (patch) | |
| tree | 950d75fda88574afb46b4aeab36e96f3c089a3bb /internal/config/config_test.go | |
| parent | fb83c4d70616ec23d8a5397409a5d31c70b70d66 (diff) | |
| download | n2usenet-e9fbbe3373eb66a345f5e3829e2563b94dc92051.tar.gz n2usenet-e9fbbe3373eb66a345f5e3829e2563b94dc92051.tar.xz n2usenet-e9fbbe3373eb66a345f5e3829e2563b94dc92051.zip | |
Diffstat (limited to 'internal/config/config_test.go')
| -rw-r--r-- | internal/config/config_test.go | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/internal/config/config_test.go b/internal/config/config_test.go new file mode 100644 index 0000000..fdb02e4 --- /dev/null +++ b/internal/config/config_test.go @@ -0,0 +1,151 @@ +package config + +import ( + "os" + "path/filepath" + "strings" + "testing" + "time" +) + +func validConfig() Config { + return Config{ + Listen: "127.0.0.1:8095", + SMTP: SMTPConfig{ + Host: "mail.virebent.art", + Port: 587, + Recipient: "mail2news@mail2news.tcpreset.net", + EnvelopeFrom: "n2usenet@virebent.art", + Sender: "n2usenet@virebent.art", + TLSServerName: "mail.virebent.art", + RequireTLS: true, + ProbeInterval: 15 * time.Minute, + }, + Security: SecurityConfig{ + MinHashcashBits: 20, + MinMessageBytes: 10, + MaxMessageBytes: 65536, + MaxNewsgroups: 3, + RateLimitCount: 10, + RateLimitWindow: time.Hour, + IdenticonsCLI: "/usr/local/bin/identicons-cli", + RequireFace: true, + }, + } +} + +func TestLoadAcceptsLegacyHeaderFromAsSender(t *testing.T) { + t.Setenv("N2U_SMTP_HEADER_FROM", "legacy-sender@virebent.art") + + cfg, err := Load() + if err != nil { + t.Fatalf("Load returned error: %v", err) + } + if got, want := cfg.SMTP.Sender, "legacy-sender@virebent.art"; got != want { + t.Fatalf("Sender = %q, want %q", got, want) + } +} + +func TestLoadPrefersSenderOverLegacyHeaderFrom(t *testing.T) { + t.Setenv("N2U_SMTP_SENDER", "sender@virebent.art") + t.Setenv("N2U_SMTP_HEADER_FROM", "legacy-sender@virebent.art") + + cfg, err := Load() + if err != nil { + t.Fatalf("Load returned error: %v", err) + } + if got, want := cfg.SMTP.Sender, "sender@virebent.art"; got != want { + t.Fatalf("Sender = %q, want %q", got, want) + } +} + +func TestValidateSMTPAuthentication(t *testing.T) { + tests := []struct { + name string + mutate func(*Config) + wantErr string + }{ + { + name: "credentials with STARTTLS", + mutate: func(cfg *Config) { + cfg.SMTP.Username = "n2usenet@virebent.art" + cfg.SMTP.Password = "test-password" + }, + }, + { + name: "missing password", + mutate: func(cfg *Config) { + cfg.SMTP.Username = "n2usenet@virebent.art" + }, + wantErr: "must be configured together", + }, + { + name: "missing username", + mutate: func(cfg *Config) { + cfg.SMTP.Password = "test-password" + }, + wantErr: "must be configured together", + }, + { + name: "credentials without TLS", + mutate: func(cfg *Config) { + cfg.SMTP.Username = "n2usenet@virebent.art" + cfg.SMTP.Password = "test-password" + cfg.SMTP.RequireTLS = false + }, + wantErr: "requires TLS", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := validConfig() + tt.mutate(&cfg) + err := cfg.Validate() + if tt.wantErr == "" { + if err != nil { + t.Fatalf("Validate returned error: %v", err) + } + return + } + if err == nil || !strings.Contains(err.Error(), tt.wantErr) { + t.Fatalf("Validate error = %v, want substring %q", err, tt.wantErr) + } + }) + } +} + +func TestLoadReadsSMTPPasswordFile(t *testing.T) { + passwordPath := filepath.Join(t.TempDir(), "smtp-password") + if err := os.WriteFile(passwordPath, []byte("test-password\n"), 0600); err != nil { + t.Fatalf("write password file: %v", err) + } + t.Setenv("N2U_SMTP_USERNAME", "n2usenet@virebent.art") + t.Setenv("N2U_SMTP_PASSWORD_FILE", passwordPath) + t.Setenv("N2U_SMTP_REQUIRE_TLS", "true") + + cfg, err := Load() + if err != nil { + t.Fatalf("Load returned error: %v", err) + } + if got, want := cfg.SMTP.Password, "test-password"; got != want { + t.Fatalf("Password = %q, want %q", got, want) + } +} + +func TestLoadReadsPersistentCSRFKey(t *testing.T) { + keyPath := filepath.Join(t.TempDir(), "csrf-key") + want := strings.Repeat("k", 32) + if err := os.WriteFile(keyPath, []byte(want+"\n"), 0600); err != nil { + t.Fatalf("write CSRF key file: %v", err) + } + t.Setenv("N2U_CSRF_KEY_FILE", keyPath) + + cfg, err := Load() + if err != nil { + t.Fatalf("Load returned error: %v", err) + } + if got := string(cfg.Security.CSRFKey); got != want { + t.Fatalf("CSRFKey = %q, want %q", got, want) + } +} |
