package main import ( "os" "path/filepath" "testing" ) func TestNormalizeBaseURL(t *testing.T) { got, err := normalizeBaseURL("https://mpbot.cpshelp.cn/") if err != nil { t.Fatal(err) } if got != "https://mpbot.cpshelp.cn" { t.Fatalf("got %q", got) } if _, err := normalizeBaseURL("mpbot.cpshelp.cn"); err == nil { t.Fatal("expected invalid base url error") } } func TestEndpointURL(t *testing.T) { got, err := endpointURL("https://mpbot.cpshelp.cn/", "api/account/user/info") if err != nil { t.Fatal(err) } want := "https://mpbot.cpshelp.cn/api/account/user/info" if got != want { t.Fatalf("got %q want %q", got, want) } } func TestReadJSONDataLiteralAndFile(t *testing.T) { if _, err := readJSONData(`{"ok":true}`); err != nil { t.Fatal(err) } if _, err := readJSONData(`{"ok":`); err == nil { t.Fatal("expected invalid json error") } dir := t.TempDir() path := filepath.Join(dir, "body.json") if err := os.WriteFile(path, []byte(`{"from":"file"}`), 0o644); err != nil { t.Fatal(err) } if _, err := readJSONData("@" + path); err != nil { t.Fatal(err) } } func TestConfigRoundTrip(t *testing.T) { path := filepath.Join(t.TempDir(), ".htsy", "config.json") cfg := Config{ BaseURL: "https://mpbot.cpshelp.cn", Token: "token-value", Username: "user", LoginKind: "user", } if err := saveConfig(path, cfg); err != nil { t.Fatal(err) } loaded, err := loadConfig(path) if err != nil { t.Fatal(err) } if loaded.Token != cfg.Token || loaded.Username != cfg.Username || loaded.BaseURL != cfg.BaseURL { t.Fatalf("loaded config mismatch: %+v", loaded) } } func TestTokenFromResponse(t *testing.T) { token, err := tokenFromResponse([]byte(`{"token":"top-level"}`)) if err != nil { t.Fatal(err) } if token != "top-level" { t.Fatalf("got %q", token) } token, err = tokenFromResponse([]byte(`{"code":0,"data":{"token":"nested"}}`)) if err != nil { t.Fatal(err) } if token != "nested" { t.Fatalf("got %q", token) } } func TestSplitCallArgs(t *testing.T) { tests := []struct { name string args []string wantPath string wantFlags []string wantErr bool }{ { name: "path first", args: []string{"/api/account/user/info", "-d", "{}"}, wantPath: "/api/account/user/info", wantFlags: []string{"-d", "{}"}, }, { name: "flags first", args: []string{"-d", "{}", "--raw", "/api/account/user/info"}, wantPath: "/api/account/user/info", wantFlags: []string{"-d", "{}", "--raw"}, }, { name: "equals flag", args: []string{"--data={}", "/api/account/user/info"}, wantPath: "/api/account/user/info", wantFlags: []string{"--data={}"}, }, { name: "missing endpoint", args: []string{"-d", "{}"}, wantErr: true, }, { name: "missing flag value", args: []string{"/api/account/user/info", "-d"}, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotPath, gotFlags, err := splitCallArgs(tt.args) if tt.wantErr { if err == nil { t.Fatal("expected error") } return } if err != nil { t.Fatal(err) } if gotPath != tt.wantPath { t.Fatalf("path got %q want %q", gotPath, tt.wantPath) } if len(gotFlags) != len(tt.wantFlags) { t.Fatalf("flags got %#v want %#v", gotFlags, tt.wantFlags) } for i := range gotFlags { if gotFlags[i] != tt.wantFlags[i] { t.Fatalf("flags got %#v want %#v", gotFlags, tt.wantFlags) } } }) } }