package docs import ( "archive/zip" "bytes" "encoding/json" "io" "net/http" "strings" "testing" ) // richDocJSON is a Tiptap document exercising headings, marks, and a list — // including CJK text, which every format must carry through intact. const richDocJSON = `{"type":"doc","content":[` + `{"type":"heading","attrs":{"level":2},"content":[{"type":"text","text":"My Section"}]},` + `{"type":"paragraph","content":[{"type":"text","text":"Hello "},{"type":"text","marks":[{"type":"bold"}],"text":"world"},{"type":"text","text":" 你好"}]},` + `{"type":"bulletList","content":[` + `{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"first"}]}]},` + `{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"second"}]}]}` + `]}` + `]}` func seedRichDoc(t *testing.T, srv http.Handler) string { t.Helper() id := newDoc(t, srv) body := `{"title":"日记 Diary","content":` + jsonString(richDocJSON) + `,"content_text":"My Section\nHello world 你好\nfirst\nsecond","word_count":6}` if rec := do(t, srv, http.MethodPut, "/"+id, body); rec.Code != http.StatusOK { t.Fatalf("seed rich doc: code=%d body=%s", rec.Code, rec.Body) } return id } // jsonString quotes a string as a JSON string literal (so the Tiptap JSON can be // embedded as the "content" field value). func jsonString(s string) string { b, _ := json.Marshal(s) return string(b) } func TestExportMarkdown(t *testing.T) { srv := newTestServer(t) id := seedRichDoc(t, srv) rec := do(t, srv, http.MethodGet, "/"+id+"/export?format=md", "") if rec.Code != http.StatusOK { t.Fatalf("export md: code=%d body=%s", rec.Code, rec.Body) } if ct := rec.Header().Get("Content-Type"); !strings.HasPrefix(ct, "text/markdown") { t.Fatalf("unexpected content-type: %q", ct) } out := rec.Body.String() for _, want := range []string{"## My Section", "**world**", "你好", "- first", "- second"} { if !strings.Contains(out, want) { t.Fatalf("markdown missing %q in:\n%s", want, out) } } // CJK filename must survive in the RFC 5987 form. if cd := rec.Header().Get("Content-Disposition"); !strings.Contains(cd, "filename*=UTF-8''") { t.Fatalf("expected RFC 5987 filename, got %q", cd) } } func TestExportHTML(t *testing.T) { srv := newTestServer(t) id := seedRichDoc(t, srv) rec := do(t, srv, http.MethodGet, "/"+id+"/export?format=html", "") out := rec.Body.String() for _, want := range []string{"", "