jsonapi_spec_helpers 0.4.10 → 1.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7de8f729627057f5996f8455bc769caf8d0f5bbd
4
- data.tar.gz: 05436bab3f0d5377a8ecdffc549f10e475233d5e
3
+ metadata.gz: 17ecff418f690fa93ed1e4a44d139c46a9b00beb
4
+ data.tar.gz: 4e74adb0ea0593f7a28e7bc7485f20e6d55a1d08
5
5
  SHA512:
6
- metadata.gz: 9ec2ad279e5282fb83f7899d29af184e56efc37ee4aaa81eaa8020fbcbce920e0c3b49d66868219190c4c3a14a84f15fd9b78f10a22adf529b028550e4fc84f9
7
- data.tar.gz: da684de42e3c316343abcba437afcbc447a2fa6a44771778a75516feec6aba1be69d76cb25f50b248d853da0de319a9b235f13558b8efa5d7278fe2269f6d4b8
6
+ metadata.gz: 58f02d6265d70de7e97c544646698e71852421ae213f53e74f5e4bb187ffafb6fb29fabb63929906fbfea8a8d7f5a4cd6996a1514ee620a6e38e23e99903582c
7
+ data.tar.gz: c216961f4a62b64fb0a42058c1a3fcab986a9c1e4b43a2a7f1da61f8981b90bceb4eeb4b9f57263d902f62f78caae97f3ef529706893f6ed27d851a420237ecd
@@ -23,5 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "actionpack", "~> 5.0"
24
24
  spec.add_development_dependency "bundler", "~> 1.11"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "jsonapi_compliable", '>= 1.0.alpha.1'
26
27
  spec.add_dependency "rspec", "~> 3.0"
27
28
  end
@@ -1,16 +1,51 @@
1
1
  module JsonapiSpecHelpers
2
2
  module Errors
3
3
  class Base < StandardError; end
4
- class IncludedOutOfBounds < Base
5
- def initialize(type, index, array)
6
- @type = type; @index = index; @array = array
4
+
5
+ class LinksNotFound < Base
6
+ def initialize(name)
7
+ @name = name
8
+ end
9
+
10
+ def message
11
+ "Relationship with name '#{@name}' has no links!"
12
+ end
13
+ end
14
+
15
+ class SideloadNotFound < Base
16
+ def initialize(name)
17
+ @name = name
18
+ end
19
+
20
+ def message
21
+ "Relationship with name '#{@name}' not found!"
22
+ end
23
+ end
24
+
25
+ class NoResponse < Base
26
+ def message
27
+ "Cannot parse response - missing #response.body!"
28
+ end
29
+ end
30
+
31
+ class NoData < Base
32
+ def initialize(payload)
33
+ @payload = payload
34
+ end
35
+
36
+ def message
37
+ "Payload did not contain 'data'! Payload was:\n\n#{JSON.pretty_generate(@payload)}"
38
+ end
39
+ end
40
+
41
+ class NoSideloads < Base
42
+ def initialize(payload)
43
+ @payload = payload
7
44
  end
8
45
 
9
46
  def message
10
- "You attempted to get an item at index #{@index} of the type '#{@type}' " \
11
- "from the included property of your JSON payload. But it contained " \
12
- "#{@array.length} '#{@type}'"
47
+ "Tried to find sideload, but the payload did not contain 'included'! Payload was:\n\n#{JSON.pretty_generate(@payload)}"
13
48
  end
14
49
  end
15
50
  end
16
- end
51
+ end
@@ -0,0 +1,70 @@
1
+ module JsonapiSpecHelpers
2
+ class ErrorsProxy
3
+ class Error
4
+ attr_reader :json
5
+
6
+ def initialize(json)
7
+ @json = json
8
+ end
9
+
10
+ def attribute
11
+ @json[:meta][:attribute]
12
+ end
13
+
14
+ # TODO: move to top-level code in errorable
15
+ def code
16
+ @json[:meta][:code]
17
+ end
18
+
19
+ def message
20
+ @json[:meta][:message]
21
+ end
22
+
23
+ def title
24
+ @json[:title]
25
+ end
26
+
27
+ def detail
28
+ @json[:detail]
29
+ end
30
+
31
+ def status
32
+ @json[:status]
33
+ end
34
+ end
35
+
36
+ include Enumerable
37
+
38
+ def initialize(array)
39
+ @errors = array.map { |e| Error.new(e) }
40
+ end
41
+
42
+ def [](key)
43
+ @errors[key]
44
+ end
45
+
46
+ def each(&blk)
47
+ @errors.each(&blk)
48
+ end
49
+
50
+ def length
51
+ count
52
+ end
53
+
54
+ def to_h
55
+ {}.tap do |hash|
56
+ @errors.each do |e|
57
+ hash[e.attribute] = e.message
58
+ end
59
+ end
60
+ end
61
+
62
+ def method_missing(id, *args, &blk)
63
+ if error = @errors.find { |e| e.attribute == id }
64
+ return error
65
+ else
66
+ super
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,77 +1,40 @@
1
1
  module JsonapiSpecHelpers
2
2
  module Helpers
3
- def json
4
- JSON.parse(response.body)
5
- end
6
-
7
- def json_item(from: nil)
8
- from = json if from.nil?
9
- data = from.has_key?('data') ? from['data'] : from
10
-
11
- {}.tap do |item|
12
- item['id'] = data['id']
13
- item['jsonapi_type'] = data['type']
14
- item.merge!(data['attributes']) if data.has_key?('attributes')
15
- end
16
- end
3
+ extend ActiveSupport::Concern
17
4
 
18
- def json_items(*indices)
19
- items = []
20
- json['data'].each_with_index do |datum, index|
21
- included = indices.empty? || indices.include?(index)
22
- items << json_item(from: datum) if included
5
+ def json
6
+ if response && response.body
7
+ JSON.parse(response.body).with_indifferent_access
8
+ else
9
+ raise Errors::NoResponse.new
23
10
  end
24
- indices.length == 1 ? items[0] : items
25
- end
26
-
27
- def json_related_link(payload, assn_name)
28
- link = payload['relationships'][assn_name]['links']['related']['href']
29
- fail "link for #{assn_name} not found" unless link
30
- URI.decode(link)
31
11
  end
32
12
 
33
- def json_included_types
34
- (json['included'] || []).map { |i| i['type'] }.uniq
35
- end
36
-
37
- def json_includes(type, *indices)
38
- included = (json['included'] || []).select { |data| data['type'] == type }
39
- indices = (0...included.length).to_a if indices.empty?
40
- includes = []
41
- indices.each do |index|
42
- single_included = included.at(index)
43
- if single_included.nil?
44
- raise Errors::IncludedOutOfBounds.new(type, index, included)
13
+ def jsonapi_data
14
+ @jsonapi_data ||= begin
15
+ if _jsonapi_data.is_a?(Hash)
16
+ node(from: _jsonapi_data)
17
+ else
18
+ _jsonapi_data.map { |datum| node(from: datum) }
45
19
  end
46
- includes << json_item(from: single_included)
47
20
  end
48
- includes
49
21
  end
50
22
 
51
- def json_include(type, index = 0)
52
- json_includes(type, index)[0]
53
- end
23
+ def jsonapi_included(type = nil)
24
+ variable = :"@jsonapi_included#{type}"
25
+ memo = instance_variable_get(variable)
26
+ return memo if memo
54
27
 
55
- def json_ids(integers = false)
56
- ids = json['data'].map { |d| d['id'] }
57
- ids.map! { |id| Integer(id) } if integers
58
- ids
28
+ nodes = _jsonapi_included.map { |i| node(from: i) }
29
+ if type
30
+ nodes.select! { |n| n.jsonapi_type == type }
31
+ end
32
+ instance_variable_set(variable, nodes)
33
+ nodes
59
34
  end
60
35
 
61
- def validation_errors
62
- @validation_errors ||= {}.tap do |errors|
63
- return errors if json['errors'].nil?
64
- json['errors'].each do |e|
65
- attr = e['meta']['attribute'].to_sym
66
- message = e['meta']['message']
67
-
68
- if errors[attr]
69
- errors[attr] = Array(errors[attr]).push(message)
70
- else
71
- errors[attr] = message
72
- end
73
- end
74
- end
36
+ def jsonapi_errors
37
+ @jsonapi_errors ||= ErrorsProxy.new(json['errors'] || [])
75
38
  end
76
39
 
77
40
  def jsonapi_headers
@@ -100,8 +63,35 @@ module JsonapiSpecHelpers
100
63
  delete url, headers: jsonapi_headers
101
64
  end
102
65
 
103
- def jsonapi_payload(input)
104
- PayloadSanitizer.new(input).sanitize
66
+ def datetime(value)
67
+ JsonapiCompliable::Types[:datetime][:read][value]
68
+ end
69
+
70
+ # @api private
71
+ def node(from: nil)
72
+ from = json if from.nil?
73
+ data = from.has_key?('data') ? from['data'] : from
74
+ hash = {}
75
+ hash['id'] = data['id']
76
+ hash['jsonapi_type'] = data['type']
77
+ hash.merge!(data['attributes']) if data.has_key?('attributes')
78
+ Node.new(hash, data['relationships'], self)
79
+ end
80
+
81
+ private
82
+
83
+ # @api private
84
+ def _jsonapi_data
85
+ json['data'] || raise(Errors::NoData.new(json))
86
+ end
87
+
88
+ # @api private
89
+ def _jsonapi_included
90
+ if json.has_key?('included')
91
+ json['included']
92
+ else
93
+ raise Errors::NoSideloads.new(json)
94
+ end
105
95
  end
106
96
  end
107
97
  end
@@ -0,0 +1,81 @@
1
+ module JsonapiSpecHelpers
2
+ class Node
3
+ attr_reader :attributes, :relationships
4
+
5
+ def initialize(attributes, relationships, context)
6
+ @attributes = attributes.with_indifferent_access
7
+ @relationships = relationships
8
+ @context = context
9
+ end
10
+
11
+ def id
12
+ rawid.to_i
13
+ end
14
+
15
+ def rawid
16
+ @attributes['id']
17
+ end
18
+
19
+ def jsonapi_type
20
+ @attributes['jsonapi_type']
21
+ end
22
+
23
+ def has_key?(key)
24
+ @attributes.has_key?(key)
25
+ end
26
+
27
+ def [](key)
28
+ @attributes[key] || @attributes[key.to_s]
29
+ end
30
+
31
+ def []=(key, val)
32
+ @attributes[key] = val
33
+ end
34
+
35
+ def attributes
36
+ @attributes
37
+ end
38
+
39
+ def method_missing(id, *args, &blk)
40
+ if @attributes.has_key?(id)
41
+ @attributes[id]
42
+ else
43
+ super
44
+ end
45
+ end
46
+
47
+ def link(relationship_name, name)
48
+ if @relationships.has_key?(relationship_name)
49
+ links = @relationships[relationship_name][:links]
50
+ raise Errors::LinksNotFound.new(relationship_name) unless links
51
+ links[name]
52
+ else
53
+ raise Errors::SideloadNotFound.new(relationship_name)
54
+ end
55
+ end
56
+
57
+ def sideload(relationship_name)
58
+ unless @relationships.has_key?(relationship_name)
59
+ raise Errors::SideloadNotFound.new(relationship_name)
60
+ end
61
+ rel = @relationships[relationship_name]
62
+ rel = rel[:data]
63
+ return if rel.nil?
64
+ if rel.is_a?(Hash)
65
+ include_for(rel[:type], rel[:id])
66
+ else
67
+ rel.map { |r| include_for(r[:type], r[:id]) }
68
+ end
69
+ end
70
+ alias :sideloads :sideload
71
+
72
+ private
73
+
74
+ def include_for(type, id)
75
+ data = @context.json[:included].find do |i|
76
+ i[:type] == type && i[:id] == id
77
+ end
78
+ @context.node(from: data)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,44 @@
1
+ require 'jsonapi_spec_helpers'
2
+
3
+ ::RSpec.shared_context 'resource testing', type: :resource do |parameter|
4
+ let(:resource) { described_class }
5
+ let(:params) { {} }
6
+
7
+ # If you need to set context:
8
+ #
9
+ # JsonapiCompliable.with_context my_context, {} do
10
+ # render
11
+ # end
12
+ def render(runtime_options = {})
13
+ json = proxy.to_jsonapi(runtime_options)
14
+ response.body = json
15
+ json
16
+ end
17
+
18
+ def proxy
19
+ @proxy ||= begin
20
+ ctx = ::JsonapiSpecHelpers::TestRunner.new(resource, params)
21
+ defined?(base_scope) ? ctx.proxy(base_scope) : ctx.proxy
22
+ end
23
+ end
24
+
25
+ def records
26
+ proxy.data
27
+ end
28
+
29
+ def response
30
+ @response ||= OpenStruct.new
31
+ end
32
+ end
33
+
34
+ module JsonapiSpecHelpers
35
+ module RSpec
36
+ def self.included(klass)
37
+ klass.send(:include, JsonapiSpecHelpers)
38
+
39
+ ::RSpec.configure do |rspec|
40
+ rspec.include_context "resource testing", type: :resource
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module JsonapiSpecHelpers
2
- VERSION = "0.4.10"
2
+ VERSION = "1.0.alpha.2"
3
3
  end
@@ -1,58 +1,37 @@
1
1
  require 'json'
2
+ require 'pp'
3
+ require 'active_support/core_ext/string'
4
+ require 'active_support/core_ext/hash'
5
+ require 'jsonapi_compliable'
6
+
2
7
  require 'jsonapi_spec_helpers/version'
3
8
  require 'jsonapi_spec_helpers/helpers'
4
- require 'jsonapi_spec_helpers/payload'
5
- require 'jsonapi_spec_helpers/payload_sanitizer'
9
+ require 'jsonapi_spec_helpers/node'
10
+ require 'jsonapi_spec_helpers/errors_proxy'
6
11
  require 'jsonapi_spec_helpers/errors'
7
12
 
8
13
  module JsonapiSpecHelpers
9
14
  def self.included(klass)
10
- # don't load RSpec until included
11
- require 'jsonapi_spec_helpers/matchers'
12
15
  klass.send(:include, Helpers)
13
- if defined?(Rails)
14
- load_payloads!
15
- end
16
16
  end
17
17
 
18
- def self.load_payloads!
19
- Dir[Rails.root.join('spec/payloads/**/*.rb')].each { |f| require f }
18
+ class TestRunner < ::JsonapiCompliable::Runner
19
+ def current_user
20
+ nil
21
+ end
20
22
  end
21
23
 
22
- def assert_payload(name, record, json, &blk)
23
- unless payload = JsonapiSpecHelpers::Payload.registry[name]
24
- raise "No payloads registered for '#{name}'"
24
+ module Sugar
25
+ def d
26
+ jsonapi_data
25
27
  end
26
28
 
27
- if blk
28
- payload = payload.fork
29
- payload.instance_eval(&blk)
29
+ def included(type = nil)
30
+ jsonapi_included(type)
30
31
  end
31
32
 
32
- aggregate_failures "payload has correct key/values" do
33
- payload.keys.each_pair do |attribute, options|
34
- prc = options[:proc]
35
- if (expect(json).to have_payload_key(attribute, options[:allow_nil])) == true
36
- unless options[:allow_nil]
37
- output = instance_exec(record, &prc)
38
- expect(json[attribute.to_s]).to match_payload(attribute, output)
39
-
40
- if options[:type]
41
- expect(json[attribute.to_s]).to match_type(attribute, options[:type])
42
- end
43
- end
44
- end
45
- end
46
-
47
- payload.no_keys.each do |no_key|
48
- expect(json).to_not have_payload_key(no_key, {})
49
- end
50
-
51
- unexpected_keys = json.keys - payload.keys.keys.map(&:to_s)
52
- unexpected_keys.reject! { |k| %w(id jsonapi_type).include?(k) }
53
- unexpected_keys.each do |key|
54
- expect(key).to be_not_in_payload
55
- end
33
+ def errors
34
+ jsonapi_errors
56
35
  end
57
36
  end
58
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_spec_helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.10
4
+ version: 1.0.alpha.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-28 00:00:00.000000000 Z
11
+ date: 2018-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: jsonapi_compliable
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 1.0.alpha.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 1.0.alpha.1
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rspec
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -114,10 +128,10 @@ files:
114
128
  - jsonapi_spec_helpers.gemspec
115
129
  - lib/jsonapi_spec_helpers.rb
116
130
  - lib/jsonapi_spec_helpers/errors.rb
131
+ - lib/jsonapi_spec_helpers/errors_proxy.rb
117
132
  - lib/jsonapi_spec_helpers/helpers.rb
118
- - lib/jsonapi_spec_helpers/matchers.rb
119
- - lib/jsonapi_spec_helpers/payload.rb
120
- - lib/jsonapi_spec_helpers/payload_sanitizer.rb
133
+ - lib/jsonapi_spec_helpers/node.rb
134
+ - lib/jsonapi_spec_helpers/rspec.rb
121
135
  - lib/jsonapi_spec_helpers/version.rb
122
136
  homepage:
123
137
  licenses:
@@ -134,12 +148,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
148
  version: '0'
135
149
  required_rubygems_version: !ruby/object:Gem::Requirement
136
150
  requirements:
137
- - - ">="
151
+ - - ">"
138
152
  - !ruby/object:Gem::Version
139
- version: '0'
153
+ version: 1.3.1
140
154
  requirements: []
141
155
  rubyforge_project:
142
- rubygems_version: 2.6.12
156
+ rubygems_version: 2.6.13
143
157
  signing_key:
144
158
  specification_version: 4
145
159
  summary: Spec helpers for jsonapi
@@ -1,61 +0,0 @@
1
- require 'rspec/matchers'
2
-
3
- RSpec::Matchers.define :match_payload do |attribute, expected|
4
- match do |actual|
5
- if expected.respond_to?(:as_json)
6
- expected = expected.as_json
7
- end
8
-
9
- actual == expected
10
- end
11
-
12
- failure_message do |actual|
13
- "Expected JSON payload to have key '#{attribute}' == #{expected.inspect} but was #{actual.inspect}"
14
- end
15
- end
16
-
17
- RSpec::Matchers.define :match_type do |attribute, type|
18
- match do |actual|
19
- if type.is_a?(Array)
20
- type.any? { |t| actual.is_a?(t) }
21
- else
22
- actual.is_a?(type)
23
- end
24
- end
25
-
26
- failure_message do |actual|
27
- "Expected JSON payload key '#{attribute}' to have type #{type} but was #{actual.class}"
28
- end
29
- end
30
-
31
- RSpec::Matchers.define :have_payload_key do |expected, allow_nil|
32
- match do |json|
33
- @has_key = json.has_key?(expected.to_s)
34
- @has_value = !json[expected.to_s].nil?
35
-
36
- if allow_nil
37
- @has_key
38
- else
39
- @has_key && @has_value
40
- end
41
- end
42
-
43
- failure_message do |actual|
44
- msg = !allow_nil && @has_key ? "nil. Use 'key(:foo, allow_nil: true)' to allow nils" : "not present"
45
- "Expected JSON payload to have key '#{expected}' but was #{msg}"
46
- end
47
-
48
- failure_message_when_negated do |actual|
49
- "Expected JSON payload to NOT have key '#{expected}' but was present"
50
- end
51
- end
52
-
53
- RSpec::Matchers.define :be_not_in_payload do |expected|
54
- match do |json|
55
- false
56
- end
57
-
58
- failure_message do |actual|
59
- "JSON payload contained unexpected key '#{actual}'"
60
- end
61
- end
@@ -1,66 +0,0 @@
1
- module JsonapiSpecHelpers
2
- class Payload
3
- class << self
4
- attr_accessor :registry
5
- end
6
- self.registry = {}
7
-
8
- attr_accessor :name, :type, :keys, :no_keys
9
-
10
- def self.register(name, &blk)
11
- instance = new
12
- instance.instance_eval(&blk)
13
- instance.name = name
14
- registry[name] = instance
15
- end
16
-
17
- def self.by_type(type)
18
- found = nil
19
- registry.each_pair do |name, payload|
20
- found = payload if payload.type == type
21
- end
22
- raise "Could not find payload for type #{type}" unless found
23
- found
24
- end
25
-
26
- def fork
27
- instance = self.class.new
28
- instance.keys = keys.dup
29
- instance.no_keys = no_keys.dup
30
- instance
31
- end
32
-
33
- def initialize
34
- @keys = {}
35
- @no_keys = []
36
- end
37
-
38
- def no_key(name)
39
- @keys.delete(name)
40
- @no_keys << name
41
- end
42
-
43
- def type(val = nil)
44
- if val
45
- @type = val
46
- else
47
- @type || name.to_s.pluralize.to_sym
48
- end
49
- end
50
-
51
- def key(name, *args, &blk)
52
- options = args.last.is_a?(Hash) ? args.pop : {}
53
- options[:type] = args.first
54
- options[:allow_nil] ||= false
55
- @no_keys.reject! { |k| k == name }
56
- prc = blk
57
- prc = ->(record) { record.send(name) } if prc.nil?
58
- @keys[name] = options.merge(proc: prc)
59
- end
60
-
61
- def timestamps!
62
- @keys[:created_at] = key(:created_at, String)
63
- @keys[:updated_at] = key(:updated_at, String)
64
- end
65
- end
66
- end
@@ -1,93 +0,0 @@
1
- module JsonapiSpecHelpers
2
- class PayloadSanitizer
3
- def initialize(payload)
4
- @payload = payload
5
- @included = []
6
- end
7
-
8
- def resource
9
- @resource ||= sane_resource(@payload)
10
- end
11
-
12
- def sanitize
13
- resource[:relationships].each_pair do |key, relationship_payload|
14
- set_default_relationship_payload(key, relationship_payload)
15
-
16
- if relationship_payload.is_a?(Array)
17
- relationship_payload.each do |p|
18
- process_relationship(key, p)
19
- end
20
- else
21
- process_relationship(key, relationship_payload)
22
- end
23
- end
24
-
25
- payload = { data: data }
26
- payload[:included] = @included
27
- payload
28
- end
29
-
30
- def included
31
- @included
32
- end
33
-
34
- def add_include(incl)
35
- @included.push(incl) if @included.index(incl).nil?
36
- end
37
-
38
- def resource_identifier
39
- {}.tap do |ri|
40
- ri[:id] = resource[:id] if resource[:id]
41
- ri[:type] = resource[:type]
42
- end
43
- end
44
-
45
- def data
46
- @data ||= {}.tap do |d|
47
- d[:id] = resource[:id] if resource[:id]
48
- d[:type] = resource[:type]
49
- d[:attributes] = resource[:attributes]
50
- end
51
- end
52
-
53
- private
54
-
55
- def set_default_relationship_payload(key, payload)
56
- data[:relationships] ||= {}
57
- if payload.is_a?(Array)
58
- data[:relationships][key] ||= { data: [] }
59
- else
60
- data[:relationships][key] ||= { data: nil }
61
- end
62
- end
63
-
64
- def process_relationship(name, relationship_payload)
65
- sanitizer = self.class.new(relationship_payload)
66
-
67
- if data[:relationships][name][:data].is_a?(Array)
68
- data[:relationships][name][:data] << sanitizer.resource_identifier
69
- else
70
- data[:relationships][name] = { data: sanitizer.resource_identifier }
71
- end
72
-
73
- sanitized = sanitizer.sanitize
74
- add_include(sanitized[:data])
75
- sanitized[:included].each do |incl|
76
- add_include(incl)
77
- end
78
- end
79
-
80
- def sane_resource(payload)
81
- id, type = payload.delete(:id), payload.delete(:type)
82
- relationships = payload.delete(:relationships) || {}
83
- raise 'jsonapi payloads must specify a "type"' if type.nil?
84
-
85
- {
86
- id: id,
87
- type: type,
88
- attributes: payload,
89
- relationships: relationships
90
- }
91
- end
92
- end
93
- end