active_model_serializers 0.1.0

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,9 @@
1
+ Description:
2
+ Generates a serializer for the given resource with tests.
3
+
4
+ Example:
5
+ `rails generate serializer Account name created_at`
6
+
7
+ For TestUnit it creates:
8
+ Serializer: app/serializers/account_serializer.rb
9
+ TestUnit: test/unit/account_serializer_test.rb
@@ -0,0 +1,41 @@
1
+ module Rails
2
+ module Generators
3
+ class SerializerGenerator < NamedBase
4
+ source_root File.expand_path("../templates", __FILE__)
5
+ check_class_collision :suffix => "Serializer"
6
+
7
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
8
+
9
+ class_option :parent, :type => :string, :desc => "The parent class for the generated serializer"
10
+
11
+ def create_serializer_file
12
+ template 'serializer.rb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
13
+ end
14
+
15
+ # hook_for :test_framework
16
+
17
+ private
18
+
19
+ def attributes_names
20
+ attributes.select { |attr| !attr.reference? }.map { |a| a.name.to_sym }
21
+ end
22
+
23
+ def association_names
24
+ attributes.select { |attr| attr.reference? }.map { |a| a.name.to_sym }
25
+ end
26
+
27
+ def parent_class_name
28
+ if options[:parent]
29
+ options[:parent]
30
+ # Only works on 3.2
31
+ # elsif (n = Rails::Generators.namespace) && n.const_defined?(:ApplicationSerializer)
32
+ # "ApplicationSerializer"
33
+ elsif Object.const_defined?(:ApplicationSerializer)
34
+ "ApplicationSerializer"
35
+ else
36
+ "ActiveModel::Serializer"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %>Serializer < <%= parent_class_name %>
3
+ <% if attributes.any? -%> attributes <%= attributes_names.map(&:inspect).join(", ") %>
4
+ <% end -%>
5
+ <% association_names.each do |attribute| -%>
6
+ has_one :<%= attribute %>
7
+ <% end -%>
8
+ end
9
+ <% end -%>
@@ -0,0 +1,67 @@
1
+ require 'test_helper'
2
+
3
+ class Foo < Rails::Application
4
+ end
5
+
6
+ Rails.application.load_generators
7
+
8
+ require 'generators/serializer/serializer_generator'
9
+
10
+ class SerializerGeneratorTest < Rails::Generators::TestCase
11
+ destination File.expand_path("../tmp", __FILE__)
12
+ setup :prepare_destination
13
+
14
+ tests Rails::Generators::SerializerGenerator
15
+ arguments %w(account name:string description:text business:references)
16
+
17
+ def test_generates_a_serializer
18
+ run_generator
19
+ assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < ActiveModel::Serializer/
20
+ end
21
+
22
+ def test_generates_a_namespaced_serializer
23
+ run_generator ["admin/account"]
24
+ assert_file "app/serializers/admin/account_serializer.rb", /class Admin::AccountSerializer < ActiveModel::Serializer/
25
+ end
26
+
27
+ def test_uses_application_serializer_if_one_exists
28
+ Object.const_set(:ApplicationSerializer, Class.new)
29
+ run_generator
30
+ assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < ApplicationSerializer/
31
+ ensure
32
+ Object.send :remove_const, :ApplicationSerializer
33
+ end
34
+
35
+ # def test_uses_namespace_application_serializer_if_one_exists
36
+ # Object.const_set(:SerializerNamespace, Module.new)
37
+ # SerializerNamespace.const_set(:ApplicationSerializer, Class.new)
38
+ # Rails::Generators.namespace = SerializerNamespace
39
+ # run_generator
40
+ # assert_file "app/serializers/serializer_namespace/account_serializer.rb",
41
+ # /module SerializerNamespace\n class AccountSerializer < ApplicationSerializer/
42
+ # ensure
43
+ # Object.send :remove_const, :SerializerNamespace
44
+ # Rails::Generators.namespace = nil
45
+ # end
46
+
47
+ def test_uses_given_parent
48
+ Object.const_set(:ApplicationSerializer, Class.new)
49
+ run_generator ["Account", "--parent=MySerializer"]
50
+ assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < MySerializer/
51
+ ensure
52
+ Object.send :remove_const, :ApplicationSerializer
53
+ end
54
+
55
+ def test_generates_attributes_and_associations
56
+ run_generator
57
+ assert_file "app/serializers/account_serializer.rb" do |serializer|
58
+ assert_match(/^ attributes :name, :description$/, serializer)
59
+ assert_match(/^ has_one :business$/, serializer)
60
+ end
61
+ end
62
+
63
+ def test_with_no_attributes_does_not_add_extra_space
64
+ run_generator ["account"]
65
+ assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < ActiveModel::Serializer\nend/
66
+ end
67
+ end
@@ -0,0 +1,186 @@
1
+ require 'test_helper'
2
+ require 'pathname'
3
+
4
+ class RenderJsonTest < ActionController::TestCase
5
+ class JsonRenderable
6
+ def as_json(options={})
7
+ hash = { :a => :b, :c => :d, :e => :f }
8
+ hash.except!(*options[:except]) if options[:except]
9
+ hash
10
+ end
11
+
12
+ def to_json(options = {})
13
+ super :except => [:c, :e]
14
+ end
15
+ end
16
+
17
+ class JsonSerializer
18
+ def initialize(object, scope, options={})
19
+ @object, @scope, @options = object, scope, options
20
+ end
21
+
22
+ def as_json(*)
23
+ hash = { :object => @object.as_json, :scope => @scope.as_json }
24
+ hash.merge!(:options => true) if @options[:options]
25
+ hash
26
+ end
27
+ end
28
+
29
+ class JsonSerializable
30
+ def initialize(skip=false)
31
+ @skip = skip
32
+ end
33
+
34
+ def active_model_serializer
35
+ JsonSerializer unless @skip
36
+ end
37
+
38
+ def as_json(*)
39
+ { :serializable_object => true }
40
+ end
41
+ end
42
+
43
+ class TestController < ActionController::Base
44
+ protect_from_forgery
45
+
46
+ serialization_scope :current_user
47
+ attr_reader :current_user
48
+
49
+ def self.controller_path
50
+ 'test'
51
+ end
52
+
53
+ def render_json_nil
54
+ render :json => nil
55
+ end
56
+
57
+ def render_json_render_to_string
58
+ render :text => render_to_string(:json => '[]')
59
+ end
60
+
61
+ def render_json_hello_world
62
+ render :json => ActiveSupport::JSON.encode(:hello => 'world')
63
+ end
64
+
65
+ def render_json_hello_world_with_status
66
+ render :json => ActiveSupport::JSON.encode(:hello => 'world'), :status => 401
67
+ end
68
+
69
+ def render_json_hello_world_with_callback
70
+ render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert'
71
+ end
72
+
73
+ def render_json_with_custom_content_type
74
+ render :json => ActiveSupport::JSON.encode(:hello => 'world'), :content_type => 'text/javascript'
75
+ end
76
+
77
+ def render_symbol_json
78
+ render :json => ActiveSupport::JSON.encode(:hello => 'world')
79
+ end
80
+
81
+ def render_json_with_extra_options
82
+ render :json => JsonRenderable.new, :except => [:c, :e]
83
+ end
84
+
85
+ def render_json_without_options
86
+ render :json => JsonRenderable.new
87
+ end
88
+
89
+ def render_json_with_serializer
90
+ @current_user = Struct.new(:as_json).new(:current_user => true)
91
+ render :json => JsonSerializable.new
92
+ end
93
+
94
+ def render_json_with_serializer_and_options
95
+ @current_user = Struct.new(:as_json).new(:current_user => true)
96
+ render :json => JsonSerializable.new, :options => true
97
+ end
98
+
99
+ def render_json_with_serializer_api_but_without_serializer
100
+ @current_user = Struct.new(:as_json).new(:current_user => true)
101
+ render :json => JsonSerializable.new(true)
102
+ end
103
+ end
104
+
105
+ tests TestController
106
+
107
+ def setup
108
+ # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
109
+ # a more accurate simulation of what happens in "real life".
110
+ super
111
+ @controller.logger = Logger.new(nil)
112
+
113
+ @request.host = "www.nextangle.com"
114
+ end
115
+
116
+ def test_render_json_nil
117
+ get :render_json_nil
118
+ assert_equal 'null', @response.body
119
+ assert_equal 'application/json', @response.content_type
120
+ end
121
+
122
+ def test_render_json_render_to_string
123
+ get :render_json_render_to_string
124
+ assert_equal '[]', @response.body
125
+ end
126
+
127
+
128
+ def test_render_json
129
+ get :render_json_hello_world
130
+ assert_equal '{"hello":"world"}', @response.body
131
+ assert_equal 'application/json', @response.content_type
132
+ end
133
+
134
+ def test_render_json_with_status
135
+ get :render_json_hello_world_with_status
136
+ assert_equal '{"hello":"world"}', @response.body
137
+ assert_equal 401, @response.status
138
+ end
139
+
140
+ def test_render_json_with_callback
141
+ get :render_json_hello_world_with_callback
142
+ assert_equal 'alert({"hello":"world"})', @response.body
143
+ assert_equal 'application/json', @response.content_type
144
+ end
145
+
146
+ def test_render_json_with_custom_content_type
147
+ get :render_json_with_custom_content_type
148
+ assert_equal '{"hello":"world"}', @response.body
149
+ assert_equal 'text/javascript', @response.content_type
150
+ end
151
+
152
+ def test_render_symbol_json
153
+ get :render_symbol_json
154
+ assert_equal '{"hello":"world"}', @response.body
155
+ assert_equal 'application/json', @response.content_type
156
+ end
157
+
158
+ def test_render_json_forwards_extra_options
159
+ get :render_json_with_extra_options
160
+ assert_equal '{"a":"b"}', @response.body
161
+ assert_equal 'application/json', @response.content_type
162
+ end
163
+
164
+ def test_render_json_calls_to_json_from_object
165
+ get :render_json_without_options
166
+ assert_equal '{"a":"b"}', @response.body
167
+ end
168
+
169
+ def test_render_json_with_serializer
170
+ get :render_json_with_serializer
171
+ assert_match '"scope":{"current_user":true}', @response.body
172
+ assert_match '"object":{"serializable_object":true}', @response.body
173
+ end
174
+
175
+ def test_render_json_with_serializer_and_options
176
+ get :render_json_with_serializer_and_options
177
+ assert_match '"scope":{"current_user":true}', @response.body
178
+ assert_match '"object":{"serializable_object":true}', @response.body
179
+ assert_match '"options":true', @response.body
180
+ end
181
+
182
+ def test_render_json_with_serializer_api_but_without_serializer
183
+ get :render_json_with_serializer_api_but_without_serializer
184
+ assert_match '{"serializable_object":true}', @response.body
185
+ end
186
+ end
@@ -0,0 +1,11 @@
1
+ require "test_helper"
2
+
3
+ class RandomModel
4
+ include ActiveModel::SerializerSupport
5
+ end
6
+
7
+ class SerializerSupportTest < ActiveModel::TestCase
8
+ test "it returns nil if no serializer exists" do
9
+ assert_equal nil, RandomModel.new.active_model_serializer
10
+ end
11
+ end
@@ -0,0 +1,787 @@
1
+ require "test_helper"
2
+
3
+ class SerializerTest < ActiveModel::TestCase
4
+ class Model
5
+ def initialize(hash={})
6
+ @attributes = hash
7
+ end
8
+
9
+ def read_attribute_for_serialization(name)
10
+ @attributes[name]
11
+ end
12
+
13
+ def as_json(*)
14
+ { :model => "Model" }
15
+ end
16
+ end
17
+
18
+ class User
19
+ include ActiveModel::SerializerSupport
20
+
21
+ attr_accessor :superuser
22
+
23
+ def initialize(hash={})
24
+ @attributes = hash.merge(:first_name => "Jose", :last_name => "Valim", :password => "oh noes yugive my password")
25
+ end
26
+
27
+ def read_attribute_for_serialization(name)
28
+ @attributes[name]
29
+ end
30
+
31
+ def super_user?
32
+ @superuser
33
+ end
34
+ end
35
+
36
+ class Post < Model
37
+ def initialize(attributes)
38
+ super(attributes)
39
+ self.comments ||= []
40
+ end
41
+
42
+ attr_accessor :comments
43
+ def active_model_serializer; PostSerializer; end
44
+ end
45
+
46
+ class Comment < Model
47
+ def active_model_serializer; CommentSerializer; end
48
+ end
49
+
50
+ class UserSerializer < ActiveModel::Serializer
51
+ attributes :first_name, :last_name
52
+
53
+ def serializable_hash
54
+ attributes.merge(:ok => true).merge(scope)
55
+ end
56
+ end
57
+
58
+ class DefaultUserSerializer < ActiveModel::Serializer
59
+ attributes :first_name, :last_name
60
+ end
61
+
62
+ class MyUserSerializer < ActiveModel::Serializer
63
+ attributes :first_name, :last_name
64
+
65
+ def serializable_hash
66
+ hash = attributes
67
+ hash = hash.merge(:super_user => true) if my_user.super_user?
68
+ hash
69
+ end
70
+ end
71
+
72
+ class CommentSerializer
73
+ def initialize(comment, scope, options={})
74
+ @comment, @scope = comment, scope
75
+ end
76
+
77
+ def serializable_hash
78
+ { :title => @comment.read_attribute_for_serialization(:title) }
79
+ end
80
+
81
+ def as_json(options=nil)
82
+ options ||= {}
83
+ if options[:root] == false
84
+ serializable_hash
85
+ else
86
+ { :comment => serializable_hash }
87
+ end
88
+ end
89
+ end
90
+
91
+ class PostSerializer < ActiveModel::Serializer
92
+ attributes :title, :body
93
+ has_many :comments, :serializer => CommentSerializer
94
+ end
95
+
96
+ def test_attributes
97
+ user = User.new
98
+ user_serializer = DefaultUserSerializer.new(user, {})
99
+
100
+ hash = user_serializer.as_json
101
+
102
+ assert_equal({
103
+ :default_user => { :first_name => "Jose", :last_name => "Valim" }
104
+ }, hash)
105
+ end
106
+
107
+ def test_attributes_method
108
+ user = User.new
109
+ user_serializer = UserSerializer.new(user, {})
110
+
111
+ hash = user_serializer.as_json
112
+
113
+ assert_equal({
114
+ :user => { :first_name => "Jose", :last_name => "Valim", :ok => true }
115
+ }, hash)
116
+ end
117
+
118
+ def test_serializer_receives_scope
119
+ user = User.new
120
+ user_serializer = UserSerializer.new(user, {:scope => true})
121
+
122
+ hash = user_serializer.as_json
123
+
124
+ assert_equal({
125
+ :user => {
126
+ :first_name => "Jose",
127
+ :last_name => "Valim",
128
+ :ok => true,
129
+ :scope => true
130
+ }
131
+ }, hash)
132
+ end
133
+
134
+ def test_pretty_accessors
135
+ user = User.new
136
+ user.superuser = true
137
+ user_serializer = MyUserSerializer.new(user, nil)
138
+
139
+ hash = user_serializer.as_json
140
+
141
+ assert_equal({
142
+ :my_user => {
143
+ :first_name => "Jose", :last_name => "Valim", :super_user => true
144
+ }
145
+ }, hash)
146
+ end
147
+
148
+ def test_has_many
149
+ user = User.new
150
+
151
+ post = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com")
152
+ comments = [Comment.new(:title => "Comment1"), Comment.new(:title => "Comment2")]
153
+ post.comments = comments
154
+
155
+ post_serializer = PostSerializer.new(post, user)
156
+
157
+ assert_equal({
158
+ :post => {
159
+ :title => "New Post",
160
+ :body => "Body of new post",
161
+ :comments => [
162
+ { :title => "Comment1" },
163
+ { :title => "Comment2" }
164
+ ]
165
+ }
166
+ }, post_serializer.as_json)
167
+ end
168
+
169
+ class Blog < Model
170
+ attr_accessor :author
171
+ end
172
+
173
+ class AuthorSerializer < ActiveModel::Serializer
174
+ attributes :first_name, :last_name
175
+ end
176
+
177
+ class BlogSerializer < ActiveModel::Serializer
178
+ has_one :author, :serializer => AuthorSerializer
179
+ end
180
+
181
+ def test_has_one
182
+ user = User.new
183
+ blog = Blog.new
184
+ blog.author = user
185
+
186
+ json = BlogSerializer.new(blog, user).as_json
187
+ assert_equal({
188
+ :blog => {
189
+ :author => {
190
+ :first_name => "Jose",
191
+ :last_name => "Valim"
192
+ }
193
+ }
194
+ }, json)
195
+ end
196
+
197
+ def test_overridden_associations
198
+ author_serializer = Class.new(ActiveModel::Serializer) do
199
+ attributes :first_name
200
+ end
201
+
202
+ blog_serializer = Class.new(ActiveModel::Serializer) do
203
+ def person
204
+ object.author
205
+ end
206
+
207
+ has_one :person, :serializer => author_serializer
208
+ end
209
+
210
+ user = User.new
211
+ blog = Blog.new
212
+ blog.author = user
213
+
214
+ json = blog_serializer.new(blog, user).as_json
215
+ assert_equal({
216
+ :person => {
217
+ :first_name => "Jose"
218
+ }
219
+ }, json)
220
+ end
221
+
222
+ def post_serializer(type)
223
+ Class.new(ActiveModel::Serializer) do
224
+ attributes :title, :body
225
+ has_many :comments, :serializer => CommentSerializer
226
+
227
+ if type != :super
228
+ define_method :serializable_hash do
229
+ post_hash = attributes
230
+ post_hash.merge!(send(type))
231
+ post_hash
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ def test_associations
238
+ post = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com")
239
+ comments = [Comment.new(:title => "Comment1"), Comment.new(:title => "Comment2")]
240
+ post.comments = comments
241
+
242
+ serializer = post_serializer(:associations).new(post, nil)
243
+
244
+ assert_equal({
245
+ :title => "New Post",
246
+ :body => "Body of new post",
247
+ :comments => [
248
+ { :title => "Comment1" },
249
+ { :title => "Comment2" }
250
+ ]
251
+ }, serializer.as_json)
252
+ end
253
+
254
+ def test_association_ids
255
+ serializer = post_serializer(:association_ids)
256
+
257
+ serializer.class_eval do
258
+ def as_json(*)
259
+ { :post => serializable_hash }.merge(associations)
260
+ end
261
+ end
262
+
263
+ post = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com")
264
+ comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
265
+ post.comments = comments
266
+
267
+ serializer = serializer.new(post, nil)
268
+
269
+ assert_equal({
270
+ :post => {
271
+ :title => "New Post",
272
+ :body => "Body of new post",
273
+ :comments => [1, 2]
274
+ },
275
+ :comments => [
276
+ { :title => "Comment1" },
277
+ { :title => "Comment2" }
278
+ ]
279
+ }, serializer.as_json)
280
+ end
281
+
282
+ def test_associations_with_nil_association
283
+ user = User.new
284
+ blog = Blog.new
285
+
286
+ json = BlogSerializer.new(blog, user).as_json
287
+ assert_equal({
288
+ :blog => { :author => nil }
289
+ }, json)
290
+
291
+ serializer = Class.new(BlogSerializer) do
292
+ root :blog
293
+
294
+ def serializable_hash
295
+ attributes.merge(association_ids)
296
+ end
297
+ end
298
+
299
+ json = serializer.new(blog, user).as_json
300
+ assert_equal({ :blog => { :author => nil } }, json)
301
+ end
302
+
303
+ def test_custom_root
304
+ user = User.new
305
+ blog = Blog.new
306
+
307
+ serializer = Class.new(BlogSerializer) do
308
+ root :my_blog
309
+ end
310
+
311
+ assert_equal({ :my_blog => { :author => nil } }, serializer.new(blog, user).as_json)
312
+ end
313
+
314
+ def test_false_root
315
+ user = User.new
316
+ blog = Blog.new
317
+
318
+ serializer = Class.new(BlogSerializer) do
319
+ root false
320
+ end
321
+
322
+ assert_equal({ :author => nil }, serializer.new(blog, user).as_json)
323
+
324
+ # test inherited false root
325
+ serializer = Class.new(serializer)
326
+ assert_equal({ :author => nil }, serializer.new(blog, user).as_json)
327
+ end
328
+
329
+ def test_embed_ids
330
+ serializer = post_serializer(:super)
331
+
332
+ serializer.class_eval do
333
+ root :post
334
+ embed :ids
335
+ end
336
+
337
+ post = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com")
338
+ comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
339
+ post.comments = comments
340
+
341
+ serializer = serializer.new(post, nil)
342
+
343
+ assert_equal({
344
+ :post => {
345
+ :title => "New Post",
346
+ :body => "Body of new post",
347
+ :comments => [1, 2]
348
+ }
349
+ }, serializer.as_json)
350
+ end
351
+
352
+ def test_embed_ids_include_true
353
+ serializer = post_serializer(:super)
354
+
355
+ serializer.class_eval do
356
+ root :post
357
+ embed :ids, :include => true
358
+ end
359
+
360
+ post = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com")
361
+ comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
362
+ post.comments = comments
363
+
364
+ serializer = serializer.new(post, nil)
365
+
366
+ assert_equal({
367
+ :post => {
368
+ :title => "New Post",
369
+ :body => "Body of new post",
370
+ :comments => [1, 2]
371
+ },
372
+ :comments => [
373
+ { :title => "Comment1" },
374
+ { :title => "Comment2" }
375
+ ]
376
+ }, serializer.as_json)
377
+ end
378
+
379
+ def test_embed_objects
380
+ serializer = post_serializer(:super)
381
+
382
+ serializer.class_eval do
383
+ root :post
384
+ embed :objects
385
+ end
386
+
387
+ post = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com")
388
+ comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
389
+ post.comments = comments
390
+
391
+ serializer = serializer.new(post, nil)
392
+
393
+ assert_equal({
394
+ :post => {
395
+ :title => "New Post",
396
+ :body => "Body of new post",
397
+ :comments => [
398
+ { :title => "Comment1" },
399
+ { :title => "Comment2" }
400
+ ]
401
+ }
402
+ }, serializer.as_json)
403
+ end
404
+
405
+ def test_array_serializer
406
+ model = Model.new
407
+ user = User.new
408
+ comments = Comment.new(:title => "Comment1", :id => 1)
409
+
410
+ array = [model, user, comments]
411
+ serializer = array.active_model_serializer.new(array, {:scope => true})
412
+ assert_equal([
413
+ { :model => "Model" },
414
+ { :user => { :last_name=>"Valim", :ok=>true, :first_name=>"Jose", :scope => true } },
415
+ { :comment => { :title => "Comment1" } }
416
+ ], serializer.as_json)
417
+ end
418
+
419
+ class CustomBlog < Blog
420
+ attr_accessor :public_posts, :public_user
421
+ end
422
+
423
+ class CustomBlogSerializer < ActiveModel::Serializer
424
+ has_many :public_posts, :key => :posts, :serializer => PostSerializer
425
+ has_one :public_user, :key => :user, :serializer => UserSerializer
426
+ end
427
+
428
+ def test_associations_with_as
429
+ posts = [
430
+ Post.new(:title => 'First Post', :body => 'text'),
431
+ Post.new(:title => 'Second Post', :body => 'text')
432
+ ]
433
+ user = User.new
434
+
435
+ custom_blog = CustomBlog.new
436
+ custom_blog.public_posts = posts
437
+ custom_blog.public_user = user
438
+
439
+ serializer = CustomBlogSerializer.new(custom_blog, :scope => true)
440
+
441
+ assert_equal({
442
+ :custom_blog => {
443
+ :posts => [
444
+ {:title => 'First Post', :body => 'text', :comments => []},
445
+ {:title => 'Second Post', :body => 'text', :comments => []}
446
+ ],
447
+ :user => {
448
+ :first_name => "Jose",
449
+ :last_name => "Valim", :ok => true,
450
+ :scope => true
451
+ }
452
+ }
453
+ }, serializer.as_json)
454
+ end
455
+
456
+ def test_implicity_detection_for_association_serializers
457
+ implicit_serializer = Class.new(ActiveModel::Serializer) do
458
+ root :custom_blog
459
+ const_set(:UserSerializer, UserSerializer)
460
+ const_set(:PostSerializer, PostSerializer)
461
+
462
+ has_many :public_posts, :key => :posts
463
+ has_one :public_user, :key => :user
464
+ end
465
+
466
+ posts = [
467
+ Post.new(:title => 'First Post', :body => 'text', :comments => []),
468
+ Post.new(:title => 'Second Post', :body => 'text', :comments => [])
469
+ ]
470
+ user = User.new
471
+
472
+ custom_blog = CustomBlog.new
473
+ custom_blog.public_posts = posts
474
+ custom_blog.public_user = user
475
+
476
+ serializer = implicit_serializer.new(custom_blog, :scope => true)
477
+
478
+ assert_equal({
479
+ :custom_blog => {
480
+ :posts => [
481
+ {:title => 'First Post', :body => 'text', :comments => []},
482
+ {:title => 'Second Post', :body => 'text', :comments => []}
483
+ ],
484
+ :user => {
485
+ :first_name => "Jose",
486
+ :last_name => "Valim", :ok => true,
487
+ :scope => true
488
+ }
489
+ }
490
+ }, serializer.as_json)
491
+ end
492
+
493
+ def test_attribute_key
494
+ serializer_class = Class.new(ActiveModel::Serializer) do
495
+ root :user
496
+
497
+ attribute :first_name, :key => :firstName
498
+ attribute :last_name, :key => :lastName
499
+ attribute :password
500
+ end
501
+
502
+ serializer = serializer_class.new(User.new, nil)
503
+
504
+ assert_equal({
505
+ :user => {
506
+ :firstName => "Jose",
507
+ :lastName => "Valim",
508
+ :password => "oh noes yugive my password"
509
+ }
510
+ }, serializer.as_json)
511
+ end
512
+
513
+ def setup_model
514
+ Class.new do
515
+ class << self
516
+ def columns_hash
517
+ { "name" => Struct.new(:type).new(:string), "age" => Struct.new(:type).new(:integer) }
518
+ end
519
+
520
+ def reflect_on_association(name)
521
+ case name
522
+ when :posts
523
+ Struct.new(:macro, :name).new(:has_many, :posts)
524
+ when :parent
525
+ Struct.new(:macro, :name).new(:belongs_to, :parent)
526
+ end
527
+ end
528
+ end
529
+ end
530
+ end
531
+
532
+ def test_schema
533
+ model = setup_model
534
+
535
+ serializer = Class.new(ActiveModel::Serializer) do
536
+ class << self; self; end.class_eval do
537
+ define_method(:model_class) do model end
538
+ end
539
+
540
+ attributes :name, :age
541
+ has_many :posts, :serializer => Class.new
542
+ has_one :parent, :serializer => Class.new
543
+ end
544
+
545
+ assert_equal serializer.schema, {
546
+ :attributes => { :name => :string, :age => :integer },
547
+ :associations => {
548
+ :posts => { :has_many => :posts },
549
+ :parent => { :belongs_to => :parent }
550
+ }
551
+ }
552
+ end
553
+
554
+ def test_schema_with_as
555
+ model = setup_model
556
+
557
+ serializer = Class.new(ActiveModel::Serializer) do
558
+ class << self; self; end.class_eval do
559
+ define_method(:model_class) do model end
560
+ end
561
+
562
+ attributes :name, :age
563
+ has_many :posts, :key => :my_posts, :serializer => Class.new
564
+ has_one :parent, :key => :my_parent, :serializer => Class.new
565
+ end
566
+
567
+ assert_equal serializer.schema, {
568
+ :attributes => { :name => :string, :age => :integer },
569
+ :associations => {
570
+ :my_posts => { :has_many => :posts },
571
+ :my_parent => { :belongs_to => :parent }
572
+ }
573
+ }
574
+ end
575
+
576
+ def test_embed_id_for_has_one
577
+ author_serializer = Class.new(ActiveModel::Serializer)
578
+
579
+ serializer_class = Class.new(ActiveModel::Serializer) do
580
+ embed :ids
581
+ root :post
582
+
583
+ attributes :title, :body
584
+ has_one :author, :serializer => author_serializer
585
+ end
586
+
587
+ post_class = Class.new(Model) do
588
+ attr_accessor :author
589
+ end
590
+
591
+ author_class = Class.new(Model)
592
+
593
+ post = post_class.new(:title => "New Post", :body => "It's a new post!")
594
+ author = author_class.new(:id => 5)
595
+ post.author = author
596
+
597
+ hash = serializer_class.new(post, nil)
598
+
599
+ assert_equal({
600
+ :post => {
601
+ :title => "New Post",
602
+ :body => "It's a new post!",
603
+ :author => 5
604
+ }
605
+ }, hash.as_json)
606
+ end
607
+
608
+ def test_embed_objects_for_has_one
609
+ author_serializer = Class.new(ActiveModel::Serializer) do
610
+ attributes :id, :name
611
+ end
612
+
613
+ serializer_class = Class.new(ActiveModel::Serializer) do
614
+ root :post
615
+
616
+ attributes :title, :body
617
+ has_one :author, :serializer => author_serializer
618
+ end
619
+
620
+ post_class = Class.new(Model) do
621
+ attr_accessor :author
622
+ end
623
+
624
+ author_class = Class.new(Model)
625
+
626
+ post = post_class.new(:title => "New Post", :body => "It's a new post!")
627
+ author = author_class.new(:id => 5, :name => "Tom Dale")
628
+ post.author = author
629
+
630
+ hash = serializer_class.new(post, nil)
631
+
632
+ assert_equal({
633
+ :post => {
634
+ :title => "New Post",
635
+ :body => "It's a new post!",
636
+ :author => { :id => 5, :name => "Tom Dale" }
637
+ }
638
+ }, hash.as_json)
639
+ end
640
+
641
+ def test_root_provided_in_options
642
+ author_serializer = Class.new(ActiveModel::Serializer) do
643
+ attributes :id, :name
644
+ end
645
+
646
+ serializer_class = Class.new(ActiveModel::Serializer) do
647
+ root :post
648
+
649
+ attributes :title, :body
650
+ has_one :author, :serializer => author_serializer
651
+ end
652
+
653
+ post_class = Class.new(Model) do
654
+ attr_accessor :author
655
+ end
656
+
657
+ author_class = Class.new(Model)
658
+
659
+ post = post_class.new(:title => "New Post", :body => "It's a new post!")
660
+ author = author_class.new(:id => 5, :name => "Tom Dale")
661
+ post.author = author
662
+
663
+ assert_equal({
664
+ :blog_post => {
665
+ :title => "New Post",
666
+ :body => "It's a new post!",
667
+ :author => { :id => 5, :name => "Tom Dale" }
668
+ }
669
+ }, serializer_class.new(post, nil, :root => :blog_post).as_json)
670
+
671
+ assert_equal({
672
+ :title => "New Post",
673
+ :body => "It's a new post!",
674
+ :author => { :id => 5, :name => "Tom Dale" }
675
+ }, serializer_class.new(post, nil, :root => false).as_json)
676
+
677
+ assert_equal({
678
+ :blog_post => {
679
+ :title => "New Post",
680
+ :body => "It's a new post!",
681
+ :author => { :id => 5, :name => "Tom Dale" }
682
+ }
683
+ }, serializer_class.new(post, nil).as_json(:root => :blog_post))
684
+
685
+ assert_equal({
686
+ :title => "New Post",
687
+ :body => "It's a new post!",
688
+ :author => { :id => 5, :name => "Tom Dale" }
689
+ }, serializer_class.new(post, nil).as_json(:root => false))
690
+ end
691
+
692
+ def test_serializer_has_access_to_root_object
693
+ hash_object = nil
694
+
695
+ author_serializer = Class.new(ActiveModel::Serializer) do
696
+ attributes :id, :name
697
+
698
+ define_method :serializable_hash do
699
+ hash_object = @hash
700
+ super()
701
+ end
702
+ end
703
+
704
+ serializer_class = Class.new(ActiveModel::Serializer) do
705
+ root :post
706
+
707
+ attributes :title, :body
708
+ has_one :author, :serializer => author_serializer
709
+ end
710
+
711
+ post_class = Class.new(Model) do
712
+ attr_accessor :author
713
+ end
714
+
715
+ author_class = Class.new(Model)
716
+
717
+ post = post_class.new(:title => "New Post", :body => "It's a new post!")
718
+ author = author_class.new(:id => 5, :name => "Tom Dale")
719
+ post.author = author
720
+
721
+ expected = serializer_class.new(post, nil).as_json
722
+ assert_equal expected, hash_object
723
+ end
724
+
725
+ # the point of this test is to illustrate that deeply nested serializers
726
+ # still side-load at the root.
727
+ def test_embed_with_include_inserts_at_root
728
+ tag_serializer = Class.new(ActiveModel::Serializer) do
729
+ attributes :id, :name
730
+ end
731
+
732
+ comment_serializer = Class.new(ActiveModel::Serializer) do
733
+ embed :ids, :include => true
734
+ attributes :id, :body
735
+ has_many :tags, :serializer => tag_serializer
736
+ end
737
+
738
+ post_serializer = Class.new(ActiveModel::Serializer) do
739
+ embed :ids, :include => true
740
+ attributes :id, :title, :body
741
+ has_many :comments, :serializer => comment_serializer
742
+ end
743
+
744
+ post_class = Class.new(Model) do
745
+ attr_accessor :comments
746
+
747
+ define_method :active_model_serializer do
748
+ post_serializer
749
+ end
750
+ end
751
+
752
+ comment_class = Class.new(Model) do
753
+ attr_accessor :tags
754
+ end
755
+
756
+ tag_class = Class.new(Model)
757
+
758
+ post = post_class.new(:title => "New Post", :body => "NEW POST", :id => 1)
759
+ comment1 = comment_class.new(:body => "EWOT", :id => 1)
760
+ comment2 = comment_class.new(:body => "YARLY", :id => 2)
761
+ tag1 = tag_class.new(:name => "lolcat", :id => 1)
762
+ tag2 = tag_class.new(:name => "nyancat", :id => 2)
763
+ tag3 = tag_class.new(:name => "violetcat", :id => 3)
764
+
765
+ post.comments = [comment1, comment2]
766
+ comment1.tags = [tag1, tag3]
767
+ comment2.tags = [tag1, tag2]
768
+
769
+ actual = ActiveModel::ArraySerializer.new([post], nil, :root => :posts).as_json
770
+ assert_equal({
771
+ :posts => [
772
+ { :title => "New Post", :body => "NEW POST", :id => 1, :comments => [1,2] }
773
+ ],
774
+
775
+ :comments => [
776
+ { :body => "EWOT", :id => 1, :tags => [1,3] },
777
+ { :body => "YARLY", :id => 2, :tags => [1,2] }
778
+ ],
779
+
780
+ :tags => [
781
+ { :name => "lolcat", :id => 1 },
782
+ { :name => "violetcat", :id => 3 },
783
+ { :name => "nyancat", :id => 2 }
784
+ ]
785
+ }, actual)
786
+ end
787
+ end