1package tinyclient23import (4 "strings"5 "testing"6)78func TestRoomAttachmentsParsesNIP92AndStripsReferences(t *testing.T) {9 url := "https://cdn.example.test/photo.png"10 row := map[string]any{"content": "Look  and " + url, "tags": [][]string{{"imeta", "url " + url, "m image/png", "x " + strings.Repeat("a", 64), "size 42", "alt a <photo>"}}}11 got := roomAttachments(row)12 if len(got) != 1 || got[0].URL != url || got[0].MIME != "image/png" || got[0].Hash != strings.Repeat("a", 64) || got[0].Size != 42 || got[0].Name != "a <photo>" {13 t.Fatalf("attachments = %#v", got)14 }15 if text := roomAttachmentContent(valueMap(row)["content"].(string), got); text != valueMap(row)["content"].(string) {16 t.Fatalf("content = %q", text)17 }18}1920func TestRoomAttachmentsRejectUnsafeAndBoundValues(t *testing.T) {21 long := strings.Repeat("x", 5000)22 row := map[string]any{"content": "https://cdn.example/file", "tags": [][]string{{"imeta", "url javascript:alert(1)", "m image/svg+xml"}, {"imeta", "url data:image/png;base64,abc", "m image/png"}, {"imeta", "url https://cdn.example/file", "m application/octet-stream", "filename " + long}}}23 got := roomAttachments(row)24 if len(got) != 1 || got[0].URL != "https://cdn.example/file" {25 t.Fatalf("unsafe attachments = %#v", got)26 }27}2829func TestRoomAttachmentsIgnoreCodeAndDeduplicate(t *testing.T) {30 url := "https://cdn.example.test/photo.png"31 row := map[string]any{"content": "`" + url + "`\n" + url, "tags": [][]string{{"imeta", "url " + url, "m image/png"}, {"imeta", "url " + url, "m image/png"}}}32 if got := roomAttachments(row); len(got) != 1 {33 t.Fatalf("attachments = %#v", got)34 }35 row["content"] = "```\n" + url + "\n```"36 if got := roomAttachments(row); len(got) != 0 {37 t.Fatalf("code attachment = %#v", got)38 }39}4041func TestRoomAttachmentMarkupEscapesAndClassifiesMedia(t *testing.T) {42 items := []roomAttachment{{URL: "https://cdn.example/a.mp4?a=1&b=2", MIME: "video/mp4", Name: "A \"clip\""}, {URL: "https://cdn.example/report.pdf", MIME: "application/pdf", Name: "report.pdf", Size: 2048}}43 markup := string(roomAttachmentMarkup(items))44 for _, want := range []string{"room-attachments", "<video", "controls", "report.pdf", "download", "2 KB"} {45 if !strings.Contains(markup, want) {46 t.Errorf("markup missing %q: %s", want, markup)47 }48 }49 if strings.Contains(markup, `class=`) || strings.Contains(markup, `javascript:`) {50 t.Fatalf("unsafe markup: %s", markup)51 }52}