diff --git a/Gemfile b/Gemfile index 5d0dc4b58..a2732d4f9 100644 --- a/Gemfile +++ b/Gemfile @@ -125,6 +125,7 @@ group :test do # gem 'simplecov', require: false gem 'vcr' gem 'webmock' + gem 'graphql-client' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/Gemfile.lock b/Gemfile.lock index 4a60500d8..7925485c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -204,6 +204,9 @@ GEM railties sprockets-rails graphql (2.0.9) + graphql-client (0.18.0) + activesupport (>= 3.0) + graphql groupdate (6.1.0) activesupport (>= 5.2) guard (2.18.0) @@ -555,6 +558,7 @@ DEPENDENCIES geocoder (~> 1.6.0) graphiql-rails graphql + graphql-client groupdate guard guard-livereload (~> 2.5) diff --git a/app/graphql/types/article_type.rb b/app/graphql/types/article_type.rb index 3c163bfac..4563ab720 100644 --- a/app/graphql/types/article_type.rb +++ b/app/graphql/types/article_type.rb @@ -29,8 +29,7 @@ class ArticleType < Types::BaseObject method: :body field :image, String, - description: 'The image of the article (a URL)', - method: :highres_image + description: 'The image of the article (a URL)' field :date_published, GraphQL::Types::ISO8601DateTime, description: 'Date that the article was published on PlaceCal', @@ -50,5 +49,15 @@ class ArticleType < Types::BaseObject # creativeWorkStatus: string, from is_draft # author: person, from user + + def image + return nil unless object.article_image_url.present? + + url = URI::HTTP.build(Rails.application.default_url_options) + url.scheme = Rails.application.default_url_options[:protocol] + url.path = object.article_image_url + + url.to_s + end end end diff --git a/app/graphql/types/partner_type.rb b/app/graphql/types/partner_type.rb index 362c9fb06..fe1ffc7b8 100644 --- a/app/graphql/types/partner_type.rb +++ b/app/graphql/types/partner_type.rb @@ -68,6 +68,7 @@ def logo return nil unless object.logo_url.present? url = URI::HTTP.build(Rails.application.default_url_options) + url.scheme = Rails.application.default_url_options[:protocol] url.path = object.logo_url url.to_s diff --git a/test/fixtures/files/good-cat-picture.jpg b/test/fixtures/files/good-cat-picture.jpg new file mode 100644 index 000000000..f39cc186b Binary files /dev/null and b/test/fixtures/files/good-cat-picture.jpg differ diff --git a/test/system/graphql/graphql_test.rb b/test/system/graphql/graphql_test.rb new file mode 100644 index 000000000..696c30e9e --- /dev/null +++ b/test/system/graphql/graphql_test.rb @@ -0,0 +1,148 @@ +require_relative "../application_system_test_case" + +=begin + +This is basically a stand alone script that pokes the GraphQL endpoint +running on the server through a network connection (just as how users +will use the endpoint on staging/production). It does not use any +internal code like /test/integration/graphql/* + +We could be being overly paranoid here but it may become useful for +catching the kind of bugs that only show up on a real network +connection. + +NOTE: we are mainly interested in testing the endpoints that +the Trans Dimension elm app uses. +=end + +require 'graphql/client' +require 'graphql/client/http' + + +module PlaceCalApi + extend self + + PING_QUERY_STRING = + "query { ping }" + + ARTICLE_CONNECTION_QUERY_STRING = <<-QUERY + query { articleConnection { edges { + node { + articleBody + datePublished + headline + providers { id } + image + } } } } + QUERY + + PARTNERS_BY_TAG_QUERY_STRING = <<-QUERY + query($tagId: ID!) { + partnersByTag(tagId: $tagId) { + id + name + description + summary + contact { email, telephone } + url + address { streetAddress, postalCode, addressRegion, geo { latitude, longitude } } + areasServed { name abbreviatedName } + logo + } } + QUERY + + + def configure(default_url_options) + @url = URI::HTTP::build(default_url_options) + @url.path = '/api/v1/graphql' + + @http = GraphQL::Client::HTTP.new(@url.to_s) + @schema = GraphQL::Client.load_schema(@http) + @client = GraphQL::Client.new(schema: @schema, execute: @http) + + define_constant 'PingQuery', @client.parse(PING_QUERY_STRING) + + define_constant 'ArticleConnectionQuery', @client.parse(ARTICLE_CONNECTION_QUERY_STRING) + + define_constant 'PartnersByTagQuery', @client.parse(PARTNERS_BY_TAG_QUERY_STRING) + end + + # the API endpoints + def do_ping_query + @client.query PingQuery + end + + def do_article_connection_query + @client.query ArticleConnectionQuery + end + + def do_partners_by_tag_query(tag_id) + @client.query PartnersByTagQuery, variables: { 'tagId': tag_id } + end + + private + + def define_constant(name, value) + return if const_defined?(name) + const_set name, value + end +end + + +class GraphQLTest < ApplicationSystemTestCase + # This tests a number of small (critical) bits of the GraphQL + # system so its name is bit generic + # TODO: maybe more tests covering the API? + + include ActionDispatch::TestProcess::FixtureFile + + setup do + # test that we are sending back the correct protocol as well + Rails.application.default_url_options[:protocol] = 'https' + + create_default_site + + @server = Capybara.current_session.server + + app_routes = Rails.application.routes + app_routes.default_url_options[:host] = @server.host + app_routes.default_url_options[:port] = @server.port + + PlaceCalApi.configure app_routes.default_url_options + end + + test "ping works" do + result = PlaceCalApi.do_ping_query + assert result.errors.empty? + assert result.data.ping =~ /^Hello World! The time is \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, + 'missing PING data response' + end + + test 'news article connection with image url' do + upload = fixture_file_upload('good-cat-picture.jpg') + article = create(:article, article_image: upload) + + result = PlaceCalApi.do_article_connection_query + + article = result.data.article_connection.edges.first.node.to_h + assert article, 'article node not found' + + url = article['image'] + assert url =~ %r{\Ahttps://#{@server.host}:#{@server.port}/}, 'article image is not full URL' + end + + test 'partners by tag has correct logo url' do + upload = fixture_file_upload('good-cat-picture.jpg') + partner = create(:partner, image: upload) + tag = create(:tag) + partner.tags << tag + + result = PlaceCalApi.do_partners_by_tag_query(tag.id) + partner = result.data.partners_by_tag.first.to_h + assert partner + + url = partner['logo'] + assert url =~ %r{\Ahttps://#{@server.host}:#{@server.port}/}, 'partner logo is not full URL' + end +end +