File: include_test.rb

package info (click to toggle)
ruby-active-model-serializers 0.10.12-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,752 kB
  • sloc: ruby: 13,138; sh: 53; makefile: 6
file content (248 lines) | stat: -rw-r--r-- 7,639 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# frozen_string_literal: true

require 'test_helper'

module ActionController
  module Serialization
    class Json
      class IncludeTest < ActionController::TestCase
        INCLUDE_STRING = 'posts.comments'.freeze
        INCLUDE_HASH = { posts: :comments }.freeze
        DEEP_INCLUDE = 'posts.comments.author'.freeze

        class IncludeTestController < ActionController::Base
          def setup_data
            ActionController::Base.cache_store.clear

            @author = Author.new(id: 1, name: 'Steve K.')

            @post = Post.new(id: 42, title: 'New Post', body: 'Body')
            @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
            @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')

            @post.comments = [@first_comment, @second_comment]
            @post.author = @author

            @first_comment.post = @post
            @second_comment.post = @post

            @blog = Blog.new(id: 1, name: 'My Blog!!')
            @post.blog = @blog
            @author.posts = [@post]

            @first_comment.author = @author
            @second_comment.author = @author
            @author.comments = [@first_comment, @second_comment]
            @author.roles = []
            @author.bio = {}
          end

          def render_without_include
            setup_data
            render json: @author, adapter: :json
          end

          def render_resource_with_include_hash
            setup_data
            render json: @author, include: INCLUDE_HASH, adapter: :json
          end

          def render_resource_with_include_string
            setup_data
            render json: @author, include: INCLUDE_STRING, adapter: :json
          end

          def render_resource_with_deep_include
            setup_data
            render json: @author, include: DEEP_INCLUDE, adapter: :json
          end

          def render_without_recursive_relationships
            # testing recursive includes ('**') can't have any cycles in the
            # relationships, or we enter an infinite loop.
            author = Author.new(id: 11, name: 'Jane Doe')
            post = Post.new(id: 12, title: 'Hello World', body: 'My first post')
            comment = Comment.new(id: 13, body: 'Commentary')
            author.posts = [post]
            post.comments = [comment]
            render json: author
          end
        end

        tests IncludeTestController

        def test_render_without_include
          get :render_without_include
          response = JSON.parse(@response.body)
          expected = {
            'author' => {
              'id' => 1,
              'name' => 'Steve K.',
              'posts' => [
                {
                  'id' => 42, 'title' => 'New Post', 'body' => 'Body'
                }
              ],
              'roles' => [],
              'bio' => {}
            }
          }

          assert_equal(expected, response)
        end

        def test_render_resource_with_include_hash
          get :render_resource_with_include_hash
          response = JSON.parse(@response.body)

          assert_equal(expected_include_response, response)
        end

        def test_render_resource_with_include_string
          get :render_resource_with_include_string

          response = JSON.parse(@response.body)

          assert_equal(expected_include_response, response)
        end

        def test_render_resource_with_deep_include
          get :render_resource_with_deep_include

          response = JSON.parse(@response.body)

          assert_equal(expected_deep_include_response, response)
        end

        def test_render_with_empty_default_includes
          with_default_includes '' do
            get :render_without_include
            response = JSON.parse(@response.body)
            expected = {
              'author' => {
                'id' => 1,
                'name' => 'Steve K.'
              }
            }
            assert_equal(expected, response)
          end
        end

        def test_render_with_recursive_default_includes
          with_default_includes '**' do
            get :render_without_recursive_relationships
            response = JSON.parse(@response.body)

            expected = {
              'id' => 11,
              'name' => 'Jane Doe',
              'roles' => nil,
              'bio' => nil,
              'posts' => [
                {
                  'id' => 12,
                  'title' => 'Hello World',
                  'body' => 'My first post',
                  'comments' => [
                    {
                      'id' => 13,
                      'body' => 'Commentary',
                      'post' => nil, # not set to avoid infinite recursion
                      'author' => nil, # not set to avoid infinite recursion
                    }
                  ],
                  'blog' => {
                    'id' => 999,
                    'name' => 'Custom blog',
                    'writer' => nil,
                    'articles' => nil
                  },
                  'author' => nil # not set to avoid infinite recursion
                }
              ]
            }
            assert_equal(expected, response)
          end
        end

        def test_render_with_includes_overrides_default_includes
          with_default_includes '' do
            get :render_resource_with_include_hash
            response = JSON.parse(@response.body)

            assert_equal(expected_include_response, response)
          end
        end

        private

        def expected_include_response
          {
            'author' => {
              'id' => 1,
              'name' => 'Steve K.',
              'posts' => [
                {
                  'id' => 42, 'title' => 'New Post', 'body' => 'Body',
                  'comments' => [
                    {
                      'id' => 1, 'body' => 'ZOMG A COMMENT'
                    },
                    {
                      'id' => 2, 'body' => 'ZOMG ANOTHER COMMENT'
                    }
                  ]
                }
              ]
            }
          }
        end

        def expected_deep_include_response
          {
            'author' => {
              'id' => 1,
              'name' => 'Steve K.',
              'posts' => [
                {
                  'id' => 42, 'title' => 'New Post', 'body' => 'Body',
                  'comments' => [
                    {
                      'id' => 1, 'body' => 'ZOMG A COMMENT',
                      'author' => {
                        'id' => 1,
                        'name' => 'Steve K.'
                      }
                    },
                    {
                      'id' => 2, 'body' => 'ZOMG ANOTHER COMMENT',
                      'author' => {
                        'id' => 1,
                        'name' => 'Steve K.'
                      }
                    }
                  ]
                }
              ]
            }
          }
        end

        def with_default_includes(include_directive)
          original = ActiveModelSerializers.config.default_includes
          ActiveModelSerializers.config.default_includes = include_directive
          clear_include_directive_cache
          yield
        ensure
          ActiveModelSerializers.config.default_includes = original
          clear_include_directive_cache
        end

        def clear_include_directive_cache
          ActiveModelSerializers
            .instance_variable_set(:@default_include_directive, nil)
        end
      end
    end
  end
end