shamu 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/lib/shamu/entities/entity.rb +3 -0
- data/lib/shamu/json_api/base_builder.rb +8 -48
- data/lib/shamu/json_api/builder_methods/identifier.rb +34 -0
- data/lib/shamu/json_api/builder_methods/link.rb +25 -0
- data/lib/shamu/json_api/builder_methods/meta.rb +18 -0
- data/lib/shamu/json_api/builder_methods.rb +9 -0
- data/lib/shamu/json_api/context.rb +5 -5
- data/lib/shamu/json_api/error.rb +0 -7
- data/lib/shamu/json_api/error_builder.rb +50 -39
- data/lib/shamu/json_api/presenter.rb +36 -4
- data/lib/shamu/json_api/relationship_builder.rb +16 -2
- data/lib/shamu/json_api/resource_builder.rb +3 -13
- data/lib/shamu/json_api/response.rb +31 -14
- data/lib/shamu/json_api.rb +4 -0
- data/lib/shamu/locale/en.yml +0 -1
- data/lib/shamu/rails/json_api.rb +116 -141
- data/lib/shamu/rails/json_api_responder.rb +53 -0
- data/lib/shamu/rails/railtie.rb +8 -1
- data/lib/shamu/rails.rb +1 -0
- data/lib/shamu/version.rb +1 -1
- data/spec/lib/shamu/json_api/base_builder_spec.rb +0 -19
- data/spec/lib/shamu/json_api/context_spec.rb +3 -3
- data/spec/lib/shamu/json_api/error_builder_spec.rb +0 -8
- data/spec/lib/shamu/json_api/relationship_builder_spec.rb +22 -0
- data/spec/lib/shamu/json_api/resource_builder_spec.rb +17 -0
- data/spec/lib/shamu/json_api/response_spec.rb +34 -4
- data/spec/lib/shamu/rails/json_api_responder_spec.rb +153 -0
- data/spec/lib/shamu/rails/json_api_spec.rb +11 -8
- metadata +10 -3
data/lib/shamu/rails/json_api.rb
CHANGED
@@ -9,160 +9,131 @@ module Shamu
|
|
9
9
|
|
10
10
|
included do
|
11
11
|
before_action do
|
12
|
-
|
12
|
+
render json: json_error( "The 'include' parameter is not supported" ), status: :bad_request if params[:include] # rubocop:disable Metrics/LineLength
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
# @param [Object] resource to present as JSON.
|
23
|
-
# @param [JsonApi::Presenter] presenter to use when building the
|
24
|
-
# response. If not given, attempts to find a presenter. See
|
25
|
-
# {#json_context}
|
26
|
-
# @param (see #json_context)
|
27
|
-
# @yield (response) write additional top-level links and meta
|
28
|
-
# information.
|
29
|
-
# @yieldparam [JsonApi::Response] response
|
30
|
-
# @return [JsonApi::Response] the presented json response.
|
31
|
-
def json_resource( resource, presenter = nil, **context, &block )
|
32
|
-
context = json_context( **context )
|
33
|
-
response = Shamu::JsonApi::Response.new( context )
|
34
|
-
response.resource resource, presenter
|
35
|
-
yield response if block_given?
|
36
|
-
response
|
37
|
-
end
|
16
|
+
def process_action( * )
|
17
|
+
# If no format has been specfied, default to json_api
|
18
|
+
request.parameters[:format] ||= "json_api"
|
19
|
+
super
|
20
|
+
end
|
38
21
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
json_paginate_resources response, resources, pagination
|
57
|
-
yield response if block_given?
|
58
|
-
response
|
59
|
-
end
|
22
|
+
# Builds a well-formed JSON API response for a single resource.
|
23
|
+
#
|
24
|
+
# @param [Object] resource to present as JSON.
|
25
|
+
# @param [Class] presenter {Presenter} class to use when building the
|
26
|
+
# response for the given resource. If not given, attempts to find a
|
27
|
+
# presenter by calling {Context#find_presenter}.
|
28
|
+
# @param (see #json_context)
|
29
|
+
# @yield (response) write additional top-level links and meta
|
30
|
+
# information.
|
31
|
+
# @yieldparam [JsonApi::Response] response
|
32
|
+
# @return [JsonApi::Response] the presented JSON response.
|
33
|
+
def json_resource( resource, presenter = nil, **context, &block )
|
34
|
+
response = build_json_response( context )
|
35
|
+
response.resource resource, presenter
|
36
|
+
yield response if block_given?
|
37
|
+
response
|
38
|
+
end
|
60
39
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
40
|
+
# Builds a well-formed JSON API response for a collection of resources.
|
41
|
+
#
|
42
|
+
# @param [Enumerable<Object>] resources to present as a JSON array.
|
43
|
+
# @param [Class] presenter {Presenter} class to use when building the
|
44
|
+
# response for each of the resources. If not given, attempts to find
|
45
|
+
# a presenter by calling {Context#find_presenter}
|
46
|
+
# @param (see #json_context)
|
47
|
+
# @yield (response) write additional top-level links and meta
|
48
|
+
# information.
|
49
|
+
# @yieldparam [JsonApi::Response] response
|
50
|
+
# @return [JsonApi::Response] the presented JSON response.
|
51
|
+
def json_collection( resources, presenter = nil, pagination: :auto, **context, &block )
|
52
|
+
response = build_json_response( context )
|
53
|
+
response.collection resources, presenter
|
54
|
+
json_paginate_resources response, resources, pagination
|
55
|
+
yield response if block_given?
|
56
|
+
response
|
57
|
+
end
|
74
58
|
|
75
|
-
|
76
|
-
|
77
|
-
|
59
|
+
# Add page-based pagination links for the resources to the builder.
|
60
|
+
#
|
61
|
+
# @param [#current_page,#next_page,#previous_page] resources a collection that responds to `#current_page`
|
62
|
+
# @param [JsonApi::BaseBuilder] builder to add links to.
|
63
|
+
# @param [String] param the name of the page parameter to adjust for
|
64
|
+
# @return [void]
|
65
|
+
def json_paginate( resources, builder, param: "page[number]" )
|
66
|
+
page = resources.current_page
|
67
|
+
|
68
|
+
if resources.respond_to?( :next_page ) ? resources.next_page : true
|
69
|
+
builder.link :next, url_for( params.reverse_merge( param => resources.current_page + 1 ) )
|
78
70
|
end
|
79
71
|
|
80
|
-
|
81
|
-
|
82
|
-
# Write an error response. See {Shamu::JsonApi::Response#error} for details.
|
83
|
-
#
|
84
|
-
# @param (see Shamu::JsonApi::Response#error)
|
85
|
-
# @return [Shamu::JsonApi::Response]
|
86
|
-
# @yield (builder)
|
87
|
-
# @yieldparam [Shamu::JsonApi::ErrorBuilder] builder to customize the
|
88
|
-
# error response.
|
89
|
-
def json_error( exception = nil, http_status = :auto, **context, &block )
|
90
|
-
context = json_context( **context )
|
91
|
-
response = Shamu::JsonApi::Response.new( context )
|
92
|
-
|
93
|
-
http_status = json_http_status_code_from_error( exception ) if http_status == :auto
|
94
|
-
http_status = ::Rack::Utils.status_code( http_status ) if http_status
|
95
|
-
response.error( exception, http_status, &block )
|
96
|
-
response
|
72
|
+
if resources.respond_to?( :prev_page ) ? resources.prev_page : page > 1
|
73
|
+
builder.link :prev, url_for( params.reverse_merge( param => resources.current_page - 1 ) )
|
97
74
|
end
|
75
|
+
end
|
98
76
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
#
|
113
|
-
# See {JsonApi::Context#find_presenter}.
|
114
|
-
# @param [Hash<Class,Class>] presenters a hash that maps resource classes
|
115
|
-
# to the presenter class to use when building responses. See
|
116
|
-
# {JsonApi::Context#find_presenter}.
|
117
|
-
def json_context( fields: :not_set, namespaces: :not_set, presenters: :not_set )
|
118
|
-
Shamu::JsonApi::Context.new fields: fields == :not_set ? json_context_fields : fields,
|
119
|
-
namespaces: namespaces == :not_set ? json_context_namespaces : namespaces,
|
120
|
-
presenters: presenters == :not_set ? json_context_presenters : presenters
|
77
|
+
# Write an error response. See {Shamu::JsonApi::Response#error} for details.
|
78
|
+
#
|
79
|
+
# @param (see Shamu::JsonApi::Response#error)
|
80
|
+
# @yield (builder)
|
81
|
+
# @yieldparam [Shamu::JsonApi::ErrorBuilder] builder to customize the
|
82
|
+
# error response.
|
83
|
+
# @return [JsonApi::Response] the presented JSON response.
|
84
|
+
def json_error( error = nil, **context, &block )
|
85
|
+
response = build_json_response( context )
|
86
|
+
|
87
|
+
response.error error do |builder|
|
88
|
+
builder.http_status json_http_status_code_from_error( error )
|
89
|
+
yield builder if block_given?
|
121
90
|
end
|
122
91
|
|
123
|
-
|
124
|
-
|
125
|
-
# @!visibility public
|
126
|
-
#
|
127
|
-
# Render a JSON API response for a resource, collection or error.
|
128
|
-
#
|
129
|
-
# @overload json_api( error:, status: :auto, **context, &block )
|
130
|
-
# @param [Exception] error an error to report
|
131
|
-
# @param [Symbol,Integer] status the HTTP status code to return. If
|
132
|
-
# :auto, attempts to determine the proper response from the
|
133
|
-
# exception and request type.
|
134
|
-
# @param (see #json_context)
|
135
|
-
# @overload json_api( resource:, status: :auto, presenter: nil, **context, &block )
|
136
|
-
# @param [Object] resource the resource to render.
|
137
|
-
# @param [Symbol,Integer] status the HTTP status code. If :auto
|
138
|
-
# attempts to determine the proper response from the request type.
|
139
|
-
# @param (see #json_resource)
|
140
|
-
# @param [Shamu::JsonApi::Presenter] presenter to use when serializing
|
141
|
-
# the resource.
|
142
|
-
# @overload json_api( collection:, status: :ok, presenter: nil, **context, &block )
|
143
|
-
# @param [Array<Object>] collection to render.
|
144
|
-
# @param [Symbol,Integer] statis HTTP status code.
|
145
|
-
# @param (see #json_collection)
|
146
|
-
# @param [Shamu::JsonApi::Presenter] presenter to use when serializing
|
147
|
-
# each of the resources.
|
148
|
-
def json_api( error: nil, resource: nil, collection: nil, status: :auto, presenter: nil, pagination: :auto, **context, &block ) # rubocop:disable Metrics/LineLength
|
149
|
-
options = { layout: nil }
|
150
|
-
|
151
|
-
options[:json] =
|
152
|
-
if error
|
153
|
-
status = json_http_status_code_from_error( error ) if status == :auto
|
154
|
-
json_error( error, status, **context, &block )
|
155
|
-
elsif collection
|
156
|
-
status = :ok if status == :auto
|
157
|
-
json_collection( collection, presenter, pagination: pagination, **context, &block )
|
158
|
-
else
|
159
|
-
status = json_http_status_code_from_request if status == :auto
|
160
|
-
json_resource( resource, presenter, **context, &block )
|
161
|
-
end
|
92
|
+
response
|
93
|
+
end
|
162
94
|
|
163
|
-
|
164
|
-
|
165
|
-
|
95
|
+
# Write all the validation errors from a record to the response.
|
96
|
+
#
|
97
|
+
# @param (see Shamu::JsonApi::Response#validation_errors)
|
98
|
+
# @yield (builder, attr, message)
|
99
|
+
# @yieldparam (see Shamu::JsonApi::Response#validation_errors)
|
100
|
+
# @return [JsonApi::Response] the presented JSON response.
|
101
|
+
def json_validation_errors( errors, **context, &block )
|
102
|
+
response = build_json_response( context )
|
103
|
+
response.validation_errors errors, &block
|
104
|
+
|
105
|
+
response
|
106
|
+
end
|
107
|
+
|
108
|
+
JSON_CONTEXT_KEYWORDS = [ :fields, :namespaces, :presenters ].freeze
|
109
|
+
|
110
|
+
# @!visibility public
|
111
|
+
#
|
112
|
+
# Build a {JsonApi::Context} for the current request and controller.
|
113
|
+
#
|
114
|
+
# @param [Hash<Symbol,Array>] fields to include in the response. If not
|
115
|
+
# provided looks for a `fields` request argument and parses that.
|
116
|
+
# See {JsonApi::Context#initialize}.
|
117
|
+
# @param [Array<String>] namespaces to look for {Presenter presenters}.
|
118
|
+
# If not provided automatically adds the controller name and it's
|
119
|
+
# namespace.
|
120
|
+
#
|
121
|
+
# For example in the `Users::AccountController` it will add the
|
122
|
+
# `Users::Accounts` and `Users` namespaces.
|
123
|
+
#
|
124
|
+
# See {JsonApi::Context#find_presenter}.
|
125
|
+
# @param [Hash<Class,Class>] presenters a hash that maps resource classes
|
126
|
+
# to the presenter class to use when building responses. See
|
127
|
+
# {JsonApi::Context#find_presenter}.
|
128
|
+
# @return [JsonApi::Context] the builder context honoring any filter
|
129
|
+
# parameters sent by the client.
|
130
|
+
def json_context( fields: :not_set, namespaces: :not_set, presenters: :not_set )
|
131
|
+
Shamu::JsonApi::Context.new fields: fields == :not_set ? json_context_fields : fields,
|
132
|
+
namespaces: namespaces == :not_set ? json_context_namespaces : namespaces,
|
133
|
+
presenters: presenters == :not_set ? json_context_presenters : presenters
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
166
137
|
|
167
138
|
def json_context_fields
|
168
139
|
params[:fields]
|
@@ -212,6 +183,10 @@ module Shamu
|
|
212
183
|
else :ok
|
213
184
|
end
|
214
185
|
end
|
186
|
+
|
187
|
+
def build_json_response( context )
|
188
|
+
Shamu::JsonApi::Response.new( json_context( **context.slice( *JSON_CONTEXT_KEYWORDS ) ) )
|
189
|
+
end
|
215
190
|
end
|
216
191
|
end
|
217
192
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Shamu
|
2
|
+
module Rails
|
3
|
+
|
4
|
+
# Support JSON API responses with the standard rails `#respond_with` method.
|
5
|
+
module JsonApiResponder
|
6
|
+
|
7
|
+
# Render the response as JSON
|
8
|
+
# @return [String]
|
9
|
+
def to_json
|
10
|
+
if has_errors?
|
11
|
+
display_errors
|
12
|
+
elsif get?
|
13
|
+
display resource
|
14
|
+
elsif put? || patch?
|
15
|
+
display resource, :location => api_location
|
16
|
+
elsif post?
|
17
|
+
display resource, :status => :created, :location => api_location
|
18
|
+
else
|
19
|
+
head :no_content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias_method :to_json_api, :to_json
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
# @visibility private
|
27
|
+
def display( resource, given_options = {} )
|
28
|
+
given_options.merge!( options )
|
29
|
+
|
30
|
+
json =
|
31
|
+
if resource.is_a?( Enumerable )
|
32
|
+
controller.json_collection resource, **given_options
|
33
|
+
else
|
34
|
+
controller.json_resource resource, **given_options
|
35
|
+
end
|
36
|
+
|
37
|
+
super json, given_options
|
38
|
+
end
|
39
|
+
|
40
|
+
# @visibility private
|
41
|
+
def display_errors
|
42
|
+
controller.render format => controller.json_validation_errors( resource_errors ), :status => :unprocessable_entity # rubocop:disable Metrics/LineLength
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def validation_resource?( resource )
|
48
|
+
resource.respond_to?( :valid? ) && resource.respond_to?( :errors )
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/shamu/rails/railtie.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "shamu/rack"
|
2
|
+
require "shamu/json_api"
|
2
3
|
|
3
4
|
module Shamu
|
4
5
|
module Rails
|
@@ -16,7 +17,13 @@ module Shamu
|
|
16
17
|
::ActionController::Base.send :include, Shamu::Rails::Controller
|
17
18
|
::ActionController::Base.send :include, Shamu::Rails::Entity
|
18
19
|
::ActionController::Base.send :include, Shamu::Rails::Features
|
19
|
-
|
20
|
+
|
21
|
+
Mime::Type.register Shamu::JsonApi::MIME_TYPE, :json_api
|
22
|
+
|
23
|
+
ActionController::Renderers.add :json_api do |obj, _options|
|
24
|
+
self.content_type ||= Mime[:json_api]
|
25
|
+
obj
|
26
|
+
end
|
20
27
|
end
|
21
28
|
end
|
22
29
|
|
data/lib/shamu/rails.rb
CHANGED
data/lib/shamu/version.rb
CHANGED
@@ -4,18 +4,6 @@ describe Shamu::JsonApi::BaseBuilder do
|
|
4
4
|
let( :context ) { Shamu::JsonApi::Context.new }
|
5
5
|
let( :builder ) { Shamu::JsonApi::BaseBuilder.new( context ) }
|
6
6
|
|
7
|
-
before( :each ) do
|
8
|
-
builder.identifier "example", 1
|
9
|
-
end
|
10
|
-
|
11
|
-
describe "#identifier" do
|
12
|
-
it "writes type and id" do
|
13
|
-
builder.identifier "spec", 5
|
14
|
-
|
15
|
-
expect( builder.compile ).to include type: "spec", id: "5"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
7
|
describe "#link" do
|
20
8
|
it "adds a link" do
|
21
9
|
builder.link :self, "http://localhost"
|
@@ -32,11 +20,4 @@ describe Shamu::JsonApi::BaseBuilder do
|
|
32
20
|
end
|
33
21
|
end
|
34
22
|
|
35
|
-
describe "#compile" do
|
36
|
-
it "fails if identifier has not been specified" do
|
37
|
-
expect do
|
38
|
-
Shamu::JsonApi::BaseBuilder.new( context ).compile
|
39
|
-
end.to raise_error Shamu::JsonApi::IncompleteResourceError
|
40
|
-
end
|
41
|
-
end
|
42
23
|
end
|
@@ -43,18 +43,18 @@ describe Shamu::JsonApi::Context do
|
|
43
43
|
klass = Class.new( Shamu::JsonApi::Presenter )
|
44
44
|
|
45
45
|
context = Shamu::JsonApi::Context.new presenters: { String => klass }
|
46
|
-
expect( context.find_presenter( "Ms. Piggy" ) ).to
|
46
|
+
expect( context.find_presenter( "Ms. Piggy" ) ).to eq klass
|
47
47
|
end
|
48
48
|
|
49
49
|
it "finds implicitly named presenter in namespaces" do
|
50
50
|
context = Shamu::JsonApi::Context.new namespaces: [ "JsonApiContextSpec" ]
|
51
|
-
expect( context.find_presenter( :symbols ) ).to
|
51
|
+
expect( context.find_presenter( :symbols ) ).to eq JsonApiContextSpec::SymbolPresenter
|
52
52
|
end
|
53
53
|
|
54
54
|
it "finds implicitly named model_name presenter in namespaces" do
|
55
55
|
resource = double model_name: ActiveModel::Name.new( Class, nil, "JsonApiContextSpec::Symbol" )
|
56
56
|
context = Shamu::JsonApi::Context.new namespaces: [ "JsonApiContextSpec" ]
|
57
|
-
expect( context.find_presenter( resource ) ).to
|
57
|
+
expect( context.find_presenter( resource ) ).to eq JsonApiContextSpec::SymbolPresenter
|
58
58
|
end
|
59
59
|
|
60
60
|
it "raises if no presenter can be found" do
|
@@ -3,14 +3,6 @@ require "spec_helper"
|
|
3
3
|
describe Shamu::JsonApi::ErrorBuilder do
|
4
4
|
let( :builder ) { Shamu::JsonApi::ErrorBuilder.new }
|
5
5
|
|
6
|
-
describe "#summary" do
|
7
|
-
it "infers title" do
|
8
|
-
builder.summary 422, :not_allowed
|
9
|
-
|
10
|
-
expect( builder.compile ).to include title: "Not Allowed"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
6
|
describe "#exception" do
|
15
7
|
before( :each ) do
|
16
8
|
builder.exception NotImplementedError.new( "Nope, we haven't done that yet" )
|
@@ -1,5 +1,27 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Shamu::JsonApi::RelationshipBuilder do
|
4
|
+
let( :context ) { Shamu::JsonApi::Context.new }
|
5
|
+
let( :builder ) { Shamu::JsonApi::RelationshipBuilder.new( context ) }
|
6
|
+
|
7
|
+
before( :each ) do
|
8
|
+
builder.identifier "example", 1
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#compile" do
|
12
|
+
it "fails if identifier has not been specified" do
|
13
|
+
expect do
|
14
|
+
Shamu::JsonApi::RelationshipBuilder.new( context ).compile
|
15
|
+
end.to raise_error Shamu::JsonApi::IncompleteResourceError
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#identifier" do
|
20
|
+
it "writes type and id" do
|
21
|
+
builder.identifier "spec", 5
|
22
|
+
|
23
|
+
expect( builder.compile ).to include data: hash_including( type: "spec", id: "5" )
|
24
|
+
end
|
25
|
+
end
|
4
26
|
|
5
27
|
end
|
@@ -4,10 +4,19 @@ describe Shamu::JsonApi::RelationshipBuilder do
|
|
4
4
|
let( :context ) { Shamu::JsonApi::Context.new }
|
5
5
|
let( :builder ) { Shamu::JsonApi::ResourceBuilder.new( context ) }
|
6
6
|
|
7
|
+
|
7
8
|
before( :each ) do
|
8
9
|
builder.identifier "example", 1
|
9
10
|
end
|
10
11
|
|
12
|
+
describe "#identifier" do
|
13
|
+
it "writes type and id" do
|
14
|
+
builder.identifier "spec", 5
|
15
|
+
|
16
|
+
expect( builder.compile ).to include type: "spec", id: "5"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
11
20
|
describe "#attribute" do
|
12
21
|
it "adds to the attributes node" do
|
13
22
|
builder.attribute name: "Jim"
|
@@ -49,4 +58,12 @@ describe Shamu::JsonApi::RelationshipBuilder do
|
|
49
58
|
end
|
50
59
|
end
|
51
60
|
|
61
|
+
describe "#compile" do
|
62
|
+
it "fails if identifier has not been specified" do
|
63
|
+
expect do
|
64
|
+
Shamu::JsonApi::ResourceBuilder.new( context ).compile
|
65
|
+
end.to raise_error Shamu::JsonApi::IncompleteResourceError
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
52
69
|
end
|
@@ -1,14 +1,21 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
require "active_model"
|
2
3
|
|
3
4
|
describe Shamu::JsonApi::Response do
|
4
5
|
let( :context ) { Shamu::JsonApi::Context.new }
|
5
6
|
let( :response ) { Shamu::JsonApi::Response.new context }
|
6
7
|
|
7
8
|
it "uses presenter if given" do
|
8
|
-
presenter = double
|
9
|
-
expect( presenter ).to receive( :
|
10
|
-
|
11
|
-
|
9
|
+
presenter = double
|
10
|
+
expect( presenter ).to receive( :new ) do |resource, builder|
|
11
|
+
instance = Shamu::JsonApi::Presenter.new resource, builder
|
12
|
+
|
13
|
+
expect( instance ).to receive( :present ) do
|
14
|
+
builder.identifier :response, 9
|
15
|
+
end
|
16
|
+
|
17
|
+
instance
|
18
|
+
end
|
12
19
|
|
13
20
|
response.resource double, presenter
|
14
21
|
end
|
@@ -39,4 +46,27 @@ describe Shamu::JsonApi::Response do
|
|
39
46
|
|
40
47
|
expect( response.compile ).to include errors: [ hash_including( code: "not_implemented" ) ]
|
41
48
|
end
|
49
|
+
|
50
|
+
it "writes validation errors" do
|
51
|
+
klass = Class.new do
|
52
|
+
include ActiveModel::Validations
|
53
|
+
|
54
|
+
attr_reader :title
|
55
|
+
validates :title, presence: true
|
56
|
+
|
57
|
+
validate :general_problem
|
58
|
+
|
59
|
+
def general_problem
|
60
|
+
errors.add :base, "nope"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
allow( klass ).to receive( :name ).and_return "Example"
|
65
|
+
record = klass.new
|
66
|
+
record.valid?
|
67
|
+
|
68
|
+
response.validation_errors record.errors
|
69
|
+
expect( response.compile ).to include errors: include( hash_including( source: { pointer: "/data/attributes/title" } ) ) # rubocop:disable Metrics/LineLength
|
70
|
+
expect( response.compile ).to include errors: include( hash_including( source: { pointer: "/data" } ) )
|
71
|
+
end
|
42
72
|
end
|