simple_jsonapi 1.0.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 +7 -0
- data/.gitignore +10 -0
- data/.rubocop.yml +131 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +5 -0
- data/Jenkinsfile +92 -0
- data/LICENSE.txt +22 -0
- data/README.md +532 -0
- data/Rakefile +10 -0
- data/lib/simple_jsonapi.rb +112 -0
- data/lib/simple_jsonapi/definition/attribute.rb +45 -0
- data/lib/simple_jsonapi/definition/base.rb +50 -0
- data/lib/simple_jsonapi/definition/concerns/has_links_object.rb +36 -0
- data/lib/simple_jsonapi/definition/concerns/has_meta_object.rb +36 -0
- data/lib/simple_jsonapi/definition/error.rb +70 -0
- data/lib/simple_jsonapi/definition/error_source.rb +29 -0
- data/lib/simple_jsonapi/definition/link.rb +27 -0
- data/lib/simple_jsonapi/definition/meta.rb +27 -0
- data/lib/simple_jsonapi/definition/relationship.rb +60 -0
- data/lib/simple_jsonapi/definition/resource.rb +104 -0
- data/lib/simple_jsonapi/error_serializer.rb +76 -0
- data/lib/simple_jsonapi/errors/bad_request.rb +11 -0
- data/lib/simple_jsonapi/errors/exception_serializer.rb +6 -0
- data/lib/simple_jsonapi/errors/wrapped_error.rb +35 -0
- data/lib/simple_jsonapi/errors/wrapped_error_serializer.rb +35 -0
- data/lib/simple_jsonapi/helpers/exceptions.rb +39 -0
- data/lib/simple_jsonapi/helpers/serializer_inferrer.rb +136 -0
- data/lib/simple_jsonapi/helpers/serializer_methods.rb +36 -0
- data/lib/simple_jsonapi/node/attributes.rb +51 -0
- data/lib/simple_jsonapi/node/base.rb +91 -0
- data/lib/simple_jsonapi/node/data/collection.rb +25 -0
- data/lib/simple_jsonapi/node/data/singular.rb +26 -0
- data/lib/simple_jsonapi/node/document/base.rb +62 -0
- data/lib/simple_jsonapi/node/document/collection.rb +17 -0
- data/lib/simple_jsonapi/node/document/errors.rb +17 -0
- data/lib/simple_jsonapi/node/document/singular.rb +17 -0
- data/lib/simple_jsonapi/node/error.rb +55 -0
- data/lib/simple_jsonapi/node/error_source.rb +40 -0
- data/lib/simple_jsonapi/node/errors.rb +28 -0
- data/lib/simple_jsonapi/node/included.rb +45 -0
- data/lib/simple_jsonapi/node/object_links.rb +40 -0
- data/lib/simple_jsonapi/node/object_meta.rb +40 -0
- data/lib/simple_jsonapi/node/relationship.rb +79 -0
- data/lib/simple_jsonapi/node/relationship_data/base.rb +53 -0
- data/lib/simple_jsonapi/node/relationship_data/collection.rb +32 -0
- data/lib/simple_jsonapi/node/relationship_data/singular.rb +33 -0
- data/lib/simple_jsonapi/node/relationships.rb +60 -0
- data/lib/simple_jsonapi/node/resource/base.rb +21 -0
- data/lib/simple_jsonapi/node/resource/full.rb +49 -0
- data/lib/simple_jsonapi/node/resource/linkage.rb +25 -0
- data/lib/simple_jsonapi/parameters/fields_spec.rb +45 -0
- data/lib/simple_jsonapi/parameters/include_spec.rb +57 -0
- data/lib/simple_jsonapi/parameters/sort_spec.rb +107 -0
- data/lib/simple_jsonapi/serializer.rb +89 -0
- data/lib/simple_jsonapi/version.rb +3 -0
- data/simple_jsonapi.gemspec +29 -0
- data/test/errors/bad_request_test.rb +34 -0
- data/test/errors/error_serializer_test.rb +229 -0
- data/test/errors/exception_serializer_test.rb +25 -0
- data/test/errors/wrapped_error_serializer_test.rb +91 -0
- data/test/errors/wrapped_error_test.rb +44 -0
- data/test/parameters/fields_spec_test.rb +56 -0
- data/test/parameters/include_spec_test.rb +58 -0
- data/test/parameters/sort_spec_test.rb +65 -0
- data/test/resources/attributes_test.rb +109 -0
- data/test/resources/extras_test.rb +70 -0
- data/test/resources/id_and_type_test.rb +76 -0
- data/test/resources/inclusion_test.rb +134 -0
- data/test/resources/links_test.rb +63 -0
- data/test/resources/meta_test.rb +49 -0
- data/test/resources/relationships_test.rb +262 -0
- data/test/resources/sorting_test.rb +79 -0
- data/test/resources/sparse_fieldset_test.rb +160 -0
- data/test/root_objects_test.rb +165 -0
- data/test/test_helper.rb +31 -0
- metadata +235 -0
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ErrorSerializerTest < Minitest::Spec
|
4
|
+
class Problem < TestModel
|
5
|
+
attr_accessor :id, :name, :number, :date
|
6
|
+
end
|
7
|
+
|
8
|
+
class DefaultsSerializer < SimpleJsonapi::ErrorSerializer
|
9
|
+
end
|
10
|
+
|
11
|
+
class BlocksSerializer < SimpleJsonapi::ErrorSerializer
|
12
|
+
id(&:id)
|
13
|
+
status { "422" }
|
14
|
+
code(&:number)
|
15
|
+
title(&:name)
|
16
|
+
detail { |err| "#{err.name} #{err.number}" }
|
17
|
+
source do
|
18
|
+
pointer { |err| "/to/#{err.name}" }
|
19
|
+
parameter { |err| err.class.name }
|
20
|
+
end
|
21
|
+
about_link { |err| "https://www.patientslikeme.com/error/#{err.id}" }
|
22
|
+
meta(:date) { |err| err.date&.iso8601 }
|
23
|
+
end
|
24
|
+
|
25
|
+
class ProcsSerializer < SimpleJsonapi::ErrorSerializer
|
26
|
+
id ->(err) { err.id }
|
27
|
+
status ->(_err) { "422" }
|
28
|
+
code ->(err) { err.number }
|
29
|
+
title ->(err) { err.name }
|
30
|
+
detail ->(err) { "#{err.name} #{err.number}" }
|
31
|
+
source do
|
32
|
+
pointer ->(err) { "/to/#{err.name}" }
|
33
|
+
parameter ->(err) { err.class.name }
|
34
|
+
end
|
35
|
+
about_link ->(err) { "https://www.patientslikeme.com/error/#{err.id}" }
|
36
|
+
meta :date, ->(err) { err.date&.iso8601 }
|
37
|
+
end
|
38
|
+
|
39
|
+
class ValuesSerializer < SimpleJsonapi::ErrorSerializer
|
40
|
+
id "42"
|
41
|
+
status "422"
|
42
|
+
code "the_code"
|
43
|
+
title "the title"
|
44
|
+
detail "the details"
|
45
|
+
source do
|
46
|
+
pointer "/to/somewhere"
|
47
|
+
parameter "the_parameter"
|
48
|
+
end
|
49
|
+
about_link "https://www.patientslikeme.com/errors"
|
50
|
+
meta :date, "2017-01-01"
|
51
|
+
end
|
52
|
+
|
53
|
+
let(:problem) { Problem.new(id: 12, name: "BadThing", number: "999", date: Date.new(2017, 7, 1)) }
|
54
|
+
|
55
|
+
let(:default_serialized) do
|
56
|
+
SimpleJsonapi.render_errors(problem, serializer: DefaultsSerializer)[:errors].first
|
57
|
+
end
|
58
|
+
let(:blocks_serialized) do
|
59
|
+
SimpleJsonapi.render_errors(problem, serializer: BlocksSerializer)[:errors].first
|
60
|
+
end
|
61
|
+
let(:procs_serialized) do
|
62
|
+
SimpleJsonapi.render_errors(problem, serializer: ProcsSerializer)[:errors].first
|
63
|
+
end
|
64
|
+
let(:values_serialized) do
|
65
|
+
SimpleJsonapi.render_errors(problem, serializer: ValuesSerializer)[:errors].first
|
66
|
+
end
|
67
|
+
|
68
|
+
describe SimpleJsonapi::ErrorSerializer do
|
69
|
+
describe "id property" do
|
70
|
+
it "is excluded by default" do
|
71
|
+
refute default_serialized.key?(:id)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "accepts a block" do
|
75
|
+
assert_equal "12", blocks_serialized[:id]
|
76
|
+
end
|
77
|
+
|
78
|
+
it "accepts a proc" do
|
79
|
+
assert_equal "12", procs_serialized[:id]
|
80
|
+
end
|
81
|
+
|
82
|
+
it "accepts a value" do
|
83
|
+
assert_equal "42", values_serialized[:id]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "status property" do
|
88
|
+
it "is excluded by default" do
|
89
|
+
refute default_serialized.key?(:status)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "accepts a block" do
|
93
|
+
assert_equal "422", blocks_serialized[:status]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "accepts a proc" do
|
97
|
+
assert_equal "422", procs_serialized[:status]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "accepts a value" do
|
101
|
+
assert_equal "422", values_serialized[:status]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "code property" do
|
106
|
+
it "is excluded by default" do
|
107
|
+
refute default_serialized.key?(:code)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "accepts a block" do
|
111
|
+
assert_equal "999", blocks_serialized[:code]
|
112
|
+
end
|
113
|
+
|
114
|
+
it "accepts a proc" do
|
115
|
+
assert_equal "999", procs_serialized[:code]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "accepts a value" do
|
119
|
+
assert_equal "the_code", values_serialized[:code]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "title property" do
|
124
|
+
it "is excluded by default" do
|
125
|
+
refute default_serialized.key?(:title)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "accepts a block" do
|
129
|
+
assert_equal "BadThing", blocks_serialized[:title]
|
130
|
+
end
|
131
|
+
|
132
|
+
it "accepts a proc" do
|
133
|
+
assert_equal "BadThing", procs_serialized[:title]
|
134
|
+
end
|
135
|
+
|
136
|
+
it "accepts a value" do
|
137
|
+
assert_equal "the title", values_serialized[:title]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "detail property" do
|
142
|
+
it "is excluded by default" do
|
143
|
+
refute default_serialized.key?(:detail)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "accepts a block" do
|
147
|
+
assert_equal "BadThing 999", blocks_serialized[:detail]
|
148
|
+
end
|
149
|
+
|
150
|
+
it "accepts a proc" do
|
151
|
+
assert_equal "BadThing 999", procs_serialized[:detail]
|
152
|
+
end
|
153
|
+
|
154
|
+
it "accepts a value" do
|
155
|
+
assert_equal "the details", values_serialized[:detail]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "source object" do
|
160
|
+
it "is excluded by default" do
|
161
|
+
refute default_serialized.key?(:source)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "source pointer property" do
|
166
|
+
it "accepts a block" do
|
167
|
+
assert_equal "/to/BadThing", blocks_serialized.dig(:source, :pointer)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "accepts a proc" do
|
171
|
+
assert_equal "/to/BadThing", procs_serialized.dig(:source, :pointer)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "accepts a value" do
|
175
|
+
assert_equal "/to/somewhere", values_serialized.dig(:source, :pointer)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "source parameter property" do
|
180
|
+
it "accepts a block" do
|
181
|
+
assert_equal problem.class.name, blocks_serialized.dig(:source, :parameter)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "accepts a proc" do
|
185
|
+
assert_equal problem.class.name, procs_serialized.dig(:source, :parameter)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "accepts a value" do
|
189
|
+
assert_equal "the_parameter", values_serialized.dig(:source, :parameter)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "about link" do
|
194
|
+
it "is excluded by default" do
|
195
|
+
refute default_serialized.key?(:links)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "accepts a block" do
|
199
|
+
assert_equal "https://www.patientslikeme.com/error/12", blocks_serialized.dig(:links, :about)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "accepts a proc" do
|
203
|
+
assert_equal "https://www.patientslikeme.com/error/12", procs_serialized.dig(:links, :about)
|
204
|
+
end
|
205
|
+
|
206
|
+
it "accepts a value" do
|
207
|
+
assert_equal "https://www.patientslikeme.com/errors", values_serialized.dig(:links, :about)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "meta information" do
|
212
|
+
it "is excluded by default" do
|
213
|
+
refute default_serialized.key?(:meta)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "accepts a block" do
|
217
|
+
assert_equal "2017-07-01", blocks_serialized.dig(:meta, :date)
|
218
|
+
end
|
219
|
+
|
220
|
+
it "accepts a proc" do
|
221
|
+
assert_equal "2017-07-01", procs_serialized.dig(:meta, :date)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "accepts a value" do
|
225
|
+
assert_equal "2017-01-01", values_serialized.dig(:meta, :date)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ExceptionSerializerTest < Minitest::Spec
|
4
|
+
class SampleException < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:exception) { SampleException.new("the message") }
|
8
|
+
let(:serialized) do
|
9
|
+
SimpleJsonapi.render_errors(exception, serializer: SimpleJsonapi::Errors::ExceptionSerializer)[:errors].first
|
10
|
+
end
|
11
|
+
|
12
|
+
describe SimpleJsonapi::Errors::ExceptionSerializer do
|
13
|
+
it "sets code to the class name in snake case" do
|
14
|
+
assert_equal "exception_serializer_test_sample_exception", serialized[:code]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "sets title to the class name" do
|
18
|
+
assert_equal "ExceptionSerializerTest::SampleException", serialized[:title]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sets detail to the message" do
|
22
|
+
assert_equal "the message", serialized[:detail]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class WrappedErrorSerializerTest < Minitest::Spec
|
4
|
+
let(:cause) { StandardError.new("the message") }
|
5
|
+
|
6
|
+
let(:wrapped) do
|
7
|
+
SimpleJsonapi::Errors::WrappedError.new(
|
8
|
+
cause,
|
9
|
+
id: "the id",
|
10
|
+
status: "the status",
|
11
|
+
code: "the code",
|
12
|
+
title: "the title",
|
13
|
+
detail: "the detail",
|
14
|
+
source_pointer: "the source pointer",
|
15
|
+
source_parameter: "the source parameter",
|
16
|
+
about_link: "the about link",
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:serialized) do
|
21
|
+
rendered_errors = SimpleJsonapi.render_errors(
|
22
|
+
wrapped,
|
23
|
+
serializer: SimpleJsonapi::Errors::WrappedErrorSerializer,
|
24
|
+
)
|
25
|
+
rendered_errors[:errors].first
|
26
|
+
end
|
27
|
+
|
28
|
+
describe SimpleJsonapi::Errors::WrappedErrorSerializer do
|
29
|
+
it "outputs the id property" do
|
30
|
+
assert_equal "the id", serialized[:id]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "outputs the status property" do
|
34
|
+
assert_equal "the status", serialized[:status]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "outputs the code property" do
|
38
|
+
assert_equal "the code", serialized[:code]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "outputs the title property" do
|
42
|
+
assert_equal "the title", serialized[:title]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "outputs the detail property" do
|
46
|
+
assert_equal "the detail", serialized[:detail]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "outputs the nested source pointer" do
|
50
|
+
assert_equal "the source pointer", serialized[:source][:pointer]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "outputs the nested source parameter" do
|
54
|
+
assert_equal "the source parameter", serialized[:source][:parameter]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "outputs an about link" do
|
58
|
+
assert_equal "the about link", serialized[:links][:about]
|
59
|
+
end
|
60
|
+
|
61
|
+
it "omits blank properties" do
|
62
|
+
blank_error = SimpleJsonapi::Errors::WrappedError.new(
|
63
|
+
cause,
|
64
|
+
id: " ",
|
65
|
+
status: " ",
|
66
|
+
code: " ",
|
67
|
+
title: " ",
|
68
|
+
detail: " ",
|
69
|
+
source_pointer: " ",
|
70
|
+
source_parameter: " ",
|
71
|
+
about_link: " ",
|
72
|
+
)
|
73
|
+
|
74
|
+
rendered_errors = SimpleJsonapi.render_errors(
|
75
|
+
blank_error, serializer:
|
76
|
+
SimpleJsonapi::Errors::WrappedErrorSerializer,
|
77
|
+
)
|
78
|
+
|
79
|
+
serialized_blank = rendered_errors[:errors].first
|
80
|
+
|
81
|
+
refute_includes serialized_blank.keys, :id
|
82
|
+
refute_includes serialized_blank.keys, :status
|
83
|
+
refute_includes serialized_blank.keys, :code
|
84
|
+
refute_includes serialized_blank.keys, :title
|
85
|
+
refute_includes serialized_blank.keys, :detail
|
86
|
+
refute_includes serialized_blank.keys, :source
|
87
|
+
refute_includes serialized_blank.keys, :source
|
88
|
+
refute_includes serialized_blank.keys, :links
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class WrappedErrorTest < Minitest::Spec
|
4
|
+
let(:cause) { StandardError.new("the message") }
|
5
|
+
|
6
|
+
let(:wrapped) do
|
7
|
+
SimpleJsonapi::Errors::WrappedError.new(
|
8
|
+
cause,
|
9
|
+
id: "the id",
|
10
|
+
status: "the status",
|
11
|
+
code: "the code",
|
12
|
+
title: "the title",
|
13
|
+
detail: "the detail",
|
14
|
+
source_pointer: "the source pointer",
|
15
|
+
source_parameter: "the source parameter",
|
16
|
+
about_link: "the about link",
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe SimpleJsonapi::Errors::WrappedError do
|
21
|
+
describe "cause" do
|
22
|
+
it "defaults to nil" do
|
23
|
+
assert_nil SimpleJsonapi::Errors::WrappedError.new.cause
|
24
|
+
end
|
25
|
+
|
26
|
+
it "is stored" do
|
27
|
+
assert_equal cause, wrapped.cause
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "other properties" do
|
32
|
+
it "are stored" do
|
33
|
+
assert_equal "the id", wrapped.id
|
34
|
+
assert_equal "the status", wrapped.status
|
35
|
+
assert_equal "the code", wrapped.code
|
36
|
+
assert_equal "the title", wrapped.title
|
37
|
+
assert_equal "the detail", wrapped.detail
|
38
|
+
assert_equal "the source pointer", wrapped.source_pointer
|
39
|
+
assert_equal "the source parameter", wrapped.source_parameter
|
40
|
+
assert_equal "the about link", wrapped.about_link
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FieldsSpecTest < Minitest::Spec
|
4
|
+
describe SimpleJsonapi::Parameters::FieldsSpec do
|
5
|
+
describe "parsing" do
|
6
|
+
it "accepts comma-delimited strings" do
|
7
|
+
spec = SimpleJsonapi::Parameters::FieldsSpec.new(
|
8
|
+
"orders" => "customer_name,description",
|
9
|
+
"line_items" => "order_id,product_id",
|
10
|
+
)
|
11
|
+
|
12
|
+
assert_equal [:customer_name, :description], spec[:orders]
|
13
|
+
assert_equal [:order_id, :product_id], spec[:line_items]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "accepts arrays of strings" do
|
17
|
+
spec = SimpleJsonapi::Parameters::FieldsSpec.new(
|
18
|
+
"orders" => ["customer_name", "description"],
|
19
|
+
"line_items" => ["order_id", "product_id"],
|
20
|
+
)
|
21
|
+
|
22
|
+
assert_equal [:customer_name, :description], spec[:orders]
|
23
|
+
assert_equal [:order_id, :product_id], spec[:line_items]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "accepts arrays of symbols" do
|
27
|
+
spec = SimpleJsonapi::Parameters::FieldsSpec.new(
|
28
|
+
orders: [:customer_name, :description],
|
29
|
+
line_items: [:order_id, :product_id],
|
30
|
+
)
|
31
|
+
|
32
|
+
assert_equal [:customer_name, :description], spec[:orders]
|
33
|
+
assert_equal [:order_id, :product_id], spec[:line_items]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "all_fields?" do
|
38
|
+
it "is true if nothing is defined for the type" do
|
39
|
+
spec = SimpleJsonapi::Parameters::FieldsSpec.new
|
40
|
+
assert_equal true, spec.all_fields?(:orders)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "is false if the type is assigned any fields" do
|
44
|
+
spec = SimpleJsonapi::Parameters::FieldsSpec.new(
|
45
|
+
"orders" => "customer_name,description",
|
46
|
+
)
|
47
|
+
assert_equal false, spec.all_fields?(:orders)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "is false if the type is assigned an empty list" do
|
51
|
+
spec = SimpleJsonapi::Parameters::FieldsSpec.new("orders" => "")
|
52
|
+
assert_equal false, spec.all_fields?(:orders)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|