Refactor GraphQL controller specs
This commit is contained in:
1
Gemfile
1
Gemfile
@@ -96,6 +96,7 @@ group :test do
|
|||||||
gem 'poltergeist'
|
gem 'poltergeist'
|
||||||
gem 'coveralls', require: false
|
gem 'coveralls', require: false
|
||||||
gem 'email_spec'
|
gem 'email_spec'
|
||||||
|
gem 'http'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
|||||||
15
Gemfile.lock
15
Gemfile.lock
@@ -143,6 +143,8 @@ GEM
|
|||||||
railties (>= 3.2.6, < 5.0)
|
railties (>= 3.2.6, < 5.0)
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.2.5)
|
||||||
docile (1.1.5)
|
docile (1.1.5)
|
||||||
|
domain_name (0.5.20161021)
|
||||||
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
easy_translate (0.5.0)
|
easy_translate (0.5.0)
|
||||||
json
|
json
|
||||||
thread
|
thread
|
||||||
@@ -189,6 +191,15 @@ GEM
|
|||||||
hashie (3.4.3)
|
hashie (3.4.3)
|
||||||
highline (1.7.8)
|
highline (1.7.8)
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
|
http (2.1.0)
|
||||||
|
addressable (~> 2.3)
|
||||||
|
http-cookie (~> 1.0)
|
||||||
|
http-form_data (~> 1.0.1)
|
||||||
|
http_parser.rb (~> 0.6.0)
|
||||||
|
http-cookie (1.0.3)
|
||||||
|
domain_name (~> 0.5)
|
||||||
|
http-form_data (1.0.1)
|
||||||
|
http_parser.rb (0.6.0)
|
||||||
httpi (2.4.1)
|
httpi (2.4.1)
|
||||||
rack
|
rack
|
||||||
i18n (0.7.0)
|
i18n (0.7.0)
|
||||||
@@ -423,6 +434,9 @@ GEM
|
|||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (3.0.3)
|
uglifier (3.0.3)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
|
unf (0.1.4)
|
||||||
|
unf_ext
|
||||||
|
unf_ext (0.0.7.2)
|
||||||
unicode-display_width (1.1.1)
|
unicode-display_width (1.1.1)
|
||||||
unicorn (5.1.0)
|
unicorn (5.1.0)
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
@@ -484,6 +498,7 @@ DEPENDENCIES
|
|||||||
graphiql-rails
|
graphiql-rails
|
||||||
graphql
|
graphql
|
||||||
groupdate (~> 3.1.0)
|
groupdate (~> 3.1.0)
|
||||||
|
http
|
||||||
i18n-tasks
|
i18n-tasks
|
||||||
initialjs-rails (= 0.2.0.4)
|
initialjs-rails (= 0.2.0.4)
|
||||||
invisible_captcha (~> 0.9.1)
|
invisible_captcha (~> 0.9.1)
|
||||||
|
|||||||
@@ -264,7 +264,6 @@ Rails.application.routes.draw do
|
|||||||
|
|
||||||
# GraphQL
|
# GraphQL
|
||||||
mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql'
|
mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql'
|
||||||
get '/graphql', to: 'graphql#query'
|
|
||||||
post '/graphql', to: 'graphql#query'
|
post '/graphql', to: 'graphql#query'
|
||||||
|
|
||||||
if Rails.env.development?
|
if Rails.env.development?
|
||||||
|
|||||||
@@ -1,63 +1,73 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
require 'http'
|
||||||
|
|
||||||
describe GraphqlController do
|
describe GraphqlController do
|
||||||
let!(:uri) { URI::HTTP.build(host: 'localhost', path: '/graphql', port: 3000) }
|
let(:uri) { URI::HTTP.build(host: 'localhost', path: '/graphql', port: 3000) }
|
||||||
|
let(:query_string) { "" }
|
||||||
|
let(:body) { {query: query_string}.to_json }
|
||||||
|
|
||||||
describe "GET request" do
|
describe "POST requests" do
|
||||||
it "is accepted when valid" do
|
let(:author) { create(:user) }
|
||||||
# Like POST requests but the query string goes in the URL
|
let(:proposal) { create(:proposal, author: author) }
|
||||||
# More info at: http://graphql.org/learn/serving-over-http/#get-request
|
let(:response) { HTTP.headers('Content-Type' => 'application/json').post(uri, body: body) }
|
||||||
skip
|
let(:response_body) { JSON.parse(response.body) }
|
||||||
|
|
||||||
|
context "when query string is valid" do
|
||||||
|
let(:query_string) { "{ proposal(id: #{proposal.id}) { title, author { username } } }" }
|
||||||
|
let(:returned_proposal) { response_body['data']['proposal'] }
|
||||||
|
|
||||||
|
it "returns HTTP 200 OK" do
|
||||||
|
expect(response.code).to eq(200)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "is rejected when not valid" do
|
it "returns first-level fields" do
|
||||||
skip
|
expect(returned_proposal['title']).to eq(proposal.title)
|
||||||
# Just doing this to trigger Travis CI build
|
end
|
||||||
|
|
||||||
|
it "returns nested fields" do
|
||||||
|
expect(returned_proposal['author']['username']).to eq(author.username)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST request" do
|
context "when query string asks for invalid fields" do
|
||||||
let(:post_request) {
|
let(:query_string) { "{ proposal(id: #{proposal.id}) { missing_field } }" }
|
||||||
req = Net::HTTP::Post.new(uri)
|
|
||||||
req['Content-Type'] = 'application/json'
|
|
||||||
req
|
|
||||||
}
|
|
||||||
|
|
||||||
it "succeeds when valid" do
|
it "returns HTTP 200 OK" do
|
||||||
body = { query: "{ proposals(first: 2) { edges { node { id } } } }" }.to_json
|
expect(response.code).to eq(200)
|
||||||
response = Net::HTTP.start(uri.host, uri.port) do |http|
|
|
||||||
post_request.body = body
|
|
||||||
http.request(post_request)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Is it enough to check the status code or should I also check the body?
|
it "doesn't return any data" do
|
||||||
expect(response.code.to_i).to eq(200)
|
expect(response_body['data']).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "succeeds and returns an error when disclosed attributes are requested" do
|
it "returns error inside body" do
|
||||||
body = { query: "{ user(id: 1) { encrypted_password } }" }.to_json
|
expect(response_body['errors']).to be_present
|
||||||
response = Net::HTTP.start(uri.host, uri.port) do |http|
|
end
|
||||||
post_request.body = body
|
|
||||||
http.request(post_request)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
body_hash = JSON.parse(response.body)
|
context "when query string is not valid" do
|
||||||
expect(body_hash['errors']).to be_present
|
let(:query_string) { "invalid" }
|
||||||
|
|
||||||
|
it "returns HTTP 400 Bad Request" do
|
||||||
|
expect(response.code).to eq(400)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "fails when no query string is provided" do
|
context "when query string is missing" do
|
||||||
body = {}.to_json
|
let(:query_string) { nil }
|
||||||
response = Net::HTTP.start(uri.host, uri.port) do |http|
|
|
||||||
post_request.body = body
|
it "returns HTTP 400 Bad Request" do
|
||||||
http.request(post_request)
|
expect(response.code).to eq(400)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: I must find a way to handle this better. Right now it shows a 500
|
context "when body is missing" do
|
||||||
# Internal Server Error, I think I should always return a valid (but empty)
|
let(:body) { nil }
|
||||||
# JSON document like '{}'
|
|
||||||
expect(response.code.to_i).not_to eq(200)
|
it "returns HTTP 400 Bad Request" do
|
||||||
|
expect(response.code).to eq(400)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user