fast_jsonapi 1.0.16

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