jsonapi 0.1.1.beta2 → 0.1.1.beta6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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