Skip to content

Commit 31b305e

Browse files
authored
Merge pull request #1104 from cerebris/pr/1099
Adds test to 1099
2 parents 8314445 + 230e244 commit 31b305e

File tree

4 files changed

+55
-5
lines changed

4 files changed

+55
-5
lines changed

lib/jsonapi/exceptions.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,11 +465,12 @@ def errors
465465
end
466466

467467
class ValidationErrors < Error
468-
attr_reader :error_messages, :error_metadata, :resource_relationships
468+
attr_reader :error_messages, :error_metadata, :resource_relationships, :resource_class
469469

470470
def initialize(resource, error_object_overrides = {})
471471
@error_messages = resource.model_error_messages
472472
@error_metadata = resource.validation_error_metadata
473+
@resource_class = resource.class
473474
@resource_relationships = resource.class._relationships.keys
474475
@key_formatter = JSONAPI.configuration.key_formatter
475476
super(error_object_overrides)
@@ -491,7 +492,7 @@ def json_api_error(attr_key, message)
491492
create_error_object(code: JSONAPI::VALIDATION_ERROR,
492493
status: :unprocessable_entity,
493494
title: message,
494-
detail: "#{format_key(attr_key)} - #{message}",
495+
detail: detail(attr_key, message),
495496
source: { pointer: pointer(attr_key) },
496497
meta: metadata_for(attr_key, message))
497498
end
@@ -501,14 +502,23 @@ def metadata_for(attr_key, message)
501502
error_metadata[attr_key] ? error_metadata[attr_key][message] : nil
502503
end
503504

505+
def detail(attr_key, message)
506+
general_error?(attr_key) ? message : "#{format_key(attr_key)} - #{message}"
507+
end
508+
504509
def pointer(attr_or_relationship_name)
510+
return '/data' if general_error?(attr_or_relationship_name)
505511
formatted_attr_or_relationship_name = format_key(attr_or_relationship_name)
506512
if resource_relationships.include?(attr_or_relationship_name)
507513
"/data/relationships/#{formatted_attr_or_relationship_name}"
508514
else
509515
"/data/attributes/#{formatted_attr_or_relationship_name}"
510516
end
511517
end
518+
519+
def general_error?(attr_key)
520+
attr_key.to_sym == :base && !resource_class._has_attribute?(attr_key)
521+
end
512522
end
513523

514524
class SaveFailed < Error

lib/jsonapi/resource.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,10 @@ def _attribute_delegated_name(attr)
837837
@_attributes.fetch(attr.to_sym, {}).fetch(:delegate, attr)
838838
end
839839

840+
def _has_attribute?(attr)
841+
@_attributes.keys.include?(attr.to_sym)
842+
end
843+
840844
def _updatable_attributes
841845
_attributes.map { |key, options| key unless options[:readonly] }.compact
842846
end

test/controllers/controller_test.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1869,11 +1869,21 @@ def test_update_bad_attributes
18691869
assert_response :bad_request
18701870
end
18711871

1872-
def test_delete_with_validation_error
1872+
def test_delete_with_validation_error_base
18731873
post = Post.create!(title: "can't destroy me", author: Person.first)
18741874
delete :destroy, params: { id: post.id }
18751875

18761876
assert_equal "can't destroy me", json_response['errors'][0]['title']
1877+
assert_equal "/data", json_response['errors'][0]['source']['pointer']
1878+
assert_response :unprocessable_entity
1879+
end
1880+
1881+
def test_delete_with_validation_error_attr
1882+
post = Post.create!(title: "locked title", author: Person.first)
1883+
delete :destroy, params: { id: post.id }
1884+
1885+
assert_equal "is locked", json_response['errors'][0]['title']
1886+
assert_equal "/data/attributes/title", json_response['errors'][0]['source']['pointer']
18771887
assert_response :unprocessable_entity
18781888
end
18791889

@@ -3755,6 +3765,15 @@ def test_caching_with_join_from_resource_with_sql_fragment
37553765
assert_cacheable_get :index, params: {include: 'section'}
37563766
assert_response :success
37573767
end
3768+
3769+
def test_delete_with_validation_error_base_on_resource
3770+
post = Post.create!(title: "can't destroy me either", author: Person.first)
3771+
delete :destroy, params: { id: post.id }
3772+
3773+
assert_equal "can't destroy me", json_response['errors'][0]['title']
3774+
assert_equal "/data/attributes/base", json_response['errors'][0]['source']['pointer']
3775+
assert_response :unprocessable_entity
3776+
end
37583777
end
37593778

37603779
class Api::V6::SectionsControllerTest < ActionController::TestCase

test/fixtures/active_record.rb

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,19 @@ class Post < ActiveRecord::Base
376376
before_destroy :destroy_callback
377377

378378
def destroy_callback
379-
if title == "can't destroy me"
380-
errors.add(:title, "can't destroy me")
379+
case title
380+
when "can't destroy me", "can't destroy me either"
381+
errors.add(:base, "can't destroy me")
382+
383+
# :nocov:
384+
if Rails::VERSION::MAJOR >= 5
385+
throw(:abort)
386+
else
387+
return false
388+
end
389+
# :nocov:
390+
when "locked title"
391+
errors.add(:title, "is locked")
381392

382393
# :nocov:
383394
if Rails::VERSION::MAJOR >= 5
@@ -1775,6 +1786,12 @@ class PostResource < PostResource
17751786
def self.records(options = {})
17761787
_model_class.all.joins('INNER JOIN people on people.id = author_id')
17771788
end
1789+
1790+
attribute :base
1791+
1792+
def base
1793+
_model.title
1794+
end
17781795
end
17791796

17801797
class CustomerResource < JSONAPI::Resource

0 commit comments

Comments
 (0)