diff --git a/CHANGELOG b/CHANGELOG index a06f831..293d70d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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 diff --git a/spec/actions/articles/show_spec.cr b/spec/actions/articles/show_spec.cr new file mode 100644 index 0000000..88d6bc0 --- /dev/null +++ b/spec/actions/articles/show_spec.cr @@ -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 diff --git a/spec/classes/page_converter_spec.cr b/spec/classes/page_converter_spec.cr index 39f89e0..ccb07db 100644 --- a/spec/classes/page_converter_spec.cr +++ b/spec/classes/page_converter_spec.cr @@ -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} } } } diff --git a/spec/setup/clean_database.cr b/spec/setup/clean_database.cr deleted file mode 100644 index a1bc631..0000000 --- a/spec/setup/clean_database.cr +++ /dev/null @@ -1,3 +0,0 @@ -Spec.before_each do - AppDatabase.truncate -end diff --git a/spec/support/action_helpers.cr b/spec/support/action_helpers.cr new file mode 100644 index 0000000..70358b3 --- /dev/null +++ b/spec/support/action_helpers.cr @@ -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 diff --git a/src/actions/articles/show.cr b/src/actions/articles/show.cr index 15b65a7..9a09acc 100644 --- a/src/actions/articles/show.cr +++ b/src/actions/articles/show.cr @@ -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 diff --git a/src/actions/errors/show.cr b/src/actions/errors/show.cr index 0afdd0b..82c70b6 100644 --- a/src/actions/errors/show.cr +++ b/src/actions/errors/show.cr @@ -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 diff --git a/src/classes/page_converter.cr b/src/classes/page_converter.cr index a277f96..fb454cd 100644 --- a/src/classes/page_converter.cr +++ b/src/classes/page_converter.cr @@ -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 diff --git a/src/models/missing_page.cr b/src/models/missing_page.cr new file mode 100644 index 0000000..72ce452 --- /dev/null +++ b/src/models/missing_page.cr @@ -0,0 +1,5 @@ +class MissingPage +end + +class MissingPageError < Exception +end diff --git a/src/models/post_response.cr b/src/models/post_response.cr index 478884b..b295ffd 100644 --- a/src/models/post_response.cr +++ b/src/models/post_response.cr @@ -8,7 +8,7 @@ class PostResponse end class Data < Base - property post : Post + property post : Post? end class Post < Base diff --git a/src/version.cr b/src/version.cr index a4c4b6c..a1ac6c2 100644 --- a/src/version.cr +++ b/src/version.cr @@ -1,3 +1,3 @@ module Scribe - VERSION = "2022-05-21" + VERSION = "2022-06-17" end