| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package render
- import (
- "bytes"
- "encoding/json"
- "errors"
- "os"
- "path/filepath"
- "testing"
- "github.com/kotoyuuko/zenmux-usage-cli/internal/api"
- )
- func TestRenderJSONSingle_BytePassthrough(t *testing.T) {
- src, err := os.ReadFile(filepath.Join("..", "api", "testdata", "sample.json"))
- if err != nil {
- t.Fatal(err)
- }
- var buf bytes.Buffer
- if err := RenderJSONSingle(&buf, src); err != nil {
- t.Fatalf("RenderJSONSingle: %v", err)
- }
- // Output must parse as the same JSON body.
- var orig, got map[string]any
- if err := json.Unmarshal(src, &orig); err != nil {
- t.Fatalf("parse src: %v", err)
- }
- if err := json.Unmarshal(buf.Bytes(), &got); err != nil {
- t.Fatalf("parse out: %v", err)
- }
- origStr, _ := json.Marshal(orig)
- gotStr, _ := json.Marshal(got)
- if string(origStr) != string(gotStr) {
- t.Errorf("roundtrip mismatch:\nwant %s\n got %s", origStr, gotStr)
- }
- // Must end with a newline.
- if buf.Len() == 0 || buf.Bytes()[buf.Len()-1] != '\n' {
- t.Error("output should end with a newline")
- }
- }
- func TestRenderJSONMulti_ShapeAndOrder(t *testing.T) {
- src, _ := os.ReadFile(filepath.Join("..", "api", "testdata", "sample.json"))
- var r api.Response
- if err := json.Unmarshal(src, &r); err != nil {
- t.Fatalf("parse sample: %v", err)
- }
- results := []AccountResult{
- {Name: "personal", Response: &r},
- {Name: "work", Err: errors.New("authentication rejected: HTTP 401")},
- {Name: "extra", Response: &api.Response{Success: false, Error: "quota exhausted"}},
- }
- var buf bytes.Buffer
- if err := RenderJSONMulti(&buf, results); err != nil {
- t.Fatalf("RenderJSONMulti: %v", err)
- }
- var got []map[string]any
- if err := json.Unmarshal(buf.Bytes(), &got); err != nil {
- t.Fatalf("parse out: %v", err)
- }
- if len(got) != 3 {
- t.Fatalf("want 3 entries, got %d", len(got))
- }
- if got[0]["account"] != "personal" || got[1]["account"] != "work" || got[2]["account"] != "extra" {
- t.Errorf("order wrong: %+v", got)
- }
- // personal: success=true, data non-null, error=null
- if got[0]["success"] != true {
- t.Error("personal.success should be true")
- }
- if got[0]["data"] == nil {
- t.Error("personal.data should be populated")
- }
- if got[0]["error"] != nil {
- t.Errorf("personal.error should be null, got %v", got[0]["error"])
- }
- // work: success=false, data=null, error non-empty
- if got[1]["success"] != false {
- t.Error("work.success should be false")
- }
- if got[1]["data"] != nil {
- t.Error("work.data should be null")
- }
- if got[1]["error"] == nil || got[1]["error"].(string) == "" {
- t.Error("work.error should be non-empty")
- }
- // extra: API-level failure (success=false in body). data=null, error from payload.
- if got[2]["success"] != false {
- t.Error("extra.success should be false")
- }
- if got[2]["data"] != nil {
- t.Error("extra.data should be null")
- }
- if got[2]["error"].(string) != "quota exhausted" {
- t.Errorf("extra.error = %q, want quota exhausted", got[2]["error"])
- }
- }
|