M CHANGELOG => CHANGELOG +4 -0
@@ 1,5 1,9 @@
2022-05-21
+* Show error page for missing posts
+
+2022-05-21
+
* Remove the need for a fake DATABASE_URL
2022-04-04
A spec/actions/articles/show_spec.cr => spec/actions/articles/show_spec.cr +15 -0
@@ 0,0 1,15 @@
+require "../../spec_helper"
+
+include ActionHelpers
+
+describe Articles::Show do
+ context "if the article is missing" do
+ it "should raise a MissingPageError" do
+ context = action_context(path: "/abc123")
+
+ expect_raises(MissingPageError) do
+ Articles::Show.new(context, params).call
+ end
+ end
+ end
+end
M spec/classes/page_converter_spec.cr => spec/classes/page_converter_spec.cr +38 -44
@@ 17,8 17,8 @@ describe PageConverter do
}
]
JSON
- data_json = default_data_json(title, paragraph_json)
- data = PostResponse::Data.from_json(data_json)
+ data_json = default_post_json(title, paragraph_json)
+ data = PostResponse::Post.from_json(data_json)
page = PageConverter.new.convert(data)
@@ 26,52 26,48 @@ describe PageConverter do
end
it "sets the author" do
- data_json = <<-JSON
+ post_json = <<-JSON
{
- "post": {
- "title": "This is a story",
- "createdAt": 0,
- "creator": {
- "id": "abc123",
- "name": "Author"
- },
- "content": {
- "bodyModel": {
- "paragraphs": []
- }
+ "title": "This is a story",
+ "createdAt": 0,
+ "creator": {
+ "id": "abc123",
+ "name": "Author"
+ },
+ "content": {
+ "bodyModel": {
+ "paragraphs": []
}
}
}
JSON
- data = PostResponse::Data.from_json(data_json)
+ post = PostResponse::Post.from_json(post_json)
- page = PageConverter.new.convert(data)
+ page = PageConverter.new.convert(post)
page.author.name.should eq "Author"
page.author.id.should eq "abc123"
end
it "sets the publish date/time" do
- data_json = <<-JSON
+ post_json = <<-JSON
{
- "post": {
- "title": "This is a story",
- "createdAt": 1000,
- "creator": {
- "id": "abc123",
- "name": "Author"
- },
- "content": {
- "bodyModel": {
- "paragraphs": []
- }
+ "title": "This is a story",
+ "createdAt": 1000,
+ "creator": {
+ "id": "abc123",
+ "name": "Author"
+ },
+ "content": {
+ "bodyModel": {
+ "paragraphs": []
}
}
}
JSON
- data = PostResponse::Data.from_json(data_json)
+ post = PostResponse::Post.from_json(post_json)
- page = PageConverter.new.convert(data)
+ page = PageConverter.new.convert(post)
page.created_at.should eq Time.utc(1970, 1, 1, 0, 0, 1)
end
@@ 98,8 94,8 @@ describe PageConverter do
}
]
JSON
- data_json = default_data_json(title, paragraph_json)
- data = PostResponse::Data.from_json(data_json)
+ post_json = default_post_json(title, paragraph_json)
+ data = PostResponse::Post.from_json(post_json)
page = PageConverter.new.convert(data)
@@ 115,23 111,21 @@ def default_paragraph_json
"[]"
end
-def default_data_json(
+def default_post_json(
title : String = "This is a story",
paragraph_json : String = default_paragraph_json
)
<<-JSON
{
- "post": {
- "title": "#{title}",
- "createdAt": 1628974309758,
- "creator": {
- "id": "abc123",
- "name": "Author"
- },
- "content": {
- "bodyModel": {
- "paragraphs": #{paragraph_json}
- }
+ "title": "#{title}",
+ "createdAt": 1628974309758,
+ "creator": {
+ "id": "abc123",
+ "name": "Author"
+ },
+ "content": {
+ "bodyModel": {
+ "paragraphs": #{paragraph_json}
}
}
}
D spec/setup/clean_database.cr => spec/setup/clean_database.cr +0 -3
@@ 1,3 0,0 @@
-Spec.before_each do
- AppDatabase.truncate
-end
A spec/support/action_helpers.cr => spec/support/action_helpers.cr +12 -0
@@ 0,0 1,12 @@
+module ActionHelpers
+ private def action_context(path = "/")
+ io = IO::Memory.new
+ request = HTTP::Request.new("GET", path)
+ response = HTTP::Server::Response.new(io)
+ HTTP::Server::Context.new(request, response)
+ end
+
+ private def params
+ {} of String => String
+ end
+end
M src/actions/articles/show.cr => src/actions/articles/show.cr +10 -2
@@ 6,8 6,8 @@ class Articles::Show < BrowserAction
case post_id
in Monads::Just
response = client_class.post_data(post_id.value!)
- page = PageConverter.new.convert(response.data)
- html ShowPage, page: page
+ page = PageConverter.new.convert(response.data.post)
+ render_page(page)
in Monads::Nothing, Monads::Maybe
html(
Errors::ParseErrorPage,
@@ 18,6 18,14 @@ class Articles::Show < BrowserAction
end
end
+ def render_page(page : Page)
+ html ShowPage, page: page
+ end
+
+ def render_page(page : MissingPage)
+ raise MissingPageError.new
+ end
+
def client_class
if use_local?
LocalClient
M src/actions/errors/show.cr => src/actions/errors/show.cr +4 -0
@@ 4,6 4,10 @@ class Errors::Show < Lucky::ErrorAction
default_format :html
dont_report [Lucky::RouteNotFoundError, Avram::RecordNotFoundError]
+ def render(error : MissingPageError)
+ error_html message: "This article is missing.", status: 404
+ end
+
def render(error : Lucky::RouteNotFoundError | Avram::RecordNotFoundError)
if html?
error_html "Sorry, we couldn't find that page.", status: 404
M src/classes/page_converter.cr => src/classes/page_converter.cr +12 -8
@@ 1,20 1,24 @@
class PageConverter
- def convert(data : PostResponse::Data) : Page
- title, content = title_and_content(data)
- author = data.post.creator
- created_at = Time.unix_ms(data.post.createdAt)
+ def convert(post : PostResponse::Post) : Page
+ title, content = title_and_content(post)
+ author = post.creator
+ created_at = Time.unix_ms(post.createdAt)
gist_store = gist_store(content)
Page.new(
title: title,
author: author,
- created_at: Time.unix_ms(data.post.createdAt),
+ created_at: Time.unix_ms(post.createdAt),
nodes: ParagraphConverter.new.convert(content, gist_store)
)
end
- def title_and_content(data : PostResponse::Data) : {String, Array(PostResponse::Paragraph)}
- title = data.post.title
- paragraphs = data.post.content.bodyModel.paragraphs
+ def convert(post : Nil) : MissingPage
+ MissingPage.new
+ end
+
+ def title_and_content(post : PostResponse::Post) : {String, Array(PostResponse::Paragraph)}
+ title = post.title
+ paragraphs = post.content.bodyModel.paragraphs
non_content_paragraphs = paragraphs.reject { |para| para.text == title }
{title, non_content_paragraphs}
end
A src/models/missing_page.cr => src/models/missing_page.cr +5 -0
@@ 0,0 1,5 @@
+class MissingPage
+end
+
+class MissingPageError < Exception
+end
M src/models/post_response.cr => src/models/post_response.cr +1 -1
@@ 8,7 8,7 @@ class PostResponse
end
class Data < Base
- property post : Post
+ property post : Post?
end
class Post < Base
M src/version.cr => src/version.cr +1 -1
@@ 1,3 1,3 @@
module Scribe
- VERSION = "2022-05-21"
+ VERSION = "2022-06-17"
end