From b029c2c5da8f4b17d3bab03c59a8a5fa3b1d205b Mon Sep 17 00:00:00 2001 From: aCandidMind Date: Wed, 13 Sep 2017 17:49:26 +0200 Subject: [PATCH 1/2] Don't raise on missing data payload --- lib/jsonapi_compliable/base.rb | 2 +- lib/jsonapi_compliable/deserializer.rb | 2 +- spec/deserializer_spec.rb | 34 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/jsonapi_compliable/base.rb b/lib/jsonapi_compliable/base.rb index d1fa897..2da1487 100644 --- a/lib/jsonapi_compliable/base.rb +++ b/lib/jsonapi_compliable/base.rb @@ -243,7 +243,7 @@ def default_jsonapi_render_options private def force_includes? - not deserialized_params.data.nil? + not deserialized_params.data.empty? end def perform_render_jsonapi(opts) diff --git a/lib/jsonapi_compliable/deserializer.rb b/lib/jsonapi_compliable/deserializer.rb index 3420aee..f2f8f26 100644 --- a/lib/jsonapi_compliable/deserializer.rb +++ b/lib/jsonapi_compliable/deserializer.rb @@ -55,7 +55,7 @@ def initialize(payload, env) # @return [Hash] the raw :data value of the payload def data - @payload[:data] + @payload[:data] || {} end # @return [String] the raw :id value of the payload diff --git a/spec/deserializer_spec.rb b/spec/deserializer_spec.rb index c683032..1b0c582 100644 --- a/spec/deserializer_spec.rb +++ b/spec/deserializer_spec.rb @@ -12,6 +12,28 @@ let(:instance) { described_class.new(payload, {}) } + describe '#data' do + subject { instance.data } + + context 'when data is present' do + it 'returns the proper sub-object' do + expect(subject).to eq(payload[:data]) + end + end + + context 'when data is absent' do + let(:payload) do + { + foo: 'bar' + } + end + + it 'returns an empty hash' do + expect(subject).to eq({}) + end + end + end + describe '#attributes' do subject { instance.attributes } @@ -31,6 +53,18 @@ expect(subject[:id]).to eq('123') end end + + context 'when data is absent' do + let(:payload) do + { + foo: 'bar' + } + end + + it 'returns an empty hash' do + expect(subject).to eq({}) + end + end end describe '#relationships' do From 7707eae1071425a7fab0a3cecad5e446d1c0bc41 Mon Sep 17 00:00:00 2001 From: aCandidMind Date: Fri, 15 Sep 2017 18:36:20 +0200 Subject: [PATCH 2/2] For requests other than GET or DELETE raise on missing data --- lib/jsonapi_compliable/base.rb | 2 +- lib/jsonapi_compliable/deserializer.rb | 10 ++++++++-- lib/jsonapi_compliable/errors.rb | 9 +++++---- spec/deserializer_spec.rb | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/jsonapi_compliable/base.rb b/lib/jsonapi_compliable/base.rb index 2da1487..0dfd56f 100644 --- a/lib/jsonapi_compliable/base.rb +++ b/lib/jsonapi_compliable/base.rb @@ -117,7 +117,7 @@ def jsonapi_scope(scope, opts = {}) # @see Deserializer#initialize # @return [Deserializer] def deserialized_params - @deserialized_params ||= JsonapiCompliable::Deserializer.new(params, request.env) + @deserialized_params ||= JsonapiCompliable::Deserializer.new(params, request.method, request.env) end # Create the resource model and process all nested relationships via the diff --git a/lib/jsonapi_compliable/deserializer.rb b/lib/jsonapi_compliable/deserializer.rb index f2f8f26..b2fa843 100644 --- a/lib/jsonapi_compliable/deserializer.rb +++ b/lib/jsonapi_compliable/deserializer.rb @@ -46,16 +46,22 @@ # { type: 'authors', method: :create, temp_id: 'abc123' } class JsonapiCompliable::Deserializer # @param payload [Hash] The incoming payload with symbolized keys + # @param method [String] The method that the request was sent with # @param env [Hash] the Rack env (e.g. +request.env+). - def initialize(payload, env) + def initialize(payload, method, env) @payload = payload @payload = @payload[:_jsonapi] if @payload.has_key?(:_jsonapi) + @method = method @env = env end # @return [Hash] the raw :data value of the payload def data - @payload[:data] || {} + if ["GET", "DELETE"].include?(@method) + @payload[:data] || {} + else + @payload[:data] or raise JsonapiCompliable::Errors::BadRequest.new("No data payload present") + end end # @return [String] the raw :id value of the payload diff --git a/lib/jsonapi_compliable/errors.rb b/lib/jsonapi_compliable/errors.rb index 13e02cf..7be98dd 100644 --- a/lib/jsonapi_compliable/errors.rb +++ b/lib/jsonapi_compliable/errors.rb @@ -1,9 +1,10 @@ module JsonapiCompliable module Errors - class BadFilter < StandardError; end - class ValidationError < StandardError; end + class ValidationError < RuntimeError; end + class BadRequest < RuntimeError; end + class BadFilter < BadRequest; end - class UnsupportedPageSize < StandardError + class UnsupportedPageSize < BadRequest def initialize(size, max) @size, @max = size, max end @@ -13,7 +14,7 @@ def message end end - class StatNotFound < StandardError + class StatNotFound < BadRequest def initialize(attribute, calculation) @attribute = attribute @calculation = calculation diff --git a/spec/deserializer_spec.rb b/spec/deserializer_spec.rb index 1b0c582..8f3191f 100644 --- a/spec/deserializer_spec.rb +++ b/spec/deserializer_spec.rb @@ -10,7 +10,7 @@ } end - let(:instance) { described_class.new(payload, {}) } + let(:instance) { described_class.new(payload, "GET", {}) } describe '#data' do subject { instance.data }