diff --git a/lib/micropub/models/post_json_parser.rb b/lib/micropub/models/post_json_parser.rb new file mode 100644 index 0000000..d005a86 --- /dev/null +++ b/lib/micropub/models/post_json_parser.rb @@ -0,0 +1,38 @@ +class PostJSONParser + def initialize(json) + @data = JSON.parse(json) + end + + def params + { + "title" => title, + "content" => content, + "category" => category, + }.compact + end + + private + + attr_accessor :data + + def title + data.dig("properties", "title", 0) + end + + def content + data.dig("properties", "content", 0) || nested_content + end + + def nested_content + text = data.dig("properties", "content", "text", 0) + html = data.dig("properties", "content", "html", 0) + + return nil if text.nil? && html.nil? + + { "text" => text, "html" => html }.compact + end + + def category + data.dig("properties", "category") + end +end diff --git a/lib/micropub/webserver.rb b/lib/micropub/webserver.rb index b706f7b..9c76416 100644 --- a/lib/micropub/webserver.rb +++ b/lib/micropub/webserver.rb @@ -41,13 +41,17 @@ module Micropub def post_params if request.env["CONTENT_TYPE"] == "application/json" - request.body.rewind - JSON.parse(request.body.read) + json_params else params end end + def json_params + request.body.rewind + PostJSONParser.new(request.body.read).params + end + def valid_token? token = Indieauth::Token.new(endpoints.token_endpoint) diff --git a/test/lib/micropub/models/post_json_parser_test.rb b/test/lib/micropub/models/post_json_parser_test.rb new file mode 100644 index 0000000..e7a84d0 --- /dev/null +++ b/test/lib/micropub/models/post_json_parser_test.rb @@ -0,0 +1,79 @@ +require "test_helper" + +require "micropub/models/post_json_parser" + +describe PostJSONParser do + describe "#params" do + it "parses basic attributes" do + json = <<~JS + { + "type": ["h-entry"], + "properties": { + "content": ["Hello, World!"] + } + } + JS + + parser = PostJSONParser.new(json) + + _(parser.params).must_equal( + { "content" => "Hello, World!" } + ) + end + + it "parses content with nested text" do + json = <<~JS + { + "type": ["h-entry"], + "properties": { + "content": { + "text": ["Hello, World!"] + } + } + } + JS + + parser = PostJSONParser.new(json) + + _(parser.params).must_equal( + { "content" => { "text" => "Hello, World!" } } + ) + end + + it "parses content with nested html" do + json = <<~JS + { + "type": ["h-entry"], + "properties": { + "content": { + "html": ["
Hello, World!
"] + } + } + } + JS + + parser = PostJSONParser.new(json) + + _(parser.params).must_equal( + { "content" => { "html" => "Hello, World!
" } } + ) + end + + it "parses a single category" do + json = <<~JS + { + "type": ["h-entry"], + "properties": { + "category": ["test"] + } + } + JS + + parser = PostJSONParser.new(json) + + _(parser.params).must_equal( + { "category" => ["test"] } + ) + end + end +end diff --git a/test/requests/create_post_test.rb b/test/requests/create_post_test.rb index 3b5faf0..f238ff6 100644 --- a/test/requests/create_post_test.rb +++ b/test/requests/create_post_test.rb @@ -62,8 +62,11 @@ describe "create post" do it "creates a post with JSON" do post_json = { - content: "Hello, World!", - category: ["one", "two", "three"], + type: "h-entry", + properties: { + content: ["Hello, World!"], + category: ["one", "two", "three"], + }, }.to_json post "/micropub/main", post_json, { "CONTENT_TYPE" => "application/json" } @@ -76,8 +79,11 @@ describe "create post" do it "creates a post with JSON and HTML content" do post_json = { - content: { html: "Hello, World!
" }, - category: ["one", "two", "three"], + type: "h-entry", + properties: { + content: { html: ["Hello, World!
"] }, + category: ["one", "two", "three"], + }, }.to_json post "/micropub/main", post_json, { "CONTENT_TYPE" => "application/json" }