inline_forms_installer 8.1.40 → 8.1.42

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: 94ac8df294cd719110b2360768007fbfb8c26c95749c95323a0e61b969801b4e
4
- data.tar.gz: b5c245794ab67879467b227eef31fb523927f5c8f27634bb48f173222246da0c
3
+ metadata.gz: d09ceda3c59a9d785f9a7270e58254f1ace6e43ed605f9681e8046c1ad67f8a7
4
+ data.tar.gz: 35178d8b5bf044d7f941efa611bd39512f3060bc996b7669a12ed9e8c6721e6a
5
5
  SHA512:
6
- metadata.gz: c8e07fcf3fa59b3a0c0a8b548ec06f78032e9659410351abe5ae13f2d03e2b8f66e4d3321f2111367dd9aec31daaa8263b1eeabfb79d2736fc2fb0745652ff12
7
- data.tar.gz: 866e3d7586e1e03b3d19e5023f834f8665794d436e17b7a6d58f95a8c1aa095c3cff58687d34b18cd77be65fc875d24517a4c130d1792ee7a2c895341b903d9a
6
+ metadata.gz: c57d71b4fa224a31135385f43175c50fcf4e54611965797726b3a8ea4dd89233e9bcac54a2f4180fbf8a5c692f9cc0b7710adee7040bca89dd291c59c43fe178
7
+ data.tar.gz: 7ca6d416410ef9d1342c6bd6339b3be6f6bdda2923465d1653d357729c0b3b94a90b2f00ed98e33f855fda4722d0b5a0580436c5358fdae278119d9bf9661ce1
@@ -20,6 +20,7 @@ module InlineFormsInstaller
20
20
  DATABASE_OPTIONS = %w[sqlite mysql]
21
21
  method_option :database, aliases: "-d", banner: DATABASE_OPTIONS.join("|"), desc: "specify development database"
22
22
  method_option :example, type: :boolean, desc: "install the example app. uses sqlite as development database"
23
+ method_option :schema_edit, type: :boolean, default: false, desc: "mount the schema-change GUI (inline_forms_schema_edit gem); implied by --example"
23
24
  method_option :email, aliases: "-e", default: "admin@example.com", desc: "specify admin email"
24
25
  method_option :password, aliases: "-p", default: "admin999", desc: "specify admin password"
25
26
  method_option :skiprvm, aliases: "--no-rvm", type: :boolean, default: false, desc: "install inline_forms without RVM"
@@ -125,6 +126,8 @@ module InlineFormsInstaller
125
126
  ENV["using_sqlite"] = using_sqlite?.to_s
126
127
  ENV["database"] = database
127
128
  ENV["install_example"] = install_example?.to_s
129
+ # The example app always mounts the schema GUI (it demos + tests it).
130
+ ENV["install_schema_edit"] = (options[:schema_edit] || install_example?).to_s
128
131
  # Match the generated `.ruby-version` to the version manager actually in
129
132
  # use. RVM's `.ruby-version` reader needs the `ruby-X.Y.Z` form — a bare
130
133
  # `X.Y.Z` makes `rvm use .` bail with "do not know how to handle" and skip
@@ -45,7 +45,7 @@ def install_prerelease_gems_from_roots!
45
45
  roots.uniq!
46
46
  return if roots.empty?
47
47
 
48
- %w[validation_hints inline_forms inline_forms_installer].each do |name|
48
+ %w[validation_hints inline_forms inline_forms_installer inline_forms_schema_edit].each do |name|
49
49
  # Pick the *highest version*, not the highest filename. String sort
50
50
  # placed `inline_forms-8.1.7.gem` above `inline_forms-8.1.10.gem`
51
51
  # because "7" > "1" lexicographically — silently picking up a stale
@@ -62,7 +62,13 @@ def install_prerelease_gems_from_roots!
62
62
  # the exact shape that bit us between 8.1.6 (default gemset's
63
63
  # highest installer) and 8.1.10.
64
64
  candidates = roots.flat_map { |root|
65
- Dir[File.join(root, "#{name}-*.gem"), File.join(root, "pkg", "#{name}-*.gem")]
65
+ # inline_forms_schema_edit lives in a subdirectory of the inline_forms
66
+ # checkout with its own pkg/; glob both layouts for every name (the
67
+ # extra patterns simply match nothing for the root-level gems).
68
+ Dir[File.join(root, "#{name}-*.gem"),
69
+ File.join(root, "pkg", "#{name}-*.gem"),
70
+ File.join(root, name, "#{name}-*.gem"),
71
+ File.join(root, name, "pkg", "#{name}-*.gem")]
66
72
  }
67
73
  gem_file = candidates.max_by do |path|
68
74
  ver_str = File.basename(path, ".gem").sub(/\A#{Regexp.escape(name)}-/, "")
@@ -119,6 +125,18 @@ if ENV["INLINE_FORMS_GEMFILE_PATH"] && File.directory?(ENV["INLINE_FORMS_GEMFILE
119
125
  else
120
126
  gem "inline_forms", "~> 8"
121
127
  end
128
+ # Schema-change GUI (separate mountable engine gem): only when requested via
129
+ # `--schema-edit` (implied by `--example`). Apps that never change their own
130
+ # schema ship without this surface entirely.
131
+ if ENV["install_schema_edit"] == "true"
132
+ schema_edit_path = ENV["INLINE_FORMS_GEMFILE_PATH"] &&
133
+ File.join(ENV["INLINE_FORMS_GEMFILE_PATH"], "inline_forms_schema_edit")
134
+ if schema_edit_path && File.directory?(schema_edit_path)
135
+ gem "inline_forms_schema_edit", path: schema_edit_path
136
+ else
137
+ gem "inline_forms_schema_edit", "~> 8"
138
+ end
139
+ end
122
140
  # jQuery is required by Foundation 6's JS only. jQuery UI is fully gone since
123
141
  # 8.1.26 (native date/time/month inputs in 8.1.25; datalist combobox + range
124
142
  # slider in 8.1.26), as are jquery-timepicker-rails, jquery-ui-rails and
@@ -831,6 +849,32 @@ copy_file File.join(INSTALLER_ROOT,'lib/installer_templates/capistrano/Capfile')
831
849
  say "- Unicorn Config..."
832
850
  copy_file File.join(INSTALLER_ROOT,'lib/installer_templates/unicorn/production.rb'), "config/unicorn/production.rb"
833
851
 
852
+ # Schema-change GUI (dev-only authoring; InlineForms::SchemaController from
853
+ # the inline_forms_schema_edit gem). Wired only when requested via
854
+ # `--schema-edit` (implied by `--example`): routes + a "+ field" nav link.
855
+ # Applies inline_forms_addto through the browser; does NOT run db:migrate.
856
+ # Must precede the example section: its test gate exercises these routes.
857
+ if ENV['install_schema_edit'] == 'true'
858
+ say "- Schema GUI: routes + nav link + batch tables..."
859
+ # One line: the gem owns its route set, so gem upgrades can add routes
860
+ # without editing the app's routes.rb.
861
+ route 'InlineFormsSchemaEdit.draw_routes(self)'
862
+
863
+ # Batch-pipeline tables (drafted intents + batches). The generator writes
864
+ # the migration; migrate here for sqlite (mysql apps migrate by hand, same
865
+ # policy as the main install).
866
+ run "bundle exec rails g inline_forms_schema_edit:install"
867
+ run "bundle exec rake db:migrate" if ENV['using_sqlite'] == 'true'
868
+
869
+ if File.exist?("app/views/_inline_forms_tabs.html.erb")
870
+ inject_into_file "app/views/_inline_forms_tabs.html.erb",
871
+ " <li class=\"menu-text\">\n" \
872
+ " <a href=\"/schema/new\" data-turbo=\"false\" title=\"Add a field to a model (dev only)\">+ field</a>\n" \
873
+ " </li>\n",
874
+ before: " </ul>\n </div>\n <div class=\"top-bar-right\">"
875
+ end
876
+ end
877
+
834
878
  # Git
835
879
  say "- adding and committing to git..."
836
880
 
@@ -1498,6 +1542,16 @@ if ENV['install_example'] == 'true'
1498
1542
  say "- Running showcase migrations (create table + join + seed)..."
1499
1543
  run "bundle exec rake db:migrate"
1500
1544
 
1545
+ # End-to-end exercise of `rails g inline_forms_addto` on an existing model.
1546
+ # Apartment is _enabled and uses the stock inline_forms show (Owner's tabbed
1547
+ # controller whitelists fields, so a new field would be hidden there). This
1548
+ # proves generate + migrate + boot + render + update against a real app; the
1549
+ # accompanying integration test is example_app_apartment_addto_field_test.rb.
1550
+ say "- addto demo: adding Apartment#internal_note via inline_forms_addto..."
1551
+ sleep 1
1552
+ run "bundle exec rails g inline_forms_addto Apartment internal_note:string"
1553
+ run "bundle exec rake db:migrate"
1554
+
1501
1555
  example_views_root = File.join(INSTALLER_ROOT, "lib/installer_templates/example_app_views")
1502
1556
  Dir.glob(File.join(example_views_root, "**", "*")).sort.each do |abs|
1503
1557
  next unless File.file?(abs)
@@ -1506,6 +1560,7 @@ if ENV['install_example'] == 'true'
1506
1560
  end
1507
1561
 
1508
1562
  route 'get "apartments/name_list", to: "apartments#name_list", as: :apartment_name_list'
1563
+
1509
1564
  route "root :to => 'apartments#index'"
1510
1565
 
1511
1566
  example_tests_root = File.join(INSTALLER_ROOT, "lib/installer_templates/example_app_tests")
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  module InlineFormsInstaller
4
- VERSION = "8.1.40"
4
+ VERSION = "8.1.42"
5
5
 
6
6
  # Canonical bare Ruby version (must match gemspec `required_ruby_version`).
7
7
  # Written verbatim into generated apps' `.ruby-version` for rbenv/chruby/asdf/
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../example_app/example_integration_test_case"
4
+
5
+ # End-to-end coverage for `rails g inline_forms_addto Apartment
6
+ # internal_note:string`, which the installer runs during --example. Proves the
7
+ # generated column migrated, the new attribute_list row renders on the stock
8
+ # show panel, and an inline edit/update round-trips through the generic
9
+ # controller.
10
+ class ExampleAppApartmentAddtoFieldTest < ExampleAppIntegrationTestCase
11
+ setup do
12
+ @apartment = Apartment.find_or_create_by!(name: "Addto Field Apt") do |a|
13
+ a.title = "Addto Field Title"
14
+ end
15
+ @frame_id = "apartment_#{@apartment.id}_internal_note"
16
+ @turbo_headers = { "Turbo-Frame" => @frame_id }
17
+ end
18
+
19
+ test "internal_note column exists after the addto migration" do
20
+ assert_includes Apartment.column_names, "internal_note",
21
+ "inline_forms_addto migration should have added the internal_note column"
22
+ end
23
+
24
+ test "internal_note row renders on the stock show panel" do
25
+ row_frame = "apartment_#{@apartment.id}"
26
+ get apartment_path(@apartment, update: row_frame),
27
+ headers: { "Turbo-Frame" => row_frame, "Accept" => "text/html" }
28
+
29
+ assert_response :success
30
+ assert_includes @response.body, @frame_id,
31
+ "the addto attribute_list row should render its own per-field turbo-frame"
32
+ end
33
+
34
+ test "internal_note inline edit and update round-trips" do
35
+ get edit_apartment_path(
36
+ @apartment,
37
+ attribute: "internal_note",
38
+ form_element: "text_field",
39
+ update: @frame_id
40
+ ), headers: @turbo_headers
41
+ assert_response :success
42
+ assert_includes @response.body, %(<turbo-frame id="#{@frame_id}">)
43
+
44
+ put apartment_path(
45
+ @apartment,
46
+ attribute: "internal_note",
47
+ form_element: "text_field",
48
+ update: @frame_id
49
+ ), params: { internal_note: "Boiler serviced 2026-07" }, headers: @turbo_headers
50
+ assert_response :success
51
+ assert_includes @response.body, "Boiler serviced 2026-07"
52
+ assert_equal "Boiler serviced 2026-07", @apartment.reload.internal_note
53
+ end
54
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../example_app/example_integration_test_case"
4
+
5
+ # The dev-only schema-change GUI (InlineForms::SchemaController), mounted only
6
+ # in the example app. Non-destructive coverage: the new form renders and a
7
+ # preview of a brand-new scalar field on Apartment renders with no schema
8
+ # change. Apply (the actual generator run) is covered by the engine dummy suite
9
+ # (recording executor) and inline_forms_addto_generator_test, so this test does
10
+ # not mutate the generated app during the shared gate.
11
+ class ExampleAppSchemaEditTest < ExampleAppIntegrationTestCase
12
+ test "schema/new renders the add-a-field form" do
13
+ get "/schema/new"
14
+ assert_response :success
15
+ assert_includes @response.body, "Form element"
16
+ assert_includes @response.body, "text_field"
17
+ end
18
+
19
+ test "schema/preview shows a new scalar field on Apartment without changing the schema" do
20
+ refute_includes Apartment.column_names, "staff_note",
21
+ "precondition: staff_note must not already exist"
22
+
23
+ post "/schema/preview",
24
+ params: { model_name: "Apartment", attribute: "staff_note",
25
+ form_element: "text_field", after: "name" }
26
+
27
+ assert_response :success
28
+ assert_includes @response.body, "staff_note (new)"
29
+ assert_includes @response.body, %(name="staff_note")
30
+
31
+ Apartment.reset_column_information
32
+ refute_includes Apartment.column_names, "staff_note",
33
+ "preview must not add a column"
34
+ end
35
+
36
+ # Batch pipeline (phases 1-3): the install generator created the tables,
37
+ # so draft -> submit -> token export works end to end in a generated app.
38
+ # No codegen happens (batch mode never generates in the request cycle), so
39
+ # this cannot mutate the app during the shared gate.
40
+ test "batch drafting, freeze on submit, and token-authenticated export" do
41
+ post "/schema/draft",
42
+ params: { model_name: "Apartment", attribute: "staff_note",
43
+ form_element: "text_field", after: "name", label: "Staff note" }
44
+ assert_response :redirect
45
+
46
+ batch = InlineForms::SchemaBatch.with_status(:draft).last
47
+ assert_equal 1, batch.intents.count
48
+
49
+ get "/schema"
50
+ assert_response :success
51
+ assert_includes @response.body, "staff_note"
52
+
53
+ post "/schema/batch/submit"
54
+ batch.reload
55
+ assert_equal "submitted", batch.status
56
+ assert_match(/\Asha256:/, batch.content_digest)
57
+ refute batch.intents.first.update(label: "changed"), "frozen after submit"
58
+
59
+ original_token = InlineFormsSchemaEdit.export_token
60
+ InlineFormsSchemaEdit.export_token = "gate-test-token"
61
+ begin
62
+ get "/schema/batches/#{batch.id}/export.json"
63
+ assert_response :unauthorized, "token configured but not provided"
64
+
65
+ get "/schema/batches/#{batch.id}/export.json",
66
+ headers: { "Authorization" => "Bearer gate-test-token" }
67
+ assert_response :success
68
+ payload = JSON.parse(@response.body)
69
+ assert_equal batch.content_digest, payload["digest"]
70
+ assert_equal "staff_note", payload["intents"].first["attribute"]
71
+ ensure
72
+ InlineFormsSchemaEdit.export_token = original_token
73
+ end
74
+ end
75
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inline_forms_installer
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.1.40
4
+ version: 8.1.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ace Suares
@@ -87,6 +87,7 @@ files:
87
87
  - lib/installer_templates/example_app_assets/seed_images/apt3_loft.png
88
88
  - lib/installer_templates/example_app_assets/seed_images/apt3_view.png
89
89
  - lib/installer_templates/example_app_tests/test/example_app/example_integration_test_case.rb
90
+ - lib/installer_templates/example_app_tests/test/integration/example_app_apartment_addto_field_test.rb
90
91
  - lib/installer_templates/example_app_tests/test/integration/example_app_apartment_field_turbo_test.rb
91
92
  - lib/installer_templates/example_app_tests/test/integration/example_app_apartment_name_list_test.rb
92
93
  - lib/installer_templates/example_app_tests/test/integration/example_app_apartment_name_required_test.rb
@@ -103,6 +104,7 @@ files:
103
104
  - lib/installer_templates/example_app_tests/test/integration/example_app_photos_test.rb
104
105
  - lib/installer_templates/example_app_tests/test/integration/example_app_production_ssl_test.rb
105
106
  - lib/installer_templates/example_app_tests/test/integration/example_app_routing_test.rb
107
+ - lib/installer_templates/example_app_tests/test/integration/example_app_schema_edit_test.rb
106
108
  - lib/installer_templates/example_app_tests/test/integration/example_app_showcase_choice_scale_fields_test.rb
107
109
  - lib/installer_templates/example_app_tests/test/integration/example_app_showcase_date_time_fields_test.rb
108
110
  - lib/installer_templates/example_app_tests/test/integration/example_app_showcase_gallery_test.rb