restpack_serializer 0.6.7 → 0.6.12
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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/Rakefile +1 -0
- data/lib/restpack_serializer.rb +1 -1
- data/lib/restpack_serializer/serializable.rb +17 -5
- data/lib/restpack_serializer/serializable/side_loading.rb +5 -1
- data/lib/restpack_serializer/version.rb +1 -1
- data/performance/mem.rb +49 -0
- data/restpack_serializer.gemspec +8 -9
- data/spec/factory/factory_spec.rb +21 -14
- data/spec/fixtures/db.rb +0 -11
- data/spec/restpack_serializer_spec.rb +4 -4
- data/spec/result_spec.rb +16 -15
- data/spec/serializable/filterable_spec.rb +1 -1
- data/spec/serializable/options_spec.rb +40 -35
- data/spec/serializable/paging_spec.rb +88 -81
- data/spec/serializable/resource_spec.rb +11 -10
- data/spec/serializable/serializer_spec.rb +79 -41
- data/spec/serializable/side_loading/belongs_to_spec.rb +16 -13
- data/spec/serializable/side_loading/has_and_belongs_many_spec.rb +7 -7
- data/spec/serializable/side_loading/has_many_spec.rb +19 -20
- data/spec/serializable/side_loading/side_loading_spec.rb +21 -19
- data/spec/serializable/single_spec.rb +4 -4
- data/spec/serializable/sortable_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/factory.rb +20 -26
- metadata +31 -40
@@ -8,32 +8,35 @@ describe RestPack::Serializer::Paging do
|
|
8
8
|
|
9
9
|
context "#page" do
|
10
10
|
let(:page) { MyApp::SongSerializer.page(params, scope, context) }
|
11
|
-
let(:params) { {
|
11
|
+
let(:params) { {} }
|
12
12
|
let(:scope) { nil }
|
13
|
-
let(:context) { {
|
13
|
+
let(:context) { {} }
|
14
14
|
|
15
15
|
context "with defaults" do
|
16
16
|
it "page defaults to 1" do
|
17
|
-
page[:meta][:songs][:page].
|
17
|
+
expect(page[:meta][:songs][:page]).to eq(1)
|
18
18
|
end
|
19
|
+
|
19
20
|
it "page_size defaults to 10" do
|
20
|
-
page[:meta][:songs][:page_size].
|
21
|
+
expect(page[:meta][:songs][:page_size]).to eq(10)
|
21
22
|
end
|
23
|
+
|
22
24
|
it "includes valid paging meta data" do
|
23
|
-
page[:meta][:songs][:count].
|
24
|
-
page[:meta][:songs][:page_count].
|
25
|
-
page[:meta][:songs][:first_href].
|
26
|
-
page[:meta][:songs][:previous_page].
|
27
|
-
page[:meta][:songs][:previous_href].
|
28
|
-
page[:meta][:songs][:next_page].
|
29
|
-
page[:meta][:songs][:next_href].
|
30
|
-
page[:meta][:songs][:last_href].
|
25
|
+
expect(page[:meta][:songs][:count]).to eq(18)
|
26
|
+
expect(page[:meta][:songs][:page_count]).to eq(2)
|
27
|
+
expect(page[:meta][:songs][:first_href]).to eq('/songs')
|
28
|
+
expect(page[:meta][:songs][:previous_page]).to eq(nil)
|
29
|
+
expect(page[:meta][:songs][:previous_href]).to eq(nil)
|
30
|
+
expect(page[:meta][:songs][:next_page]).to eq(2)
|
31
|
+
expect(page[:meta][:songs][:next_href]).to eq('/songs?page=2')
|
32
|
+
expect(page[:meta][:songs][:last_href]).to eq('/songs?page=2')
|
31
33
|
end
|
34
|
+
|
32
35
|
it "includes links" do
|
33
|
-
page[:links].
|
34
|
-
'songs.album' => { :
|
35
|
-
'songs.artist' => { :
|
36
|
-
|
36
|
+
expect(page[:links]).to eq(
|
37
|
+
'songs.album' => { href: "/albums/{songs.album}", type: :albums },
|
38
|
+
'songs.artist' => { href: "/artists/{songs.artist}", type: :artists }
|
39
|
+
)
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
@@ -42,42 +45,44 @@ describe RestPack::Serializer::Paging do
|
|
42
45
|
@original_prefix = MyApp::SongSerializer.href_prefix
|
43
46
|
MyApp::SongSerializer.href_prefix = '/api/v3'
|
44
47
|
end
|
45
|
-
after
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
MyApp::SongSerializer.page(params, scope, context)
|
50
|
-
end
|
48
|
+
after { MyApp::SongSerializer.href_prefix = @original_prefix }
|
49
|
+
|
50
|
+
let(:page) { MyApp::SongSerializer.page(params, scope, context) }
|
51
|
+
|
51
52
|
it 'should use prefixed links' do
|
52
|
-
page[:meta][:songs][:next_href].
|
53
|
+
expect(page[:meta][:songs][:next_href]).to eq('/api/v3/songs?page=2')
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
57
|
context "with custom page size" do
|
57
58
|
let(:params) { { page_size: '3' } }
|
59
|
+
|
58
60
|
it "returns custom page sizes" do
|
59
|
-
page[:meta][:songs][:page_size].
|
60
|
-
page[:meta][:songs][:page_count].
|
61
|
+
expect(page[:meta][:songs][:page_size]).to eq(3)
|
62
|
+
expect(page[:meta][:songs][:page_count]).to eq(6)
|
61
63
|
end
|
64
|
+
|
62
65
|
it "includes the custom page size in the page hrefs" do
|
63
|
-
page[:meta][:songs][:next_page].
|
64
|
-
page[:meta][:songs][:next_href].
|
65
|
-
page[:meta][:songs][:last_href].
|
66
|
+
expect(page[:meta][:songs][:next_page]).to eq(2)
|
67
|
+
expect(page[:meta][:songs][:next_href]).to eq('/songs?page=2&page_size=3')
|
68
|
+
expect(page[:meta][:songs][:last_href]).to eq('/songs?page=6&page_size=3')
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
69
72
|
context "with custom filter" do
|
70
73
|
context "valid :title" do
|
71
74
|
let(:params) { { title: @album1.songs[0].title } }
|
75
|
+
|
72
76
|
it "returns the album" do
|
73
|
-
page[:meta][:songs][:count].
|
77
|
+
expect(page[:meta][:songs][:count]).to eq(1)
|
74
78
|
end
|
75
79
|
end
|
76
80
|
|
77
81
|
context "invalid :title" do
|
78
82
|
let(:params) { { title: "this doesn't exist" } }
|
83
|
+
|
79
84
|
it "returns the album" do
|
80
|
-
page[:meta][:songs][:count].
|
85
|
+
expect(page[:meta][:songs][:count]).to eq(0)
|
81
86
|
end
|
82
87
|
end
|
83
88
|
end
|
@@ -87,13 +92,13 @@ describe RestPack::Serializer::Paging do
|
|
87
92
|
|
88
93
|
it "returns reversed titles" do
|
89
94
|
first = MyApp::Song.first
|
90
|
-
page[:songs].first[:title].
|
95
|
+
expect(page[:songs].first[:title]).to eq(first.title.reverse)
|
91
96
|
end
|
92
97
|
end
|
93
98
|
|
94
99
|
it "serializes results" do
|
95
100
|
first = MyApp::Song.first
|
96
|
-
page[:songs].first.
|
101
|
+
expect(page[:songs].first).to eq(
|
97
102
|
id: first.id.to_s,
|
98
103
|
title: first.title,
|
99
104
|
album_id: first.album_id,
|
@@ -101,17 +106,17 @@ describe RestPack::Serializer::Paging do
|
|
101
106
|
album: first.album_id.to_s,
|
102
107
|
artist: first.artist_id.to_s
|
103
108
|
}
|
104
|
-
|
109
|
+
)
|
105
110
|
end
|
106
111
|
|
107
112
|
context "first page" do
|
108
113
|
let(:params) { { page: '1' } }
|
109
114
|
|
110
115
|
it "returns first page" do
|
111
|
-
page[:meta][:songs][:page].
|
112
|
-
page[:meta][:songs][:page_size].
|
113
|
-
page[:meta][:songs][:previous_page].
|
114
|
-
page[:meta][:songs][:next_page].
|
116
|
+
expect(page[:meta][:songs][:page]).to eq(1)
|
117
|
+
expect(page[:meta][:songs][:page_size]).to eq(10)
|
118
|
+
expect(page[:meta][:songs][:previous_page]).to eq(nil)
|
119
|
+
expect(page[:meta][:songs][:next_page]).to eq(2)
|
115
120
|
end
|
116
121
|
end
|
117
122
|
|
@@ -119,11 +124,11 @@ describe RestPack::Serializer::Paging do
|
|
119
124
|
let(:params) { { page: '2' } }
|
120
125
|
|
121
126
|
it "returns second page" do
|
122
|
-
page[:songs].length.
|
123
|
-
page[:meta][:songs][:page].
|
124
|
-
page[:meta][:songs][:previous_page].
|
125
|
-
page[:meta][:songs][:next_page].
|
126
|
-
page[:meta][:songs][:previous_href].
|
127
|
+
expect(page[:songs].length).to eq(8)
|
128
|
+
expect(page[:meta][:songs][:page]).to eq(2)
|
129
|
+
expect(page[:meta][:songs][:previous_page]).to eq(1)
|
130
|
+
expect(page[:meta][:songs][:next_page]).to eq(nil)
|
131
|
+
expect(page[:meta][:songs][:previous_href]).to eq('/songs')
|
127
132
|
end
|
128
133
|
end
|
129
134
|
|
@@ -131,48 +136,49 @@ describe RestPack::Serializer::Paging do
|
|
131
136
|
let(:params) { { include: 'albums' } }
|
132
137
|
|
133
138
|
it "includes side-loaded models" do
|
134
|
-
page[:linked][:albums].
|
139
|
+
expect(page[:linked][:albums]).not_to eq(nil)
|
135
140
|
end
|
136
141
|
|
137
142
|
it "includes the side-loads in the main meta data" do
|
138
|
-
page[:meta][:songs][:include].
|
143
|
+
expect(page[:meta][:songs][:include]).to eq(%w(albums))
|
139
144
|
end
|
140
145
|
|
141
146
|
it "includes the side-loads in page hrefs" do
|
142
|
-
page[:meta][:songs][:next_href].
|
147
|
+
expect(page[:meta][:songs][:next_href]).to eq('/songs?page=2&include=albums')
|
143
148
|
end
|
144
149
|
|
145
150
|
it "includes links between documents" do
|
146
151
|
song = page[:songs].first
|
147
152
|
song_model = MyApp::Song.find(song[:id])
|
148
|
-
song[:links][:album].
|
149
|
-
song[:links][:artist].
|
153
|
+
expect(song[:links][:album]).to eq(song_model.album_id.to_s)
|
154
|
+
expect(song[:links][:artist]).to eq(song_model.artist_id.to_s)
|
150
155
|
|
151
156
|
album = page[:linked][:albums].first
|
152
157
|
album_model = MyApp::Album.find(album[:id])
|
153
158
|
|
154
|
-
album[:links][:artist].
|
155
|
-
(page[:songs].map { |song| song[:id] } - album[:links][:songs]).empty
|
159
|
+
expect(album[:links][:artist]).to eq(album_model.artist_id.to_s)
|
160
|
+
expect((page[:songs].map { |song| song[:id] } - album[:links][:songs]).empty?).to eq(true)
|
156
161
|
end
|
157
162
|
|
158
163
|
context "with includes as comma delimited string" do
|
159
164
|
let(:params) { { include: "albums,artists" } }
|
165
|
+
|
160
166
|
it "includes side-loaded models" do
|
161
|
-
page[:linked][:albums].
|
162
|
-
page[:linked][:artists].
|
167
|
+
expect(page[:linked][:albums]).not_to eq(nil)
|
168
|
+
expect(page[:linked][:artists]).not_to eq(nil)
|
163
169
|
end
|
164
170
|
|
165
171
|
it "includes the side-loads in page hrefs" do
|
166
|
-
page[:meta][:songs][:next_href].
|
172
|
+
expect(page[:meta][:songs][:next_href]).to eq('/songs?page=2&include=albums,artists')
|
167
173
|
end
|
168
174
|
|
169
175
|
it "includes links" do
|
170
|
-
page[:links]['songs.album'].
|
171
|
-
page[:links]['songs.artist'].
|
172
|
-
page[:links]['albums.songs'].
|
173
|
-
page[:links]['albums.artist'].
|
174
|
-
page[:links]['artists.songs'].
|
175
|
-
page[:links]['artists.albums'].
|
176
|
+
expect(page[:links]['songs.album']).not_to eq(nil)
|
177
|
+
expect(page[:links]['songs.artist']).not_to eq(nil)
|
178
|
+
expect(page[:links]['albums.songs']).not_to eq(nil)
|
179
|
+
expect(page[:links]['albums.artist']).not_to eq(nil)
|
180
|
+
expect(page[:links]['artists.songs']).not_to eq(nil)
|
181
|
+
expect(page[:links]['artists.albums']).not_to eq(nil)
|
176
182
|
end
|
177
183
|
end
|
178
184
|
end
|
@@ -182,7 +188,7 @@ describe RestPack::Serializer::Paging do
|
|
182
188
|
let(:params) { {} }
|
183
189
|
|
184
190
|
it "returns a page of all data" do
|
185
|
-
page[:meta][:songs][:count].
|
191
|
+
expect(page[:meta][:songs][:count]).to eq(18)
|
186
192
|
end
|
187
193
|
end
|
188
194
|
|
@@ -190,11 +196,11 @@ describe RestPack::Serializer::Paging do
|
|
190
196
|
let(:params) { { album_id: @album1.id.to_s } }
|
191
197
|
|
192
198
|
it "returns a page with songs from album1" do
|
193
|
-
page[:meta][:songs][:count].
|
199
|
+
expect(page[:meta][:songs][:count]).to eq(@album1.songs.length)
|
194
200
|
end
|
195
201
|
|
196
202
|
it "includes the filter in page hrefs" do
|
197
|
-
page[:meta][:songs][:next_href].
|
203
|
+
expect(page[:meta][:songs][:next_href]).to eq("/songs?page=2&album_id=#{@album1.id}")
|
198
204
|
end
|
199
205
|
end
|
200
206
|
end
|
@@ -204,7 +210,7 @@ describe RestPack::Serializer::Paging do
|
|
204
210
|
let(:params) { {} }
|
205
211
|
|
206
212
|
it "uses the model's sorting" do
|
207
|
-
page[:songs].first[:id].to_i
|
213
|
+
expect(page[:songs].first[:id].to_i < page[:songs].last[:id].to_i).to eq(true)
|
208
214
|
end
|
209
215
|
end
|
210
216
|
|
@@ -212,11 +218,11 @@ describe RestPack::Serializer::Paging do
|
|
212
218
|
let(:params) { { sort: '-title' } }
|
213
219
|
|
214
220
|
it 'returns a page with sorted songs' do
|
215
|
-
page[:songs].first[:title]
|
221
|
+
expect(page[:songs].first[:title] > page[:songs].last[:title]).to eq(true)
|
216
222
|
end
|
217
223
|
|
218
224
|
it 'includes the sorting in page hrefs' do
|
219
|
-
page[:meta][:songs][:next_href].
|
225
|
+
expect(page[:meta][:songs][:next_href]).to eq('/songs?page=2&sort=-title')
|
220
226
|
end
|
221
227
|
end
|
222
228
|
end
|
@@ -230,7 +236,7 @@ describe RestPack::Serializer::Paging do
|
|
230
236
|
let(:scope) { MyApp::Album.classic }
|
231
237
|
|
232
238
|
it "returns a page of scoped data" do
|
233
|
-
page[:meta][:albums][:count].
|
239
|
+
expect(page[:meta][:albums][:count]).to eq(2)
|
234
240
|
end
|
235
241
|
end
|
236
242
|
end
|
@@ -242,43 +248,44 @@ describe RestPack::Serializer::Paging do
|
|
242
248
|
|
243
249
|
context "with defaults" do
|
244
250
|
it "includes valid paging meta data" do
|
245
|
-
page[:meta][:songs][:count].
|
246
|
-
page[:meta][:songs][:page_count].
|
247
|
-
page[:meta][:songs][:previous_page].
|
248
|
-
page[:meta][:songs][:next_page].
|
251
|
+
expect(page[:meta][:songs][:count]).to eq(18)
|
252
|
+
expect(page[:meta][:songs][:page_count]).to eq(2)
|
253
|
+
expect(page[:meta][:songs][:previous_page]).to eq(nil)
|
254
|
+
expect(page[:meta][:songs][:next_page]).to eq(2)
|
249
255
|
end
|
250
256
|
end
|
251
257
|
|
252
258
|
context "with custom page size" do
|
253
259
|
let(:params) { { page_size: '3' } }
|
260
|
+
|
254
261
|
it "returns custom page sizes" do
|
255
|
-
page[:meta][:songs][:page_size].
|
256
|
-
page[:meta][:songs][:page_count].
|
262
|
+
expect(page[:meta][:songs][:page_size]).to eq(3)
|
263
|
+
expect(page[:meta][:songs][:page_count]).to eq(6)
|
257
264
|
end
|
258
265
|
end
|
259
266
|
end
|
260
267
|
|
261
268
|
context "paging with paged side-load" do
|
262
269
|
let(:page) { MyApp::AlbumSerializer.page_with_options(options) }
|
263
|
-
let(:options) { RestPack::Serializer::Options.new(MyApp::AlbumSerializer,
|
270
|
+
let(:options) { RestPack::Serializer::Options.new(MyApp::AlbumSerializer, include: 'songs') }
|
264
271
|
|
265
272
|
it "includes side-loaded paging data in meta data" do
|
266
|
-
page[:meta][:albums].
|
267
|
-
page[:meta][:albums][:page].
|
268
|
-
page[:meta][:songs].
|
269
|
-
page[:meta][:songs][:page].
|
273
|
+
expect(page[:meta][:albums]).not_to eq(nil)
|
274
|
+
expect(page[:meta][:albums][:page]).to eq(1)
|
275
|
+
expect(page[:meta][:songs]).not_to eq(nil)
|
276
|
+
expect(page[:meta][:songs][:page]).to eq(1)
|
270
277
|
end
|
271
278
|
end
|
272
279
|
|
273
280
|
context "paging with two paged side-loads" do
|
274
281
|
let(:page) { MyApp::ArtistSerializer.page_with_options(options) }
|
275
|
-
let(:options) { RestPack::Serializer::Options.new(MyApp::ArtistSerializer,
|
282
|
+
let(:options) { RestPack::Serializer::Options.new(MyApp::ArtistSerializer, include: 'albums,songs') }
|
276
283
|
|
277
284
|
it "includes side-loaded paging data in meta data" do
|
278
|
-
page[:meta][:albums].
|
279
|
-
page[:meta][:albums][:page].
|
280
|
-
page[:meta][:songs].
|
281
|
-
page[:meta][:songs][:page].
|
285
|
+
expect(page[:meta][:albums]).not_to eq(nil)
|
286
|
+
expect(page[:meta][:albums][:page]).to eq(1)
|
287
|
+
expect(page[:meta][:songs]).not_to eq(nil)
|
288
|
+
expect(page[:meta][:songs][:page]).to eq(1)
|
282
289
|
end
|
283
290
|
end
|
284
291
|
end
|
@@ -9,18 +9,18 @@ describe RestPack::Serializer::Resource do
|
|
9
9
|
let(:resource) { MyApp::SongSerializer.resource(params, scope, context) }
|
10
10
|
let(:params) { { id: @song.id } }
|
11
11
|
let(:scope) { nil }
|
12
|
-
let(:context) { {
|
12
|
+
let(:context) { {} }
|
13
13
|
|
14
14
|
it "returns a resource by id" do
|
15
|
-
resource[:songs].count.
|
16
|
-
resource[:songs][0][:id].
|
15
|
+
expect(resource[:songs].count).to eq(1)
|
16
|
+
expect(resource[:songs][0][:id]).to eq(@song.id.to_s)
|
17
17
|
end
|
18
18
|
|
19
19
|
context "with context" do
|
20
20
|
let(:context) { { reverse_title?: true } }
|
21
21
|
|
22
22
|
it "returns reversed titles" do
|
23
|
-
resource[:songs][0][:title].
|
23
|
+
expect(resource[:songs][0][:title]).to eq(@song.title.reverse)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -28,19 +28,20 @@ describe RestPack::Serializer::Resource do
|
|
28
28
|
let(:params) { { id: @song.id, include: 'albums' } }
|
29
29
|
|
30
30
|
it "includes side-loaded models" do
|
31
|
-
resource[:linked][:albums].count.
|
32
|
-
resource[:linked][:albums].first[:id].
|
31
|
+
expect(resource[:linked][:albums].count).to eq(1)
|
32
|
+
expect(resource[:linked][:albums].first[:id]).to eq(@song.album.id.to_s)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "includes the side-loads in the main meta data" do
|
36
|
-
resource[:meta][:songs][:include].
|
36
|
+
expect(resource[:meta][:songs][:include]).to eq(%w(albums))
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
describe "missing resource" do
|
41
41
|
let(:params) { { id: "-99" } }
|
42
|
+
|
42
43
|
it "returns no resource" do
|
43
|
-
resource[:songs].length.
|
44
|
+
expect(resource[:songs].length).to eq(0)
|
44
45
|
end
|
45
46
|
|
46
47
|
#TODO: add specs for jsonapi error format when it has been standardised
|
@@ -49,11 +50,11 @@ describe RestPack::Serializer::Resource do
|
|
49
50
|
end
|
50
51
|
|
51
52
|
describe "song with no artist" do
|
52
|
-
let(:song) { FactoryGirl.create(:song, :
|
53
|
+
let(:song) { FactoryGirl.create(:song, artist: nil) }
|
53
54
|
let(:resource) { MyApp::SongSerializer.resource(id: song.id.to_s) }
|
54
55
|
|
55
56
|
it "should not have an artist link" do
|
56
|
-
resource[:songs][0][:links].keys.
|
57
|
+
expect(resource[:songs][0][:links].keys).not_to include(:artist)
|
57
58
|
end
|
58
59
|
end
|
59
60
|
end
|
@@ -27,7 +27,7 @@ describe RestPack::Serializer do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it ".as_json serializes to an empty hash" do
|
30
|
-
EmptySerializer.as_json(person).
|
30
|
+
expect(EmptySerializer.as_json(person)).to eq({})
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -71,11 +71,32 @@ describe RestPack::Serializer do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it ".as_json serializes" do
|
74
|
-
serialized = DerivedSerializer.as_json({},
|
75
|
-
serialized.
|
74
|
+
serialized = DerivedSerializer.as_json({}, include_food?: false, name: 'Ben', age: 1)
|
75
|
+
expect(serialized).to eq({ #NOTE: I think this should include colour as DerivedSerializer defines it, but this would be a big breaking change
|
76
76
|
name: "Ben",
|
77
77
|
age: 1
|
78
|
-
}
|
78
|
+
})
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "serializer instance variables" do
|
83
|
+
class MemoizingSerializer
|
84
|
+
include RestPack::Serializer
|
85
|
+
|
86
|
+
attributes :id, :memoized_id
|
87
|
+
|
88
|
+
def memoized_id
|
89
|
+
@memoized_id ||= id
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it "does not reuse instance variable values" do
|
94
|
+
people = [Person.new(id: 123), Person.new(id: 456)]
|
95
|
+
serialized = MemoizingSerializer.as_json(people)
|
96
|
+
expect(serialized).to eq([
|
97
|
+
{ id: "123", memoized_id: "123" },
|
98
|
+
{ id: "456", memoized_id: "456" }
|
99
|
+
])
|
79
100
|
end
|
80
101
|
end
|
81
102
|
|
@@ -116,34 +137,35 @@ describe RestPack::Serializer do
|
|
116
137
|
|
117
138
|
def custom_attributes
|
118
139
|
{
|
119
|
-
:
|
140
|
+
custom_key: "custom value for model id #{@model.id}"
|
120
141
|
}
|
121
142
|
end
|
122
143
|
end
|
123
144
|
|
124
145
|
describe ".serialize" do
|
125
146
|
it "serializes to an array" do
|
126
|
-
serializer.class.serialize(person).
|
147
|
+
expect(serializer.class.serialize(person)).to eq(
|
127
148
|
people: [{
|
128
149
|
id: '123', name: 'Gavin', description: 'This is person #123',
|
129
150
|
href: '/people/123', custom_key: 'custom value for model id 123'
|
130
151
|
}]
|
131
|
-
|
152
|
+
)
|
132
153
|
end
|
133
154
|
end
|
134
155
|
|
135
156
|
describe ".as_json" do
|
136
157
|
it "serializes specified attributes" do
|
137
|
-
serializer.as_json(person).
|
158
|
+
expect(serializer.as_json(person)).to eq(
|
138
159
|
id: '123', name: 'Gavin', description: 'This is person #123',
|
139
160
|
href: '/people/123', custom_key: 'custom value for model id 123'
|
140
|
-
|
161
|
+
)
|
141
162
|
end
|
142
163
|
|
143
164
|
context "an array" do
|
144
165
|
let(:people) { [person, person] }
|
166
|
+
|
145
167
|
it "results in a serialized array" do
|
146
|
-
serializer.as_json(people).
|
168
|
+
expect(serializer.as_json(people)).to eq([
|
147
169
|
{
|
148
170
|
id: '123', name: 'Gavin', description: 'This is person #123',
|
149
171
|
href: '/people/123', custom_key: 'custom value for model id 123'
|
@@ -152,11 +174,12 @@ describe RestPack::Serializer do
|
|
152
174
|
id: '123', name: 'Gavin', description: 'This is person #123',
|
153
175
|
href: '/people/123', custom_key: 'custom value for model id 123'
|
154
176
|
}
|
155
|
-
]
|
177
|
+
])
|
156
178
|
end
|
179
|
+
|
157
180
|
context "#array_as_json" do
|
158
181
|
it "results in a serialized array" do
|
159
|
-
serializer.class.array_as_json(people).
|
182
|
+
expect(serializer.class.array_as_json(people)).to eq([
|
160
183
|
{
|
161
184
|
id: '123', name: 'Gavin', description: 'This is person #123',
|
162
185
|
href: '/people/123', custom_key: 'custom value for model id 123'
|
@@ -165,75 +188,75 @@ describe RestPack::Serializer do
|
|
165
188
|
id: '123', name: 'Gavin', description: 'This is person #123',
|
166
189
|
href: '/people/123', custom_key: 'custom value for model id 123'
|
167
190
|
}
|
168
|
-
]
|
191
|
+
])
|
169
192
|
end
|
170
193
|
end
|
171
194
|
end
|
172
195
|
|
173
196
|
context "nil" do
|
174
197
|
it "results in nil" do
|
175
|
-
serializer.as_json(nil).
|
198
|
+
expect(serializer.as_json(nil)).to eq(nil)
|
176
199
|
end
|
177
200
|
end
|
178
201
|
|
179
202
|
context "with options" do
|
180
203
|
it "excludes specified attributes" do
|
181
|
-
serializer.as_json(person,
|
204
|
+
expect(serializer.as_json(person, include_description?: false)).to eq(
|
182
205
|
id: '123', name: 'Gavin', href: '/people/123',
|
183
206
|
custom_key: 'custom value for model id 123'
|
184
|
-
|
207
|
+
)
|
185
208
|
end
|
186
209
|
|
187
210
|
it "excludes custom attributes if specified" do
|
188
|
-
hash = serializer.as_json(person,
|
189
|
-
hash[:admin_info].
|
211
|
+
hash = serializer.as_json(person, is_admin?: false)
|
212
|
+
expect(hash[:admin_info]).to eq(nil)
|
190
213
|
end
|
191
214
|
|
192
215
|
it "includes custom attributes if specified" do
|
193
|
-
hash = serializer.as_json(person,
|
194
|
-
hash[:admin_info].
|
216
|
+
hash = serializer.as_json(person, is_admin?: true)
|
217
|
+
expect(hash[:admin_info]).to eq(
|
195
218
|
key: "super_secret_sauce",
|
196
219
|
array: [
|
197
220
|
name: 'Alex'
|
198
221
|
]
|
199
|
-
|
222
|
+
)
|
200
223
|
end
|
201
224
|
|
202
225
|
it "excludes a blacklist of attributes if specified as an array" do
|
203
|
-
serializer.as_json(person,
|
226
|
+
expect(serializer.as_json(person, attribute_blacklist: [:name, :description])).to eq(
|
204
227
|
id: '123',
|
205
228
|
href: '/people/123',
|
206
229
|
custom_key: 'custom value for model id 123'
|
207
|
-
|
230
|
+
)
|
208
231
|
end
|
209
232
|
|
210
233
|
it "excludes a blacklist of attributes if specified as a string" do
|
211
|
-
serializer.as_json(person,
|
234
|
+
expect(serializer.as_json(person, attribute_blacklist: 'name, description')).to eq(
|
212
235
|
id: '123',
|
213
236
|
href: '/people/123',
|
214
237
|
custom_key: 'custom value for model id 123'
|
215
|
-
|
238
|
+
)
|
216
239
|
end
|
217
240
|
|
218
241
|
it "includes a whitelist of attributes if specified as an array" do
|
219
|
-
serializer.as_json(person,
|
242
|
+
expect(serializer.as_json(person, attribute_whitelist: [:name, :description])).to eq(
|
220
243
|
name: 'Gavin',
|
221
244
|
description: 'This is person #123',
|
222
245
|
custom_key: 'custom value for model id 123'
|
223
|
-
|
246
|
+
)
|
224
247
|
end
|
225
248
|
|
226
249
|
it "includes a whitelist of attributes if specified as a string" do
|
227
|
-
serializer.as_json(person,
|
250
|
+
expect(serializer.as_json(person, attribute_whitelist: 'name, description')).to eq(
|
228
251
|
name: 'Gavin',
|
229
252
|
description: 'This is person #123',
|
230
253
|
custom_key: 'custom value for model id 123'
|
231
|
-
|
254
|
+
)
|
232
255
|
end
|
233
256
|
|
234
257
|
it "raises an exception if both the whitelist and blacklist are provided" do
|
235
258
|
expect do
|
236
|
-
serializer.as_json(person,
|
259
|
+
serializer.as_json(person, attribute_whitelist: [:name], attribute_blacklist: [:id])
|
237
260
|
end.to raise_error(ArgumentError, "the context can't define both an `attribute_whitelist` and an `attribute_blacklist`")
|
238
261
|
end
|
239
262
|
end
|
@@ -245,10 +268,10 @@ describe RestPack::Serializer do
|
|
245
268
|
it "includes 'links' data for :belongs_to associations" do
|
246
269
|
@album1 = FactoryGirl.create(:album_with_songs, song_count: 11)
|
247
270
|
json = serializer.as_json(@album1.songs.first)
|
248
|
-
json[:links].
|
271
|
+
expect(json[:links]).to eq(
|
249
272
|
artist: @album1.artist_id.to_s,
|
250
273
|
album: @album1.id.to_s
|
251
|
-
|
274
|
+
)
|
252
275
|
end
|
253
276
|
end
|
254
277
|
|
@@ -256,12 +279,13 @@ describe RestPack::Serializer do
|
|
256
279
|
let(:artist_factory) { FactoryGirl.create :artist_with_fans }
|
257
280
|
let(:artist_serializer) { MyApp::ArtistSerializer.new }
|
258
281
|
let(:json) { artist_serializer.as_json(artist_factory) }
|
259
|
-
let(:side_load_ids) { artist_has_association.map {|obj| obj.id.to_s } }
|
282
|
+
let(:side_load_ids) { artist_has_association.map { |obj| obj.id.to_s } }
|
260
283
|
|
261
284
|
context "when the association has been eager loaded" do
|
262
285
|
before do
|
263
|
-
artist_factory.fans.
|
286
|
+
allow(artist_factory.fans).to receive(:loaded?).and_return(true)
|
264
287
|
end
|
288
|
+
|
265
289
|
it "does not make a query to retrieve id values" do
|
266
290
|
expect(artist_factory.fans).not_to receive(:pluck)
|
267
291
|
json
|
@@ -289,9 +313,23 @@ describe RestPack::Serializer do
|
|
289
313
|
end
|
290
314
|
end
|
291
315
|
|
316
|
+
describe "to_json" do
|
317
|
+
context "class method" do
|
318
|
+
it "delegates to as_json" do
|
319
|
+
expect(PersonSerializer.as_json(person).to_json).to eq(PersonSerializer.to_json(person))
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
context "instance method" do
|
324
|
+
it "delegates to as_json" do
|
325
|
+
expect(serializer.as_json(person).to_json).to eq(serializer.to_json(person))
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
292
330
|
describe "#model_class" do
|
293
331
|
it "extracts the Model name from the Serializer name" do
|
294
|
-
PersonSerializer.model_class.
|
332
|
+
expect(PersonSerializer.model_class).to eq(Person)
|
295
333
|
end
|
296
334
|
|
297
335
|
context "with namespaced model class" do
|
@@ -306,7 +344,7 @@ describe RestPack::Serializer do
|
|
306
344
|
end
|
307
345
|
|
308
346
|
it "returns the correct class" do
|
309
|
-
NamespacedSerializer.model_class.
|
347
|
+
expect(NamespacedSerializer.model_class).to eq(SomeNamespace::Model)
|
310
348
|
end
|
311
349
|
end
|
312
350
|
end
|
@@ -314,15 +352,15 @@ describe RestPack::Serializer do
|
|
314
352
|
describe "#key" do
|
315
353
|
context "with default key" do
|
316
354
|
it "returns the correct key" do
|
317
|
-
PersonSerializer.key.
|
355
|
+
expect(PersonSerializer.key).to eq(:people)
|
318
356
|
end
|
319
357
|
|
320
358
|
it "has correct #singular_key" do
|
321
|
-
PersonSerializer.singular_key.
|
359
|
+
expect(PersonSerializer.singular_key).to eq(:person)
|
322
360
|
end
|
323
361
|
|
324
362
|
it "has correct #plural_key" do
|
325
|
-
PersonSerializer.plural_key.
|
363
|
+
expect(PersonSerializer.plural_key).to eq(:people)
|
326
364
|
end
|
327
365
|
end
|
328
366
|
|
@@ -333,11 +371,11 @@ describe RestPack::Serializer do
|
|
333
371
|
end
|
334
372
|
|
335
373
|
it "returns the correct key" do
|
336
|
-
SerializerWithCustomKey.key.
|
374
|
+
expect(SerializerWithCustomKey.key).to eq(:customers)
|
337
375
|
end
|
338
376
|
|
339
377
|
it "has correct #singular_key" do
|
340
|
-
SerializerWithCustomKey.singular_key.
|
378
|
+
expect(SerializerWithCustomKey.singular_key).to eq(:customer)
|
341
379
|
end
|
342
380
|
end
|
343
381
|
end
|