fast_jsonapi 1.0.16

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.
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ describe FastJsonapi::ObjectSerializer do
4
+ include_context 'movie class'
5
+
6
+ context 'when testing instance methods of object serializer' do
7
+ it 'returns correct hash when serializable_hash is called' do
8
+ options = {}
9
+ options[:meta] = { total: 2 }
10
+ options[:include] = [:actors]
11
+ serializable_hash = MovieSerializer.new([movie, movie], options).serializable_hash
12
+
13
+ expect(serializable_hash[:data].length).to eq 2
14
+ expect(serializable_hash[:data][0][:relationships].length).to eq 3
15
+ expect(serializable_hash[:data][0][:attributes].length).to eq 2
16
+
17
+ expect(serializable_hash[:meta]).to be_instance_of(Hash)
18
+
19
+ expect(serializable_hash[:included]).to be_instance_of(Array)
20
+ expect(serializable_hash[:included][0]).to be_instance_of(Hash)
21
+ expect(serializable_hash[:included].length).to eq 3
22
+
23
+ serializable_hash = MovieSerializer.new(movie).serializable_hash
24
+
25
+ expect(serializable_hash[:data]).to be_instance_of(Hash)
26
+ expect(serializable_hash[:meta]).to be nil
27
+ expect(serializable_hash[:included]).to be nil
28
+ end
29
+
30
+ it 'returns correct number of records when serialized_json is called for an array' do
31
+ options = {}
32
+ options[:meta] = { total: 2 }
33
+ json = MovieSerializer.new([movie, movie], options).serialized_json
34
+ serializable_hash = JSON.parse(json)
35
+ expect(serializable_hash['data'].length).to eq 2
36
+ expect(serializable_hash['meta']).to be_instance_of(Hash)
37
+ end
38
+
39
+ it 'returns correct id when serialized_json is called for a single object' do
40
+ json = MovieSerializer.new(movie).serialized_json
41
+ serializable_hash = JSON.parse(json)
42
+ expect(serializable_hash['data']['id']).to eq movie.id.to_s
43
+ end
44
+
45
+ it 'returns correct json when serializing nil' do
46
+ json = MovieSerializer.new(nil).serialized_json
47
+ serializable_hash = JSON.parse(json)
48
+ expect(serializable_hash['data']).to eq nil
49
+ end
50
+
51
+ it 'returns correct json when record id is nil' do
52
+ movie.id = nil
53
+ json = MovieSerializer.new(movie).serialized_json
54
+ serializable_hash = JSON.parse(json)
55
+ expect(serializable_hash['data']['id']).to be nil
56
+ end
57
+
58
+ it 'returns correct json when has_many returns []' do
59
+ movie.actor_ids = []
60
+ json = MovieSerializer.new(movie).serialized_json
61
+ serializable_hash = JSON.parse(json)
62
+ expect(serializable_hash['data']['relationships']['actors']['data'].length).to eq 0
63
+ end
64
+
65
+ it 'returns correct json when belongs_to returns nil' do
66
+ movie.owner_id = nil
67
+ json = MovieSerializer.new(movie).serialized_json
68
+ serializable_hash = JSON.parse(json)
69
+ expect(serializable_hash['data']['relationships']['owner']['data']).to be nil
70
+ end
71
+
72
+ it 'returns correct json when serializing []' do
73
+ json = MovieSerializer.new([]).serialized_json
74
+ serializable_hash = JSON.parse(json)
75
+ expect(serializable_hash['data']).to eq []
76
+ end
77
+
78
+ it 'returns errors when serializing with non-existent includes key' do
79
+ options = {}
80
+ options[:meta] = { total: 2 }
81
+ options[:include] = [:blah_blah]
82
+ expect { MovieSerializer.new([movie, movie], options).serializable_hash }.to raise_error(ArgumentError)
83
+ end
84
+
85
+ it 'returns keys when serializing with empty string/nil array includes key' do
86
+ options = {}
87
+ options[:meta] = { total: 2 }
88
+ options[:include] = ['']
89
+ expect(MovieSerializer.new([movie, movie], options).serializable_hash.keys).to eq [:data, :meta]
90
+ options[:include] = [nil]
91
+ expect(MovieSerializer.new([movie, movie], options).serializable_hash.keys).to eq [:data, :meta]
92
+ end
93
+ end
94
+
95
+ context 'when testing included do block of object serializer' do
96
+ it 'should set default_type based on serializer class name' do
97
+ class BlahSerializer
98
+ include FastJsonapi::ObjectSerializer
99
+ end
100
+ expect(BlahSerializer.record_type).to be :blah
101
+ end
102
+
103
+ it 'should set default_type for a multi word class name' do
104
+ class BlahBlahSerializer
105
+ include FastJsonapi::ObjectSerializer
106
+ end
107
+ expect(BlahBlahSerializer.record_type).to be :blah_blah
108
+ end
109
+
110
+ it 'shouldnt set default_type for a serializer that doesnt follow convention' do
111
+ class BlahBlahSerializerBuilder
112
+ include FastJsonapi::ObjectSerializer
113
+ end
114
+ expect(BlahBlahSerializerBuilder.record_type).to be_nil
115
+ end
116
+
117
+ it 'shouldnt set default_type for a serializer that doesnt follow convention' do
118
+ module V1
119
+ class BlahSerializer
120
+ include FastJsonapi::ObjectSerializer
121
+ end
122
+ end
123
+ expect(V1::BlahSerializer.record_type).to be :blah
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe FastJsonapi::ObjectSerializer do
4
+ include_context 'movie class'
5
+
6
+ context 'when testing object serializer with ruby struct' do
7
+ it 'returns correct hash when serializable_hash is called' do
8
+ options = {}
9
+ options[:meta] = { total: 2 }
10
+ options[:include] = [:actors]
11
+ serializable_hash = MovieSerializer.new([movie_struct, movie_struct], options).serializable_hash
12
+
13
+ expect(serializable_hash[:data].length).to eq 2
14
+ expect(serializable_hash[:data][0][:relationships].length).to eq 3
15
+ expect(serializable_hash[:data][0][:attributes].length).to eq 2
16
+
17
+ expect(serializable_hash[:meta]).to be_instance_of(Hash)
18
+
19
+ expect(serializable_hash[:included]).to be_instance_of(Array)
20
+ expect(serializable_hash[:included][0]).to be_instance_of(Hash)
21
+ expect(serializable_hash[:included].length).to eq 3
22
+
23
+ serializable_hash = MovieSerializer.new(movie_struct).serializable_hash
24
+
25
+ expect(serializable_hash[:data]).to be_instance_of(Hash)
26
+ expect(serializable_hash[:meta]).to be nil
27
+ expect(serializable_hash[:included]).to be nil
28
+ expect(serializable_hash[:data][:id]).to eq movie_struct.id.to_s
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe FastJsonapi::ObjectSerializer do
4
+ include_context "movie class"
5
+
6
+ context 'when testing class methods of serialization core' do
7
+ it 'returns correct hash when id_hash is called' do
8
+ inputs = [{id: 23, record_type: :movie}, {id: 'x', record_type: 'person'}]
9
+ inputs.each do |hash|
10
+ result_hash = MovieSerializer.send(:id_hash, hash[:id], hash[:record_type])
11
+ expect(result_hash[:id]).to eq hash[:id].to_s
12
+ expect(result_hash[:type]).to eq hash[:record_type]
13
+ end
14
+
15
+ result_hash = MovieSerializer.send(:id_hash, nil, 'movie')
16
+ expect(result_hash).to be nil
17
+ end
18
+
19
+ it 'returns correct hash when ids_hash is called' do
20
+ inputs = [{ids: %w(1 2 3), record_type: :movie}, {ids: %w(x y z), record_type: 'person'}]
21
+ inputs.each do |hash|
22
+ results = MovieSerializer.send(:ids_hash, hash[:ids], hash[:record_type])
23
+ expect(results.map{|h| h[:id]}).to eq hash[:ids]
24
+ expect(results[0][:type]).to eq hash[:record_type]
25
+ end
26
+
27
+ result = MovieSerializer.send(:ids_hash, [], 'movie')
28
+ expect(result).to be_empty
29
+ end
30
+
31
+ it 'returns correct hash when attributes_hash is called' do
32
+ attributes_hash = MovieSerializer.send(:attributes_hash, movie)
33
+ attribute_names = attributes_hash.keys.sort
34
+ expect(attribute_names).to eq MovieSerializer.attributes_to_serialize.keys.sort
35
+ MovieSerializer.attributes_to_serialize.each do |key, method_name|
36
+ value = attributes_hash[key]
37
+ expect(value).to eq movie.send(method_name)
38
+ end
39
+ end
40
+
41
+ it 'returns the correct empty result when relationships_hash is called' do
42
+ movie.actor_ids = []
43
+ movie.owner_id = nil
44
+ relationships_hash = MovieSerializer.send(:relationships_hash, movie)
45
+ expect(relationships_hash[:actors][:data]).to eq([])
46
+ expect(relationships_hash[:owner][:data]).to eq(nil)
47
+ end
48
+
49
+ it 'returns correct keys when relationships_hash is called' do
50
+ relationships_hash = MovieSerializer.send(:relationships_hash, movie)
51
+ relationship_names = relationships_hash.keys.sort
52
+ relationships_hashes = MovieSerializer.relationships_to_serialize.values
53
+ expected_names = relationships_hashes.map{|relationship| relationship[:key]}.sort
54
+ expect(relationship_names).to eq expected_names
55
+ end
56
+
57
+ it 'returns correct values when relationships_hash is called' do
58
+ relationships_hash = MovieSerializer.relationships_hash(movie)
59
+ actors_hash = movie.actor_ids.map { |id| {id: id.to_s, type: :actor} }
60
+ owner_hash = {id: movie.owner_id.to_s, type: :user}
61
+ expect(relationships_hash[:actors][:data]).to match_array actors_hash
62
+ expect(relationships_hash[:owner][:data]).to eq owner_hash
63
+ end
64
+
65
+ it 'returns correct hash when record_hash is called' do
66
+ record_hash = MovieSerializer.send(:record_hash, movie)
67
+ expect(record_hash[:id]).to eq movie.id.to_s
68
+ expect(record_hash[:type]).to eq MovieSerializer.record_type
69
+ expect(record_hash).to have_key(:attributes) if MovieSerializer.attributes_to_serialize.present?
70
+ expect(record_hash).to have_key(:relationships) if MovieSerializer.relationships_to_serialize.present?
71
+ end
72
+
73
+ it 'serializes known included records only once' do
74
+ includes_list = [:actors]
75
+ known_included_objects = {}
76
+ included_records = []
77
+ [movie, movie].each do |record|
78
+ included_records.concat MovieSerializer.send(:get_included_records, record, includes_list, known_included_objects)
79
+ end
80
+ expect(included_records.size).to eq 3
81
+ end
82
+ end
83
+
84
+ end
@@ -0,0 +1,83 @@
1
+ RSpec.shared_context 'ams movie class' do
2
+ before(:context) do
3
+ # models
4
+ class AMSMovie < ActiveModelSerializers::Model
5
+ attr_accessor :id, :name, :release_year, :actors, :owner, :movie_type
6
+ end
7
+
8
+ class AMSActor < ActiveModelSerializers::Model
9
+ attr_accessor :id, :name, :email
10
+ end
11
+
12
+ class AMSUser < ActiveModelSerializers::Model
13
+ attr_accessor :id, :name
14
+ end
15
+ class AMSMovieType < ActiveModelSerializers::Model
16
+ attr_accessor :id, :name
17
+ end
18
+ # serializers
19
+ class AMSMovieSerializer < ActiveModel::Serializer
20
+ type 'movie'
21
+ attributes :name, :release_year
22
+ has_many :actors
23
+ has_one :owner
24
+ belongs_to :movie_type
25
+ end
26
+
27
+ class AMSActorSerializer < ActiveModel::Serializer
28
+ type 'actor'
29
+ attributes :name, :email
30
+ end
31
+
32
+ class AMSUserSerializer < ActiveModel::Serializer
33
+ type 'user'
34
+ attributes :name
35
+ end
36
+ class AMSMovieTypeSerializer < ActiveModel::Serializer
37
+ type 'movie_type'
38
+ attributes :name
39
+ end
40
+ end
41
+
42
+ after(:context) do
43
+ classes_to_remove = %i[AMSMovie AMSMovieSerializer]
44
+ classes_to_remove.each do |klass_name|
45
+ Object.send(:remove_const, klass_name) if Object.constants.include?(klass_name)
46
+ end
47
+ end
48
+
49
+ let(:ams_actors) do
50
+ 3.times.map do |i|
51
+ a = AMSActor.new
52
+ a.id = i + 1
53
+ a.name = "Test #{a.id}"
54
+ a.email = "test#{a.id}@test.com"
55
+ a
56
+ end
57
+ end
58
+
59
+ let(:ams_user) do
60
+ ams_user = AMSUser.new
61
+ ams_user.id = 3
62
+ ams_user
63
+ end
64
+
65
+ let(:ams_movie_type) do
66
+ ams_movie_type = AMSMovieType.new
67
+ ams_movie_type.id = 1
68
+ ams_movie_type.name = 'episode'
69
+ ams_movie_type
70
+ end
71
+
72
+ def build_ams_movies(count)
73
+ count.times.map do |i|
74
+ m = AMSMovie.new
75
+ m.id = i + 1
76
+ m.name = 'test movie'
77
+ m.actors = ams_actors
78
+ m.owner = ams_user
79
+ m.movie_type = ams_movie_type
80
+ m
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,192 @@
1
+ RSpec.shared_context 'movie class' do
2
+
3
+ # Movie, Actor Classes and serializers
4
+ before(:context) do
5
+ # models
6
+ class Movie
7
+ attr_accessor :id, :name, :release_year, :actor_ids, :owner_id, :movie_type_id
8
+
9
+ def actors
10
+ actor_ids.map do |id|
11
+ a = Actor.new
12
+ a.id = id
13
+ a.name = "Test #{a.id}"
14
+ a.email = "test#{a.id}@test.com"
15
+ a
16
+ end
17
+ end
18
+
19
+ def movie_type
20
+ mt = MovieType.new
21
+ mt.id = movie_type_id
22
+ mt.name = 'Episode'
23
+ mt
24
+ end
25
+
26
+ def cache_key
27
+ "#{id}"
28
+ end
29
+ end
30
+
31
+ class Actor
32
+ attr_accessor :id, :name, :email
33
+ end
34
+
35
+ class MovieType
36
+ attr_accessor :id, :name
37
+ end
38
+
39
+ # serializers
40
+ class MovieSerializer
41
+ include FastJsonapi::ObjectSerializer
42
+ set_type :movie
43
+ attributes :name, :release_year
44
+ has_many :actors
45
+ belongs_to :owner, record_type: :user
46
+ belongs_to :movie_type
47
+ end
48
+
49
+ class CachingMovieSerializer
50
+ include FastJsonapi::ObjectSerializer
51
+ set_type :movie
52
+ attributes :name, :release_year
53
+ has_many :actors
54
+ belongs_to :owner, record_type: :user
55
+ belongs_to :movie_type
56
+
57
+ cache_options enabled: true
58
+ end
59
+
60
+ class CachingMovieWithHasManySerializer
61
+ include FastJsonapi::ObjectSerializer
62
+ set_type :movie
63
+ attributes :name, :release_year
64
+ has_many :actors, cached: true
65
+ belongs_to :owner, record_type: :user
66
+ belongs_to :movie_type
67
+
68
+ cache_options enabled: true
69
+ end
70
+
71
+ class ActorSerializer
72
+ include FastJsonapi::ObjectSerializer
73
+ set_type :actor
74
+ attributes :name, :email
75
+ end
76
+
77
+ class MovieTypeSerializer
78
+ include FastJsonapi::ObjectSerializer
79
+ set_type :movie_type
80
+ attributes :name
81
+ end
82
+ end
83
+
84
+
85
+ # Namespaced MovieSerializer
86
+ before(:context) do
87
+ # namespaced model stub
88
+ module AppName
89
+ module V1
90
+ class MovieSerializer
91
+ include FastJsonapi::ObjectSerializer
92
+ # to test if compute_serializer_name works
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+
99
+ # Hyphenated keys for the serializer
100
+ before(:context) do
101
+ class HyphenMovieSerializer
102
+ include FastJsonapi::ObjectSerializer
103
+ use_hyphen
104
+ set_type :movie
105
+ attributes :name, :release_year
106
+ has_many :actors
107
+ belongs_to :owner, record_type: :user
108
+ belongs_to :movie_type
109
+ end
110
+
111
+ class HyphenMovieTypeSerializer
112
+ include FastJsonapi::ObjectSerializer
113
+ use_hyphen
114
+ set_type :movie_type
115
+ attributes :name
116
+ end
117
+ end
118
+
119
+
120
+ # Movie and Actor struct
121
+ before(:context) do
122
+ MovieStruct = Struct.new(
123
+ :id, :name, :release_year, :actor_ids, :actors, :owner_id, :owner, :movie_type_id
124
+ )
125
+
126
+ ActorStruct = Struct.new(
127
+ :id, :name, :email
128
+ )
129
+ end
130
+
131
+ after(:context) do
132
+ classes_to_remove = %i[
133
+ Movie
134
+ MovieSerializer
135
+ Actor
136
+ ActorSerializer
137
+ MovieType
138
+ MovieTypeSerializer
139
+ AppName::V1::MovieSerializer
140
+ MovieStruct
141
+ ActorStruct
142
+ HyphenMovieSerializer
143
+ ]
144
+ classes_to_remove.each do |klass_name|
145
+ Object.send(:remove_const, klass_name) if Object.constants.include?(klass_name)
146
+ end
147
+ end
148
+
149
+ let(:movie_struct) do
150
+
151
+ actors = []
152
+
153
+ 3.times.each do |id|
154
+ a = ActorStruct.new
155
+ a[:id] = id
156
+ a[:name] = id.to_s
157
+ actors << a
158
+ end
159
+
160
+ m = MovieStruct.new
161
+ m[:id] = 23
162
+ m[:name] = 'struct movie'
163
+ m[:release_year] = 1987
164
+ m[:actor_ids] = [1,2,3]
165
+ m[:owner_id] = 3
166
+ m[:movie_type_id] = 2
167
+ m[:actors] = actors
168
+ m
169
+ end
170
+
171
+ let(:movie) do
172
+ m = Movie.new
173
+ m.id = 232
174
+ m.name = 'test movie'
175
+ m.actor_ids = [1, 2, 3]
176
+ m.owner_id = 3
177
+ m.movie_type_id = 1
178
+ m
179
+ end
180
+
181
+ def build_movies(count)
182
+ count.times.map do |i|
183
+ m = Movie.new
184
+ m.id = i + 1
185
+ m.name = 'test movie'
186
+ m.actor_ids = [1, 2, 3]
187
+ m.owner_id = 3
188
+ m.movie_type_id = 1
189
+ m
190
+ end
191
+ end
192
+ end