jsonapi 0.1.1.beta2 → 0.1.1.beta6

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.
@@ -1,41 +0,0 @@
1
- module JSONAPI
2
- # c.f. http://jsonapi.org/format/#document-resource-object-relationships
3
- class Relationships
4
- include Enumerable
5
-
6
- def initialize(relationships_hash, options = {})
7
- fail InvalidDocument,
8
- "the value of 'relationships' MUST be an object" unless
9
- relationships_hash.is_a?(Hash)
10
-
11
- @hash = relationships_hash
12
- @relationships = {}
13
- relationships_hash.each do |rel_name, rel_hash|
14
- @relationships[rel_name.to_s] = Relationship.new(rel_hash, options)
15
- define_singleton_method(rel_name) do
16
- @relationships[rel_name.to_s]
17
- end
18
- end
19
- end
20
-
21
- def to_hash
22
- @hash
23
- end
24
-
25
- def each(&block)
26
- @relationships.each(&block)
27
- end
28
-
29
- def [](rel_name)
30
- @relationships[rel_name.to_s]
31
- end
32
-
33
- def defined?(rel_name)
34
- @relationships.key?(rel_name.to_s)
35
- end
36
-
37
- def keys
38
- @relationships.keys
39
- end
40
- end
41
- end
@@ -1,46 +0,0 @@
1
- module JSONAPI
2
- # c.f. http://jsonapi.org/format/#document-resource-objects
3
- class Resource
4
- attr_reader :id, :type, :attributes, :relationships, :links, :meta
5
-
6
- def initialize(resource_hash, options = {})
7
- @hash = resource_hash
8
- @options = options.dup
9
- @id_optional = @options.delete(:id_optional)
10
- validate!(resource_hash)
11
- @id = resource_hash['id']
12
- @type = resource_hash['type']
13
- @attributes_hash = resource_hash['attributes'] || {}
14
- @attributes = Attributes.new(@attributes_hash, @options)
15
- @relationships_hash = resource_hash['relationships'] || {}
16
- @relationships = Relationships.new(@relationships_hash, @options)
17
- @links_hash = resource_hash['links'] || {}
18
- @links = Links.new(@links_hash, @options)
19
- @meta = resource_hash['meta'] if resource_hash.key?('meta')
20
- end
21
-
22
- def to_hash
23
- @hash
24
- end
25
-
26
- private
27
-
28
- def validate!(resource_hash)
29
- case
30
- when !@id_optional && !resource_hash.key?('id')
31
- # We might want to take care of
32
- # > Exception: The id member is not required when the resource object
33
- # > originates at the client and represents a new resource to be created
34
- # > on the server.
35
- # in the future.
36
- fail InvalidDocument, "a resource object MUST contain an 'id'"
37
- when !@id_optional && !resource_hash['id'].is_a?(String)
38
- fail InvalidDocument, "the value of 'id' MUST be a string"
39
- when !resource_hash.key?('type')
40
- fail InvalidDocument, "a resource object MUST contain a 'type'"
41
- when !resource_hash['type'].is_a?(String)
42
- fail InvalidDocument, "the value of 'type' MUST be a string"
43
- end
44
- end
45
- end
46
- end
@@ -1,36 +0,0 @@
1
- module JSONAPI
2
- # c.f. http://jsonapi.org/format/#document-resource-identifier-objects
3
- class ResourceIdentifier
4
- attr_reader :id, :type
5
-
6
- def initialize(resource_identifier_hash, options = {})
7
- @hash = resource_identifier_hash
8
-
9
- validate!(resource_identifier_hash)
10
-
11
- @id = resource_identifier_hash['id']
12
- @type = resource_identifier_hash['type']
13
- end
14
-
15
- def to_hash
16
- @hash
17
- end
18
-
19
- private
20
-
21
- def validate!(resource_identifier_hash)
22
- case
23
- when !resource_identifier_hash.key?('id')
24
- fail InvalidDocument,
25
- "a resource identifier object MUST contain an 'id'"
26
- when !resource_identifier_hash['id'].is_a?(String)
27
- fail InvalidDocument, "the value of 'id' MUST be a string"
28
- when !resource_identifier_hash.key?('type')
29
- fail InvalidDocument,
30
- "a resource identifier object MUST contain a 'type'"
31
- when !resource_identifier_hash['type'].is_a?(String)
32
- fail InvalidDocument, "the value of 'type' MUST be a string"
33
- end
34
- end
35
- end
36
- end
@@ -1,3 +0,0 @@
1
- module JSONAPI
2
- VERSION = '0.1.1.beta2'.freeze
3
- end
@@ -1,95 +0,0 @@
1
- require 'jsonapi'
2
-
3
- describe JSONAPI, '#parse' do
4
- it 'succeeds when there are no duplicates' do
5
- payload = {
6
- 'data' => [
7
- {
8
- 'type' => 'articles',
9
- 'id' => '1',
10
- 'attributes' => {
11
- 'title' => 'JSON API paints my bikeshed!'
12
- },
13
- 'links' => {
14
- 'self' => 'http://example.com/articles/1'
15
- },
16
- 'relationships' => {
17
- 'author' => {
18
- 'links' => {
19
- 'self' => 'http://example.com/articles/1/relationships/author',
20
- 'related' => 'http://example.com/articles/1/author'
21
- },
22
- 'data' => { 'type' => 'people', 'id' => '9' }
23
- },
24
- 'journal' => {
25
- 'data' => nil
26
- },
27
- 'comments' => {
28
- 'links' => {
29
- 'self' => 'http://example.com/articles/1/relationships/comments',
30
- 'related' => 'http://example.com/articles/1/comments'
31
- },
32
- 'data' => [
33
- { 'type' => 'comments', 'id' => '5' },
34
- { 'type' => 'comments', 'id' => '12' }
35
- ]
36
- }
37
- }
38
- }]
39
- }
40
-
41
- JSONAPI.parse(payload, verify_duplicates: true)
42
- end
43
-
44
- it 'fails when there are duplicates within primary data' do
45
- payload = {
46
- 'data' => [
47
- {
48
- 'type' => 'articles',
49
- 'id' => '1'
50
- }, {
51
- 'type' => 'articles',
52
- 'id' => '1'
53
- }]
54
- }
55
-
56
- expect { JSONAPI.parse(payload, verify_duplicates: true) }
57
- .to raise_error(JSONAPI::InvalidDocument)
58
- end
59
-
60
- it 'fails when there are duplicates within included' do
61
- payload = {
62
- 'data' => nil,
63
- 'included' => [
64
- {
65
- 'type' => 'articles',
66
- 'id' => '1'
67
- }, {
68
- 'type' => 'articles',
69
- 'id' => '1'
70
- }]
71
- }
72
-
73
- expect { JSONAPI.parse(payload, verify_duplicates: true) }
74
- .to raise_error(JSONAPI::InvalidDocument)
75
- end
76
-
77
- it 'fails when there are duplicates within primary data' do
78
- payload = {
79
- 'data' => [
80
- {
81
- 'type' => 'articles',
82
- 'id' => '1'
83
- }
84
- ],
85
- 'included' => [
86
- {
87
- 'type' => 'articles',
88
- 'id' => '1'
89
- }]
90
- }
91
-
92
- expect { JSONAPI.parse(payload, verify_duplicates: true) }
93
- .to raise_error(JSONAPI::InvalidDocument)
94
- end
95
- end
@@ -1,161 +0,0 @@
1
- require 'jsonapi'
2
-
3
- describe JSONAPI, '#parse' do
4
- it 'succeeds when no included property is provided' do
5
- payload = {
6
- 'data' => [
7
- {
8
- 'type' => 'articles',
9
- 'id' => '1',
10
- 'attributes' => {
11
- 'title' => 'JSON API paints my bikeshed!'
12
- },
13
- 'links' => {
14
- 'self' => 'http://example.com/articles/1'
15
- },
16
- 'relationships' => {
17
- 'author' => {
18
- 'links' => {
19
- 'self' => 'http://example.com/articles/1/relationships/author',
20
- 'related' => 'http://example.com/articles/1/author'
21
- },
22
- 'data' => { 'type' => 'people', 'id' => '9' }
23
- },
24
- 'journal' => {
25
- 'data' => nil
26
- },
27
- 'comments' => {
28
- 'links' => {
29
- 'self' => 'http://example.com/articles/1/relationships/comments',
30
- 'related' => 'http://example.com/articles/1/comments'
31
- },
32
- 'data' => [
33
- { 'type' => 'comments', 'id' => '5' },
34
- { 'type' => 'comments', 'id' => '12' }
35
- ]
36
- }
37
- }
38
- }]
39
- }
40
-
41
- JSONAPI.parse(payload, verify_linkage: true)
42
- end
43
-
44
- it 'succeeds when full linkage is respected' do
45
- payload = {
46
- 'data' => [
47
- {
48
- 'type' => 'articles',
49
- 'id' => '1',
50
- 'attributes' => {
51
- 'title' => 'JSON API paints my bikeshed!'
52
- },
53
- 'links' => {
54
- 'self' => 'http://example.com/articles/1'
55
- },
56
- 'relationships' => {
57
- 'author' => {
58
- 'links' => {
59
- 'self' => 'http://example.com/articles/1/relationships/author',
60
- 'related' => 'http://example.com/articles/1/author'
61
- },
62
- 'data' => { 'type' => 'people', 'id' => '9' }
63
- },
64
- 'journal' => {
65
- 'data' => nil
66
- },
67
- 'comments' => {
68
- 'links' => {
69
- 'self' => 'http://example.com/articles/1/relationships/comments',
70
- 'related' => 'http://example.com/articles/1/comments'
71
- },
72
- 'data' => [
73
- { 'type' => 'comments', 'id' => '5' },
74
- { 'type' => 'comments', 'id' => '12' }
75
- ]
76
- }
77
- }
78
- }],
79
- 'included' => [
80
- {
81
- 'type' => 'comments',
82
- 'id' => '5'
83
- }, {
84
- 'type' => 'comments',
85
- 'id' => '12'
86
- }, {
87
- 'type' => 'comments',
88
- 'id' => '13'
89
- }, {
90
- 'type' => 'people',
91
- 'id' => '9',
92
- 'relationships' => {
93
- 'comments' => {
94
- 'data' => [
95
- {
96
- 'type' => 'comments',
97
- 'id' => '13'
98
- }
99
- ]
100
- }
101
- }
102
- }
103
- ]
104
- }
105
-
106
- JSONAPI.parse(payload, verify_linkage: true)
107
- end
108
-
109
- it 'fails when full linkage is not respected' do
110
- payload = {
111
- 'data' => [
112
- {
113
- 'type' => 'articles',
114
- 'id' => '1',
115
- 'attributes' => {
116
- 'title' => 'JSON API paints my bikeshed!'
117
- },
118
- 'links' => {
119
- 'self' => 'http://example.com/articles/1'
120
- },
121
- 'relationships' => {
122
- 'author' => {
123
- 'links' => {
124
- 'self' => 'http://example.com/articles/1/relationships/author',
125
- 'related' => 'http://example.com/articles/1/author'
126
- },
127
- 'data' => { 'type' => 'people', 'id' => '9' }
128
- },
129
- 'journal' => {
130
- 'data' => nil
131
- },
132
- 'comments' => {
133
- 'links' => {
134
- 'self' => 'http://example.com/articles/1/relationships/comments',
135
- 'related' => 'http://example.com/articles/1/comments'
136
- },
137
- 'data' => [
138
- { 'type' => 'comments', 'id' => '5' },
139
- { 'type' => 'comments', 'id' => '12' }
140
- ]
141
- }
142
- }
143
- }],
144
- 'included' => [
145
- {
146
- 'type' => 'comments',
147
- 'id' => '5'
148
- }, {
149
- 'type' => 'comments',
150
- 'id' => '12'
151
- }, {
152
- 'type' => 'comments',
153
- 'id' => '13'
154
- }
155
- ]
156
- }
157
-
158
- expect { JSONAPI.parse(payload, verify_linkage: true) }
159
- .to raise_error(JSONAPI::InvalidDocument)
160
- end
161
- end
@@ -1,59 +0,0 @@
1
- require 'jsonapi/include_directive'
2
-
3
- describe JSONAPI::IncludeDirective::Parser, '.parse_include_args' do
4
- it 'handles arrays of symbols and hashes' do
5
- args = [:friends,
6
- comments: [:author],
7
- posts: [:author,
8
- comments: [:author]]]
9
- hash = JSONAPI::IncludeDirective::Parser.parse_include_args(args)
10
- expected = {
11
- friends: {},
12
- comments: { author: {} },
13
- posts: { author: {}, comments: { author: {} } }
14
- }
15
-
16
- expect(hash).to eq expected
17
- end
18
-
19
- it 'handles strings with spaces' do
20
- str = 'friends, comments.author, posts.author, posts.comments.author'
21
- hash = JSONAPI::IncludeDirective::Parser.parse_include_args(str)
22
- expected = {
23
- friends: {},
24
- comments: { author: {} },
25
- posts: { author: {}, comments: { author: {} } }
26
- }
27
-
28
- expect(hash).to eq expected
29
- end
30
-
31
- it 'handles common prefixes in strings' do
32
- args = ['friends', 'comments.author', 'posts.author',
33
- 'posts.comments.author']
34
- hash = JSONAPI::IncludeDirective::Parser.parse_include_args(args)
35
- expected = {
36
- friends: {},
37
- comments: { author: {} },
38
- posts: { author: {}, comments: { author: {} } }
39
- }
40
-
41
- expect(hash).to eq expected
42
- end
43
-
44
- it 'handles an empty string' do
45
- args = ''
46
- hash = JSONAPI::IncludeDirective::Parser.parse_include_args(args)
47
- expected = {}
48
-
49
- expect(hash).to eq expected
50
- end
51
-
52
- it 'handles an empty array' do
53
- args = []
54
- hash = JSONAPI::IncludeDirective::Parser.parse_include_args(args)
55
- expected = {}
56
-
57
- expect(hash).to eq expected
58
- end
59
- end