From 4cde8c19298cb8bc45e577e14b1a9c7ffe62be1e Mon Sep 17 00:00:00 2001 From: Bruce Bolt Date: Thu, 2 Jan 2025 11:04:33 +0000 Subject: [PATCH] Properly support multiple content types in details fields According to ADR-004, it is possible to represent content in an array format containing multiple types. This can include already parsed govspeak in HTML format or only govspeak. In the latter case, Publishing API parses this and converts to HTML before sending the content to Content Store. This replicates that behaviour for GraphQL responses, expanding this to all fields within `details`, not just the body. It also has the side effect of supporting embeddded content and full change history in GraphQL responses. --- app/graphql/types/edition_type.rb | 21 +++++------ spec/graphql/types/edition_type_spec.rb | 50 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/app/graphql/types/edition_type.rb b/app/graphql/types/edition_type.rb index a93e740f3..9c098834a 100644 --- a/app/graphql/types/edition_type.rb +++ b/app/graphql/types/edition_type.rb @@ -153,17 +153,6 @@ class WhipOrganisation < Types::BaseObject field :supports_historical_accounts, Boolean field :whip_organisation, WhipOrganisation field :world_locations, [EditionType], null: false - - def body - return object[:body] if object[:body].is_a?(String) - - govspeak = object.fetch(:body, []) - .filter { _1[:content_type] == "text/govspeak" } - .map { _1[:content] } - .first - - Govspeak::Document.new(govspeak).to_html if govspeak.present? - end end field :active, Boolean, null: false @@ -197,6 +186,16 @@ def body field :web_url, String field :withdrawn_notice, WithdrawnNotice + def details + Presenters::ContentTypeResolver.new("text/html").resolve( + Presenters::DetailsPresenter.new( + object.to_h[:details], + Presenters::ChangeHistoryPresenter.new(object), + Presenters::ContentEmbedPresenter.new(object), + ).details, + ) + end + def withdrawn_notice return nil unless object.unpublishing&.withdrawal? diff --git a/spec/graphql/types/edition_type_spec.rb b/spec/graphql/types/edition_type_spec.rb index 490e72b7e..ee02011dc 100644 --- a/spec/graphql/types/edition_type_spec.rb +++ b/spec/graphql/types/edition_type_spec.rb @@ -30,4 +30,54 @@ end end end + + context "content types in the details" do + context "when the body is a string" do + it "returns the string" do + edition = create(:edition, details: { body: "some text" }) + + expect( + run_graphql_field( + "Edition.details", + edition, + )[:body], + ).to eq("some text") + end + end + + context "when there are multiple content types and one is html" do + it "returns the html" do + edition = create(:edition, details: { + body: [ + { content_type: "text/govspeak", content: "some text" }, + { content_type: "text/html", content: "

some other text

" }, + ], + }) + + expect( + run_graphql_field( + "Edition.details", + edition, + )[:body], + ).to eq("

some other text

") + end + end + + context "when there are multiple content types and none are html" do + it "converts the govspeak to html" do + edition = create(:edition, details: { + body: [ + { content_type: "text/govspeak", content: "some text" }, + ], + }) + + expect( + run_graphql_field( + "Edition.details", + edition, + )[:body], + ).to eq("

some text

\n") + end + end + end end