fix(graphql): properly handle variables json parse errors
This commit is contained in:
parent
3b0cb8bfe9
commit
2ed26e8699
2 changed files with 70 additions and 62 deletions
|
@ -10,7 +10,7 @@ class API::V2::GraphqlController < API::V2::BaseController
|
||||||
operation_name: params[:operationName])
|
operation_name: params[:operationName])
|
||||||
|
|
||||||
render json: result
|
render json: result
|
||||||
rescue GraphQL::ParseError => exception
|
rescue GraphQL::ParseError, JSON::ParserError => exception
|
||||||
handle_parse_error(exception)
|
handle_parse_error(exception)
|
||||||
rescue => exception
|
rescue => exception
|
||||||
if Rails.env.production?
|
if Rails.env.production?
|
||||||
|
@ -26,7 +26,7 @@ class API::V2::GraphqlController < API::V2::BaseController
|
||||||
super
|
super
|
||||||
|
|
||||||
payload.merge!({
|
payload.merge!({
|
||||||
graphql_operation: operation_log(params[:query], params[:operationName], params[:variables]&.to_unsafe_h)
|
graphql_operation: operation_log(params[:query], params[:operationName], to_unsafe_hash(params[:variables]))
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -59,6 +59,23 @@ class API::V2::GraphqlController < API::V2::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_unsafe_hash(ambiguous_param)
|
||||||
|
case ambiguous_param
|
||||||
|
when String
|
||||||
|
if ambiguous_param.present?
|
||||||
|
JSON.parse(ambiguous_param)
|
||||||
|
else
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
when ActionController::Parameters
|
||||||
|
ambiguous_param.to_unsafe_h
|
||||||
|
else
|
||||||
|
ambiguous_param
|
||||||
|
end
|
||||||
|
rescue JSON::ParserError
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
def handle_parse_error(exception)
|
def handle_parse_error(exception)
|
||||||
render json: {
|
render json: {
|
||||||
errors: [
|
errors: [
|
||||||
|
|
|
@ -94,11 +94,12 @@ describe API::V2::GraphqlController do
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
end
|
end
|
||||||
|
let(:variables) { {} }
|
||||||
let(:body) { JSON.parse(subject.body, symbolize_names: true) }
|
let(:body) { JSON.parse(subject.body, symbolize_names: true) }
|
||||||
let(:gql_data) { body[:data] }
|
let(:gql_data) { body[:data] }
|
||||||
let(:gql_errors) { body[:errors] }
|
let(:gql_errors) { body[:errors] }
|
||||||
|
|
||||||
subject { post :execute, params: { query: query } }
|
subject { post :execute, params: { query: query, variables: variables } }
|
||||||
|
|
||||||
context "when authenticated with legacy token" do
|
context "when authenticated with legacy token" do
|
||||||
let(:authorization_header) { ActionController::HttpAuthentication::Token.encode_credentials(legacy_token) }
|
let(:authorization_header) { ActionController::HttpAuthentication::Token.encode_credentials(legacy_token) }
|
||||||
|
@ -823,21 +824,34 @@ describe API::V2::GraphqlController do
|
||||||
|
|
||||||
describe "mutations" do
|
describe "mutations" do
|
||||||
describe 'dossierEnvoyerMessage' do
|
describe 'dossierEnvoyerMessage' do
|
||||||
context 'success' do
|
let(:query) do
|
||||||
let(:query) do
|
"mutation($input: DossierEnvoyerMessageInput!) {
|
||||||
"mutation {
|
dossierEnvoyerMessage(input: $input) {
|
||||||
dossierEnvoyerMessage(input: {
|
message {
|
||||||
dossierId: \"#{dossier.to_typed_id}\",
|
body
|
||||||
instructeurId: \"#{instructeur.to_typed_id}\",
|
|
||||||
body: \"Bonjour\",
|
|
||||||
attachment: \"#{blob.signed_id}\"
|
|
||||||
}) {
|
|
||||||
message {
|
|
||||||
body
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}"
|
errors {
|
||||||
end
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
end
|
||||||
|
let(:variables) { { input: input } }
|
||||||
|
let(:input) do
|
||||||
|
{
|
||||||
|
dossierId: dossier_id,
|
||||||
|
instructeurId: instructeur_id,
|
||||||
|
body: input_body,
|
||||||
|
attachment: attachment
|
||||||
|
}
|
||||||
|
end
|
||||||
|
let(:dossier_id) { dossier.to_typed_id }
|
||||||
|
let(:instructeur_id) { instructeur.to_typed_id }
|
||||||
|
let(:input_body) { "Bonjour" }
|
||||||
|
let(:attachment) { nil }
|
||||||
|
|
||||||
|
context 'success' do
|
||||||
|
let(:attachment) { blob.signed_id }
|
||||||
|
|
||||||
it "should post a message" do
|
it "should post a message" do
|
||||||
expect(gql_errors).to eq(nil)
|
expect(gql_errors).to eq(nil)
|
||||||
|
@ -845,48 +859,41 @@ describe API::V2::GraphqlController do
|
||||||
expect(gql_data).to eq(dossierEnvoyerMessage: {
|
expect(gql_data).to eq(dossierEnvoyerMessage: {
|
||||||
message: {
|
message: {
|
||||||
body: "Bonjour"
|
body: "Bonjour"
|
||||||
}
|
},
|
||||||
|
errors: nil
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'schema error' do
|
context 'schema error' do
|
||||||
let(:query) do
|
let(:input) do
|
||||||
"mutation {
|
{
|
||||||
dossierEnvoyerMessage(input: {
|
dossierId: dossier_id,
|
||||||
dossierId: \"#{dossier.to_typed_id}\",
|
instructeurId: instructeur_id
|
||||||
instructeurId: \"#{instructeur.to_typed_id}\"
|
}
|
||||||
}) {
|
|
||||||
message {
|
|
||||||
body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should fail" do
|
it "should fail" do
|
||||||
expect(gql_data).to eq(nil)
|
expect(gql_data).to eq(nil)
|
||||||
expect(gql_errors).not_to eq(nil)
|
expect(gql_errors).not_to eq(nil)
|
||||||
|
expect(body[:errors].first[:message]).to eq("Variable $input of type DossierEnvoyerMessageInput! was provided invalid value for body (Expected value to not be null)")
|
||||||
|
expect(body[:errors].first.key?(:backtrace)).to be_falsey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'variables error' do
|
||||||
|
let(:variables) { "{" }
|
||||||
|
|
||||||
|
it "should fail" do
|
||||||
|
expect(gql_data).to eq(nil)
|
||||||
|
expect(gql_errors).not_to eq(nil)
|
||||||
|
expect(body[:errors].first[:message]).to eq("809: unexpected token at '{'")
|
||||||
|
expect(body[:errors].first.key?(:backtrace)).to be_falsey
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'validation error' do
|
context 'validation error' do
|
||||||
let(:query) do
|
let(:input_body) { "" }
|
||||||
"mutation {
|
|
||||||
dossierEnvoyerMessage(input: {
|
|
||||||
dossierId: \"#{dossier.to_typed_id}\",
|
|
||||||
instructeurId: \"#{instructeur.to_typed_id}\",
|
|
||||||
body: \"\"
|
|
||||||
}) {
|
|
||||||
message {
|
|
||||||
body
|
|
||||||
}
|
|
||||||
errors {
|
|
||||||
message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should fail" do
|
it "should fail" do
|
||||||
expect(gql_errors).to eq(nil)
|
expect(gql_errors).to eq(nil)
|
||||||
|
@ -898,23 +905,7 @@ describe API::V2::GraphqlController do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'upload error' do
|
context 'upload error' do
|
||||||
let(:query) do
|
let(:attachment) { 'fake' }
|
||||||
"mutation {
|
|
||||||
dossierEnvoyerMessage(input: {
|
|
||||||
dossierId: \"#{dossier.to_typed_id}\",
|
|
||||||
instructeurId: \"#{instructeur.to_typed_id}\",
|
|
||||||
body: \"Hello world\",
|
|
||||||
attachment: \"fake\"
|
|
||||||
}) {
|
|
||||||
message {
|
|
||||||
body
|
|
||||||
}
|
|
||||||
errors {
|
|
||||||
message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should fail" do
|
it "should fail" do
|
||||||
expect(gql_errors).to eq(nil)
|
expect(gql_errors).to eq(nil)
|
||||||
|
|
Loading…
Reference in a new issue