propel_api 0.2.1 → 0.3.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 +4 -4
- data/CHANGELOG.md +97 -0
- data/README.md +239 -4
- data/lib/generators/propel_api/controller/controller_generator.rb +26 -0
- data/lib/generators/propel_api/core/named_base.rb +97 -1
- data/lib/generators/propel_api/core/relationship_inferrer.rb +4 -11
- data/lib/generators/propel_api/install/install_generator.rb +39 -2
- data/lib/generators/propel_api/resource/resource_generator.rb +205 -63
- data/lib/generators/propel_api/templates/config/propel_api.rb.tt +26 -1
- data/lib/generators/propel_api/templates/controllers/api_base_controller.rb +75 -0
- data/lib/generators/propel_api/templates/controllers/api_controller_graphiti.rb +3 -3
- data/lib/generators/propel_api/templates/controllers/api_controller_propel_facets.rb +22 -12
- data/lib/generators/propel_api/templates/controllers/example_controller.rb.tt +2 -2
- data/lib/generators/propel_api/templates/errors/propel_api_csrf_error.rb +19 -0
- data/lib/generators/propel_api/templates/scaffold/facet_controller_template.rb.tt +41 -8
- data/lib/generators/propel_api/templates/scaffold/facet_model_template.rb.tt +43 -10
- data/lib/generators/propel_api/templates/scaffold/graphiti_controller_template.rb.tt +1 -1
- data/lib/generators/propel_api/templates/scaffold/graphiti_resource_template.rb.tt +2 -2
- data/lib/generators/propel_api/templates/seeds/seeds_template.rb.tt +65 -17
- data/lib/generators/propel_api/templates/tests/controller_test_template.rb.tt +40 -6
- data/lib/generators/propel_api/templates/tests/fixtures_template.yml.tt +61 -18
- data/lib/generators/propel_api/templates/tests/integration_test_template.rb.tt +154 -42
- data/lib/generators/propel_api/templates/tests/model_test_template.rb.tt +20 -0
- data/lib/propel_api.rb +1 -1
- metadata +24 -2
@@ -1,8 +1,29 @@
|
|
1
1
|
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
2
2
|
|
3
3
|
one:
|
4
|
+
<% # Handle polymorphic associations first -%>
|
5
|
+
<% polymorphic_associations.each do |poly_assoc| -%>
|
6
|
+
<% parent_info = polymorphic_parent_for_fixture(poly_assoc[:field_name], 0) -%>
|
7
|
+
<%= poly_assoc[:field_name] %>: <%= parent_info[:fixture_name] %> (<%= parent_info[:parent_type] %>)
|
8
|
+
<% end -%>
|
9
|
+
<% # Handle regular references (excluding polymorphic ones) -%>
|
10
|
+
<% polymorphic_field_names = polymorphic_associations.map { |assoc| assoc[:field_name].to_s } -%>
|
4
11
|
<% attributes.each do |attribute| -%>
|
5
|
-
<%
|
12
|
+
<% # Skip polymorphic references - check both Rails detection and our field names -%>
|
13
|
+
<% is_polymorphic = (attribute.respond_to?(:polymorphic?) && attribute.polymorphic?) || polymorphic_field_names.include?(attribute.name.to_s) -%>
|
14
|
+
<% if attribute.type == :references && !is_polymorphic -%>
|
15
|
+
<% if attribute.name == 'organization' -%>
|
16
|
+
<%= attribute.name %>: acme_org
|
17
|
+
<% elsif attribute.name == 'user' -%>
|
18
|
+
<%= attribute.name %>: john_user
|
19
|
+
<% elsif attribute.name == 'agency' -%>
|
20
|
+
<%= attribute.name %>: marketing_agency
|
21
|
+
<% else -%>
|
22
|
+
<%= attribute.name %>: one
|
23
|
+
<% end -%>
|
24
|
+
<% elsif attribute.type == :references && is_polymorphic -%>
|
25
|
+
<% # Polymorphic references are handled above, skip them here -%>
|
26
|
+
<% elsif attribute.type == :string -%>
|
6
27
|
<% if attribute.name == 'organization' -%>
|
7
28
|
<%= attribute.name %>: acme_org
|
8
29
|
<% elsif attribute.name == 'user' -%>
|
@@ -19,7 +40,7 @@ one:
|
|
19
40
|
<%= attribute.name %>: test_user_1
|
20
41
|
<% elsif attribute.name.to_s.match?(/\A(phone|phone_number)\z/i) -%>
|
21
42
|
<%= attribute.name %>: "+1-555-0001"
|
22
|
-
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address)\z/i) -%>
|
43
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
23
44
|
<%= attribute.name %>: "https://example1.com"
|
24
45
|
<% elsif attribute.name.to_s.match?(/\A(name|title|label)\z/i) -%>
|
25
46
|
<%= attribute.name %>: "Test <%= attribute.name.humanize %> One"
|
@@ -80,11 +101,11 @@ one:
|
|
80
101
|
<%= attribute.name %>: "2024-06-15 10:30:00"
|
81
102
|
<% elsif attribute.type == :time -%>
|
82
103
|
<%= attribute.name %>: "10:30:00"
|
83
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
84
|
-
<% if attribute.name == '
|
85
|
-
<%= attribute.name %>: {
|
104
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
105
|
+
<% if attribute.name == 'metadata' -%>
|
106
|
+
<%= attribute.name %>: { resource_type: "<%= singular_table_name %>", category: "test", tags: ["fixture", "one"], attributes: { priority: "high", status_info: { verified: true, active: true } } }
|
86
107
|
<% elsif attribute.name == 'settings' -%>
|
87
|
-
<%= attribute.name %>: {
|
108
|
+
<%= attribute.name %>: { ui_preferences: { theme: "light", language: "en", notifications: { email: true, sms: false, push: true } }, feature_flags: { beta_features: false, analytics: true } }
|
88
109
|
<% else -%>
|
89
110
|
<%= attribute.name %>: { test_data: "fixture_one" }
|
90
111
|
<% end -%>
|
@@ -94,8 +115,17 @@ one:
|
|
94
115
|
<% end -%>
|
95
116
|
|
96
117
|
two:
|
118
|
+
<% # Handle polymorphic associations first -%>
|
119
|
+
<% polymorphic_associations.each do |poly_assoc| -%>
|
120
|
+
<% parent_info = polymorphic_parent_for_fixture(poly_assoc[:field_name], 1) -%>
|
121
|
+
<%= poly_assoc[:field_name] %>: <%= parent_info[:fixture_name] %> (<%= parent_info[:parent_type] %>)
|
122
|
+
<% end -%>
|
123
|
+
<% # Handle regular references (excluding polymorphic ones) -%>
|
124
|
+
<% polymorphic_field_names = polymorphic_associations.map { |assoc| assoc[:field_name].to_s } -%>
|
97
125
|
<% attributes.each do |attribute| -%>
|
98
|
-
<%
|
126
|
+
<% # Skip polymorphic references - check both Rails detection and our field names -%>
|
127
|
+
<% is_polymorphic = (attribute.respond_to?(:polymorphic?) && attribute.polymorphic?) || polymorphic_field_names.include?(attribute.name.to_s) -%>
|
128
|
+
<% if attribute.type == :references && !is_polymorphic -%>
|
99
129
|
<% if attribute.name == 'organization' -%>
|
100
130
|
<%= attribute.name %>: tech_startup
|
101
131
|
<% elsif attribute.name == 'user' -%>
|
@@ -105,6 +135,8 @@ two:
|
|
105
135
|
<% else -%>
|
106
136
|
<%= attribute.name %>: one
|
107
137
|
<% end -%>
|
138
|
+
<% elsif attribute.type == :references && is_polymorphic -%>
|
139
|
+
<% # Polymorphic references are handled above, skip them here -%>
|
108
140
|
<% elsif attribute.type == :string -%>
|
109
141
|
<% if attribute.name.to_s.match?(/\A(email|email_address)\z/i) -%>
|
110
142
|
<%= attribute.name %>: test2@example.com
|
@@ -112,7 +144,7 @@ two:
|
|
112
144
|
<%= attribute.name %>: test_user_2
|
113
145
|
<% elsif attribute.name.to_s.match?(/\A(phone|phone_number)\z/i) -%>
|
114
146
|
<%= attribute.name %>: "+1-555-0002"
|
115
|
-
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address)\z/i) -%>
|
147
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
116
148
|
<%= attribute.name %>: "https://example2.com"
|
117
149
|
<% elsif attribute.name.to_s.match?(/\A(name|title|label)\z/i) -%>
|
118
150
|
<%= attribute.name %>: "Test <%= attribute.name.humanize %> Two"
|
@@ -173,11 +205,11 @@ two:
|
|
173
205
|
<%= attribute.name %>: "2023-12-25 15:45:00"
|
174
206
|
<% elsif attribute.type == :time -%>
|
175
207
|
<%= attribute.name %>: "15:45:00"
|
176
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
177
|
-
<% if attribute.name == '
|
178
|
-
<%= attribute.name %>: {
|
208
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
209
|
+
<% if attribute.name == 'metadata' -%>
|
210
|
+
<%= attribute.name %>: { resource_type: "<%= singular_table_name %>", category: "premium", tags: ["fixture", "two"], attributes: { priority: "medium", status_info: { verified: false, active: true } } }
|
179
211
|
<% elsif attribute.name == 'settings' -%>
|
180
|
-
<%= attribute.name %>: {
|
212
|
+
<%= attribute.name %>: { ui_preferences: { theme: "dark", language: "fr", notifications: { email: true, sms: true, push: false } }, feature_flags: { beta_features: true, analytics: false } }
|
181
213
|
<% else -%>
|
182
214
|
<%= attribute.name %>: { test_data: "fixture_two" }
|
183
215
|
<% end -%>
|
@@ -187,8 +219,17 @@ two:
|
|
187
219
|
<% end -%>
|
188
220
|
|
189
221
|
three:
|
222
|
+
<% # Handle polymorphic associations first -%>
|
223
|
+
<% polymorphic_associations.each do |poly_assoc| -%>
|
224
|
+
<% parent_info = polymorphic_parent_for_fixture(poly_assoc[:field_name], 2) -%>
|
225
|
+
<%= poly_assoc[:field_name] %>: <%= parent_info[:fixture_name] %> (<%= parent_info[:parent_type] %>)
|
226
|
+
<% end -%>
|
227
|
+
<% # Handle regular references (excluding polymorphic ones) -%>
|
228
|
+
<% polymorphic_field_names = polymorphic_associations.map { |assoc| assoc[:field_name].to_s } -%>
|
190
229
|
<% attributes.each do |attribute| -%>
|
191
|
-
<%
|
230
|
+
<% # Skip polymorphic references - check both Rails detection and our field names -%>
|
231
|
+
<% is_polymorphic = (attribute.respond_to?(:polymorphic?) && attribute.polymorphic?) || polymorphic_field_names.include?(attribute.name.to_s) -%>
|
232
|
+
<% if attribute.type == :references && !is_polymorphic -%>
|
192
233
|
<% if attribute.name == 'organization' -%>
|
193
234
|
<%= attribute.name %>: acme_org
|
194
235
|
<% elsif attribute.name == 'user' -%>
|
@@ -198,6 +239,8 @@ three:
|
|
198
239
|
<% else -%>
|
199
240
|
<%= attribute.name %>: one
|
200
241
|
<% end -%>
|
242
|
+
<% elsif attribute.type == :references && is_polymorphic -%>
|
243
|
+
<% # Polymorphic references are handled above, skip them here -%>
|
201
244
|
<% elsif attribute.type == :string -%>
|
202
245
|
<% if attribute.name.to_s.match?(/\A(email|email_address)\z/i) -%>
|
203
246
|
<%= attribute.name %>: test3@example.com
|
@@ -205,7 +248,7 @@ three:
|
|
205
248
|
<%= attribute.name %>: test_user_3
|
206
249
|
<% elsif attribute.name.to_s.match?(/\A(phone|phone_number)\z/i) -%>
|
207
250
|
<%= attribute.name %>: "+1-555-0003"
|
208
|
-
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address)\z/i) -%>
|
251
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
209
252
|
<%= attribute.name %>: "https://example3.com"
|
210
253
|
<% elsif attribute.name.to_s.match?(/\A(name|title|label)\z/i) -%>
|
211
254
|
<%= attribute.name %>: "Test <%= attribute.name.humanize %> Three"
|
@@ -266,11 +309,11 @@ three:
|
|
266
309
|
<%= attribute.name %>: "2025-03-10 08:15:00"
|
267
310
|
<% elsif attribute.type == :time -%>
|
268
311
|
<%= attribute.name %>: "08:15:00"
|
269
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
270
|
-
<% if attribute.name == '
|
271
|
-
<%= attribute.name %>: {
|
312
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
313
|
+
<% if attribute.name == 'metadata' -%>
|
314
|
+
<%= attribute.name %>: { resource_type: "<%= singular_table_name %>", category: "basic", tags: ["fixture", "three"], attributes: { priority: "low", status_info: { verified: true, active: false } } }
|
272
315
|
<% elsif attribute.name == 'settings' -%>
|
273
|
-
<%= attribute.name %>: {
|
316
|
+
<%= attribute.name %>: { ui_preferences: { theme: "auto", language: "es", notifications: { email: false, sms: true, push: true } }, feature_flags: { beta_features: false, analytics: true } }
|
274
317
|
<% else -%>
|
275
318
|
<%= attribute.name %>: { test_data: "fixture_three" }
|
276
319
|
<% end -%>
|
@@ -2,12 +2,28 @@
|
|
2
2
|
|
3
3
|
require "test_helper"
|
4
4
|
|
5
|
+
<%
|
6
|
+
# Check attributes directly instead of database columns (more reliable during generation)
|
7
|
+
has_agency_id = attributes.any? { |attr| attr.name == 'agency' && attr.type == :references }
|
8
|
+
has_user_id = attributes.any? { |attr| attr.name == 'user' && attr.type == :references }
|
9
|
+
-%>
|
10
|
+
|
5
11
|
class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
6
12
|
|
7
13
|
def setup
|
8
14
|
@organization = organizations(:acme_org)
|
9
15
|
@user = users(:john_user)
|
10
16
|
@agency = agencies(:marketing_agency)
|
17
|
+
<% polymorphic_associations.each do |assoc| -%>
|
18
|
+
<% assoc[:parent_types].each_with_index do |parent_type, index| -%>
|
19
|
+
<% if index == 0 -%>
|
20
|
+
@<%= parent_type.underscore %> = <%= parent_type.underscore.pluralize %>(<%= case parent_type.underscore; when 'agency'; ':marketing_agency'; when 'user'; ':john_user'; when 'organization'; ':acme_org'; else; ':one'; end %>)
|
21
|
+
@<%= assoc[:field_name] %> = @<%= parent_type.underscore %> # Default polymorphic parent for tests
|
22
|
+
<% else -%>
|
23
|
+
@<%= parent_type.underscore %> = <%= parent_type.underscore.pluralize %>(<%= case parent_type.underscore; when 'agency'; ':marketing_agency'; when 'user'; ':john_user'; when 'organization'; ':acme_org'; else; ':one'; end %>)
|
24
|
+
<% end -%>
|
25
|
+
<% end -%>
|
26
|
+
<% end -%>
|
11
27
|
<% if singular_table_name == 'organization' -%>
|
12
28
|
@<%= singular_table_name %> = <%= table_name %>(:acme_org)
|
13
29
|
<% elsif singular_table_name == 'user' -%>
|
@@ -16,12 +32,27 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
16
32
|
@<%= singular_table_name %> = <%= table_name %>(:marketing_agency)
|
17
33
|
<% else -%>
|
18
34
|
@<%= singular_table_name %> = <%= table_name %>(:one)
|
35
|
+
<% end -%>
|
36
|
+
<% if has_user_reference? -%>
|
37
|
+
@user = users(:john_user)
|
38
|
+
<% end -%>
|
39
|
+
<% # Set up polymorphic associations using --parents specification -%>
|
40
|
+
<% polymorphic_associations.each do |assoc| -%>
|
41
|
+
<% if assoc[:parent_types] && assoc[:parent_types].any? -%>
|
42
|
+
<% first_parent = assoc[:parent_types].first -%>
|
43
|
+
# Set up polymorphic association for <%= assoc[:field_name] %> using specified parents
|
44
|
+
@<%= first_parent.underscore %> = <%= first_parent.underscore.pluralize %>(<%= case first_parent.underscore; when 'agency'; ':marketing_agency'; when 'user'; ':john_user'; when 'organization'; ':acme_org'; else; ':one'; end %>)
|
45
|
+
@<%= assoc[:field_name] %> = @<%= first_parent.underscore %> # Use first specified parent type
|
46
|
+
<% assoc[:parent_types][1..-1].each do |parent_type| -%>
|
47
|
+
@<%= parent_type.underscore %> = <%= parent_type.underscore.pluralize %>(<%= case parent_type.underscore; when 'agency'; ':marketing_agency'; when 'user'; ':john_user'; when 'organization'; ':acme_org'; else; ':one'; end %>)
|
48
|
+
<% end -%>
|
49
|
+
<% end -%>
|
19
50
|
<% end -%>
|
20
51
|
@token = @user.generate_jwt_token
|
21
52
|
@auth_headers = { 'Authorization' => "Bearer #{@token}" }
|
22
53
|
|
23
54
|
# Ensure test <%= singular_table_name %> belongs to test user's organization
|
24
|
-
<%
|
55
|
+
<% if has_organization_reference? -%>
|
25
56
|
@<%= singular_table_name %>.update!(organization: @organization)
|
26
57
|
<% end -%>
|
27
58
|
end
|
@@ -45,12 +76,21 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
45
76
|
|
46
77
|
<% attributes.each_with_index do |attribute, index| -%>
|
47
78
|
<% if attribute.type == :references -%>
|
79
|
+
<% if attribute.respond_to?(:polymorphic?) && attribute.polymorphic? -%>
|
80
|
+
<%= attribute.name %>_id: @<%= attribute.name %>.id,
|
81
|
+
<%= attribute.name %>_type: @<%= attribute.name %>.class.name<%= ',' if index < attributes.length - 1 %>
|
82
|
+
<% else -%>
|
48
83
|
<%= attribute.name %>_id: @<%= attribute.name %>.id<%= ',' if index < attributes.length - 1 %>
|
84
|
+
<% end -%>
|
49
85
|
<% elsif attribute.type == :string && !reference_names.include?(attribute.name) -%>
|
50
86
|
<% if attribute.name.to_s.match?(/email/) -%>
|
51
87
|
<%= attribute.name %>: "workflow@example.com"<%= ',' if index < attributes.length - 1 %>
|
52
88
|
<% elsif attribute.name.to_s.match?(/password/) -%>
|
53
89
|
<%= attribute.name %>: "password123"<%= ',' if index < attributes.length - 1 %>
|
90
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
91
|
+
<%= attribute.name %>: "https://workflow.example.com"<%= ',' if index < attributes.length - 1 %>
|
92
|
+
<% elsif attribute.name.to_s.end_with?('_type') -%>
|
93
|
+
<%= attribute.name %>: @<%= attribute.name.gsub('_type', '') %>.class.name<%= ',' if index < attributes.length - 1 %>
|
54
94
|
<% else -%>
|
55
95
|
<%= attribute.name %>: "Workflow Test <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
56
96
|
<% end -%>
|
@@ -64,11 +104,18 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
64
104
|
<%= attribute.name %>: 100.50<%= ',' if index < attributes.length - 1 %>
|
65
105
|
<% elsif attribute.type == :datetime -%>
|
66
106
|
<%= attribute.name %>: Time.current<%= ',' if index < attributes.length - 1 %>
|
67
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
68
|
-
<% if attribute.name == '
|
69
|
-
<%= attribute.name %>: {
|
107
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
108
|
+
<% if attribute.name == 'metadata' -%>
|
109
|
+
<%= attribute.name %>: { resource_type: "<%= singular_table_name %>", category: "test", tags: ["integration", "auto_generated"], attributes: { priority: "medium", status_info: { verified: true, active: true } } }<%= ',' if index < attributes.length - 1 %>
|
70
110
|
<% elsif attribute.name == 'settings' -%>
|
71
|
-
<%= attribute.name %>: {
|
111
|
+
<%= attribute.name %>: {
|
112
|
+
ui_preferences: {
|
113
|
+
theme: "dark",
|
114
|
+
language: "en",
|
115
|
+
notifications: { email: true, sms: false, push: true }
|
116
|
+
},
|
117
|
+
feature_flags: { beta_features: false, analytics: true }
|
118
|
+
}<%= ',' if index < attributes.length - 1 %>
|
72
119
|
<% else -%>
|
73
120
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
74
121
|
<% end -%>
|
@@ -103,7 +150,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
103
150
|
|
104
151
|
# Verify created <%= singular_table_name %> data
|
105
152
|
assert_equal @organization.id, created_<%= singular_table_name %>['organization']['id']
|
106
|
-
<%
|
153
|
+
<% if has_user_id && singular_table_name != 'user' -%>
|
107
154
|
assert_equal @user.id, created_<%= singular_table_name %>['user']['id']
|
108
155
|
<% end -%>
|
109
156
|
<% attributes.each do |attribute| -%>
|
@@ -131,17 +178,28 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
131
178
|
if created_<%= singular_table_name %>['<%= attribute.name %>'].present?
|
132
179
|
assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/, created_<%= singular_table_name %>['<%= attribute.name %>'], "<%= attribute.name %> should be ISO timestamp format")
|
133
180
|
end
|
134
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
135
|
-
<% if attribute.name == '
|
136
|
-
#
|
137
|
-
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>'], "
|
138
|
-
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "
|
181
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
182
|
+
<% if attribute.name == 'metadata' -%>
|
183
|
+
# Metadata field should be a hash with generic structure
|
184
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>'], "Metadata should be a JSON object"
|
185
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "resource_type", "Metadata should contain resource_type"
|
186
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "category", "Metadata should contain category"
|
187
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "tags", "Metadata should contain tags array"
|
188
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "attributes", "Metadata should contain attributes object"
|
189
|
+
assert_kind_of Array, created_<%= singular_table_name %>['<%= attribute.name %>']['tags'], "Tags should be an array"
|
190
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>']['attributes'], "Attributes should be a hash"
|
191
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>']['attributes'].keys, "priority", "Attributes should contain priority"
|
192
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>']['attributes'].keys, "status_info", "Attributes should contain status_info"
|
139
193
|
<% elsif attribute.name == 'settings' -%>
|
140
|
-
# Settings field should be a hash with
|
194
|
+
# Settings field should be a hash with generic structure
|
141
195
|
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>'], "Settings should be a JSON object"
|
142
|
-
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "
|
143
|
-
|
144
|
-
|
196
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "ui_preferences", "Settings should contain ui_preferences"
|
197
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "feature_flags", "Settings should contain feature_flags"
|
198
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>']['ui_preferences'], "UI preferences should be a hash"
|
199
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>']['feature_flags'], "Feature flags should be a hash"
|
200
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>']['ui_preferences'].keys, "theme", "UI preferences should contain theme"
|
201
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>']['ui_preferences'].keys, "notifications", "UI preferences should contain notifications"
|
202
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>']['ui_preferences']['notifications'], "Notifications should be a hash"
|
145
203
|
<% else -%>
|
146
204
|
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>'], "<%= attribute.name %> should be a JSON object"
|
147
205
|
<% end -%>
|
@@ -271,6 +329,10 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
271
329
|
<%= attribute.name %>: "pagination#{i}@example.com"<%= ',' if index < attributes.length - 1 %>
|
272
330
|
<% elsif attribute.name.include?('email') -%>
|
273
331
|
<%= attribute.name %>: "pagination#{i}@example.com"<%= ',' if index < attributes.length - 1 %>
|
332
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
333
|
+
<%= attribute.name %>: "https://pagination#{i}.example.com"<%= ',' if index < attributes.length - 1 %>
|
334
|
+
<% elsif attribute.name.to_s.end_with?('_type') -%>
|
335
|
+
<%= attribute.name %>: @<%= attribute.name.gsub('_type', '') %>.class.name<%= ',' if index < attributes.length - 1 %>
|
274
336
|
<% else -%>
|
275
337
|
<%= attribute.name %>: "Pagination Test <%= attribute.name.humanize %> #{i}"<%= ',' if index < attributes.length - 1 %>
|
276
338
|
<% end -%>
|
@@ -356,11 +418,6 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
356
418
|
# Test 4: Tenancy context behavior based on configuration
|
357
419
|
require_org_id = PropelAuthentication.configuration.require_organization_id
|
358
420
|
require_user_id = PropelAuthentication.configuration.require_user_id
|
359
|
-
<%
|
360
|
-
# Check attributes directly instead of database columns (more reliable during generation)
|
361
|
-
has_agency_id = attributes.any? { |attr| attr.name == 'agency' && attr.type == :references }
|
362
|
-
has_user_id = attributes.any? { |attr| attr.name == 'user' && attr.type == :references }
|
363
|
-
-%>
|
364
421
|
|
365
422
|
<% if has_agency_id -%>
|
366
423
|
# Model with agency - provide agency_id but test missing organization_id
|
@@ -368,7 +425,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
368
425
|
unique_id = "#{Time.current.to_i}_#{SecureRandom.hex(6)}"
|
369
426
|
test_params = { email_address: "tenancy_test_#{unique_id}@example.com", username: "tenancy_test_#{unique_id}", password: "password123", agency_id: @agency.id }
|
370
427
|
<% else -%>
|
371
|
-
test_params = { title: "Test <%= class_name %>", agency_id: @agency.id }
|
428
|
+
test_params = { title: "Test <%= class_name %>", agency_id: @agency.id<% polymorphic_associations.each do |assoc| -%>, <%= assoc[:field_name] %>_id: @<%= assoc[:field_name] %>.id, <%= assoc[:field_name] %>_type: @<%= assoc[:field_name] %>.class.name<% end -%> }
|
372
429
|
<% end -%>
|
373
430
|
<% else -%>
|
374
431
|
# Model without agency - test missing organization_id only
|
@@ -376,7 +433,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
376
433
|
unique_id = "#{Time.current.to_i}_#{SecureRandom.hex(6)}"
|
377
434
|
test_params = { email_address: "tenancy_test_#{unique_id}@example.com", username: "tenancy_test_#{unique_id}", password: "password123" }
|
378
435
|
<% else -%>
|
379
|
-
test_params = { title: "Test <%= class_name %>" }
|
436
|
+
test_params = { title: "Test <%= class_name %>"<% polymorphic_associations.each do |assoc| -%>, <%= assoc[:field_name] %>_id: @<%= assoc[:field_name] %>.id, <%= assoc[:field_name] %>_type: @<%= assoc[:field_name] %>.class.name<% end -%> }
|
380
437
|
<% end -%>
|
381
438
|
<% end -%>
|
382
439
|
|
@@ -386,7 +443,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
386
443
|
|
387
444
|
if require_org_id<% if has_agency_id %> || false<% end -%> # Agency models test organization_id behavior
|
388
445
|
# Strict mode: Should return 422 when tenancy context is required but missing
|
389
|
-
assert_response :
|
446
|
+
assert_response :unprocessable_content
|
390
447
|
|
391
448
|
error_response = JSON.parse(response.body)
|
392
449
|
assert_includes error_response.keys, 'errors'
|
@@ -446,7 +503,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
446
503
|
headers: @auth_headers
|
447
504
|
<% else -%>
|
448
505
|
post <%= api_route_helper %>_url,
|
449
|
-
params: { data: { organization_id: @organization.id, agency_id: 99999, title: "Test <%= class_name %>" } },
|
506
|
+
params: { data: { organization_id: @organization.id, agency_id: 99999, title: "Test <%= class_name %>"<% polymorphic_associations.each do |assoc| -%>, <%= assoc[:field_name] %>_id: @<%= assoc[:field_name] %>.id, <%= assoc[:field_name] %>_type: @<%= assoc[:field_name] %>.class.name<% end -%> } },
|
450
507
|
headers: @auth_headers
|
451
508
|
<% end -%>
|
452
509
|
|
@@ -465,7 +522,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
465
522
|
headers: @auth_headers
|
466
523
|
<% else -%>
|
467
524
|
post <%= api_route_helper %>_url,
|
468
|
-
params: { data: { organization_id: 99999, title: "Test <%= class_name %>" } },
|
525
|
+
params: { data: { organization_id: 99999, title: "Test <%= class_name %>"<% polymorphic_associations.each do |assoc| -%>, <%= assoc[:field_name] %>_id: @<%= assoc[:field_name] %>.id, <%= assoc[:field_name] %>_type: @<%= assoc[:field_name] %>.class.name<% end -%> } },
|
469
526
|
headers: @auth_headers
|
470
527
|
<% end -%>
|
471
528
|
|
@@ -540,6 +597,10 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
540
597
|
<%= attribute.name %>: "org1_<%= attribute.name %>@example.com"<%= ',' if index < attributes.length - 1 %>
|
541
598
|
<% elsif attribute.name.include?('password') -%>
|
542
599
|
<%= attribute.name %>: "org1_secure_password"<%= ',' if index < attributes.length - 1 %>
|
600
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
601
|
+
<%= attribute.name %>: "https://org1.example.com"<%= ',' if index < attributes.length - 1 %>
|
602
|
+
<% elsif attribute.name.to_s.end_with?('_type') -%>
|
603
|
+
<%= attribute.name %>: @<%= attribute.name.gsub('_type', '') %>.class.name<%= ',' if index < attributes.length - 1 %>
|
543
604
|
<% else -%>
|
544
605
|
<%= attribute.name %>: "Org 1 <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
545
606
|
<% end -%>
|
@@ -551,11 +612,19 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
551
612
|
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
552
613
|
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
553
614
|
<%= attribute.name %>: 11.1<%= ',' if index < attributes.length - 1 %>
|
554
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
555
|
-
<% if attribute.name == '
|
556
|
-
<%= attribute.name %>: {
|
615
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
616
|
+
<% if attribute.name == 'metadata' -%>
|
617
|
+
<%= attribute.name %>: {
|
618
|
+
resource_type: "<%= singular_table_name %>",
|
619
|
+
category: "employee",
|
620
|
+
tags: ["org1", "department_test"],
|
621
|
+
attributes: {
|
622
|
+
priority: "medium",
|
623
|
+
status_info: { verified: true, active: true }
|
624
|
+
}
|
625
|
+
}<%= ',' if index < attributes.length - 1 %>
|
557
626
|
<% elsif attribute.name == 'settings' -%>
|
558
|
-
<%= attribute.name %>: { dark_mode: false,
|
627
|
+
<%= attribute.name %>: { dark_mode: false, notifications: { email: true, sms: true } }<%= ',' if index < attributes.length - 1 %>
|
559
628
|
<% else -%>
|
560
629
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
561
630
|
<% end -%>
|
@@ -578,6 +647,10 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
578
647
|
<%= attribute.name %>: "org2_<%= attribute.name %>@example.com"<%= ',' if index < attributes.length - 1 %>
|
579
648
|
<% elsif attribute.name.include?('password') -%>
|
580
649
|
<%= attribute.name %>: "org2_secure_password"<%= ',' if index < attributes.length - 1 %>
|
650
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
651
|
+
<%= attribute.name %>: "https://org2.example.com"<%= ',' if index < attributes.length - 1 %>
|
652
|
+
<% elsif attribute.name.to_s.end_with?('_type') -%>
|
653
|
+
<%= attribute.name %>: @<%= attribute.name.gsub('_type', '') %>.class.name<%= ',' if index < attributes.length - 1 %>
|
581
654
|
<% else -%>
|
582
655
|
<%= attribute.name %>: "Org 2 <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
583
656
|
<% end -%>
|
@@ -589,11 +662,19 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
589
662
|
<%= attribute.name %>: false<%= ',' if index < attributes.length - 1 %>
|
590
663
|
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
591
664
|
<%= attribute.name %>: 22.2<%= ',' if index < attributes.length - 1 %>
|
592
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
593
|
-
<% if attribute.name == '
|
594
|
-
<%= attribute.name %>: {
|
665
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
666
|
+
<% if attribute.name == 'metadata' -%>
|
667
|
+
<%= attribute.name %>: {
|
668
|
+
resource_type: "<%= singular_table_name %>",
|
669
|
+
category: "manager",
|
670
|
+
tags: ["org2", "department_test"],
|
671
|
+
attributes: {
|
672
|
+
priority: "high",
|
673
|
+
status_info: { verified: true, active: true }
|
674
|
+
}
|
675
|
+
}<%= ',' if index < attributes.length - 1 %>
|
595
676
|
<% elsif attribute.name == 'settings' -%>
|
596
|
-
<%= attribute.name %>: { dark_mode: true,
|
677
|
+
<%= attribute.name %>: { dark_mode: true, notifications: { email: false, sms: true } }<%= ',' if index < attributes.length - 1 %>
|
597
678
|
<% else -%>
|
598
679
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
599
680
|
<% end -%>
|
@@ -667,7 +748,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
667
748
|
|
668
749
|
# Verify core fields are present
|
669
750
|
assert_includes <%= singular_table_name %>_data.keys, 'id'
|
670
|
-
<%
|
751
|
+
<% if has_organization_reference? -%>
|
671
752
|
assert_includes <%= singular_table_name %>_data.keys, 'organization'
|
672
753
|
|
673
754
|
# Verify associations are properly included
|
@@ -726,6 +807,10 @@ if attributes.any? { |attr| attr.type == :references && attr.name == 'user' } &&
|
|
726
807
|
<%= attribute.name %>: "concurrent@example.com"<%= ',' if index < attributes.length - 1 %>
|
727
808
|
<% elsif attribute.name.include?('email') -%>
|
728
809
|
<%= attribute.name %>: "concurrent@example.com"<%= ',' if index < attributes.length - 1 %>
|
810
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
811
|
+
<%= attribute.name %>: "https://concurrent.example.com"<%= ',' if index < attributes.length - 1 %>
|
812
|
+
<% elsif attribute.name.to_s.end_with?('_type') -%>
|
813
|
+
<%= attribute.name %>: @<%= attribute.name.gsub('_type', '') %>.class.name<%= ',' if index < attributes.length - 1 %>
|
729
814
|
<% else -%>
|
730
815
|
<%= attribute.name %>: "Concurrent Test <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
|
731
816
|
<% end -%>
|
@@ -737,11 +822,26 @@ if attributes.any? { |attr| attr.type == :references && attr.name == 'user' } &&
|
|
737
822
|
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
738
823
|
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
739
824
|
<%= attribute.name %>: 50.5<%= ',' if index < attributes.length - 1 %>
|
740
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
741
|
-
<% if attribute.name == '
|
742
|
-
<%= attribute.name %>: {
|
825
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
826
|
+
<% if attribute.name == 'metadata' -%>
|
827
|
+
<%= attribute.name %>: {
|
828
|
+
resource_type: "<%= singular_table_name %>",
|
829
|
+
category: "admin",
|
830
|
+
tags: ["concurrent", "test"],
|
831
|
+
attributes: {
|
832
|
+
priority: "high",
|
833
|
+
status_info: { verified: true, active: true }
|
834
|
+
}
|
835
|
+
}<%= ',' if index < attributes.length - 1 %>
|
743
836
|
<% elsif attribute.name == 'settings' -%>
|
744
|
-
<%= attribute.name %>: {
|
837
|
+
<%= attribute.name %>: {
|
838
|
+
ui_preferences: {
|
839
|
+
theme: "dark",
|
840
|
+
language: "en",
|
841
|
+
notifications: { email: true, sms: false, push: true }
|
842
|
+
},
|
843
|
+
feature_flags: { beta_features: false, analytics: true }
|
844
|
+
}<%= ',' if index < attributes.length - 1 %>
|
745
845
|
<% else -%>
|
746
846
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
747
847
|
<% end -%>
|
@@ -826,6 +926,10 @@ if attributes.any? { |attr| attr.type == :references && attr.name == 'user' } &&
|
|
826
926
|
<%= attribute.name %>: "bulk#{i}@example.com"<%= ',' if index < attributes.length - 1 %>
|
827
927
|
<% elsif attribute.name.include?('email') -%>
|
828
928
|
<%= attribute.name %>: "bulk#{i}@example.com"<%= ',' if index < attributes.length - 1 %>
|
929
|
+
<% elsif attribute.name.to_s.match?(/\A(url|website|web_address|domain|domain_name)\z/i) -%>
|
930
|
+
<%= attribute.name %>: "https://bulk#{i}.example.com"<%= ',' if index < attributes.length - 1 %>
|
931
|
+
<% elsif attribute.name.to_s.end_with?('_type') -%>
|
932
|
+
<%= attribute.name %>: @<%= attribute.name.gsub('_type', '') %>.class.name<%= ',' if index < attributes.length - 1 %>
|
829
933
|
<% else -%>
|
830
934
|
<%= attribute.name %>: "Bulk Test <%= attribute.name.humanize %> #{i}"<%= ',' if index < attributes.length - 1 %>
|
831
935
|
<% end -%>
|
@@ -837,11 +941,19 @@ if attributes.any? { |attr| attr.type == :references && attr.name == 'user' } &&
|
|
837
941
|
<%= attribute.name %>: i.even?<%= ',' if index < attributes.length - 1 %>
|
838
942
|
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
839
943
|
<%= attribute.name %>: i * 10.5<%= ',' if index < attributes.length - 1 %>
|
840
|
-
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(
|
841
|
-
<% if attribute.name == '
|
842
|
-
<%= attribute.name %>: {
|
944
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
945
|
+
<% if attribute.name == 'metadata' -%>
|
946
|
+
<%= attribute.name %>: {
|
947
|
+
resource_type: "<%= singular_table_name %>",
|
948
|
+
category: "employee",
|
949
|
+
tags: ["bulk", "test_#{i}"],
|
950
|
+
attributes: {
|
951
|
+
priority: "medium",
|
952
|
+
status_info: { verified: true, active: true }
|
953
|
+
}
|
954
|
+
}<%= ',' if index < attributes.length - 1 %>
|
843
955
|
<% elsif attribute.name == 'settings' -%>
|
844
|
-
<%= attribute.name %>: { dark_mode: i.even?,
|
956
|
+
<%= attribute.name %>: { dark_mode: i.even?, notifications: { email: true, sms: i.even? } }<%= ',' if index < attributes.length - 1 %>
|
845
957
|
<% else -%>
|
846
958
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
847
959
|
<% end -%>
|
@@ -8,6 +8,16 @@ class <%= class_name %>Test < ActiveSupport::TestCase
|
|
8
8
|
@organization = organizations(:acme_org)
|
9
9
|
@user = users(:john_user)
|
10
10
|
@agency = agencies(:marketing_agency)
|
11
|
+
<% polymorphic_associations.each do |assoc| -%>
|
12
|
+
<% assoc[:parent_types].each_with_index do |parent_type, index| -%>
|
13
|
+
<% if index == 0 -%>
|
14
|
+
@<%= parent_type.underscore %> = <%= parent_type.underscore.pluralize %>(<%= case parent_type.underscore; when 'agency'; ':marketing_agency'; when 'user'; ':john_user'; when 'organization'; ':acme_org'; else; ':one'; end %>)
|
15
|
+
@<%= assoc[:field_name] %> = @<%= parent_type.underscore %> # Default polymorphic parent for tests
|
16
|
+
<% else -%>
|
17
|
+
@<%= parent_type.underscore %> = <%= parent_type.underscore.pluralize %>(<%= case parent_type.underscore; when 'agency'; ':marketing_agency'; when 'user'; ':john_user'; when 'organization'; ':acme_org'; else; ':one'; end %>)
|
18
|
+
<% end -%>
|
19
|
+
<% end -%>
|
20
|
+
<% end -%>
|
11
21
|
<% if singular_table_name == 'organization' -%>
|
12
22
|
@<%= singular_table_name %> = <%= table_name %>(:acme_org)
|
13
23
|
<% elsif singular_table_name == 'user' -%>
|
@@ -24,7 +34,17 @@ class <%= class_name %>Test < ActiveSupport::TestCase
|
|
24
34
|
|
25
35
|
test "should belong to <%= attribute.name %>" do
|
26
36
|
assert_respond_to @<%= singular_table_name %>, :<%= attribute.name %>
|
37
|
+
<% if attribute.respond_to?(:polymorphic?) && attribute.polymorphic? -%>
|
38
|
+
assert @<%= singular_table_name %>.<%= attribute.name %>.present?
|
39
|
+
# Polymorphic association - check against valid parent types
|
40
|
+
<% polymorphic_associations.each do |assoc| -%>
|
41
|
+
<% if assoc[:field_name] == attribute.name -%>
|
42
|
+
assert(<%= assoc[:parent_types].map { |type| "@#{singular_table_name}.#{attribute.name}.is_a?(#{type})" }.join(' || ') %>)
|
43
|
+
<% end -%>
|
44
|
+
<% end -%>
|
45
|
+
<% else -%>
|
27
46
|
assert_kind_of <%= attribute.name.camelize %>, @<%= singular_table_name %>.<%= attribute.name %>
|
47
|
+
<% end -%>
|
28
48
|
end
|
29
49
|
|
30
50
|
test "should be invalid without <%= attribute.name %>" do
|
data/lib/propel_api.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: propel_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Martin, Rafael Pivato, Chi Putera
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -30,6 +30,26 @@ dependencies:
|
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '9.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: pagy
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '8.0'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '10.0'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '8.0'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '10.0'
|
33
53
|
description: A comprehensive Rails generator that creates complete API resources with
|
34
54
|
models, controllers, tests, and realistic seed data. Supports both JSON Facet and
|
35
55
|
Graphiti serialization engines.
|
@@ -53,9 +73,11 @@ files:
|
|
53
73
|
- lib/generators/propel_api/install/install_generator.rb
|
54
74
|
- lib/generators/propel_api/resource/resource_generator.rb
|
55
75
|
- lib/generators/propel_api/templates/config/propel_api.rb.tt
|
76
|
+
- lib/generators/propel_api/templates/controllers/api_base_controller.rb
|
56
77
|
- lib/generators/propel_api/templates/controllers/api_controller_graphiti.rb
|
57
78
|
- lib/generators/propel_api/templates/controllers/api_controller_propel_facets.rb
|
58
79
|
- lib/generators/propel_api/templates/controllers/example_controller.rb.tt
|
80
|
+
- lib/generators/propel_api/templates/errors/propel_api_csrf_error.rb
|
59
81
|
- lib/generators/propel_api/templates/scaffold/facet_controller_template.rb.tt
|
60
82
|
- lib/generators/propel_api/templates/scaffold/facet_model_template.rb.tt
|
61
83
|
- lib/generators/propel_api/templates/scaffold/graphiti_controller_template.rb.tt
|