From 91069a72367ea2d3ed9bc88be636650536637457 Mon Sep 17 00:00:00 2001 From: Bruce Bolt Date: Wed, 30 Oct 2024 15:36:46 +0000 Subject: [PATCH] Use GraphQL for rendering World Index page This will allow us to build a proof of concept for using GraphQL on GOV.UK. It will run alongside the existing retrieval from Content Store to allow us to switch the rendering used in different environment, through a feature flag or A-B test. The feature is switched on by adding a `GRAPHQL_FEATURE_FLAG` environment variable. --- app/controllers/world_controller.rb | 10 +++- app/models/world_index_graphql.rb | 14 ++++++ .../world_index_presenter_graphql.rb | 15 ++++++ app/queries/graphql/world_index_query.rb | 31 ++++++++++++ spec/controllers/world_controller_spec.rb | 49 +++++++++++++++++-- 5 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 app/models/world_index_graphql.rb create mode 100644 app/presenters/world_index_presenter_graphql.rb create mode 100644 app/queries/graphql/world_index_query.rb diff --git a/app/controllers/world_controller.rb b/app/controllers/world_controller.rb index 3c3b84d2b..6d24dddc5 100644 --- a/app/controllers/world_controller.rb +++ b/app/controllers/world_controller.rb @@ -1,7 +1,13 @@ class WorldController < ApplicationController def index - index = WorldIndex.find!("/world") - @presented_index = WorldIndexPresenter.new(index) + if ENV["GRAPHQL_FEATURE_FLAG"] + index = WorldIndexGraphql.find!("/world") + @presented_index = WorldIndexPresenterGraphql.new(index) + else + index = WorldIndex.find!("/world") + @presented_index = WorldIndexPresenter.new(index) + end + setup_content_item_and_navigation_helpers(index) end end diff --git a/app/models/world_index_graphql.rb b/app/models/world_index_graphql.rb new file mode 100644 index 000000000..fc717724e --- /dev/null +++ b/app/models/world_index_graphql.rb @@ -0,0 +1,14 @@ +class WorldIndexGraphql + attr_reader :content_item + + def initialize(content_item) + @content_item = content_item + end + + def self.find!(base_path) + query = Graphql::WorldIndexQuery.new(base_path).query + + edition = Services.publishing_api.graphql_query(query).dig("data", "edition") + new(edition) + end +end diff --git a/app/presenters/world_index_presenter_graphql.rb b/app/presenters/world_index_presenter_graphql.rb new file mode 100644 index 000000000..526c61618 --- /dev/null +++ b/app/presenters/world_index_presenter_graphql.rb @@ -0,0 +1,15 @@ +class WorldIndexPresenterGraphql < WorldIndexPresenter + def title + @world_index.content_item["title"] + end + + def international_delegations + @world_index.content_item["internationalDelegations"] + end + +private + + def world_locations + @world_index.content_item["worldLocations"] + end +end diff --git a/app/queries/graphql/world_index_query.rb b/app/queries/graphql/world_index_query.rb new file mode 100644 index 000000000..0c45052a8 --- /dev/null +++ b/app/queries/graphql/world_index_query.rb @@ -0,0 +1,31 @@ +class Graphql::WorldIndexQuery + def initialize(base_path) + @base_path = base_path + end + + def query + <<-QUERY + fragment worldLocationInfo on WorldLocation { + active + name + slug + } + + { + edition(basePath: "#{@base_path}") { + ... on WorldIndex { + title + + worldLocations { + ...worldLocationInfo + } + + internationalDelegations { + ...worldLocationInfo + } + } + } + } + QUERY + end +end diff --git a/spec/controllers/world_controller_spec.rb b/spec/controllers/world_controller_spec.rb index ac3f20152..7c8934aca 100644 --- a/spec/controllers/world_controller_spec.rb +++ b/spec/controllers/world_controller_spec.rb @@ -1,12 +1,51 @@ RSpec.describe WorldController do describe "GET index" do - before do - stub_content_store_has_item("/world", GovukSchemas::Example.find("world_index", example_name: "world_index")) + context "without the GraphQL feature flag" do + before do + stub_content_store_has_item("/world", GovukSchemas::Example.find("world_index", example_name: "world_index")) + end + + it "has a success response" do + get :index + expect(response).to have_http_status(:success) + end end - it "has a success response" do - get :index - expect(response).to have_http_status(:success) + context "with the GraphQL feature flag" do + before do + stub_const("ENV", { "GRAPHQL_FEATURE_FLAG" => true }) + + graphql_query = Graphql::WorldIndexQuery.new("/world").query + + graphql_response = { + "data": { + "edition": { + "title": "Help and services around the world", + "worldLocations": [ + { + "active": true, + "name": "Test World Location", + "slug": "test-world-location", + }, + ], + "internationalDelegations": [ + { + "active": false, + "name": "Test International Delegation", + "slug": "test-international-delegation", + }, + ], + }, + }, + } + + stub_publishing_api_graphql_query(graphql_query, graphql_response) + end + + it "has a success response" do + get :index + expect(response).to have_http_status(:success) + end end end end