diff --git a/spec/requests/articles/show_spec.cr b/spec/requests/articles/show_spec.cr new file mode 100644 index 0000000..56ad415 --- /dev/null +++ b/spec/requests/articles/show_spec.cr @@ -0,0 +1,71 @@ +require "../../spec_helper" + +class TestClient < MediumClient + class_property last_post_id : String = "" + + def self.post_data(post_id : String) : PostResponse::Root + self.last_post_id = post_id + PostResponse::Root.from_json <<-JSON + { + "data": { + "post": { + "title": "a title", + "createdAt": 0, + "creator": { "id": "0", "name": "username" }, + "content": { "bodyModel": { "paragraphs": [] } } + } + } + } + JSON + end +end + +class Articles::Show + def client_class + TestClient + end +end + +describe Articles::Show do + it "parses the post id for urls like /@user/:post_slug" do + HttpClient.get("/@user/my-post-111111abcdef") + + TestClient.last_post_id.should eq("111111abcdef") + end + + it "parses the post id for urls like /user/:post_slug" do + HttpClient.get("/user/my-post-222222abcdef") + + TestClient.last_post_id.should eq("222222abcdef") + end + + it "parses the post id for urls like /p/:post_slug" do + HttpClient.get("/p/my-post-333333abcdef") + + TestClient.last_post_id.should eq("333333abcdef") + end + + it "parses the post id for urls like /posts/:post_slug" do + HttpClient.get("/posts/my-post-444444abcdef") + + TestClient.last_post_id.should eq("444444abcdef") + end + + it "parses the post id for urls like /p/:post_id" do + HttpClient.get("/p/555555abcdef") + + TestClient.last_post_id.should eq("555555abcdef") + end + + it "parses the post id for urls like /:post_slug" do + HttpClient.get("/my-post-666666abcdef") + + TestClient.last_post_id.should eq("666666abcdef") + end + + it "parses the post id for urls like /https:/medium.com/@user/:post_slug" do + HttpClient.get("/https:/medium.com/@user/777777abcdef") + + TestClient.last_post_id.should eq("777777abcdef") + end +end diff --git a/spec/support/api_client.cr b/spec/support/api_client.cr deleted file mode 100644 index 6bd08dc..0000000 --- a/spec/support/api_client.cr +++ /dev/null @@ -1,6 +0,0 @@ -class ApiClient < Lucky::BaseHTTPClient - def initialize - super - headers("Content-Type": "application/json") - end -end diff --git a/spec/support/http_client.cr b/spec/support/http_client.cr new file mode 100644 index 0000000..b25118b --- /dev/null +++ b/spec/support/http_client.cr @@ -0,0 +1,2 @@ +class HttpClient < Lucky::BaseHTTPClient +end diff --git a/src/actions/articles/show.cr b/src/actions/articles/show.cr index 35a66f7..8bf9fa7 100644 --- a/src/actions/articles/show.cr +++ b/src/actions/articles/show.cr @@ -1,23 +1,34 @@ require "json" class Articles::Show < BrowserAction - get "/posts/:post_slug" do - id_match = post_slug.match(/([0-9a-f]{12})$/i) - if id_match - post_id = id_match[1] - else - return html( + fallback do + maybe_post_id = post_id(context.request.path) + case maybe_post_id + in Monads::Just + response = client_class.post_data(maybe_post_id.value!) + page = PageConverter.new.convert(response.data) + html ShowPage, page: page + in Monads::Nothing, Monads::Maybe + html( Errors::ShowPage, message: "Error parsing the URL", status: 500, ) end + end + + def post_id(request_path : String) + Monads::Try(Regex::MatchData) + .new(->{ request_path.match(/([0-9a-f]+)$/i) }) + .to_maybe + .fmap(->(matches : Regex::MatchData) { matches[1] }) + end + + def client_class if Lucky::Env.use_local? - response = LocalClient.post_data(post_id) + LocalClient else - response = MediumClient.post_data(post_id) + MediumClient end - page = PageConverter.new.convert(response.data) - html ShowPage, page: page end end