propel_api 0.2.1 → 0.3.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/CHANGELOG.md +58 -0
- data/README.md +239 -4
- data/lib/generators/propel_api/core/named_base.rb +92 -1
- data/lib/generators/propel_api/core/relationship_inferrer.rb +4 -11
- data/lib/generators/propel_api/install/install_generator.rb +2 -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_controller_graphiti.rb +2 -2
- data/lib/generators/propel_api/templates/controllers/api_controller_propel_facets.rb +20 -10
- data/lib/generators/propel_api/templates/controllers/example_controller.rb.tt +2 -2
- data/lib/generators/propel_api/templates/scaffold/facet_controller_template.rb.tt +34 -9
- data/lib/generators/propel_api/templates/scaffold/facet_model_template.rb.tt +17 -8
- 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 +62 -14
- data/lib/generators/propel_api/templates/tests/controller_test_template.rb.tt +34 -6
- data/lib/generators/propel_api/templates/tests/fixtures_template.yml.tt +58 -15
- data/lib/generators/propel_api/templates/tests/integration_test_template.rb.tt +108 -36
- data/lib/generators/propel_api/templates/tests/model_test_template.rb.tt +20 -0
- data/lib/propel_api.rb +1 -1
- metadata +22 -2
@@ -8,6 +8,16 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
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 %>(<%= parent_type.underscore == 'agency' ? ':marketing_agency' : ':one' %>)
|
15
|
+
@<%= assoc[:field_name] %> = @<%= parent_type.underscore %> # Default polymorphic parent for tests
|
16
|
+
<% else -%>
|
17
|
+
@<%= parent_type.underscore %> = <%= parent_type.underscore.pluralize %>(<%= index == 1 ? ':marketing_agency' : ':one' %>)
|
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' -%>
|
@@ -21,7 +31,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
21
31
|
@auth_headers = { 'Authorization' => "Bearer #{@token}" }
|
22
32
|
|
23
33
|
# Ensure test <%= singular_table_name %> belongs to test user's organization
|
24
|
-
<%
|
34
|
+
<% if has_organization_reference? -%>
|
25
35
|
@<%= singular_table_name %>.update!(organization: @organization)
|
26
36
|
<% end -%>
|
27
37
|
end
|
@@ -45,7 +55,12 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
45
55
|
|
46
56
|
<% attributes.each_with_index do |attribute, index| -%>
|
47
57
|
<% if attribute.type == :references -%>
|
58
|
+
<% if attribute.respond_to?(:polymorphic?) && attribute.polymorphic? -%>
|
59
|
+
<%= attribute.name %>_id: @<%= attribute.name %>.id,
|
60
|
+
<%= attribute.name %>_type: @<%= attribute.name %>.class.name<%= ',' if index < attributes.length - 1 %>
|
61
|
+
<% else -%>
|
48
62
|
<%= attribute.name %>_id: @<%= attribute.name %>.id<%= ',' if index < attributes.length - 1 %>
|
63
|
+
<% end -%>
|
49
64
|
<% elsif attribute.type == :string && !reference_names.include?(attribute.name) -%>
|
50
65
|
<% if attribute.name.to_s.match?(/email/) -%>
|
51
66
|
<%= attribute.name %>: "workflow@example.com"<%= ',' if index < attributes.length - 1 %>
|
@@ -64,11 +79,18 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
64
79
|
<%= attribute.name %>: 100.50<%= ',' if index < attributes.length - 1 %>
|
65
80
|
<% elsif attribute.type == :datetime -%>
|
66
81
|
<%= 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 %>: {
|
82
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
83
|
+
<% if attribute.name == 'metadata' -%>
|
84
|
+
<%= 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
85
|
<% elsif attribute.name == 'settings' -%>
|
71
|
-
<%= attribute.name %>: {
|
86
|
+
<%= attribute.name %>: {
|
87
|
+
ui_preferences: {
|
88
|
+
theme: "dark",
|
89
|
+
language: "en",
|
90
|
+
notifications: { email: true, sms: false, push: true }
|
91
|
+
},
|
92
|
+
feature_flags: { beta_features: false, analytics: true }
|
93
|
+
}<%= ',' if index < attributes.length - 1 %>
|
72
94
|
<% else -%>
|
73
95
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
74
96
|
<% end -%>
|
@@ -131,17 +153,28 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
131
153
|
if created_<%= singular_table_name %>['<%= attribute.name %>'].present?
|
132
154
|
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
155
|
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, "
|
156
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
157
|
+
<% if attribute.name == 'metadata' -%>
|
158
|
+
# Metadata field should be a hash with generic structure
|
159
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>'], "Metadata should be a JSON object"
|
160
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "resource_type", "Metadata should contain resource_type"
|
161
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "category", "Metadata should contain category"
|
162
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "tags", "Metadata should contain tags array"
|
163
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "attributes", "Metadata should contain attributes object"
|
164
|
+
assert_kind_of Array, created_<%= singular_table_name %>['<%= attribute.name %>']['tags'], "Tags should be an array"
|
165
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>']['attributes'], "Attributes should be a hash"
|
166
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>']['attributes'].keys, "priority", "Attributes should contain priority"
|
167
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>']['attributes'].keys, "status_info", "Attributes should contain status_info"
|
139
168
|
<% elsif attribute.name == 'settings' -%>
|
140
|
-
# Settings field should be a hash with
|
169
|
+
# Settings field should be a hash with generic structure
|
141
170
|
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
|
-
|
171
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "ui_preferences", "Settings should contain ui_preferences"
|
172
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>'].keys, "feature_flags", "Settings should contain feature_flags"
|
173
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>']['ui_preferences'], "UI preferences should be a hash"
|
174
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>']['feature_flags'], "Feature flags should be a hash"
|
175
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>']['ui_preferences'].keys, "theme", "UI preferences should contain theme"
|
176
|
+
assert_includes created_<%= singular_table_name %>['<%= attribute.name %>']['ui_preferences'].keys, "notifications", "UI preferences should contain notifications"
|
177
|
+
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>']['ui_preferences']['notifications'], "Notifications should be a hash"
|
145
178
|
<% else -%>
|
146
179
|
assert_kind_of Hash, created_<%= singular_table_name %>['<%= attribute.name %>'], "<%= attribute.name %> should be a JSON object"
|
147
180
|
<% end -%>
|
@@ -368,7 +401,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
368
401
|
unique_id = "#{Time.current.to_i}_#{SecureRandom.hex(6)}"
|
369
402
|
test_params = { email_address: "tenancy_test_#{unique_id}@example.com", username: "tenancy_test_#{unique_id}", password: "password123", agency_id: @agency.id }
|
370
403
|
<% else -%>
|
371
|
-
test_params = { title: "Test <%= class_name %>", agency_id: @agency.id }
|
404
|
+
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
405
|
<% end -%>
|
373
406
|
<% else -%>
|
374
407
|
# Model without agency - test missing organization_id only
|
@@ -376,7 +409,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
376
409
|
unique_id = "#{Time.current.to_i}_#{SecureRandom.hex(6)}"
|
377
410
|
test_params = { email_address: "tenancy_test_#{unique_id}@example.com", username: "tenancy_test_#{unique_id}", password: "password123" }
|
378
411
|
<% else -%>
|
379
|
-
test_params = { title: "Test <%= class_name %>" }
|
412
|
+
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
413
|
<% end -%>
|
381
414
|
<% end -%>
|
382
415
|
|
@@ -386,7 +419,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
386
419
|
|
387
420
|
if require_org_id<% if has_agency_id %> || false<% end -%> # Agency models test organization_id behavior
|
388
421
|
# Strict mode: Should return 422 when tenancy context is required but missing
|
389
|
-
assert_response :
|
422
|
+
assert_response :unprocessable_content
|
390
423
|
|
391
424
|
error_response = JSON.parse(response.body)
|
392
425
|
assert_includes error_response.keys, 'errors'
|
@@ -446,7 +479,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
446
479
|
headers: @auth_headers
|
447
480
|
<% else -%>
|
448
481
|
post <%= api_route_helper %>_url,
|
449
|
-
params: { data: { organization_id: @organization.id, agency_id: 99999, title: "Test <%= class_name %>" } },
|
482
|
+
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
483
|
headers: @auth_headers
|
451
484
|
<% end -%>
|
452
485
|
|
@@ -465,7 +498,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
465
498
|
headers: @auth_headers
|
466
499
|
<% else -%>
|
467
500
|
post <%= api_route_helper %>_url,
|
468
|
-
params: { data: { organization_id: 99999, title: "Test <%= class_name %>" } },
|
501
|
+
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
502
|
headers: @auth_headers
|
470
503
|
<% end -%>
|
471
504
|
|
@@ -551,11 +584,19 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
551
584
|
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
552
585
|
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
553
586
|
<%= 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 %>: {
|
587
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
588
|
+
<% if attribute.name == 'metadata' -%>
|
589
|
+
<%= attribute.name %>: {
|
590
|
+
resource_type: "<%= singular_table_name %>",
|
591
|
+
category: "employee",
|
592
|
+
tags: ["org1", "department_test"],
|
593
|
+
attributes: {
|
594
|
+
priority: "medium",
|
595
|
+
status_info: { verified: true, active: true }
|
596
|
+
}
|
597
|
+
}<%= ',' if index < attributes.length - 1 %>
|
557
598
|
<% elsif attribute.name == 'settings' -%>
|
558
|
-
<%= attribute.name %>: { dark_mode: false,
|
599
|
+
<%= attribute.name %>: { dark_mode: false, notifications: { email: true, sms: true } }<%= ',' if index < attributes.length - 1 %>
|
559
600
|
<% else -%>
|
560
601
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
561
602
|
<% end -%>
|
@@ -589,11 +630,19 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
589
630
|
<%= attribute.name %>: false<%= ',' if index < attributes.length - 1 %>
|
590
631
|
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
591
632
|
<%= 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 %>: {
|
633
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
634
|
+
<% if attribute.name == 'metadata' -%>
|
635
|
+
<%= attribute.name %>: {
|
636
|
+
resource_type: "<%= singular_table_name %>",
|
637
|
+
category: "manager",
|
638
|
+
tags: ["org2", "department_test"],
|
639
|
+
attributes: {
|
640
|
+
priority: "high",
|
641
|
+
status_info: { verified: true, active: true }
|
642
|
+
}
|
643
|
+
}<%= ',' if index < attributes.length - 1 %>
|
595
644
|
<% elsif attribute.name == 'settings' -%>
|
596
|
-
<%= attribute.name %>: { dark_mode: true,
|
645
|
+
<%= attribute.name %>: { dark_mode: true, notifications: { email: false, sms: true } }<%= ',' if index < attributes.length - 1 %>
|
597
646
|
<% else -%>
|
598
647
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
599
648
|
<% end -%>
|
@@ -667,7 +716,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
|
|
667
716
|
|
668
717
|
# Verify core fields are present
|
669
718
|
assert_includes <%= singular_table_name %>_data.keys, 'id'
|
670
|
-
<%
|
719
|
+
<% if has_organization_reference? -%>
|
671
720
|
assert_includes <%= singular_table_name %>_data.keys, 'organization'
|
672
721
|
|
673
722
|
# Verify associations are properly included
|
@@ -737,11 +786,26 @@ if attributes.any? { |attr| attr.type == :references && attr.name == 'user' } &&
|
|
737
786
|
<%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
|
738
787
|
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
739
788
|
<%= 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 %>: {
|
789
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
790
|
+
<% if attribute.name == 'metadata' -%>
|
791
|
+
<%= attribute.name %>: {
|
792
|
+
resource_type: "<%= singular_table_name %>",
|
793
|
+
category: "admin",
|
794
|
+
tags: ["concurrent", "test"],
|
795
|
+
attributes: {
|
796
|
+
priority: "high",
|
797
|
+
status_info: { verified: true, active: true }
|
798
|
+
}
|
799
|
+
}<%= ',' if index < attributes.length - 1 %>
|
743
800
|
<% elsif attribute.name == 'settings' -%>
|
744
|
-
<%= attribute.name %>: {
|
801
|
+
<%= attribute.name %>: {
|
802
|
+
ui_preferences: {
|
803
|
+
theme: "dark",
|
804
|
+
language: "en",
|
805
|
+
notifications: { email: true, sms: false, push: true }
|
806
|
+
},
|
807
|
+
feature_flags: { beta_features: false, analytics: true }
|
808
|
+
}<%= ',' if index < attributes.length - 1 %>
|
745
809
|
<% else -%>
|
746
810
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
747
811
|
<% end -%>
|
@@ -837,11 +901,19 @@ if attributes.any? { |attr| attr.type == :references && attr.name == 'user' } &&
|
|
837
901
|
<%= attribute.name %>: i.even?<%= ',' if index < attributes.length - 1 %>
|
838
902
|
<% elsif attribute.type == :decimal || attribute.type == :float -%>
|
839
903
|
<%= 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 %>: {
|
904
|
+
<% elsif attribute.type == :json || attribute.name.to_s.match?(/^(metadata|settings)$/) -%>
|
905
|
+
<% if attribute.name == 'metadata' -%>
|
906
|
+
<%= attribute.name %>: {
|
907
|
+
resource_type: "<%= singular_table_name %>",
|
908
|
+
category: "employee",
|
909
|
+
tags: ["bulk", "test_#{i}"],
|
910
|
+
attributes: {
|
911
|
+
priority: "medium",
|
912
|
+
status_info: { verified: true, active: true }
|
913
|
+
}
|
914
|
+
}<%= ',' if index < attributes.length - 1 %>
|
843
915
|
<% elsif attribute.name == 'settings' -%>
|
844
|
-
<%= attribute.name %>: { dark_mode: i.even?,
|
916
|
+
<%= attribute.name %>: { dark_mode: i.even?, notifications: { email: true, sms: i.even? } }<%= ',' if index < attributes.length - 1 %>
|
845
917
|
<% else -%>
|
846
918
|
<%= attribute.name %>: {}<%= ',' if index < attributes.length - 1 %>
|
847
919
|
<% 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 %>(<%= parent_type.underscore == 'agency' ? ':marketing_agency' : ':one' %>)
|
15
|
+
@<%= assoc[:field_name] %> = @<%= parent_type.underscore %> # Default polymorphic parent for tests
|
16
|
+
<% else -%>
|
17
|
+
@<%= parent_type.underscore %> = <%= parent_type.underscore.pluralize %>(<%= index == 1 ? ':marketing_agency' : ':one' %>)
|
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.0
|
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-10 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.
|