package app import ( "strings" "testing" "github.com/krazywarez/devianter" ) // docText wraps a document body the way DeviantArt stores it. func docText(body string) devianter.Text { var t devianter.Text t.Html.Markup = `{"version":1,"document":{"type":"doc","content":[` + body + `]},"features":[]}` return t } func withDocConfig(t *testing.T) { t.Helper() proxy, uri, nsfw := CFG.Proxy, CFG.URI, CFG.Nsfw CFG.Proxy, CFG.URI, CFG.Nsfw = true, "/", true t.Cleanup(func() { CFG.Proxy, CFG.URI, CFG.Nsfw = proxy, uri, nsfw }) } // TestDocumentParagraphsMarksAndBreaks uses the shape seen on live // descriptions: paragraphs of text with link, underline and italic marks. func TestDocumentParagraphsMarksAndBreaks(t *testing.T) { withDocConfig(t) out := ParseDescription("http://localhost", docText(` {"type":"paragraph","attrs":{"textAlign":"center"},"content":[ {"type":"text","text":"| "}, {"type":"text","marks":[{"type":"link","attrs":{"href":"https://www.deviantart.com/users/outgoing?https://www.patreon.com/x","target":"_blank"}},{"type":"underline"}],"text":"PATREON"}, {"type":"hardBreak"}, {"type":"text","marks":[{"type":"italic"}],"text":"Finished for "}, {"type":"text","marks":[{"type":"textStyle"}],"text":"plain"} ]}`)) for _, want := range []string{ `

| PATREON
Finished <YCH> for plain

`, } { if !strings.Contains(out, want) { t.Errorf("output lacks %q:\n%s", want, out) } } } func TestDocumentBlocksAndLists(t *testing.T) { withDocConfig(t) out := ParseDescription("http://localhost", docText(` {"type":"heading","attrs":{"level":1},"content":[{"type":"text","text":"Title"}]}, {"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"one"}]}]}]}, {"type":"orderedList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"two"}]}]}]}, {"type":"blockquote","content":[{"type":"paragraph","content":[{"type":"text","text":"quoted"}]}]}, {"type":"codeBlock","content":[{"type":"text","text":"x < y"}]}, {"type":"horizontalRule"}, {"type":"mystery","content":[{"type":"text","text":"still shown"}]}, {"type":"mysteryLeaf","attrs":{"x":1}}`)) for _, want := range []string{"

Title

", "", "
  1. two

", "

quoted

", "
x < y
", "
", "still shown"} { if !strings.Contains(out, want) { t.Errorf("output lacks %q:\n%s", want, out) } } } // TestDocumentEmotes is the new-format half of #6: an official emote with a // source image maps to the emote route by file name, one without a source // falls back to its code. func TestDocumentEmotes(t *testing.T) { withDocConfig(t) out := ParseDescription("http://localhost", docText(` {"type":"paragraph","content":[ {"type":"da-emote","attrs":{"data-emote":":star:","data-type":"official","src":"https://e.deviantart.net/emoticons/s/star_full.gif","width":17,"height":16,"url":null,"title":null}}, {"type":"da-emote","attrs":{"data-emote":":love:","data-type":"official","src":null,"width":null,"height":null,"url":null,"title":null}}, {"type":"da-emote","attrs":{"data-emote":"","data-type":"custom","src":null}} ]}`)) for _, want := range []string{`src="http://localhost/media/emojitar/star_full?type=e" alt=":star:"`, `src="http://localhost/media/emojitar/love?type=e" alt=":love:"`} { if !strings.Contains(out, want) { t.Errorf("output lacks %q:\n%s", want, out) } } if strings.Count(out, "`, `src="http://localhost/media/file/abc/`, `alt="AShiori-chan - [CLOSED] YCH"`, `[GIF]`} { if !strings.Contains(out, want) { t.Errorf("output lacks %q:\n%s", want, out) } } } func TestDocumentHidesEmbeddedNSFWWhenDisabled(t *testing.T) { withDocConfig(t) CFG.Nsfw = false out := ParseDescription("http://localhost", docText(` {"type":"paragraph","content":[{"type":"da-deviation","attrs":{"deviation":{"deviationId":1,"isMature":true,"url":"https://www.deviantart.com/a/art/b-1","title":"secret","author":{"username":"a"}}}}]}`)) if strings.Contains(out, "secret") { t.Errorf("mature embed shown with nsfw off:\n%s", out) } } // TestDraftJSAndHTMLStillDispatch pins that the two older formats still reach // their own parsers. func TestDraftJSAndHTMLStillDispatch(t *testing.T) { withDocConfig(t) var draft devianter.Text draft.Html.Markup = `{"blocks":[{"text":"draft text","type":"unstyled","inlineStyleRanges":[],"entityRanges":[],"data":{}}],"entityMap":{}}` if out := ParseDescription("http://localhost", draft); !strings.Contains(out, "draft text") { t.Errorf("Draft.js description not rendered:\n%s", out) } var legacy devianter.Text legacy.Html.Markup = `plain html` if out := ParseDescription("http://localhost", legacy); !strings.Contains(out, "html") { t.Errorf("HTML description not rendered:\n%s", out) } }