f7ad92f4bf
The post id 34dead42a28 contained a new paragraph type: H2. Previously the only known header types were H3 and H4. In this case, the paragraph doesn't actually get rendered because it's the page title which is removed from the page nodes (see commits6baba803
and thenfba87c10
). However, it somehow an author is able to get an H2 paragraph into the page, it will display as an <h1> just as H3 displays as <h2> and H4 displays as <h3>.
428 lines
10 KiB
Crystal
428 lines
10 KiB
Crystal
require "../spec_helper"
|
|
|
|
include Nodes
|
|
|
|
describe PageContent do
|
|
it "renders a single parent/child node structure" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Paragraph.new(children: [
|
|
Text.new(content: "hi"),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p>hi</p>)
|
|
end
|
|
|
|
it "renders multiple childrens" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Paragraph.new(children: [
|
|
Text.new(content: "Hello, "),
|
|
Emphasis.new(children: [
|
|
Text.new(content: "World!"),
|
|
] of Child),
|
|
] of Child),
|
|
UnorderedList.new(children: [
|
|
ListItem.new(children: [
|
|
Text.new(content: "List!"),
|
|
] of Child),
|
|
ListItem.new(children: [
|
|
Text.new(content: "Again!"),
|
|
] of Child),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p>Hello, <em>World!</em></p><ul><li>List!</li><li>Again!</li></ul>)
|
|
end
|
|
|
|
it "renders an anchor" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Anchor.new(children: [Text.new("link")] of Child, href: "https://example.com"),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<a href="https://example.com">link</a>)
|
|
end
|
|
|
|
it "renders a blockquote" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
BlockQuote.new(children: [
|
|
Text.new("Wayne Gretzky. Michael Scott."),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<blockquote><p>Wayne Gretzky. Michael Scott.</p></blockquote>)
|
|
end
|
|
|
|
it "renders code" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Code.new(children: [
|
|
Text.new("foo = bar"),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<code>foo = bar</code>)
|
|
end
|
|
|
|
it "renders empasis" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Paragraph.new(children: [
|
|
Text.new(content: "This is "),
|
|
Emphasis.new(children: [
|
|
Text.new(content: "neat!"),
|
|
] of Child),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p>This is <em>neat!</em></p>)
|
|
end
|
|
|
|
it "renders a figure and figure caption" do
|
|
children = [Text.new("A caption")] of Child
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Figure.new(children: [
|
|
Image.new(src: "image.png", originalWidth: 100, originalHeight: 200),
|
|
FigureCaption.new(children: children),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq stripped_html <<-HTML
|
|
<figure>
|
|
<img src="https://cdn-images-1.medium.com/fit/c/100/200/image.png" width="100">
|
|
<label class="margin-toggle" for="#{children.hash}">✍︎</label>
|
|
<input class="margin-toggle" type="checkbox" id="#{children.hash}">
|
|
<span class="marginnote">
|
|
A caption
|
|
</span>
|
|
</figure>
|
|
HTML
|
|
end
|
|
|
|
it "renders a GitHub Gist" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
GithubGist.new(href: "https://gist.github.com/user/some_id"),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq stripped_html <<-HTML
|
|
<script src="https://gist.github.com/user/some_id.js"></script>
|
|
HTML
|
|
end
|
|
|
|
it "renders an H2" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Heading1.new(children: [
|
|
Text.new(content: "Title!"),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<h1>Title!</h1>)
|
|
end
|
|
|
|
it "renders an H3" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Heading2.new(children: [
|
|
Text.new(content: "Title!"),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<h2>Title!</h2>)
|
|
end
|
|
|
|
it "renders an H4" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Heading3.new(children: [
|
|
Text.new(content: "In Conclusion..."),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<h3>In Conclusion...</h3>)
|
|
end
|
|
|
|
it "renders an image" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Paragraph.new(children: [
|
|
Image.new(src: "image.png", originalWidth: 100, originalHeight: 200),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq stripped_html <<-HTML
|
|
<p>
|
|
<img src="https://cdn-images-1.medium.com/fit/c/100/200/image.png" width="100">
|
|
</p>
|
|
HTML
|
|
end
|
|
|
|
it "renders embedded content" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
EmbeddedContent.new(
|
|
src: "https://example.com",
|
|
originalWidth: 1000,
|
|
originalHeight: 600,
|
|
),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq stripped_html <<-HTML
|
|
<figure>
|
|
<iframe src="https://example.com" width="800" height="480" frameborder="0" allowfullscreen="true">
|
|
</iframe>
|
|
</figure>
|
|
HTML
|
|
end
|
|
|
|
it "renders an embedded link container" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Paragraph.new(children: [
|
|
EmbeddedLink.new(href: "https://example.com"),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq stripped_html <<-HTML
|
|
<p>
|
|
<figure>
|
|
<a href="https://example.com">Embedded content at example.com</a>
|
|
</figure>
|
|
</p>
|
|
HTML
|
|
end
|
|
|
|
it "renders an mixtape embed container" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Paragraph.new(children: [
|
|
MixtapeEmbed.new(children: [
|
|
Anchor.new(
|
|
children: [Text.new("Mixtape")] of Child,
|
|
href: "https://example.com"
|
|
),
|
|
] of Child),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq stripped_html <<-HTML
|
|
<p>
|
|
<blockquote>
|
|
<p>
|
|
<a href="https://example.com">Mixtape</a>
|
|
</p>
|
|
</blockquote>
|
|
</p>
|
|
HTML
|
|
end
|
|
|
|
it "renders an ordered list" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
OrderedList.new(children: [
|
|
ListItem.new(children: [Text.new("One")] of Child),
|
|
ListItem.new(children: [Text.new("Two")] of Child),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<ol><li>One</li><li>Two</li></ol>)
|
|
end
|
|
|
|
it "renders an preformatted text" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Paragraph.new(children: [
|
|
Text.new("Hello, world!"),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p>Hello, world!</p>)
|
|
end
|
|
|
|
it "renders an preformatted text" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Preformatted.new(children: [
|
|
Text.new("New\nline"),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<pre>New\nline</pre>)
|
|
end
|
|
|
|
it "renders strong text" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
Strong.new(children: [
|
|
Text.new("Oh yeah!"),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<strong>Oh yeah!</strong>)
|
|
end
|
|
|
|
it "renders an unordered list" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
UnorderedList.new(children: [
|
|
ListItem.new(children: [Text.new("Apple")] of Child),
|
|
ListItem.new(children: [Text.new("Banana")] of Child),
|
|
] of Child),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<ul><li>Apple</li><li>Banana</li></ul>)
|
|
end
|
|
|
|
it "renders a user anchor" do
|
|
page = Page.new(
|
|
title: "Title",
|
|
author: user_anchor_factory,
|
|
created_at: Time.local,
|
|
nodes: [
|
|
UserAnchor.new(children: [Text.new("Some User")] of Child, user_id: "abc123"),
|
|
] of Child
|
|
)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<a href="https://medium.com/u/abc123">Some User</a>)
|
|
end
|
|
end
|
|
|
|
def stripped_html(html : String)
|
|
html.gsub(/\n\s*/, "").strip
|
|
end
|
|
|
|
def user_anchor_factory(username = "someone", user_id = "abc123")
|
|
PostResponse::Creator.from_json <<-JSON
|
|
{
|
|
"id": "#{user_id}",
|
|
"name": "#{username}"
|
|
}
|
|
JSON
|
|
end
|