package main import ( "os" "path/filepath" "testing" "time" ) func TestStripVersionSuffix(t *testing.T) { tests := []struct { in, want string }{ {"apple_rn", "apple_rn"}, {"apple_rn-v2", "apple_rn"}, {"apple_bubbles-v3", "apple_bubbles"}, {"android", "android"}, } for _, tt := range tests { if got := stripVersionSuffix(tt.in); got != tt.want { t.Errorf("stripVersionSuffix(%q) = %q, want %q", tt.in, got, tt.want) } } } func TestExtractPlatform(t *testing.T) { tests := []struct { name string body string want string wantErr bool }{ { name: "platform field", body: `{"platform":"apple_bubbles","device_id":"abc123","server_id":"srv"}`, want: "apple_bubbles", }, { name: "platform with version suffix", body: `{"platform":"apple_rn-v2","device_id":"abc123","server_id":"srv"}`, want: "apple_rn", }, { name: "device_id prefix fallback", body: `{"device_id":"android_rn:token123","server_id":"srv"}`, want: "android_rn", }, { name: "missing platform", body: `{"device_id":"abc123","server_id":"srv"}`, wantErr: true, }, { name: "invalid json", body: `{`, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := extractPlatform([]byte(tt.body)) if tt.wantErr { if err == nil { t.Fatal("expected error") } return } if err != nil { t.Fatalf("unexpected error: %v", err) } if got != tt.want { t.Fatalf("extractPlatform() = %q, want %q", got, tt.want) } }) } } func TestBackendForPlatform(t *testing.T) { cfg := Config{ Routes: []Route{ {Prefixes: []string{"apple_bubbles"}, URL: "http://custom-proxy:8067"}, {Prefixes: []string{"apple_rn", "android_rn"}, URL: "https://push.mattermost.com"}, }, } tests := []struct { platform string wantURL string wantOK bool }{ {"apple_bubbles", "http://custom-proxy:8067", true}, {"apple_rn", "https://push.mattermost.com", true}, {"android_rn", "https://push.mattermost.com", true}, {"apple_rn-v2", "https://push.mattermost.com", true}, {"unknown", "", false}, } for _, tt := range tests { url, ok := cfg.BackendForPlatform(tt.platform) if ok != tt.wantOK { t.Errorf("BackendForPlatform(%q) ok = %v, want %v", tt.platform, ok, tt.wantOK) } if url != tt.wantURL { t.Errorf("BackendForPlatform(%q) url = %q, want %q", tt.platform, url, tt.wantURL) } } } func TestLoadConfigRequiresConfigFile(t *testing.T) { t.Setenv("CONFIG_FILE", "") _, err := LoadConfig() if err == nil { t.Fatal("expected error when CONFIG_FILE is unset") } } func TestLoadConfigFromFile(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "router.toml") content := ` listen = ":9090" request_timeout_sec = 30 [[routes]] prefixes = ["apple_bubbles"] url = "http://localhost:8067" ` if err := os.WriteFile(path, []byte(content), 0o644); err != nil { t.Fatal(err) } t.Setenv("CONFIG_FILE", path) t.Setenv("PORT", "") cfg, err := LoadConfig() if err != nil { t.Fatalf("LoadConfig() error: %v", err) } if cfg.Port != "9090" { t.Fatalf("Port = %q, want 9090", cfg.Port) } if cfg.RequestTimeout != 30*time.Second { t.Fatalf("RequestTimeout = %v", cfg.RequestTimeout) } if len(cfg.Routes) != 1 || cfg.Routes[0].URL != "http://localhost:8067" { t.Fatalf("Routes = %#v", cfg.Routes) } } func TestNormalizeRoutesRejectsDuplicatePrefix(t *testing.T) { _, err := normalizeRoutes([]routeConfig{ {Prefixes: []string{"apple_rn"}, URL: "http://a.example"}, {Prefixes: []string{"apple_rn"}, URL: "http://b.example"}, }) if err == nil { t.Fatal("expected duplicate prefix error") } } func TestNormalizeRoutesRequiresRoutes(t *testing.T) { _, err := normalizeRoutes(nil) if err == nil { t.Fatal("expected error for empty routes") } }