propel_api 0.1.1
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/CHANGELOG.md +59 -0
- data/LICENSE +21 -0
- data/README.md +320 -0
- data/Rakefile +36 -0
- data/lib/generators/propel_api/USAGE +8 -0
- data/lib/generators/propel_api/controller/controller_generator.rb +208 -0
- data/lib/generators/propel_api/core/base.rb +19 -0
- data/lib/generators/propel_api/core/configuration_methods.rb +187 -0
- data/lib/generators/propel_api/core/named_base.rb +457 -0
- data/lib/generators/propel_api/core/path_generation_methods.rb +45 -0
- data/lib/generators/propel_api/core/relationship_inferrer.rb +117 -0
- data/lib/generators/propel_api/install/install_generator.rb +343 -0
- data/lib/generators/propel_api/resource/resource_generator.rb +433 -0
- data/lib/generators/propel_api/templates/config/propel_api.rb.tt +149 -0
- data/lib/generators/propel_api/templates/controllers/api_controller_graphiti.rb +79 -0
- data/lib/generators/propel_api/templates/controllers/api_controller_propel_facets.rb +76 -0
- data/lib/generators/propel_api/templates/controllers/example_controller.rb.tt +96 -0
- data/lib/generators/propel_api/templates/scaffold/facet_controller_template.rb.tt +80 -0
- data/lib/generators/propel_api/templates/scaffold/facet_model_template.rb.tt +141 -0
- data/lib/generators/propel_api/templates/scaffold/graphiti_controller_template.rb.tt +82 -0
- data/lib/generators/propel_api/templates/scaffold/graphiti_model_template.rb.tt +32 -0
- data/lib/generators/propel_api/templates/seeds/seeds_template.rb.tt +493 -0
- data/lib/generators/propel_api/templates/tests/controller_test_template.rb.tt +485 -0
- data/lib/generators/propel_api/templates/tests/fixtures_template.yml.tt +250 -0
- data/lib/generators/propel_api/templates/tests/integration_test_template.rb.tt +487 -0
- data/lib/generators/propel_api/templates/tests/model_test_template.rb.tt +252 -0
- data/lib/generators/propel_api/unpack/unpack_generator.rb +304 -0
- data/lib/propel_api.rb +3 -0
- metadata +95 -0
@@ -0,0 +1,485 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class <%= controller_class_name_with_namespace %>ControllerTest < ActionDispatch::IntegrationTest
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@organization = organizations(:one)
|
9
|
+
@user = users(:one)
|
10
|
+
@<%= singular_table_name %> = <%= table_name %>(:one)
|
11
|
+
@token = @user.generate_jwt_token
|
12
|
+
@auth_headers = { 'Authorization' => "Bearer #{@token}" }
|
13
|
+
|
14
|
+
# Ensure test <%= singular_table_name %> belongs to test user's organization
|
15
|
+
@<%= singular_table_name %>.update!(organization: @organization)
|
16
|
+
end
|
17
|
+
|
18
|
+
# === AUTHENTICATION TESTS ===
|
19
|
+
|
20
|
+
test "should not access index without authentication" do
|
21
|
+
get <%= api_route_helper %>_url
|
22
|
+
assert_response :unauthorized
|
23
|
+
|
24
|
+
response_body = JSON.parse(response.body)
|
25
|
+
assert_equal "No token provided", response_body["error"]
|
26
|
+
end
|
27
|
+
|
28
|
+
test "should not access index with invalid token" do
|
29
|
+
get <%= api_route_helper %>_url, headers: { 'Authorization' => 'Bearer invalid_token' }
|
30
|
+
assert_response :unauthorized
|
31
|
+
|
32
|
+
response_body = JSON.parse(response.body)
|
33
|
+
assert_equal "Invalid token", response_body["error"]
|
34
|
+
end
|
35
|
+
|
36
|
+
test "should not access show without authentication" do
|
37
|
+
get <%= api_route_helper %>_url(@<%= singular_table_name %>)
|
38
|
+
assert_response :unauthorized
|
39
|
+
end
|
40
|
+
|
41
|
+
test "should not create without authentication" do
|
42
|
+
assert_no_difference('<%= class_name %>.count') do
|
43
|
+
post <%= api_route_helper %>_url, params: { data: valid_<%= singular_table_name %>_params }
|
44
|
+
end
|
45
|
+
assert_response :unauthorized
|
46
|
+
end
|
47
|
+
|
48
|
+
test "should not update without authentication" do
|
49
|
+
patch <%= api_route_helper %>_url(@<%= singular_table_name %>), params: { data: { title: "Updated" } }
|
50
|
+
assert_response :unauthorized
|
51
|
+
end
|
52
|
+
|
53
|
+
test "should not destroy without authentication" do
|
54
|
+
assert_no_difference('<%= class_name %>.count') do
|
55
|
+
delete <%= api_route_helper %>_url(@<%= singular_table_name %>)
|
56
|
+
end
|
57
|
+
assert_response :unauthorized
|
58
|
+
end
|
59
|
+
|
60
|
+
# === INDEX TESTS ===
|
61
|
+
|
62
|
+
test "should get index with authentication" do
|
63
|
+
get <%= api_route_helper %>_url, headers: @auth_headers
|
64
|
+
assert_response :success
|
65
|
+
|
66
|
+
response_body = JSON.parse(response.body)
|
67
|
+
assert_includes response_body.keys, 'data'
|
68
|
+
assert_includes response_body.keys, 'pagination'
|
69
|
+
|
70
|
+
# Should return array of <%= table_name %>
|
71
|
+
assert_kind_of Array, response_body['data']
|
72
|
+
end
|
73
|
+
|
74
|
+
test "should return paginated results" do
|
75
|
+
get <%= api_route_helper %>_url, headers: @auth_headers
|
76
|
+
assert_response :success
|
77
|
+
|
78
|
+
response_body = JSON.parse(response.body)
|
79
|
+
pagination = response_body['pagination']
|
80
|
+
|
81
|
+
# Should include pagination metadata
|
82
|
+
assert_includes pagination.keys, 'page'
|
83
|
+
assert_includes pagination.keys, 'items'
|
84
|
+
assert_includes pagination.keys, 'count'
|
85
|
+
assert_includes pagination.keys, 'pages'
|
86
|
+
assert_includes pagination.keys, 'last'
|
87
|
+
assert_includes pagination.keys, 'next'
|
88
|
+
assert_includes pagination.keys, 'prev'
|
89
|
+
end
|
90
|
+
|
91
|
+
test "should only show records for user's organization" do
|
92
|
+
# Create record for different organization
|
93
|
+
other_org = Organization.create!(name: "Other Organization")
|
94
|
+
other_<%= singular_table_name %> = <%= class_name %>.create!(
|
95
|
+
<% attributes.each_with_index do |attribute, index| -%>
|
96
|
+
<% if attribute.name == "organization" && attribute.type == :references -%>
|
97
|
+
<%= attribute.name %>: other_org<%= ',' if index < attributes.length - 1 %>
|
98
|
+
<% elsif attribute.name == "user" && attribute.type == :references -%>
|
99
|
+
<%= attribute.name %>: @user<%= ',' if index < attributes.length - 1 %>
|
100
|
+
<% elsif attribute.type == :references -%>
|
101
|
+
<%= attribute.name %>: @<%= attribute.name %><%= ',' if index < attributes.length - 1 %>
|
102
|
+
<% elsif attribute.type == :string -%>
|
103
|
+
<%= attribute.name %>: "Other Org <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
104
|
+
<% elsif attribute.type == :text -%>
|
105
|
+
<%= attribute.name %>: "Other org <%= attribute.name.humanize %> content"<%= ',' if index < attributes.length - 1 %>
|
106
|
+
<% elsif attribute.type == :integer -%>
|
107
|
+
<%= attribute.name %>: 999<%= ',' if index < attributes.length - 1 %>
|
108
|
+
<% elsif attribute.type == :boolean -%>
|
109
|
+
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
110
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
111
|
+
<%= attribute.name %>: 99.99<%= ',' if index < attributes.length - 1 %>
|
112
|
+
<% else -%>
|
113
|
+
<%= attribute.name %>: "other_value"<%= ',' if index < attributes.length - 1 %>
|
114
|
+
<% end -%>
|
115
|
+
<% end -%>
|
116
|
+
)
|
117
|
+
|
118
|
+
get <%= api_route_helper %>_url, headers: @auth_headers
|
119
|
+
assert_response :success
|
120
|
+
|
121
|
+
response_body = JSON.parse(response.body)
|
122
|
+
<%= table_name %>_ids = response_body['data'].map { |item| item['id'] }
|
123
|
+
|
124
|
+
# Should not include other organization's record
|
125
|
+
assert_not_includes <%= table_name %>_ids, other_<%= singular_table_name %>.id
|
126
|
+
|
127
|
+
# Should include own organization's record
|
128
|
+
assert_includes <%= table_name %>_ids, @<%= singular_table_name %>.id
|
129
|
+
end
|
130
|
+
|
131
|
+
# === SHOW TESTS ===
|
132
|
+
|
133
|
+
test "should show <%= singular_table_name %> with authentication" do
|
134
|
+
get <%= api_route_helper %>_url(@<%= singular_table_name %>), headers: @auth_headers
|
135
|
+
assert_response :success
|
136
|
+
|
137
|
+
response_body = JSON.parse(response.body)
|
138
|
+
assert_includes response_body.keys, 'data'
|
139
|
+
|
140
|
+
<%= singular_table_name %>_data = response_body['data']
|
141
|
+
assert_equal @<%= singular_table_name %>.id, <%= singular_table_name %>_data['id']
|
142
|
+
end
|
143
|
+
|
144
|
+
test "should return 404 for non-existent <%= singular_table_name %>" do
|
145
|
+
get <%= api_route_helper %>_url(0), headers: @auth_headers
|
146
|
+
assert_response :not_found
|
147
|
+
end
|
148
|
+
|
149
|
+
test "should not show <%= singular_table_name %> from different organization" do
|
150
|
+
other_org = Organization.create!(name: "Other Organization")
|
151
|
+
other_<%= singular_table_name %> = <%= class_name %>.create!(
|
152
|
+
<% attributes.each_with_index do |attribute, index| -%>
|
153
|
+
<% if attribute.name == "organization" && attribute.type == :references -%>
|
154
|
+
<%= attribute.name %>: other_org<%= ',' if index < attributes.length - 1 %>
|
155
|
+
<% elsif attribute.name == "user" && attribute.type == :references -%>
|
156
|
+
<%= attribute.name %>: @user<%= ',' if index < attributes.length - 1 %>
|
157
|
+
<% elsif attribute.type == :references -%>
|
158
|
+
<%= attribute.name %>: @<%= attribute.name %><%= ',' if index < attributes.length - 1 %>
|
159
|
+
<% elsif attribute.type == :string -%>
|
160
|
+
<%= attribute.name %>: "Other Org <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
161
|
+
<% elsif attribute.type == :text -%>
|
162
|
+
<%= attribute.name %>: "Other org <%= attribute.name.humanize %> content"<%= ',' if index < attributes.length - 1 %>
|
163
|
+
<% elsif attribute.type == :integer -%>
|
164
|
+
<%= attribute.name %>: 999<%= ',' if index < attributes.length - 1 %>
|
165
|
+
<% elsif attribute.type == :boolean -%>
|
166
|
+
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
167
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
168
|
+
<%= attribute.name %>: 99.99<%= ',' if index < attributes.length - 1 %>
|
169
|
+
<% else -%>
|
170
|
+
<%= attribute.name %>: "other_value"<%= ',' if index < attributes.length - 1 %>
|
171
|
+
<% end -%>
|
172
|
+
<% end -%>
|
173
|
+
)
|
174
|
+
|
175
|
+
get <%= api_route_helper %>_url(other_<%= singular_table_name %>), headers: @auth_headers
|
176
|
+
assert_response :not_found
|
177
|
+
end
|
178
|
+
|
179
|
+
# === CREATE TESTS ===
|
180
|
+
|
181
|
+
test "should create <%= singular_table_name %> with valid params" do
|
182
|
+
assert_difference('<%= class_name %>.count', 1) do
|
183
|
+
post <%= api_route_helper %>_url,
|
184
|
+
params: { data: valid_<%= singular_table_name %>_params },
|
185
|
+
headers: @auth_headers
|
186
|
+
end
|
187
|
+
|
188
|
+
assert_response :created
|
189
|
+
|
190
|
+
response_body = JSON.parse(response.body)
|
191
|
+
assert_includes response_body.keys, 'data'
|
192
|
+
|
193
|
+
created_<%= singular_table_name %> = response_body['data']
|
194
|
+
assert_equal @organization.id, created_<%= singular_table_name %>['organization']['id']
|
195
|
+
assert_equal @user.id, created_<%= singular_table_name %>['user']['id']
|
196
|
+
end
|
197
|
+
|
198
|
+
test "should not create <%= singular_table_name %> with invalid params" do
|
199
|
+
assert_no_difference('<%= class_name %>.count') do
|
200
|
+
post <%= api_route_helper %>_url,
|
201
|
+
params: { data: invalid_<%= singular_table_name %>_params },
|
202
|
+
headers: @auth_headers
|
203
|
+
end
|
204
|
+
|
205
|
+
assert_response :unprocessable_entity
|
206
|
+
|
207
|
+
response_body = JSON.parse(response.body)
|
208
|
+
assert_includes response_body.keys, 'errors'
|
209
|
+
end
|
210
|
+
|
211
|
+
test "should auto-assign organization and user on create" do
|
212
|
+
params = valid_<%= singular_table_name %>_params
|
213
|
+
params.delete(:organization_id) # Don't send organization_id
|
214
|
+
params.delete(:user_id) # Don't send user_id
|
215
|
+
|
216
|
+
assert_difference('<%= class_name %>.count', 1) do
|
217
|
+
post <%= api_route_helper %>_url,
|
218
|
+
params: { data: params },
|
219
|
+
headers: @auth_headers
|
220
|
+
end
|
221
|
+
|
222
|
+
assert_response :created
|
223
|
+
|
224
|
+
# Should automatically assign current user's organization and user
|
225
|
+
created_<%= singular_table_name %> = <%= class_name %>.last
|
226
|
+
assert_equal @organization.id, created_<%= singular_table_name %>.organization_id
|
227
|
+
assert_equal @user.id, created_<%= singular_table_name %>.user_id
|
228
|
+
end
|
229
|
+
|
230
|
+
# === UPDATE TESTS ===
|
231
|
+
|
232
|
+
test "should update <%= singular_table_name %> with valid params" do
|
233
|
+
<% if attributes.any? { |attr| attr.type == :string && attr.name != "organization" && attr.name != "user" } -%>
|
234
|
+
<% string_attr = attributes.find { |attr| attr.type == :string && attr.name != "organization" && attr.name != "user" } -%>
|
235
|
+
new_<%= string_attr.name %> = "Updated <%= string_attr.name.humanize %>"
|
236
|
+
|
237
|
+
patch <%= api_route_helper %>_url(@<%= singular_table_name %>),
|
238
|
+
params: { data: { <%= string_attr.name %>: new_<%= string_attr.name %> } },
|
239
|
+
headers: @auth_headers
|
240
|
+
|
241
|
+
assert_response :success
|
242
|
+
|
243
|
+
@<%= singular_table_name %>.reload
|
244
|
+
assert_equal new_<%= string_attr.name %>, @<%= singular_table_name %>.<%= string_attr.name %>
|
245
|
+
<% else -%>
|
246
|
+
# Update test for <%= singular_table_name %> - customize based on your model's attributes
|
247
|
+
patch <%= api_route_helper %>_url(@<%= singular_table_name %>),
|
248
|
+
params: { data: valid_<%= singular_table_name %>_params },
|
249
|
+
headers: @auth_headers
|
250
|
+
|
251
|
+
assert_response :success
|
252
|
+
<% end -%>
|
253
|
+
end
|
254
|
+
|
255
|
+
test "should not update <%= singular_table_name %> with invalid params" do
|
256
|
+
patch <%= api_route_helper %>_url(@<%= singular_table_name %>),
|
257
|
+
params: { data: invalid_<%= singular_table_name %>_params },
|
258
|
+
headers: @auth_headers
|
259
|
+
|
260
|
+
assert_response :unprocessable_entity
|
261
|
+
|
262
|
+
response_body = JSON.parse(response.body)
|
263
|
+
assert_includes response_body.keys, 'errors'
|
264
|
+
end
|
265
|
+
|
266
|
+
test "should not update <%= singular_table_name %> from different organization" do
|
267
|
+
other_org = Organization.create!(name: "Other Organization")
|
268
|
+
other_<%= singular_table_name %> = <%= class_name %>.create!(
|
269
|
+
<% attributes.each_with_index do |attribute, index| -%>
|
270
|
+
<% if attribute.name == "organization" && attribute.type == :references -%>
|
271
|
+
<%= attribute.name %>: other_org<%= ',' if index < attributes.length - 1 %>
|
272
|
+
<% elsif attribute.name == "user" && attribute.type == :references -%>
|
273
|
+
<%= attribute.name %>: @user<%= ',' if index < attributes.length - 1 %>
|
274
|
+
<% elsif attribute.type == :references -%>
|
275
|
+
<%= attribute.name %>: @<%= attribute.name %><%= ',' if index < attributes.length - 1 %>
|
276
|
+
<% elsif attribute.type == :string -%>
|
277
|
+
<%= attribute.name %>: "Other Org <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
278
|
+
<% elsif attribute.type == :text -%>
|
279
|
+
<%= attribute.name %>: "Other org <%= attribute.name.humanize %> content"<%= ',' if index < attributes.length - 1 %>
|
280
|
+
<% elsif attribute.type == :integer -%>
|
281
|
+
<%= attribute.name %>: 999<%= ',' if index < attributes.length - 1 %>
|
282
|
+
<% elsif attribute.type == :boolean -%>
|
283
|
+
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
284
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
285
|
+
<%= attribute.name %>: 99.99<%= ',' if index < attributes.length - 1 %>
|
286
|
+
<% else -%>
|
287
|
+
<%= attribute.name %>: "other_value"<%= ',' if index < attributes.length - 1 %>
|
288
|
+
<% end -%>
|
289
|
+
<% end -%>
|
290
|
+
)
|
291
|
+
|
292
|
+
patch <%= api_route_helper %>_url(other_<%= singular_table_name %>),
|
293
|
+
params: { data: valid_<%= singular_table_name %>_params },
|
294
|
+
headers: @auth_headers
|
295
|
+
|
296
|
+
assert_response :not_found
|
297
|
+
end
|
298
|
+
|
299
|
+
# === DESTROY TESTS ===
|
300
|
+
|
301
|
+
test "should destroy <%= singular_table_name %>" do
|
302
|
+
assert_difference('<%= class_name %>.count', -1) do
|
303
|
+
delete <%= api_route_helper %>_url(@<%= singular_table_name %>), headers: @auth_headers
|
304
|
+
end
|
305
|
+
|
306
|
+
assert_response :no_content
|
307
|
+
end
|
308
|
+
|
309
|
+
test "should not destroy <%= singular_table_name %> from different organization" do
|
310
|
+
other_org = Organization.create!(name: "Other Organization")
|
311
|
+
other_<%= singular_table_name %> = <%= class_name %>.create!(
|
312
|
+
<% attributes.each_with_index do |attribute, index| -%>
|
313
|
+
<% if attribute.name == "organization" && attribute.type == :references -%>
|
314
|
+
<%= attribute.name %>: other_org<%= ',' if index < attributes.length - 1 %>
|
315
|
+
<% elsif attribute.name == "user" && attribute.type == :references -%>
|
316
|
+
<%= attribute.name %>: @user<%= ',' if index < attributes.length - 1 %>
|
317
|
+
<% elsif attribute.type == :references -%>
|
318
|
+
<%= attribute.name %>: @<%= attribute.name %><%= ',' if index < attributes.length - 1 %>
|
319
|
+
<% elsif attribute.type == :string -%>
|
320
|
+
<%= attribute.name %>: "Other Org <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
321
|
+
<% elsif attribute.type == :text -%>
|
322
|
+
<%= attribute.name %>: "Other org <%= attribute.name.humanize %> content"<%= ',' if index < attributes.length - 1 %>
|
323
|
+
<% elsif attribute.type == :integer -%>
|
324
|
+
<%= attribute.name %>: 999<%= ',' if index < attributes.length - 1 %>
|
325
|
+
<% elsif attribute.type == :boolean -%>
|
326
|
+
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
327
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
328
|
+
<%= attribute.name %>: 99.99<%= ',' if index < attributes.length - 1 %>
|
329
|
+
<% else -%>
|
330
|
+
<%= attribute.name %>: "other_value"<%= ',' if index < attributes.length - 1 %>
|
331
|
+
<% end -%>
|
332
|
+
<% end -%>
|
333
|
+
)
|
334
|
+
|
335
|
+
assert_no_difference('<%= class_name %>.count') do
|
336
|
+
delete <%= api_route_helper %>_url(other_<%= singular_table_name %>), headers: @auth_headers
|
337
|
+
end
|
338
|
+
|
339
|
+
assert_response :not_found
|
340
|
+
end
|
341
|
+
|
342
|
+
# === PARAMETER HANDLING TESTS ===
|
343
|
+
|
344
|
+
test "should accept valid data structure" do
|
345
|
+
post <%= api_route_helper %>_url,
|
346
|
+
params: { data: valid_<%= singular_table_name %>_params },
|
347
|
+
headers: @auth_headers
|
348
|
+
|
349
|
+
assert_response :created
|
350
|
+
end
|
351
|
+
|
352
|
+
test "should reject params without data wrapper" do
|
353
|
+
post <%= api_route_helper %>_url,
|
354
|
+
params: valid_<%= singular_table_name %>_params, # No data wrapper
|
355
|
+
headers: @auth_headers
|
356
|
+
|
357
|
+
assert_response :unprocessable_entity
|
358
|
+
end
|
359
|
+
|
360
|
+
test "should filter permitted params only" do
|
361
|
+
params_with_extra = valid_<%= singular_table_name %>_params.merge(
|
362
|
+
forbidden_field: "should_be_ignored",
|
363
|
+
admin_only_field: true
|
364
|
+
)
|
365
|
+
|
366
|
+
post <%= api_route_helper %>_url,
|
367
|
+
params: { data: params_with_extra },
|
368
|
+
headers: @auth_headers
|
369
|
+
|
370
|
+
# Should create successfully but ignore forbidden fields
|
371
|
+
assert_response :created
|
372
|
+
|
373
|
+
created_<%= singular_table_name %> = <%= class_name %>.last
|
374
|
+
assert_not created_<%= singular_table_name %>.respond_to?(:forbidden_field)
|
375
|
+
end
|
376
|
+
|
377
|
+
# === JSON FACET RESPONSE TESTS ===
|
378
|
+
|
379
|
+
test "index should return short facet data" do
|
380
|
+
get <%= api_route_helper %>_url, headers: @auth_headers
|
381
|
+
assert_response :success
|
382
|
+
|
383
|
+
response_body = JSON.parse(response.body)
|
384
|
+
first_item = response_body['data'].first
|
385
|
+
|
386
|
+
# Should include ID and short facet fields
|
387
|
+
assert_includes first_item.keys, 'id'
|
388
|
+
<%
|
389
|
+
short_attributes = attributes.select do |attr|
|
390
|
+
identifying_fields = %w[name title label slug username email status state active published visible enabled]
|
391
|
+
simple_types = [:string, :integer, :boolean, :decimal, :float]
|
392
|
+
excluded_patterns = /\A(description|content|body|notes|comment|bio|about|summary|created_at|updated_at|deleted_at|password|digest|token|secret|key|salt|encrypted|confirmation|unlock|reset|api_key|access_token|refresh_token)\z/i
|
393
|
+
security_patterns = /(password|digest|token|secret|key|salt|encrypted|confirmation|unlock|reset|api_key)/i
|
394
|
+
|
395
|
+
identifying_fields.include?(attr.name.to_s) ||
|
396
|
+
(simple_types.include?(attr.type) &&
|
397
|
+
attr.name.to_s !~ excluded_patterns &&
|
398
|
+
attr.name.to_s !~ security_patterns &&
|
399
|
+
attr.name.to_s.length < 20)
|
400
|
+
end
|
401
|
+
short_attributes.each do |attribute| -%>
|
402
|
+
assert_includes first_item.keys, '<%= attribute.name %>'
|
403
|
+
<% end -%>
|
404
|
+
end
|
405
|
+
|
406
|
+
test "show should return details facet data" do
|
407
|
+
get <%= api_route_helper %>_url(@<%= singular_table_name %>), headers: @auth_headers
|
408
|
+
assert_response :success
|
409
|
+
|
410
|
+
response_body = JSON.parse(response.body)
|
411
|
+
<%= singular_table_name %>_data = response_body['data']
|
412
|
+
|
413
|
+
# Should include ID and details facet fields
|
414
|
+
assert_includes <%= singular_table_name %>_data.keys, 'id'
|
415
|
+
<%
|
416
|
+
detail_attributes = attributes.reject do |attr|
|
417
|
+
excluded_patterns = /\A(created_at|updated_at|deleted_at|password_digest|reset_password_token|confirmation_token|unlock_token)\z/i
|
418
|
+
security_patterns = /(password|digest|token|secret|key|salt|encrypted|confirmation|unlock|reset|api_key|access_token|refresh_token)/i
|
419
|
+
excluded_types = [:binary]
|
420
|
+
|
421
|
+
excluded_patterns.match?(attr.name.to_s) ||
|
422
|
+
security_patterns.match?(attr.name.to_s) ||
|
423
|
+
excluded_types.include?(attr.type)
|
424
|
+
end
|
425
|
+
detail_attributes.each do |attribute| -%>
|
426
|
+
assert_includes <%= singular_table_name %>_data.keys, '<%= attribute.name %>'
|
427
|
+
<% end -%>
|
428
|
+
end
|
429
|
+
|
430
|
+
private
|
431
|
+
|
432
|
+
def valid_<%= singular_table_name %>_params
|
433
|
+
{
|
434
|
+
<% attributes.each_with_index do |attribute, index| -%>
|
435
|
+
<% if attribute.type == :references -%>
|
436
|
+
<%= attribute.name %>_id: @<%= attribute.name %>.id<%= ',' if index < attributes.length - 1 %>
|
437
|
+
<% elsif attribute.type == :string -%>
|
438
|
+
<%= attribute.name %>: "Test <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
439
|
+
<% elsif attribute.type == :text -%>
|
440
|
+
<%= attribute.name %>: "Test <%= attribute.name.humanize %> content"<%= ',' if index < attributes.length - 1 %>
|
441
|
+
<% elsif attribute.type == :integer -%>
|
442
|
+
<%= attribute.name %>: 42<%= ',' if index < attributes.length - 1 %>
|
443
|
+
<% elsif attribute.type == :boolean -%>
|
444
|
+
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
445
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
446
|
+
<%= attribute.name %>: 123.45<%= ',' if index < attributes.length - 1 %>
|
447
|
+
<% else -%>
|
448
|
+
<%= attribute.name %>: "test_value"<%= ',' if index < attributes.length - 1 %>
|
449
|
+
<% end -%>
|
450
|
+
<% end -%>
|
451
|
+
}
|
452
|
+
end
|
453
|
+
|
454
|
+
def invalid_<%= singular_table_name %>_params
|
455
|
+
{
|
456
|
+
<% attributes.each_with_index do |attribute, index| -%>
|
457
|
+
<% if attribute.required? -%>
|
458
|
+
<% if attribute.type == :references -%>
|
459
|
+
<%= attribute.name %>_id: nil<%= ',' if index < attributes.length - 1 %>
|
460
|
+
<% elsif attribute.type == :string -%>
|
461
|
+
<%= attribute.name %>: nil<%= ',' if index < attributes.length - 1 %>
|
462
|
+
<% elsif attribute.type == :text -%>
|
463
|
+
<%= attribute.name %>: nil<%= ',' if index < attributes.length - 1 %>
|
464
|
+
<% elsif attribute.type == :integer -%>
|
465
|
+
<%= attribute.name %>: "not_a_number"<%= ',' if index < attributes.length - 1 %>
|
466
|
+
<% elsif attribute.type == :boolean -%>
|
467
|
+
<%= attribute.name %>: nil<%= ',' if index < attributes.length - 1 %>
|
468
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
469
|
+
<%= attribute.name %>: "not_a_number"<%= ',' if index < attributes.length - 1 %>
|
470
|
+
<% else -%>
|
471
|
+
<%= attribute.name %>: nil<%= ',' if index < attributes.length - 1 %>
|
472
|
+
<% end -%>
|
473
|
+
<% else -%>
|
474
|
+
<% if attribute.type == :integer -%>
|
475
|
+
<%= attribute.name %>: "not_a_number"<%= ',' if index < attributes.length - 1 %>
|
476
|
+
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
477
|
+
<%= attribute.name %>: "not_a_number"<%= ',' if index < attributes.length - 1 %>
|
478
|
+
<% else -%>
|
479
|
+
<%= attribute.name %>: ""<%= ',' if index < attributes.length - 1 %>
|
480
|
+
<% end -%>
|
481
|
+
<% end -%>
|
482
|
+
<% end -%>
|
483
|
+
}
|
484
|
+
end
|
485
|
+
end
|