|
| 1 | +require 'test_helper' |
| 2 | + |
| 3 | +=begin |
| 4 | +## http://jsonapi.org/format/#document-top-level |
| 5 | +
|
| 6 | +A document MUST contain at least one of the following top-level members: |
| 7 | +
|
| 8 | +- data: the document's "primary data" |
| 9 | +- errors: an array of error objects |
| 10 | +- meta: a meta object that contains non-standard meta-information. |
| 11 | +
|
| 12 | +The members data and errors MUST NOT coexist in the same document. |
| 13 | +
|
| 14 | +## http://jsonapi.org/format/#error-objects |
| 15 | +
|
| 16 | +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. |
| 17 | +
|
| 18 | +An error object MAY have the following members: |
| 19 | +
|
| 20 | +- id: a unique identifier for this particular occurrence of the problem. |
| 21 | +- links: a links object containing the following members: |
| 22 | + - about: a link that leads to further details about this particular occurrence of the problem. |
| 23 | +- status: the HTTP status code applicable to this problem, expressed as a string value. |
| 24 | +- code: an application-specific error code, expressed as a string value. |
| 25 | +- 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. |
| 26 | +- detail: a human-readable explanation specific to this occurrence of the problem. |
| 27 | +- source: an object containing references to the source of the error, optionally including any of the following members: |
| 28 | + - 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]. |
| 29 | + - parameter: a string indicating which query parameter caused the error. |
| 30 | +- meta: a meta object containing non-standard meta-information about the error. |
| 31 | +
|
| 32 | +=end |
| 33 | + |
| 34 | +module ActiveModel |
| 35 | + class Serializer |
| 36 | + class Adapter |
| 37 | + class JsonApi |
| 38 | + class ErrorsTest < Minitest::Test |
| 39 | + include ActiveModel::Serializer::Lint::Tests |
| 40 | + |
| 41 | + # see |
| 42 | + # https://github.com/rails/rails/blob/4-2-stable/activemodel/lib/active_model/errors.rb |
| 43 | + # The below allows you to do: |
| 44 | + # |
| 45 | + # model = ModelWithErrors.new |
| 46 | + # model.validate! # => ["cannot be nil"] |
| 47 | + # model.errors.full_messages # => ["name cannot be nil"] |
| 48 | + class ModelWithErrors |
| 49 | + include ActiveModel::Serialization |
| 50 | + def attributes |
| 51 | + { |
| 52 | + errors: errors, |
| 53 | + name: name, |
| 54 | + } |
| 55 | + end |
| 56 | + |
| 57 | + def id |
| 58 | + object_id |
| 59 | + end |
| 60 | + |
| 61 | + def cache_key |
| 62 | + "#{self.class.name.downcase}/#{id}-#{Time.now.utc.strftime("%Y%m%d%H%M%S%9N")}" |
| 63 | + end |
| 64 | + |
| 65 | + # Required dependency for ActiveModel::Errors |
| 66 | + extend ActiveModel::Naming |
| 67 | + def initialize |
| 68 | + @errors = ActiveModel::Errors.new(self) |
| 69 | + end |
| 70 | + attr_accessor :name |
| 71 | + attr_reader :errors |
| 72 | + |
| 73 | + # The following methods are needed to be minimally implemented |
| 74 | + |
| 75 | + def read_attribute_for_validation(attr) |
| 76 | + send(attr) |
| 77 | + end |
| 78 | + |
| 79 | + def self.human_attribute_name(attr, options = {}) |
| 80 | + attr |
| 81 | + end |
| 82 | + |
| 83 | + def self.lookup_ancestors |
| 84 | + [self] |
| 85 | + end |
| 86 | + end |
| 87 | + |
| 88 | + def setup |
| 89 | + @resource = ModelWithErrors.new |
| 90 | + end |
| 91 | + |
| 92 | + def test_active_model_errors |
| 93 | + options = { |
| 94 | + serializer: ActiveModel::Serializer::ErrorSerializer, |
| 95 | + adapter: :'json_api/error', |
| 96 | + } |
| 97 | + |
| 98 | + @resource.errors.add(:name, "cannot be nil") |
| 99 | + |
| 100 | + serializable_resource = ActiveModel::SerializableResource.serialize(@resource, options) |
| 101 | + assert_equal serializable_resource.serializer_instance.attributes, { } |
| 102 | + assert_equal serializable_resource.serializer_instance.object, @resource |
| 103 | + |
| 104 | + expected_errors_object = [ |
| 105 | + { |
| 106 | + source: { pointer: 'data/attributes/name' }, |
| 107 | + detail: 'cannot be nil' |
| 108 | + } |
| 109 | + ] |
| 110 | + assert_equal serializable_resource.as_json, expected_errors_object |
| 111 | + end |
| 112 | + end |
| 113 | + end |
| 114 | + end |
| 115 | + end |
| 116 | +end |
0 commit comments