Skip to content

Commit

Permalink
RFC: Json Api Errors (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
bf4 committed Jul 14, 2015
1 parent 954e4c5 commit 178dd56
Showing 1 changed file with 154 additions and 0 deletions.
154 changes: 154 additions & 0 deletions test/adapter/json_api/errors_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
require 'test_helper'

module ActiveModel
class Serializer
class Adapter
class JsonApi
class ErrorsTest < Minitest::Test

# see
# https://github.com/rails/rails/blob/4-2-stable/activemodel/lib/active_model/errors.rb
# The below allows you to do:
#
# model = ModelWithErrors.new
# model.validate! # => ["cannot be nil"]
# model.errors.full_messages # => ["name cannot be nil"]
class ModelWithErrors
# Required dependency for ActiveModel::Errors
extend ActiveModel::Naming
def initialize
@errors = ActiveModel::Errors.new(self)
end
attr_accessor :name
attr_reader :errors

# The following methods are needed to be minimally implemented

def read_attribute_for_validation(attr)
send(attr)
end

def self.human_attribute_name(attr, options = {})
attr
end

def self.lookup_ancestors
[self]
end
end

def setup
@model = ModelWithErrors.new
end

class JsonApiErrorSerializer < ActiveModel::Serializer
attribute :source
attribute :detail

def source
{pointer: "data/attributes/#{object.first}"}
end

def detail
detail = object.last
if detail.respond_to?(:join)
detail.join
else
detail
end
end
end

class JsonApiErrorsSerializer < ActiveModel::Serializer
has_many :errors, serializer: JsonApiErrorSerializer

def errors
object.messages.to_a
end
end

class ActiveModel::Serializer::Adapter::JsonApiError < ActiveModel::Serializer::Adapter::FlattenJson
end

def test_active_model_errors
@model.errors.add(:name, "cannot be nil")
serializer_opts = {serializer: JsonApiErrorSerializer}
errors = @model.errors

serializer = JsonApiErrorSerializer.new(errors.first, serializer_opts)
expected_error_object =
{
source: { pointer: 'data/attributes/name' },
detail: 'cannot be nil'
}
assert_equal serializer.attributes, expected_error_object

serializer = JsonApiErrorsSerializer.new(errors, serializer_opts)
adapter_class = ActiveModel::Serializer::Adapter::JsonApiError
adapter_opts = { adapter: :json_api_error }

adapter = ActiveModel::Serializer::Adapter.create(serializer, adapter_opts)
expected_error_response = { errors: [expected_error_object] }
assert_equal adapter.as_json, expected_error_response
end
=begin
## http://jsonapi.org/format/#document-top-level
A document MUST contain at least one of the following top-level members:
- data: the document's "primary data"
- errors: an array of error objects
- meta: a meta object that contains non-standard meta-information.
The members data and errors MUST NOT coexist in the same document.
## http://jsonapi.org/format/#error-objects
Error objects provide additional information about problems encountered while performing an operation. Error objects MUST be returned as an array keyed by errors in the top level of a JSON API document.
An error object MAY have the following members:
- id: a unique identifier for this particular occurrence of the problem.
- links: a links object containing the following members:
- about: a link that leads to further details about this particular occurrence of the problem.
- status: the HTTP status code applicable to this problem, expressed as a string value.
- code: an application-specific error code, expressed as a string value.
- title: a short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
- detail: a human-readable explanation specific to this occurrence of the problem.
- source: an object containing references to the source of the error, optionally including any of the following members:
- pointer: a JSON Pointer [RFC6901] to the associated entity in the request document [e.g. "/data" for a primary data object, or "/data/attributes/title" for a specific attribute].
- parameter: a string indicating which query parameter caused the error.
- meta: a meta object containing non-standard meta-information about the error.
## http://emberjs.com/blog/2015/06/18/ember-data-1-13-released.html#toc_using-json-api-error-object-format
Starting with Ember Data 1.13 we are using JSON API format to communicate errors from
the adapter to the store.
We are deprecating the current Ruby on Rails inspired format for creating
InvalidError objects and replacing it with proper JSON API objects. The old
format is supported with a deprecation warning in 1.13.
Deprecated format:
```js
new DS.InvalidError({
first_name: ['is invalid']
});
```
New format:
```js
new DS.InvalidError([
{
source: { pointer: 'data/attributes/first_name' },
detail: 'is invalid'
}
]);
=end
end
end
end
end
end

0 comments on commit 178dd56

Please sign in to comment.