active_model_serializers 0.1.0

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