grape-active_model_serializers 1.4.0 → 1.5.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +0 -7
- data/.travis.yml +0 -1
- data/CHANGELOG.md +25 -17
- data/README.md +8 -1
- data/UPGRADING.md +142 -6
- data/grape-active_model_serializers.gemspec +3 -3
- data/lib/grape-active_model_serializers.rb +2 -0
- data/lib/grape-active_model_serializers/endpoint_extension.rb +5 -3
- data/lib/grape-active_model_serializers/formatter.rb +14 -46
- data/lib/grape-active_model_serializers/options_builder.rb +68 -0
- data/lib/grape-active_model_serializers/serializer_resolver.rb +99 -0
- data/lib/grape-active_model_serializers/version.rb +1 -1
- data/spec/features/grape-active_model_serializers/render_spec.rb +1 -0
- data/spec/grape-active_model_serializers/endpoint_extension_spec.rb +22 -4
- data/spec/grape-active_model_serializers/formatter_spec.rb +15 -7
- data/spec/grape-active_model_serializers/versioned_api_formatter_spec.rb +22 -9
- data/spec/grape/active_model_serializers/serializer_resolver_spec.rb +146 -0
- data/spec/old_grape_ams_spec.rb +53 -11
- data/spec/support/api/users_api.rb +13 -0
- data/spec/support/api/v4/users_api.rb +15 -0
- data/spec/support/models/blog_post.rb +6 -1
- data/spec/support/models/user.rb +6 -1
- data/spec/support/serializers/v2/user_serializer.rb +5 -0
- data/spec/support/serializers/v3/user_serializer.rb +5 -0
- data/spec/support/serializers/v4/user_serializer.rb +5 -0
- data/spec/support/serializers/v5/user_serializer.rb +5 -0
- metadata +24 -8
@@ -0,0 +1,99 @@
|
|
1
|
+
module Grape
|
2
|
+
module ActiveModelSerializers
|
3
|
+
class SerializerResolver
|
4
|
+
def initialize(resource, options)
|
5
|
+
self.resource = resource
|
6
|
+
self.options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def serializer
|
10
|
+
serializer_class.new(resource, serializer_options) if serializer_class
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_accessor :resource, :options
|
16
|
+
|
17
|
+
def serializer_class
|
18
|
+
return @serializer_class if defined?(@serializer_class)
|
19
|
+
@serializer_class = resource_defined_class
|
20
|
+
@serializer_class ||= collection_class
|
21
|
+
@serializer_class ||= options[:serializer]
|
22
|
+
@serializer_class ||= namespace_inferred_class
|
23
|
+
@serializer_class ||= version_inferred_class
|
24
|
+
@serializer_class ||= resource_serializer_class
|
25
|
+
end
|
26
|
+
|
27
|
+
def serializer_options
|
28
|
+
if collection_serializer? && !options.key?(:serializer)
|
29
|
+
options.merge(each_serializer_option)
|
30
|
+
else
|
31
|
+
options
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def collection_serializer?
|
36
|
+
serializer_class == ActiveModel::Serializer.config.collection_serializer
|
37
|
+
end
|
38
|
+
|
39
|
+
def each_serializer_option
|
40
|
+
serializer_class = options[:each_serializer]
|
41
|
+
serializer_class ||= namespace_inferred_class
|
42
|
+
serializer_class ||= version_inferred_class
|
43
|
+
serializer_class ? { serializer: serializer_class } : {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def resource_defined_class
|
47
|
+
resource.serializer_class if resource.respond_to?(:serializer_class)
|
48
|
+
end
|
49
|
+
|
50
|
+
def collection_class
|
51
|
+
return nil unless resource.respond_to?(:to_ary)
|
52
|
+
ActiveModel::Serializer.config.collection_serializer
|
53
|
+
end
|
54
|
+
|
55
|
+
def namespace_inferred_class
|
56
|
+
return nil unless options.key?(:for)
|
57
|
+
namespace = options[:for].to_s.deconstantize
|
58
|
+
"#{namespace}::#{resource_serializer_klass}".safe_constantize
|
59
|
+
end
|
60
|
+
|
61
|
+
def version_inferred_class
|
62
|
+
return nil unless options.key?(:version)
|
63
|
+
"#{version}::#{resource_serializer_klass}".safe_constantize
|
64
|
+
end
|
65
|
+
|
66
|
+
def version
|
67
|
+
options[:version].try(:classify)
|
68
|
+
end
|
69
|
+
|
70
|
+
def resource_serializer_klass
|
71
|
+
@resource_serializer_klass ||= [
|
72
|
+
resource_namespace,
|
73
|
+
"#{resource_klass}Serializer"
|
74
|
+
].compact.join('::')
|
75
|
+
end
|
76
|
+
|
77
|
+
def resource_klass
|
78
|
+
resource_class.name.demodulize
|
79
|
+
end
|
80
|
+
|
81
|
+
def resource_namespace
|
82
|
+
klass = resource_class.name.deconstantize
|
83
|
+
klass.empty? ? nil : klass
|
84
|
+
end
|
85
|
+
|
86
|
+
def resource_class
|
87
|
+
if resource.respond_to?(:to_ary)
|
88
|
+
resource.try(:klass) || resource.compact.first.class
|
89
|
+
else
|
90
|
+
resource.class
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def resource_serializer_class
|
95
|
+
ActiveModel::Serializer.serializer_for(resource)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -2,9 +2,17 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'Grape::EndpointExtension' do
|
4
4
|
if Grape::Util.const_defined?('InheritableSetting')
|
5
|
-
subject
|
5
|
+
subject do
|
6
|
+
Grape::Endpoint.new(
|
7
|
+
Grape::Util::InheritableSetting.new,
|
8
|
+
path: '/',
|
9
|
+
method: 'foo'
|
10
|
+
)
|
11
|
+
end
|
6
12
|
else
|
7
|
-
subject
|
13
|
+
subject do
|
14
|
+
Grape::Endpoint.new({}, path: '/', method: 'foo')
|
15
|
+
end
|
8
16
|
end
|
9
17
|
|
10
18
|
let(:serializer) { Grape::Formatter::ActiveModelSerializers }
|
@@ -23,19 +31,29 @@ describe 'Grape::EndpointExtension' do
|
|
23
31
|
before do
|
24
32
|
allow(subject).to receive(:env).and_return({})
|
25
33
|
end
|
34
|
+
|
26
35
|
it { should respond_to(:render) }
|
27
36
|
let(:meta_content) { { total: 2 } }
|
28
37
|
let(:meta_full) { { meta: meta_content } }
|
38
|
+
|
29
39
|
context 'supplying meta' do
|
40
|
+
before do
|
41
|
+
allow(subject).to receive(:env) { { meta: meta_full } }
|
42
|
+
end
|
43
|
+
|
30
44
|
it 'passes through the Resource and uses given meta settings' do
|
31
|
-
allow(subject).to receive(:env).and_return(meta: meta_full)
|
32
45
|
expect(subject.render(users, meta_full)).to eq(users)
|
33
46
|
end
|
34
47
|
end
|
48
|
+
|
35
49
|
context 'supplying meta and key' do
|
36
50
|
let(:meta_key) { { meta_key: :custom_key_name } }
|
51
|
+
|
52
|
+
before do
|
53
|
+
allow(subject).to receive(:env) { { meta: meta_full.merge(meta_key) } }
|
54
|
+
end
|
55
|
+
|
37
56
|
it 'passes through the Resource and uses given meta settings' do
|
38
|
-
allow(subject).to receive(:env).and_return(meta: meta_full.merge(meta_key))
|
39
57
|
expect(subject.render(users, meta_full.merge(meta_key))).to eq(users)
|
40
58
|
end
|
41
59
|
end
|
@@ -18,19 +18,24 @@ describe Grape::Formatter::ActiveModelSerializers do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
let(:env) { { 'api.endpoint' => app.endpoints.first } }
|
22
|
+
let(:options) { described_class.build_options(nil, env) }
|
23
|
+
|
21
24
|
it 'should read serializer options like "root"' do
|
22
|
-
expect(
|
25
|
+
expect(options).to include(:root)
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
26
29
|
describe '.fetch_serializer' do
|
27
30
|
let(:user) { User.new(first_name: 'John') }
|
28
31
|
|
32
|
+
let(:params) { { path: '/', method: 'foo', root: false } }
|
29
33
|
if Grape::Util.const_defined?('InheritableSetting')
|
30
|
-
let(:
|
34
|
+
let(:setting) { Grape::Util::InheritableSetting.new }
|
31
35
|
else
|
32
|
-
let(:
|
36
|
+
let(:setting) { {} }
|
33
37
|
end
|
38
|
+
let(:endpoint) { Grape::Endpoint.new(setting, params) }
|
34
39
|
|
35
40
|
let(:env) { { 'api.endpoint' => endpoint } }
|
36
41
|
|
@@ -44,7 +49,10 @@ describe Grape::Formatter::ActiveModelSerializers do
|
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
47
|
-
|
52
|
+
let(:options) { described_class.build_options(user, env) }
|
53
|
+
subject { described_class.fetch_serializer(user, options) }
|
54
|
+
|
55
|
+
let(:instance_options) { subject.instance_variable_get(:@instance_options) }
|
48
56
|
|
49
57
|
it { should be_a UserSerializer }
|
50
58
|
|
@@ -53,12 +61,12 @@ describe Grape::Formatter::ActiveModelSerializers do
|
|
53
61
|
end
|
54
62
|
|
55
63
|
it 'should read default serializer options' do
|
56
|
-
expect(
|
57
|
-
expect(
|
64
|
+
expect(instance_options[:only]).to eq(:only)
|
65
|
+
expect(instance_options[:except]).to eq(:except)
|
58
66
|
end
|
59
67
|
|
60
68
|
it 'should read serializer options like "root"' do
|
61
|
-
expect(
|
69
|
+
expect(options).to include(:root)
|
62
70
|
end
|
63
71
|
end
|
64
72
|
end
|
@@ -15,25 +15,35 @@ describe Grape::Formatter::ActiveModelSerializers do
|
|
15
15
|
|
16
16
|
app.namespace('space') do |ns|
|
17
17
|
ns.get('/', root: false, apiver: 'v1') do
|
18
|
-
{
|
18
|
+
{
|
19
|
+
user: {
|
20
|
+
first_name: 'JR',
|
21
|
+
last_name: 'HE',
|
22
|
+
email: 'jrhe@github.com'
|
23
|
+
}
|
24
|
+
}
|
19
25
|
end
|
20
26
|
end
|
21
27
|
end
|
22
28
|
|
29
|
+
let(:env) { { 'api.endpoint' => app.endpoints.first } }
|
30
|
+
let(:options) { described_class.build_options(nil, env) }
|
31
|
+
|
23
32
|
it 'should read serializer options like "root"' do
|
24
|
-
expect(
|
33
|
+
expect(options).to include(:root)
|
25
34
|
end
|
26
35
|
end
|
27
36
|
|
28
37
|
describe '.fetch_serializer' do
|
29
38
|
let(:user) { User.new(first_name: 'John', email: 'j.doe@internet.com') }
|
30
39
|
|
40
|
+
let(:params) { { path: '/', method: 'foo', version: 'v1', root: false } }
|
31
41
|
if Grape::Util.const_defined?('InheritableSetting')
|
32
|
-
let(:
|
42
|
+
let(:setting) { Grape::Util::InheritableSetting.new }
|
33
43
|
else
|
34
|
-
let(:
|
44
|
+
let(:setting) { {} }
|
35
45
|
end
|
36
|
-
|
46
|
+
let(:endpoint) { Grape::Endpoint.new(setting, params) }
|
37
47
|
let(:env) { { 'api.endpoint' => endpoint } }
|
38
48
|
|
39
49
|
before do
|
@@ -46,7 +56,10 @@ describe Grape::Formatter::ActiveModelSerializers do
|
|
46
56
|
end
|
47
57
|
end
|
48
58
|
|
49
|
-
|
59
|
+
let(:options) { described_class.build_options(user, env) }
|
60
|
+
subject { described_class.fetch_serializer(user, options) }
|
61
|
+
|
62
|
+
let(:instance_options) { subject.send(:instance_options) }
|
50
63
|
|
51
64
|
it { should be_a V1::UserSerializer }
|
52
65
|
|
@@ -55,12 +68,12 @@ describe Grape::Formatter::ActiveModelSerializers do
|
|
55
68
|
end
|
56
69
|
|
57
70
|
it 'should read default serializer options' do
|
58
|
-
expect(
|
59
|
-
expect(
|
71
|
+
expect(instance_options[:only]).to eq(:only)
|
72
|
+
expect(instance_options[:except]).to eq(:except)
|
60
73
|
end
|
61
74
|
|
62
75
|
it 'should read serializer options like "root"' do
|
63
|
-
expect(
|
76
|
+
expect(options).to include(:root)
|
64
77
|
end
|
65
78
|
end
|
66
79
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
# asserts serializer resolution order:
|
5
|
+
# 1. resource_defined_class # V1::UserSerializer
|
6
|
+
# 2. collection_class # CollectionSerializer, V2::UserSerializer
|
7
|
+
# 3. options[:serializer] # V3::UserSerializer
|
8
|
+
# 4. namespace_inferred_class # V4::UserSerializer
|
9
|
+
# 5. version_inferred_class # V5::UserSerializer
|
10
|
+
# 6. resource_serializer_class # UserSerializer
|
11
|
+
# 7. missing resource # nil
|
12
|
+
|
13
|
+
describe Grape::ActiveModelSerializers::SerializerResolver do
|
14
|
+
let(:resolver) { described_class.new(resource, options) }
|
15
|
+
let(:resource) { User.new }
|
16
|
+
let(:options) {
|
17
|
+
{
|
18
|
+
serializer: options_serializer_class, # options defined
|
19
|
+
for: V4::UsersApi, # namespace inference
|
20
|
+
version: 'v5' # version inference
|
21
|
+
}
|
22
|
+
}
|
23
|
+
# resource defined
|
24
|
+
let(:resource_defined?) { true }
|
25
|
+
let(:defined_serializer_class) { V1::UserSerializer }
|
26
|
+
# options defined
|
27
|
+
let(:options_serializer_class) { V3::UserSerializer }
|
28
|
+
|
29
|
+
let(:serializer) { resolver.serializer }
|
30
|
+
|
31
|
+
before do
|
32
|
+
if resource_defined?
|
33
|
+
allow(resource).to receive(:respond_to?).and_call_original
|
34
|
+
allow(resource).to receive(:respond_to?).with(:to_ary) { true }
|
35
|
+
allow(resource).to receive(:serializer_class) { defined_serializer_class }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'resource defined' do
|
40
|
+
it 'returns serializer' do
|
41
|
+
expect(serializer).to be_kind_of(defined_serializer_class)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'not resource defined' do
|
46
|
+
let(:resource_defined?) { false }
|
47
|
+
|
48
|
+
context 'resource collection' do
|
49
|
+
let(:resource) { [User.new] }
|
50
|
+
let(:serializer_class) { ActiveModel::Serializer::CollectionSerializer }
|
51
|
+
|
52
|
+
it 'returns serializer' do
|
53
|
+
expect(serializer).to be_kind_of(serializer_class)
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'each serializer' do
|
57
|
+
let(:options) {
|
58
|
+
super().except(:serializer).merge(
|
59
|
+
each_serializer: V2::UserSerializer
|
60
|
+
)
|
61
|
+
}
|
62
|
+
let(:each_serializer) { serializer.send(:options)[:serializer] }
|
63
|
+
|
64
|
+
context 'each_serializer option' do
|
65
|
+
it 'returns expected serializer' do
|
66
|
+
expect(each_serializer).to eq(V2::UserSerializer)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'no each_serializer option' do
|
71
|
+
let(:options) { super().except(:each_serializer) }
|
72
|
+
|
73
|
+
context 'namespace inferred' do
|
74
|
+
it 'returns expected serializer' do
|
75
|
+
expect(each_serializer).to eq(V4::UserSerializer)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'not namespace inferred' do
|
80
|
+
let(:options) { super().except(:for) }
|
81
|
+
|
82
|
+
context 'version inferred' do
|
83
|
+
it 'returns expected serializer' do
|
84
|
+
expect(each_serializer).to eq(V5::UserSerializer)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'not version inferred' do
|
89
|
+
let(:options) { super().except(:version) }
|
90
|
+
|
91
|
+
it 'returns nil' do
|
92
|
+
expect(each_serializer).to eq(nil)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'not resource collection' do
|
101
|
+
context 'specified by options' do
|
102
|
+
it 'returns specified serializer' do
|
103
|
+
expect(serializer).to be_kind_of(V3::UserSerializer)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'not specified by options' do
|
108
|
+
let(:options) { super().except(:serializer) }
|
109
|
+
|
110
|
+
context 'namespace inferred' do
|
111
|
+
it 'returns inferred serializer' do
|
112
|
+
expect(serializer).to be_kind_of(V4::UserSerializer)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'not namespace inferred' do
|
117
|
+
let(:options) { super().except(:for) }
|
118
|
+
|
119
|
+
context 'version inferred' do
|
120
|
+
it 'returns inferred serializer' do
|
121
|
+
expect(serializer).to be_kind_of(V5::UserSerializer)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'not version inferred' do
|
126
|
+
let(:options) { super().except(:version) }
|
127
|
+
|
128
|
+
context 'ASM resolved' do
|
129
|
+
it 'returns serializer' do
|
130
|
+
expect(serializer).to be_kind_of(UserSerializer)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'not ASM resolved' do
|
135
|
+
let(:resource) { nil }
|
136
|
+
|
137
|
+
it 'returns nil' do
|
138
|
+
expect(serializer).to eq(nil)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/spec/old_grape_ams_spec.rb
CHANGED
@@ -10,6 +10,7 @@ describe Grape::ActiveModelSerializers do
|
|
10
10
|
subject { last_response.body }
|
11
11
|
|
12
12
|
before do
|
13
|
+
ActiveModelSerializers.config.adapter = :json
|
13
14
|
app.format :json
|
14
15
|
app.formatter :json, Grape::Formatter::ActiveModelSerializers
|
15
16
|
end
|
@@ -30,31 +31,48 @@ describe Grape::ActiveModelSerializers do
|
|
30
31
|
end
|
31
32
|
it 'uses the built in grape serializer' do
|
32
33
|
get('/home')
|
33
|
-
expect(subject).to
|
34
|
+
expect(subject).to eq(
|
35
|
+
'{"user":{"first_name":"JR","last_name":"HE"}}'
|
36
|
+
)
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
37
40
|
context "serializer isn't set" do
|
38
41
|
before do
|
39
42
|
app.get('/home') do
|
40
|
-
User.new(
|
43
|
+
User.new(
|
44
|
+
first_name: 'JR',
|
45
|
+
last_name: 'HE',
|
46
|
+
email: 'contact@jrhe.co.uk'
|
47
|
+
)
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
44
51
|
it 'infers the serializer' do
|
45
52
|
get '/home'
|
46
|
-
expect(subject).to
|
53
|
+
expect(subject).to eq(
|
54
|
+
'{"user":{"first_name":"JR","last_name":"HE"}}'
|
55
|
+
)
|
47
56
|
end
|
48
57
|
end
|
49
58
|
|
50
59
|
it 'serializes arrays of objects' do
|
51
60
|
app.get('/users') do
|
52
|
-
user = User.new(
|
61
|
+
user = User.new(
|
62
|
+
first_name: 'JR',
|
63
|
+
last_name: 'HE',
|
64
|
+
email: 'contact@jrhe.co.uk'
|
65
|
+
)
|
53
66
|
[user, user]
|
54
67
|
end
|
55
68
|
|
56
69
|
get '/users'
|
57
|
-
expect(subject).to
|
70
|
+
expect(subject).to eq(
|
71
|
+
'{"users":['\
|
72
|
+
'{"first_name":"JR","last_name":"HE"},'\
|
73
|
+
'{"first_name":"JR","last_name":"HE"}'\
|
74
|
+
']}'
|
75
|
+
)
|
58
76
|
end
|
59
77
|
|
60
78
|
context 'models with compound names' do
|
@@ -64,17 +82,29 @@ describe Grape::ActiveModelSerializers do
|
|
64
82
|
end
|
65
83
|
|
66
84
|
get '/home'
|
67
|
-
expect(subject).to
|
85
|
+
expect(subject).to eq(
|
86
|
+
'{"blog_post":'\
|
87
|
+
'{"title":"Grape AM::S Rocks!","body":"Really, it does."}'\
|
88
|
+
'}'
|
89
|
+
)
|
68
90
|
end
|
69
91
|
|
70
92
|
it "generates the proper 'root' node for serialized arrays" do
|
71
93
|
app.get('/blog_posts') do
|
72
|
-
blog_post = BlogPost.new(
|
94
|
+
blog_post = BlogPost.new(
|
95
|
+
title: 'Grape AM::S Rocks!',
|
96
|
+
body: 'Really, it does.'
|
97
|
+
)
|
73
98
|
[blog_post, blog_post]
|
74
99
|
end
|
75
100
|
|
76
101
|
get '/blog_posts'
|
77
|
-
expect(subject).to
|
102
|
+
expect(subject).to eq(
|
103
|
+
'{"blog_posts":['\
|
104
|
+
'{"title":"Grape AM::S Rocks!","body":"Really, it does."},'\
|
105
|
+
'{"title":"Grape AM::S Rocks!","body":"Really, it does."}'\
|
106
|
+
']}'
|
107
|
+
)
|
78
108
|
end
|
79
109
|
end
|
80
110
|
|
@@ -86,7 +116,9 @@ describe Grape::ActiveModelSerializers do
|
|
86
116
|
end
|
87
117
|
|
88
118
|
get '/admin/jeff'
|
89
|
-
expect(subject).to
|
119
|
+
expect(subject).to eq(
|
120
|
+
'{"user":{"first_name":"Jeff","last_name":null}}'
|
121
|
+
)
|
90
122
|
end
|
91
123
|
|
92
124
|
context 'route is in a namespace' do
|
@@ -99,7 +131,12 @@ describe Grape::ActiveModelSerializers do
|
|
99
131
|
end
|
100
132
|
|
101
133
|
get '/admin/jeff'
|
102
|
-
expect(subject).to
|
134
|
+
expect(subject).to eq(
|
135
|
+
'{"admin":['\
|
136
|
+
'{"first_name":"Jeff","last_name":null},'\
|
137
|
+
'{"first_name":"Jeff","last_name":null}'\
|
138
|
+
']}'
|
139
|
+
)
|
103
140
|
end
|
104
141
|
end
|
105
142
|
|
@@ -111,7 +148,12 @@ describe Grape::ActiveModelSerializers do
|
|
111
148
|
end
|
112
149
|
|
113
150
|
get '/people'
|
114
|
-
expect(subject).to
|
151
|
+
expect(subject).to eq(
|
152
|
+
'{"people":['\
|
153
|
+
'{"first_name":"Jeff","last_name":null},'\
|
154
|
+
'{"first_name":"Jeff","last_name":null}'\
|
155
|
+
']}'
|
156
|
+
)
|
115
157
|
end
|
116
158
|
end
|
117
159
|
end
|