propel_api 0.3.1.4 → 0.3.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57d463a766fd115825dccf217caabd982bf849c9aac5a9dfafc7ef11b2a75c04
4
- data.tar.gz: 171026f0732372a319fb79946d3c7991293542a7b080bda4559b28427017b741
3
+ metadata.gz: 91e74e1fe5e094d98139863beb372f8635300f6dafe41e9993c988c1cf98f089
4
+ data.tar.gz: df50d1039f6d627fa05ed8c53c1be23af126aecdaa2d6803ade04ba64760b061
5
5
  SHA512:
6
- metadata.gz: 0576b9c86f00a1dde3691dfafc7049d6ffcc58c0717c98cab5739b3bee7c354046f711f3eaf061caa11f6c43c29f43008e988c55d706e84dfaa57e8ca0266de4
7
- data.tar.gz: fd24e624bd103eb1bdd96c4e85701198b77964716ebf35d267b1d08f75ee7fc8f6016b85c5374eedc111bb7371af8210779874050db707c906290129fdc1d828
6
+ metadata.gz: cdb193ecf7a26a2941ca6ea07d5e8f6fc778967169ff6bde3dc0a764e9ef9bcd00ac7324954fe02f7201bea0656b69be2dc55276fada71f52a6171e0fa7dd6fe
7
+ data.tar.gz: ac9a94e0bfb83c0a5bc945a550e25672c2f471c9b10f14dc20bfb6c6548eca55b60f53f13a08d7e9dc6ec8c65d9a0aad1cb1ff488a260a3864128e1d665103f8
data/CHANGELOG.md CHANGED
@@ -10,6 +10,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
10
  ### Planned Features
11
11
  - GraphQL adapter support
12
12
 
13
+ ## [0.3.1.5] - 2025-09-11
14
+
15
+ ### 🐛 Bug Fixes
16
+ - **JSONB Support Consistency**: Ensured all template files consistently support both `:json` and `:jsonb` field types
17
+ - Fixed any remaining instances of `:json`-only checks in generator templates
18
+ - Enhanced controller parameter generation for JSONB fields across all templates
19
+ - Improved test data generation for JSONB fields in all test templates
20
+ - Consistent JSONB handling in fixtures, integration tests, and model tests
21
+
22
+ ### 📖 Documentation & Template Improvements
23
+ - **Enhanced Template Consistency**: Verified all generator templates have proper JSONB support
24
+ - Updated controller templates to handle both JSON and JSONB consistently
25
+ - Enhanced test templates for reliable JSONB field testing
26
+ - Improved fixture generation for JSONB data structures
27
+
13
28
  ## [0.3.1.4] - 2025-09-11
14
29
 
15
30
  ### 🐛 Critical Bug Fixes
@@ -31,7 +31,7 @@ module PropelApi
31
31
  base.class_option :json_defaults,
32
32
  type: :boolean,
33
33
  default: nil,
34
- desc: "Add default: '{}' to json/jsonb fields in migrations. Defaults to PropelApi configuration."
34
+ desc: "Add default: {} to json/jsonb fields in migrations. Defaults to PropelApi configuration."
35
35
  end
36
36
 
37
37
  protected
@@ -631,10 +631,10 @@ Time.current.utc.strftime("%Y%m%d%H%M%S")
631
631
  if should_add_json_defaults?
632
632
  json_attrs = attributes.select { |attr| attr.type == :json || attr.type == :jsonb }
633
633
  json_attrs.each do |attr|
634
- # Look for the json/jsonb field declaration and add default: '{}'
634
+ # Look for the json/jsonb field declaration and add default: {}
635
635
  json_field_pattern = /t\.#{attr.type} :#{attr.name}(?!\s*,\s*default:)/
636
636
  if updated_content.match?(json_field_pattern)
637
- updated_content = updated_content.gsub(json_field_pattern, "t.#{attr.type} :#{attr.name}, default: '{}'")
637
+ updated_content = updated_content.gsub(json_field_pattern, "t.#{attr.type} :#{attr.name}, default: {}")
638
638
  end
639
639
  end
640
640
  end
@@ -19,8 +19,8 @@ module PropelApi
19
19
  @enforce_tenancy = true # true = enforce tenancy (default), false = no checking
20
20
  @required_tenancy_attributes = [:organization, :agency] # Required when enforce_tenancy is true
21
21
 
22
- # JSON field defaults - automatically add default: '{}' to json/jsonb fields in migrations
23
- @json_field_defaults = true # true = add default: '{}', false = leave as default nil
22
+ # JSON field defaults - automatically add default: {} to json/jsonb fields in migrations
23
+ @json_field_defaults = true # true = add default: {}, false = leave as default nil
24
24
 
25
25
  # Initialize the configurable attribute filter
26
26
  @attribute_filter = PropelApi::AttributeFilter.new
@@ -147,9 +147,9 @@ PropelApi.configure do |config|
147
147
  config.required_tenancy_attributes = [:organization, :agency] # Both required by default
148
148
 
149
149
  # JSON field defaults configuration
150
- # Automatically adds default: '{}' to json/jsonb fields in generated migrations
150
+ # Automatically adds default: {} to json/jsonb fields in generated migrations
151
151
  # This prevents nil values and makes JSON fields more predictable
152
- config.json_field_defaults = true # Default: true (add default: '{}' to JSON fields)
152
+ config.json_field_defaults = true # Default: true (add default: {} to JSON fields)
153
153
 
154
154
  # To disable JSON defaults globally:
155
155
  # config.json_field_defaults = false
@@ -105,7 +105,7 @@ json_facet :short, fields: [:id<%
105
105
  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
106
106
 
107
107
  # Always exclude if the field contains security-sensitive words
108
- security_patterns = /(password|digest|token|secret|key|salt|encrypted|confirmation|unlock|reset|api_key)/i
108
+ security_patterns = /\A(password|password_digest|password_confirmation|digest|token|secret|key|salt|encrypted|confirmation|unlock|reset|api_key|access_token|refresh_token)\z|.*(_digest|_token|_secret|_key|_salt|_encrypted)$/i
109
109
 
110
110
  identifying_fields.include?(attr.name.to_s) ||
111
111
  (simple_types.include?(attr.type) &&
@@ -126,7 +126,7 @@ json_facet :details, fields: [:id<%
126
126
  # Exclude timestamps and internal fields
127
127
  excluded_patterns = /\A(created_at|updated_at|deleted_at|password_digest|reset_password_token|confirmation_token|unlock_token)\z/i
128
128
  # Always exclude security-sensitive fields
129
- security_patterns = /(password|digest|token|secret|key|salt|encrypted|confirmation|unlock|reset|api_key|access_token|refresh_token)/i
129
+ security_patterns = /\A(password|password_digest|password_confirmation|digest|token|secret|key|salt|encrypted|confirmation|unlock|reset|api_key|access_token|refresh_token)\z|.*(_digest|_token|_secret|_key|_salt|_encrypted)$/i
130
130
  # Exclude binary and large data types
131
131
  excluded_types = [:binary]
132
132
 
@@ -102,7 +102,13 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
102
102
  <%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
103
103
  <% elsif attribute.type == :decimal || attribute.type == :float -%>
104
104
  <%= attribute.name %>: 100.50<%= ',' if index < attributes.length - 1 %>
105
+ <% elsif attribute.type == :date -%>
106
+ <%= attribute.name %>: Date.current<%= ',' if index < attributes.length - 1 %>
105
107
  <% elsif attribute.type == :datetime -%>
108
+ <%= attribute.name %>: DateTime.current<%= ',' if index < attributes.length - 1 %>
109
+ <% elsif attribute.type == :time -%>
110
+ <%= attribute.name %>: Time.current<%= ',' if index < attributes.length - 1 %>
111
+ <% elsif attribute.type == :timestamp -%>
106
112
  <%= attribute.name %>: Time.current<%= ',' if index < attributes.length - 1 %>
107
113
  <% elsif attribute.type == :json || attribute.type == :jsonb -%>
108
114
  <% if attribute.name == 'metadata' -%>
@@ -192,7 +198,12 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
192
198
  <% elsif attribute.type == :decimal || attribute.type == :float -%>
193
199
  # Rails conventionally serializes decimal/float values as strings in JSON
194
200
  assert_equal "100.5", created_<%= singular_table_name %>['<%= attribute.name %>']
195
- <% elsif attribute.type == :datetime || attribute.type == :timestamp || (attribute.name.to_s.match?(/_at$/) && attribute.type != :json && attribute.type != :jsonb) -%>
201
+ <% elsif attribute.type == :date -%>
202
+ # Date fields should be properly formatted ISO dates
203
+ if created_<%= singular_table_name %>['<%= attribute.name %>'].present?
204
+ assert_match(/\d{4}-\d{2}-\d{2}/, created_<%= singular_table_name %>['<%= attribute.name %>'], "<%= attribute.name %> should be ISO date format")
205
+ end
206
+ <% elsif attribute.type == :datetime || attribute.type == :timestamp || attribute.type == :time || (attribute.name.to_s.match?(/_at$/) && attribute.type != :json && attribute.type != :jsonb) -%>
196
207
  # Datetime fields should be properly formatted ISO timestamps, not exact values
197
208
  if created_<%= singular_table_name %>['<%= attribute.name %>'].present?
198
209
  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")
@@ -239,7 +250,7 @@ class <%= class_name %>ApiTest < ActionDispatch::IntegrationTest
239
250
 
240
251
  # Verify data types
241
252
  assert_kind_of String, test_data['string_value'], "string_value should be a string"
242
- assert_kind_of Integer, test_data['numeric_value'], "numeric_value should be a number"
253
+ assert_kind_of String, test_data['numeric_value'], "numeric_value should be a string (HTTP API converts all values to strings)"
243
254
  assert_kind_of Array, test_data['array_value'], "array_value should be an array"
244
255
  assert_kind_of Hash, test_data['nested_object'], "nested_object should be a hash"
245
256
 
@@ -106,6 +106,14 @@ class <%= class_name %>Test < ActiveSupport::TestCase
106
106
  <%= attribute.name %>: true<%= ',' if index < attributes.length - 1 %>
107
107
  <% elsif attribute.type == :decimal || attribute.type == :float -%>
108
108
  <%= attribute.name %>: <%= (index + 1) * 10.5 %><%= ',' if index < attributes.length - 1 %>
109
+ <% elsif attribute.type == :date -%>
110
+ <%= attribute.name %>: Date.current<%= ',' if index < attributes.length - 1 %>
111
+ <% elsif attribute.type == :datetime -%>
112
+ <%= attribute.name %>: DateTime.current<%= ',' if index < attributes.length - 1 %>
113
+ <% elsif attribute.type == :time -%>
114
+ <%= attribute.name %>: Time.current<%= ',' if index < attributes.length - 1 %>
115
+ <% elsif attribute.type == :timestamp -%>
116
+ <%= attribute.name %>: Time.current<%= ',' if index < attributes.length - 1 %>
109
117
  <% else -%>
110
118
  <%= attribute.name %>: "Test <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
111
119
  <% end -%>
@@ -136,6 +144,14 @@ class <%= class_name %>Test < ActiveSupport::TestCase
136
144
  <%= attribute.name %>: false<%= ',' if index < attributes.length - 1 %>
137
145
  <% elsif attribute.type == :decimal || attribute.type == :float -%>
138
146
  <%= attribute.name %>: 99.99<%= ',' if index < attributes.length - 1 %>
147
+ <% elsif attribute.type == :date -%>
148
+ <%= attribute.name %>: Date.tomorrow<%= ',' if index < attributes.length - 1 %>
149
+ <% elsif attribute.type == :datetime -%>
150
+ <%= attribute.name %>: DateTime.tomorrow<%= ',' if index < attributes.length - 1 %>
151
+ <% elsif attribute.type == :time -%>
152
+ <%= attribute.name %>: 1.hour.from_now<%= ',' if index < attributes.length - 1 %>
153
+ <% elsif attribute.type == :timestamp -%>
154
+ <%= attribute.name %>: 1.day.from_now<%= ',' if index < attributes.length - 1 %>
139
155
  <% else -%>
140
156
  <%= attribute.name %>: "New Test <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
141
157
  <% end -%>
@@ -282,6 +298,14 @@ class <%= class_name %>Test < ActiveSupport::TestCase
282
298
  <%= attribute.name %>: 123.45<%= ',' if index < attributes.length - 1 %>
283
299
  <% elsif attribute.type == :json || attribute.type == :jsonb -%>
284
300
  <%= attribute.name %>: { "test_key" => "test_value" }<%= ',' if index < attributes.length - 1 %>
301
+ <% elsif attribute.type == :date -%>
302
+ <%= attribute.name %>: Date.current<%= ',' if index < attributes.length - 1 %>
303
+ <% elsif attribute.type == :datetime -%>
304
+ <%= attribute.name %>: DateTime.current<%= ',' if index < attributes.length - 1 %>
305
+ <% elsif attribute.type == :time -%>
306
+ <%= attribute.name %>: Time.current<%= ',' if index < attributes.length - 1 %>
307
+ <% elsif attribute.type == :timestamp -%>
308
+ <%= attribute.name %>: Time.current<%= ',' if index < attributes.length - 1 %>
285
309
  <% else -%>
286
310
  <%= attribute.name %>: "Integrity Test <%= attribute.name.humanize %>"<%= ',' if index < attributes.length - 1 %>
287
311
  <% end -%>
@@ -319,6 +343,23 @@ class <%= class_name %>Test < ActiveSupport::TestCase
319
343
  assert_equal 123.45, reloaded_<%= singular_table_name %>.<%= attribute.name %>
320
344
  <% elsif attribute.type == :json || attribute.type == :jsonb -%>
321
345
  assert_equal({ "test_key" => "test_value" }, reloaded_<%= singular_table_name %>.<%= attribute.name %>)
346
+ <% elsif attribute.type == :date -%>
347
+ # Date fields should be properly stored and retrieved
348
+ assert_not_nil reloaded_<%= singular_table_name %>.<%= attribute.name %>
349
+ assert_kind_of Date, reloaded_<%= singular_table_name %>.<%= attribute.name %>
350
+ <% elsif attribute.type == :datetime -%>
351
+ # DateTime fields should be properly stored and retrieved
352
+ assert_not_nil reloaded_<%= singular_table_name %>.<%= attribute.name %>
353
+ # Rails typically converts DateTime to Time in ActiveRecord
354
+ assert(reloaded_<%= singular_table_name %>.<%= attribute.name %>.is_a?(DateTime) || reloaded_<%= singular_table_name %>.<%= attribute.name %>.is_a?(Time))
355
+ <% elsif attribute.type == :time -%>
356
+ # Time fields should be properly stored and retrieved
357
+ assert_not_nil reloaded_<%= singular_table_name %>.<%= attribute.name %>
358
+ assert_kind_of Time, reloaded_<%= singular_table_name %>.<%= attribute.name %>
359
+ <% elsif attribute.type == :timestamp -%>
360
+ # Timestamp fields should be properly stored and retrieved
361
+ assert_not_nil reloaded_<%= singular_table_name %>.<%= attribute.name %>
362
+ assert_kind_of Time, reloaded_<%= singular_table_name %>.<%= attribute.name %>
322
363
  <% else -%>
323
364
  assert_equal "Integrity Test <%= attribute.name.humanize %>", reloaded_<%= singular_table_name %>.<%= attribute.name %>
324
365
  <% end -%>
data/lib/propel_api.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module PropelApi
2
- VERSION = "0.3.1.4"
2
+ VERSION = "0.3.1.5"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propel_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1.4
4
+ version: 0.3.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Martin, Rafael Pivato, Chi Putera