Graphql-ruby: Performing a request spec with RSpec

Created on 16 Aug 2018  路  6Comments  路  Source: rmosolgo/graphql-ruby

Is it possible to perform a request spec against the graphql endpoint?
Example:

require "rails_helper"
require 'graphql'
describe "building_permits" do
  it "returns a collection of building permits" do
    building_permit = create(:building_permit)

    post "/graphql", params: { "query"=>"{\n  buildingPermits(limit: 10) {\n    id\n  }\n}" }

    response_body = JSON.parse(response.body)

    expect(response_body).to eq( 
      {"data"=>{"buildingPermits"=>[{"id"=>building_permit.id}]}}
    )
  end
end

I'm always getting an empty result.

       expected: {"data"=>{"buildingPermits"=>[{"id"=>110}]}}
            got: {"data"=>{"buildingPermits"=>[]}}

Most helpful comment

:rage1: SPRINGGGGGGG :rage3:

All 6 comments

Yes, I certainly _expect_ it to work! Have you tried some debugging in your buildingPermits field to make sure:

  • It's being called
  • It's finding items in the database
  • Before returning, the result has the expected entries

If those aren't the case, the next thing to check is _why_ those wouldn't happen (eg, authorization, default_scope ....)

I verified its being called. I dropped the following in the graphql controller as well as the test itself:

p BuildingPermit.all

and see the ActiveRecordRelation with my BuildingPermit.

There isn't any authorization on this project yet (it's pretty new).

I also tested the same query using curl and it works. Additionally the query works with graphiql and the React front end client I created.

I'll create a second project and try to reproduce the issue and share the repo.

How weird! You mentioned that you put it in the controller and the test, but did you put debugging in the buildingPermits field? I wonder if BuildingPermit.all would return anything during that field.

Also, how does limit: 10 work in your schema?

A repro would be great, I don't really have any leads 馃槚

...one last detail, I an endpoint for the resource and its request spec works:

module Api
  module V1
    class BuildingPermitsController < ApplicationController
      def index
        render json: BuildingPermitSerializer.new(BuildingPermit.all).serialized_json
      end
    end
  end
end
require "rails_helper"

RSpec.describe "GET /building_permits", type: :request do
  it "returns an array of building_permit attributes" do
    building_permit_attributes = {
      "permit_number" =>          1,
      "permit_type_definition" => "otc alterations permit",
      "description" =>            "add steel girder, add plywood to walls, replace existing posts.",
      "proposed_use" =>           "apartments",
      "estimated_cost" =>         5750000,
      "revised_cost" =>           5750000,
    }

    building_permit = create(:building_permit, building_permit_attributes)

    get "/api/v1/building_permits"
    result = JSON.parse(response.body)["data"]

    expect(result).
      to eq([
        {
          "id" => "#{building_permit.id}",
          "type" => "building_permit",
          "attributes" => building_permit_attributes,
        },
      ])
  end
end

Gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.1'

gem 'dotenv-rails', groups: [:development, :test], require: 'dotenv/rails-now'

gem 'bootsnap', '>= 1.1.0', require: false
gem 'coffee-rails', '~> 4.2'
gem 'faraday'
gem 'fast_jsonapi'
gem 'jbuilder', '~> 2.5'
gem 'pg', '>= 0.18', '< 2.0'
gem 'puma', '~> 3.11'
gem 'rails', '~> 5.2.0'
gem 'rack-cors'
gem 'sass-rails', '~> 5.0'
gem 'sidekiq'
gem 'turbolinks', '~> 5'
gem 'uglifier', '>= 1.3.0'
gem 'webpacker', '~> 3.5'

group :development, :test do
  gem 'awesome_print'
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'factory_bot_rails'
  gem 'rspec-rails', '~> 3.6'
  gem 'sinatra'
end

group :development do
  gem 'graphql'
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'rack-mini-profiler', require: false
  gem 'rubocop-airbnb'
  gem 'spring'
  gem 'web-console', '>= 3.3.0'
  gem 'webmock'
end

group :test do
  gem 'vcr'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'graphiql-rails', group: :development

RSpec config:

#rails_helper
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.include FactoryBot::Syntax::Methods
  config.infer_spec_type_from_file_location!
  config.use_transactional_fixtures = true
end
#spec_helper
require 'webmock/rspec'
require 'sidekiq/testing'
require 'vcr'

Sidekiq::Testing.fake!

VCR.configure do |config|
  config.default_cassette_options = { record: :once, serialize_with: :json }
  config.cassette_library_dir     = "spec/support/vcr_cassettes"
  config.hook_into :webmock
  config.default_cassette_options = {
    :match_requests_on => [:method, :host, :path]
  }
end

RSpec.configure do |config|
  config.order = :random
  config.expect_with :rspec do |expectations|
    expectations.syntax = :expect
  end
  config.mock_with :rspec do |mocks|
    mocks.syntax                 = :expect
    mocks.verify_partial_doubles = true
  end

  config.warnings = false
  config.before(:each) do
    Sidekiq::Worker.clear_all
  end
end

Bah...I found the issue. I made a change to the Model but didn't stop and start spring. Sorry for the false alarm.

:rage1: SPRINGGGGGGG :rage3:

Was this page helpful?
0 / 5 - 0 ratings