inline_forms 8.1.21 → 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 +4 -4
- data/.forgejo/workflows/ci.yml +63 -0
- data/.forgejo/workflows/full-gate.yml +77 -0
- data/.gitignore +10 -5
- data/.rubocop.yml +31 -0
- data/.rubocop_todo.yml +151 -0
- data/CHANGELOG.md +305 -0
- data/CLAUDE.md +68 -0
- data/Gemfile +18 -2
- data/README.rdoc +23 -6
- data/Rakefile +53 -12
- data/app/assets/fonts/opensans-v44-latin-italic.woff2 +0 -0
- data/app/assets/fonts/opensans-v44-latin-regular.woff2 +0 -0
- data/app/assets/javascripts/inline_forms/inline_forms.js +30 -43
- data/app/assets/stylesheets/inline_forms/_foundation_icons.scss +6 -12
- data/app/assets/stylesheets/inline_forms/_theme.scss +134 -0
- data/app/assets/stylesheets/inline_forms/devise.scss +14 -13
- data/app/assets/stylesheets/inline_forms/foundation_and_overrides.scss +4 -0
- data/app/assets/stylesheets/inline_forms/inline_forms.scss +59 -68
- data/app/assets/stylesheets/inline_forms_fonts.css.erb +39 -0
- data/app/controllers/inline_forms_application_controller.rb +8 -4
- data/app/controllers/inline_forms_controller.rb +88 -14
- data/app/helpers/inline_forms_helper.rb +58 -15
- data/app/models/concerns/inline_forms/soft_deletable.rb +11 -12
- data/app/validators/curacao_id_number_validator.rb +5 -6
- data/app/validators/is_curacao_phone_validator.rb +2 -3
- data/app/validators/is_email_address_validator.rb +3 -3
- data/app/validators/must_be_a_value_validator.rb +6 -6
- data/app/views/inline_forms/_new.html.erb +4 -1
- data/app/views/inline_forms/_pending_migration_row.html.erb +15 -0
- data/app/views/inline_forms/_show.html.erb +5 -2
- data/app/views/inline_forms/field_pending.html.erb +10 -0
- data/app/views/layouts/application.html.erb +6 -3
- data/app/views/layouts/devise.html.erb +1 -0
- data/app/views/layouts/inline_forms.html.erb +7 -4
- data/archived/README.md +2 -0
- data/archived/form_elements/dns_records/README.md +25 -0
- data/archived/form_elements/question_list/README.md +25 -0
- data/inline_forms.gemspec +8 -7
- data/lib/generators/inline_forms_addto/USAGE +31 -0
- data/lib/generators/inline_forms_addto_generator.rb +198 -26
- data/lib/generators/inline_forms_attribute_overrides.rb +3 -2
- data/lib/generators/templates/application_record.rb +1 -1
- data/lib/inline_forms/archived_form_elements.rb +23 -10
- data/lib/inline_forms/attribute_list.rb +191 -0
- data/lib/inline_forms/form_element_from_callee.rb +1 -0
- data/lib/inline_forms/form_element_registry.rb +32 -32
- data/lib/inline_forms/form_elements/color_field_helper.rb +44 -0
- data/lib/inline_forms/form_elements/date_helper.rb +4 -1
- data/lib/inline_forms/form_elements/dropdown_with_other_helper.rb +25 -113
- data/lib/inline_forms/form_elements/month_year_picker_helper.rb +13 -2
- data/lib/inline_forms/form_elements/multi_image_field_helper.rb +18 -6
- data/lib/inline_forms/form_elements/slider_with_values_helper.rb +31 -64
- data/lib/inline_forms/form_elements/time_helper.rb +3 -1
- data/lib/inline_forms/gem_files.rb +27 -0
- data/lib/inline_forms/schema_apply.rb +85 -0
- data/lib/inline_forms/schema_intent.rb +76 -0
- data/lib/inline_forms/schema_label.rb +65 -0
- data/lib/inline_forms/schema_preview.rb +135 -0
- data/lib/inline_forms/tabs.rb +175 -0
- data/lib/inline_forms/turbo_tabs_builder.rb +20 -13
- data/lib/inline_forms/version.rb +2 -1
- data/lib/inline_forms.rb +145 -45
- data/lib/locales/inline_forms.en.yml +2 -0
- data/lib/locales/inline_forms.nl.yml +2 -0
- data/test/archived_form_elements_test.rb +34 -4
- data/test/attribute_list_test.rb +165 -0
- data/test/dummy/app/controllers/application_controller.rb +24 -0
- data/test/dummy/app/controllers/gizmos_controller.rb +4 -0
- data/test/dummy/app/controllers/machines_controller.rb +4 -0
- data/test/dummy/app/controllers/parts_controller.rb +4 -0
- data/test/dummy/app/controllers/widgets_controller.rb +4 -0
- data/test/dummy/app/helpers/application_helper.rb +13 -0
- data/test/dummy/app/models/application_record.rb +26 -0
- data/test/dummy/app/models/gizmo.rb +25 -0
- data/test/dummy/app/models/kind.rb +8 -0
- data/test/dummy/app/models/machine.rb +23 -0
- data/test/dummy/app/models/part.rb +16 -0
- data/test/dummy/app/models/widget.rb +39 -0
- data/test/dummy/app/views/_inline_forms_tabs.html.erb +40 -0
- data/test/dummy/config/application.rb +37 -0
- data/test/dummy/config/database.yml +3 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/initializers/inline_forms.rb +6 -0
- data/test/dummy/config/initializers/paper_trail_yaml_safe_load.rb +28 -0
- data/test/dummy/config/routes.rb +31 -0
- data/test/inline_forms_addto_generator_test.rb +220 -0
- data/test/integration/inline_forms_crud_test.rb +141 -0
- data/test/integration/legacy_elements_test.rb +42 -0
- data/test/integration/native_inputs_test.rb +138 -0
- data/test/integration/open_after_create_test.rb +85 -0
- data/test/integration/pending_migration_gate_test.rb +75 -0
- data/test/integration/schema_batch_pipeline_test.rb +189 -0
- data/test/integration/schema_edit_test.rb +141 -0
- data/test/integration/schema_preview_test.rb +65 -0
- data/test/integration_test_helper.rb +121 -0
- data/test/plain_text_configuration_test.rb +3 -3
- data/test/schema_apply_test.rb +73 -0
- data/test/schema_intent_test.rb +53 -0
- data/test/schema_label_test.rb +61 -0
- data/test/tabs_test.rb +98 -0
- data/test/user_model_config_test.rb +1 -0
- data/vendor/assets/javascripts/trix.min.js +7 -0
- data/vendor/assets/stylesheets/trix.css +470 -0
- metadata +91 -320
- data/app/assets/images/jquery-ui/animated-overlay.gif +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonal-maze_20_6e4f1c_10x10.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonal-maze_40_000000_10x10.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-medium_20_d34d17_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_0_aaaaaa_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_25_c5ddfc_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_40_db4865_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_50_262626_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_50_93c3cd_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_50_ff3853_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_75_ccd232_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_15_0b3e6f_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_15_444444_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_20_e69700_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_22_1484e6_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_26_2293f7_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_75_f3d8d8_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_8_333333_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_90_eeeeee_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_95_ffdc2e_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_10_4f4221_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_20_372806_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_25_675423_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_25_d5ac5d_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_8_261803_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_8_443113_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-medium_30_0b58a2_4x4.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-medium_80_ffff38_4x4.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_20_333333_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_30_a32d00_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_35_35414f_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_40_00498f_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_65_a6a6a6_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_10_eceadf_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_10_f8f7f6_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_15_eceadf_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_15_f7f3de_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_15_ffffff_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_65_654b24_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_68_b83400_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_303030_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_333333_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_4c4c4c_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_e69700_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_e6b900_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_15_cd0a0a_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_30_cccccc_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_40_292929_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_994d53_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_999999_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_c0402a_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_eeeeee_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_fafafa_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_fbec88_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_65_ffffff_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_75_aaaaaa_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_75_ba9217_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_75_ddd4b0_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_e4f1fb_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_f5f0e5_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_f8f8f8_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_15_5f391b_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_20_555555_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_25_cb842e_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_35_dddddd_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_40_0078a3_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_40_0a0a0a_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_40_111111_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_40_ffc73d_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_45_0078ae_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_50_3baae3_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_1c1c1c_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_f1fbe5_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_f8da4e_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_fbf5d0_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_fbf8ee_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_fcf0ba_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_60_000000_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_60_eeeeee_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_70_ede4d4_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_75_79c9ec_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_80_d7ebf9_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_85_dfeffc_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_100_ece8da_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_16_121212_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_20_111111_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_20_1c160d_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_25_333333_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_25_453326_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_30_3d3644_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_30_44372c_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_45_817865_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_45_e14f1c_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_50_6eac2c_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_55_000000_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_60_fece2f_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_70_ffdd57_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_75_2191c0_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_85_9fda58_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_90_fff9e5_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_95_f6ecd5_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_eeeeee_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f2f5f7_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f4f0ec_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f5f3e5_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f6f6f6_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f9f9f9_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_fafaf4_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_15_459e00_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_15_888888_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_20_0972a5_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_30_285c00_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_40_aaaaaa_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_55_555555_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_65_fee4bd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_70_000000_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_75_f5f5b5_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_95_cccccc_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_dcd9de_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_deedf7_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_eae6ea_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_f9f9f9_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_feeebd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_15_cc0000_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_20_201913_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_20_619226_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_25_30273a_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_25_67b021_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_25_ffef8f_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_33_003147_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_33_3a8104_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_35_222222_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_35_adadad_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_44_444444_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_45_5f5964_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_50_4eb305_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_50_aaaaaa_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_60_4ca20b_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_60_dddddd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_95_ffedad_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_100_eeeeee_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_45_cd0a0a_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_55_ffeb80_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_75_999999_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_100_f4f0ec_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_10_201913_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_10_285c00_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_15_121212_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_15_2b2922_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_25_000000_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_30_f58400_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_30_ffffff_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_50_c9c9c9_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_loop_25_000000_21x21.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_white-lines_85_f7f7ba_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_000000_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_004276_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_00498f_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_0073ea_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_0078ae_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_056b93_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_070603_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_0a82eb_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_0b54d5_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_1f1f1f_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_217bc0_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_2694e8_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_3383bb_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_3572ac_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_3d3d3d_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_3d80b3_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_454545_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_469bdd_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_4b8e0b_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_4ca300_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_4eb305_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_5fa5e3_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_666666_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_6da8d5_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_70b2e1_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_72a7cf_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_72b42d_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_734d99_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_808080_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_847e71_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_888888_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_88a206_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_8DC262_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_8c291d_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_8d78a5_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_98d2fb_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_999999_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_9bcc60_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_9ccdfc_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_9fda58_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_a83300_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_a8a3ae_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_aaaaaa_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_add978_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_b83400_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_b8ec79_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_bbbbbb_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_bd7b00_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_c02669_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_c47a23_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_c98000_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_cb672b_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_cc0000_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_cccccc_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_d19405_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_d8e7f3_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e0fdff_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e1e463_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e3ddc9_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e8e2b5_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e9cd86_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_eb990f_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ebccce_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ed9f26_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ededed_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_eeeeee_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_efec9f_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f08000_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f1fd86_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f29a00_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f2ec64_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f35f07_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f5e175_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f7a50d_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f9bd01_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f9f2bd_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fadc7a_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fbc856_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fbdb93_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fcd113_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fcdd4a_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ff0084_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ff7519_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffcf29_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffe180_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffeb33_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
- data/app/assets/stylesheets/jquery_ui/jquery.ui.accordion.css.scss +0 -39
- data/app/assets/stylesheets/jquery_ui/jquery.ui.all.css.scss +0 -14
- data/app/assets/stylesheets/jquery_ui/jquery.ui.autocomplete.css.scss +0 -17
- data/app/assets/stylesheets/jquery_ui/jquery.ui.base.css.scss +0 -27
- data/app/assets/stylesheets/jquery_ui/jquery.ui.button.css.scss +0 -115
- data/app/assets/stylesheets/jquery_ui/jquery.ui.core.css.scss +0 -92
- data/app/assets/stylesheets/jquery_ui/jquery.ui.datepicker.css.scss +0 -179
- data/app/assets/stylesheets/jquery_ui/jquery.ui.dialog.css.scss +0 -70
- data/app/assets/stylesheets/jquery_ui/jquery.ui.menu.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/jquery.ui.progressbar.css.scss +0 -29
- data/app/assets/stylesheets/jquery_ui/jquery.ui.resizable.css.scss +0 -79
- data/app/assets/stylesheets/jquery_ui/jquery.ui.selectable.css.scss +0 -16
- data/app/assets/stylesheets/jquery_ui/jquery.ui.slider.css.scss +0 -74
- data/app/assets/stylesheets/jquery_ui/jquery.ui.spinner.css.scss +0 -66
- data/app/assets/stylesheets/jquery_ui/jquery.ui.tabs.css.scss +0 -53
- data/app/assets/stylesheets/jquery_ui/jquery.ui.theme.css.scss +0 -408
- data/app/assets/stylesheets/jquery_ui/jquery.ui.tooltip.css.scss +0 -20
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.base.css.scss +0 -78
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.black-tie.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.blitzer.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.cupertino.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.dark-hive.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.dot-luv.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.eggplant.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.excite-bike.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.flick.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.hot-sneaks.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.humanity.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.le-frog.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.mint-choc.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.overcast.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.pepper-grinder.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.redmond.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.smoothness.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.south-street.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.start.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.sunny.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.swanky-purse.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.trontastic.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.ui-darkness.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.ui-lightness.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.vader.css.scss +0 -80
- /data/{lib → archived/form_elements/dns_records/lib}/inline_forms/form_elements/dns_records_helper.rb +0 -0
- /data/{lib → archived/form_elements/question_list/lib}/inline_forms/form_elements/question_list_helper.rb +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../integration_test_helper"
|
|
4
|
+
|
|
5
|
+
# Covers the pending-migration gate: an attribute_list row whose column does
|
|
6
|
+
# not exist yet (the inline_forms_addto window between the model edit and
|
|
7
|
+
# `rails db:migrate`) must render a read-only placeholder and be skipped on
|
|
8
|
+
# write, instead of 500ing on the missing column. Gizmo's list references
|
|
9
|
+
# :pending_note, which has no column on the gizmos table (see
|
|
10
|
+
# test/integration_test_helper.rb and test/dummy/app/models/gizmo.rb).
|
|
11
|
+
class PendingMigrationGateTest < InlineFormsIntegrationTestCase
|
|
12
|
+
setup do
|
|
13
|
+
@gizmo = Gizmo.create!(name: "Gadget")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test "predicate flags a phantom column and only that" do
|
|
17
|
+
g = @gizmo
|
|
18
|
+
# phantom scalar column -> pending
|
|
19
|
+
assert InlineForms.attribute_pending_migration?(g, :pending_note, :text_field)
|
|
20
|
+
# real column -> not pending
|
|
21
|
+
refute InlineForms.attribute_pending_migration?(g, :name, :text_field)
|
|
22
|
+
# header is a label, never gated
|
|
23
|
+
refute InlineForms.attribute_pending_migration?(g, :section, :header)
|
|
24
|
+
# info bound to a real column
|
|
25
|
+
refute InlineForms.attribute_pending_migration?(g, :created_at, :info)
|
|
26
|
+
# relation dropdown backed by a missing foreign key -> pending
|
|
27
|
+
assert InlineForms.attribute_pending_migration?(g, :vendor, :dropdown)
|
|
28
|
+
# no-column elements are never gated
|
|
29
|
+
refute InlineForms.attribute_pending_migration?(g, :parts, :has_many)
|
|
30
|
+
refute InlineForms.attribute_pending_migration?(g, :body, :rich_text)
|
|
31
|
+
refute InlineForms.attribute_pending_migration?(g, :report, :pdf_link)
|
|
32
|
+
# exempt virtual-backed elements (column name != attribute)
|
|
33
|
+
refute InlineForms.attribute_pending_migration?(g, :amount, :money_field)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
test "row show renders a pending placeholder and does not raise" do
|
|
37
|
+
frame = "gizmo_#{@gizmo.id}"
|
|
38
|
+
get gizmo_path(@gizmo, update: frame), headers: frame_headers(frame)
|
|
39
|
+
|
|
40
|
+
assert_response :success
|
|
41
|
+
assert_includes response.body, "pending migration"
|
|
42
|
+
# the real field still renders its own edit frame
|
|
43
|
+
assert_includes response.body, %(<turbo-frame id="gizmo_#{@gizmo.id}_name">)
|
|
44
|
+
# the phantom field is NOT rendered as an editable field frame
|
|
45
|
+
refute_includes response.body, %(<turbo-frame id="gizmo_#{@gizmo.id}_pending_note">)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
test "new form renders a pending placeholder instead of an input" do
|
|
49
|
+
get new_gizmo_path(update: "gizmos_list"), headers: frame_headers("gizmos_list")
|
|
50
|
+
|
|
51
|
+
assert_response :success
|
|
52
|
+
assert_includes response.body, "pending migration"
|
|
53
|
+
refute_includes response.body, %(name="pending_note")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test "create skips the pending column and still saves" do
|
|
57
|
+
assert_difference -> { Gizmo.count }, +1 do
|
|
58
|
+
post gizmos_path(update: "gizmos_list"),
|
|
59
|
+
params: { name: "Fresh", pending_note: "ignored — no column yet" },
|
|
60
|
+
headers: frame_headers("gizmos_list")
|
|
61
|
+
end
|
|
62
|
+
assert_response :success
|
|
63
|
+
assert Gizmo.exists?(name: "Fresh")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
test "forced update of a pending field is refused, not a 500" do
|
|
67
|
+
frame = "gizmo_#{@gizmo.id}_pending_note"
|
|
68
|
+
put gizmo_path(@gizmo, attribute: "pending_note", form_element: "text_field",
|
|
69
|
+
update: frame),
|
|
70
|
+
params: { pending_note: "x" }, headers: frame_headers(frame)
|
|
71
|
+
|
|
72
|
+
assert_response :unprocessable_entity
|
|
73
|
+
assert_includes response.body, "pending migration"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../integration_test_helper"
|
|
4
|
+
|
|
5
|
+
# The batch pipeline (phases 1-3): drafting intents into a batch, freeze on
|
|
6
|
+
# submit, token-authenticated export + status callback, and import/replay
|
|
7
|
+
# via a recording executor (never mutates the dummy tree).
|
|
8
|
+
class SchemaBatchPipelineTest < InlineFormsIntegrationTestCase
|
|
9
|
+
def teardown
|
|
10
|
+
InlineFormsSchemaEdit.export_token = nil
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def draft_widget_field!(attribute: "warehouse_note", label: "Warehouse note")
|
|
15
|
+
post inline_forms_schema_draft_path,
|
|
16
|
+
params: { model_name: "Widget", attribute: attribute,
|
|
17
|
+
form_element: "text_field", after: "name", label: label, locale: "en" }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# -- phase 1: drafting + freeze ------------------------------------------
|
|
21
|
+
|
|
22
|
+
test "drafting an intent creates a draft batch (the cart) and index shows it" do
|
|
23
|
+
draft_widget_field!
|
|
24
|
+
assert_response :redirect
|
|
25
|
+
|
|
26
|
+
batch = InlineForms::SchemaBatch.with_status(:draft).first
|
|
27
|
+
assert batch, "draft batch created"
|
|
28
|
+
assert_equal 1, batch.intents.count
|
|
29
|
+
intent = batch.intents.first
|
|
30
|
+
assert_equal %w[Widget warehouse_note text_field name], [
|
|
31
|
+
intent.target_model, intent.attr_name, intent.form_element, intent.after_attr
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
get inline_forms_schema_index_path
|
|
35
|
+
assert_response :success
|
|
36
|
+
assert_includes response.body, "warehouse_note"
|
|
37
|
+
assert_includes response.body, "Submit batch"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
test "invalid intents are rejected at drafting time" do
|
|
41
|
+
post inline_forms_schema_draft_path,
|
|
42
|
+
params: { model_name: "Widget", attribute: "name", form_element: "text_field" }
|
|
43
|
+
assert_response :success # renders :new with the error
|
|
44
|
+
assert_includes response.body, "already has a name column"
|
|
45
|
+
assert_equal 0, InlineForms::SchemaIntentRecord.count
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
test "submit freezes the batch: no more adds, edits or removals; digest sealed" do
|
|
49
|
+
draft_widget_field!
|
|
50
|
+
post inline_forms_schema_submit_batch_path
|
|
51
|
+
assert_response :redirect
|
|
52
|
+
|
|
53
|
+
batch = InlineForms::SchemaBatch.last
|
|
54
|
+
assert_equal "submitted", batch.status
|
|
55
|
+
assert batch.submitted_at
|
|
56
|
+
assert_match(/\Asha256:/, batch.content_digest)
|
|
57
|
+
|
|
58
|
+
intent = batch.intents.first
|
|
59
|
+
intent.label = "changed"
|
|
60
|
+
refute intent.save, "frozen intent must not save"
|
|
61
|
+
refute intent.destroy, "frozen intent must not be destroyed"
|
|
62
|
+
|
|
63
|
+
refute batch.intents.create(target_model: "Widget", attr_name: "late_one",
|
|
64
|
+
form_element: "text_field").persisted?,
|
|
65
|
+
"no new intents into a frozen batch"
|
|
66
|
+
|
|
67
|
+
batch.window_at = 2.days.from_now
|
|
68
|
+
refute batch.save, "frozen batch attributes must not change"
|
|
69
|
+
|
|
70
|
+
# A new draft goes into a NEW batch.
|
|
71
|
+
draft_widget_field!(attribute: "second_note")
|
|
72
|
+
assert_equal 2, InlineForms::SchemaBatch.count
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
test "submitting an empty batch is refused" do
|
|
76
|
+
post inline_forms_schema_submit_batch_path
|
|
77
|
+
assert_redirected_to inline_forms_schema_index_path
|
|
78
|
+
assert_equal 0, InlineForms::SchemaBatch.where(status: "submitted").count
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
test "status transitions follow the pipeline; illegal jumps raise" do
|
|
82
|
+
draft_widget_field!
|
|
83
|
+
batch = InlineForms::SchemaBatch.last.submit!
|
|
84
|
+
|
|
85
|
+
batch.transition!(:processing)
|
|
86
|
+
batch.transition!(:ready, git_sha: "abc123")
|
|
87
|
+
assert_equal "abc123", batch.git_sha
|
|
88
|
+
assert_raises(ArgumentError) { batch.transition!(:submitted) }
|
|
89
|
+
batch.transition!(:applied)
|
|
90
|
+
assert batch.applied_at
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# -- phase 3: machine endpoints ------------------------------------------
|
|
94
|
+
|
|
95
|
+
test "export 404s without a configured token and 401s with a wrong one" do
|
|
96
|
+
draft_widget_field!
|
|
97
|
+
batch = InlineForms::SchemaBatch.last.submit!
|
|
98
|
+
|
|
99
|
+
get inline_forms_schema_export_path(batch)
|
|
100
|
+
assert_response :not_found
|
|
101
|
+
|
|
102
|
+
InlineFormsSchemaEdit.export_token = "sekret"
|
|
103
|
+
get inline_forms_schema_export_path(batch), headers: { "Authorization" => "Bearer wrong" }
|
|
104
|
+
assert_response :unauthorized
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
test "export returns the sealed payload; draft batches are refused" do
|
|
108
|
+
InlineFormsSchemaEdit.export_token = "sekret"
|
|
109
|
+
draft_widget_field!
|
|
110
|
+
batch = InlineForms::SchemaBatch.last
|
|
111
|
+
|
|
112
|
+
get inline_forms_schema_export_path(batch), headers: { "Authorization" => "Bearer sekret" }
|
|
113
|
+
assert_response :conflict
|
|
114
|
+
|
|
115
|
+
batch.submit!
|
|
116
|
+
get inline_forms_schema_export_path(batch), headers: { "Authorization" => "Bearer sekret" }
|
|
117
|
+
assert_response :success
|
|
118
|
+
payload = JSON.parse(response.body)
|
|
119
|
+
assert_equal 1, payload["format"]
|
|
120
|
+
assert_equal batch.content_digest, payload["digest"]
|
|
121
|
+
assert_equal "warehouse_note", payload["intents"].first["attribute"]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
test "status callback drives the batch through the pipeline" do
|
|
125
|
+
InlineFormsSchemaEdit.export_token = "sekret"
|
|
126
|
+
draft_widget_field!
|
|
127
|
+
batch = InlineForms::SchemaBatch.last.submit!
|
|
128
|
+
|
|
129
|
+
post inline_forms_schema_batch_status_path(batch),
|
|
130
|
+
params: { status: "processing" }, headers: { "Authorization" => "Bearer sekret" }
|
|
131
|
+
assert_response :success
|
|
132
|
+
assert_equal "processing", batch.reload.status
|
|
133
|
+
|
|
134
|
+
post inline_forms_schema_batch_status_path(batch),
|
|
135
|
+
params: { status: "applied" }, headers: { "Authorization" => "Bearer sekret" }
|
|
136
|
+
assert_response :unprocessable_entity, "processing -> applied skips ready"
|
|
137
|
+
|
|
138
|
+
post inline_forms_schema_batch_status_path(batch),
|
|
139
|
+
params: { status: "failed", error: "test gate red" },
|
|
140
|
+
headers: { "Authorization" => "Bearer sekret" }
|
|
141
|
+
assert_equal "failed", batch.reload.status
|
|
142
|
+
assert_equal "test gate red", batch.error
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# -- phase 2: export/import round trip -----------------------------------
|
|
146
|
+
|
|
147
|
+
test "import verifies the digest and replays intents through the executor" do
|
|
148
|
+
draft_widget_field!
|
|
149
|
+
batch = InlineForms::SchemaBatch.last.submit!
|
|
150
|
+
|
|
151
|
+
payload = InlineFormsSchemaEdit::BatchExport.payload(batch)
|
|
152
|
+
|
|
153
|
+
recorded = []
|
|
154
|
+
labels = []
|
|
155
|
+
import = InlineFormsSchemaEdit::BatchImport.new(
|
|
156
|
+
payload,
|
|
157
|
+
executor: ->(args, _root) { recorded << args },
|
|
158
|
+
label_writer: ->(**kwargs) { labels << kwargs; "/dev/null/labels.yml" }
|
|
159
|
+
)
|
|
160
|
+
result = import.apply!(destination_root: Dir.tmpdir)
|
|
161
|
+
|
|
162
|
+
assert_equal 1, result.applied
|
|
163
|
+
assert_equal [ "Widget", "warehouse_note:text_field", "--after=name" ], recorded.first
|
|
164
|
+
assert_equal "Warehouse note", labels.first[:label]
|
|
165
|
+
assert_includes result.plan.join("\n"), "inline_forms_addto Widget warehouse_note:text_field"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
test "import rejects a tampered payload (digest mismatch) and stale intents" do
|
|
169
|
+
draft_widget_field!
|
|
170
|
+
batch = InlineForms::SchemaBatch.last.submit!
|
|
171
|
+
payload = InlineFormsSchemaEdit::BatchExport.payload(batch)
|
|
172
|
+
|
|
173
|
+
tampered = payload.deep_dup
|
|
174
|
+
tampered["intents"].first["attribute"] = "evil_column"
|
|
175
|
+
error = assert_raises(InlineFormsSchemaEdit::BatchImport::ImportError) do
|
|
176
|
+
InlineFormsSchemaEdit::BatchImport.new(tampered).verify!
|
|
177
|
+
end
|
|
178
|
+
assert_match(/digest mismatch/, error.message)
|
|
179
|
+
|
|
180
|
+
# A column that already exists in THIS checkout fails per-intent validation.
|
|
181
|
+
stale = InlineFormsSchemaEdit::BatchExport.payload(batch)
|
|
182
|
+
stale["intents"].first["attribute"] = "name"
|
|
183
|
+
stale["digest"] = "sha256:#{Digest::SHA256.hexdigest(JSON.generate(stale['intents']))}"
|
|
184
|
+
error = assert_raises(InlineFormsSchemaEdit::BatchImport::ImportError) do
|
|
185
|
+
InlineFormsSchemaEdit::BatchImport.new(stale).verify!
|
|
186
|
+
end
|
|
187
|
+
assert_match(/already has a name column/, error.message)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../integration_test_helper"
|
|
4
|
+
|
|
5
|
+
# The dev-only schema-change GUI (InlineForms::SchemaController): new -> preview
|
|
6
|
+
# (no migration) -> apply (runs the addto generator, no db:migrate). Apply is
|
|
7
|
+
# exercised with a RECORDING executor so the suite never mutates the dummy tree.
|
|
8
|
+
class SchemaEditTest < InlineFormsIntegrationTestCase
|
|
9
|
+
def teardown
|
|
10
|
+
InlineForms::SchemaController.generator_executor = nil
|
|
11
|
+
InlineForms::SchemaController.label_writer = nil
|
|
12
|
+
super
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "new renders the form with supported elements" do
|
|
16
|
+
get inline_forms_schema_new_path
|
|
17
|
+
assert_response :success
|
|
18
|
+
assert_includes response.body, "Model"
|
|
19
|
+
assert_includes response.body, "Form element"
|
|
20
|
+
assert_includes response.body, "text_field"
|
|
21
|
+
assert_includes response.body, "Preview"
|
|
22
|
+
# data-turbo opt-out so the standalone utility navigates on POST
|
|
23
|
+
assert_includes response.body, %(data-turbo="false")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test "info is not offered and is rejected; header is not a scalar field" do
|
|
27
|
+
refute_includes InlineForms::SchemaPreview.supported_form_elements, :header
|
|
28
|
+
refute_includes InlineForms::SchemaPreview.supported_form_elements, :info
|
|
29
|
+
|
|
30
|
+
post inline_forms_schema_preview_path,
|
|
31
|
+
params: { model_name: "Widget", attribute: "meta", form_element: "info" }
|
|
32
|
+
assert_response :success
|
|
33
|
+
assert_includes response.body, "Unsupported form element"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
test "header preview adds a no-column row (no migration, no widget)" do
|
|
37
|
+
post inline_forms_schema_preview_path,
|
|
38
|
+
params: { model_name: "Widget", attribute: "section_title",
|
|
39
|
+
form_element: "header", after: "name", label: "Section" }
|
|
40
|
+
assert_response :success
|
|
41
|
+
assert_includes response.body, "no column, no migration"
|
|
42
|
+
assert_includes response.body, "section_title (new)"
|
|
43
|
+
# header shows its label, not an input widget
|
|
44
|
+
assert_includes response.body, "Section"
|
|
45
|
+
refute_includes response.body, %(name="section_title")
|
|
46
|
+
refute_includes Widget.column_names, "section_title"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test "header apply invokes the generator without a column (no migration)" do
|
|
50
|
+
recorded = []
|
|
51
|
+
InlineForms::SchemaController.generator_executor = ->(args, _root) { recorded << args }
|
|
52
|
+
|
|
53
|
+
post inline_forms_schema_path,
|
|
54
|
+
params: { model_name: "Widget", attribute: "section_title", form_element: "header" }
|
|
55
|
+
assert_response :success
|
|
56
|
+
assert_includes response.body, "header"
|
|
57
|
+
assert_includes response.body, "no migration"
|
|
58
|
+
assert_equal [ "Widget", "section_title:header" ], recorded.first
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
test "a label is written through the injected label writer" do
|
|
62
|
+
recorded = []
|
|
63
|
+
InlineForms::SchemaController.generator_executor = ->(_args, _root) { }
|
|
64
|
+
InlineForms::SchemaController.label_writer = ->(**kw) { recorded << kw; "/tmp/inline_forms_labels.en.yml" }
|
|
65
|
+
|
|
66
|
+
post inline_forms_schema_path,
|
|
67
|
+
params: { model_name: "Widget", attribute: "section_title", form_element: "header",
|
|
68
|
+
label: "Section", locale: "en" }
|
|
69
|
+
assert_response :success
|
|
70
|
+
assert_includes response.body, "Wrote label"
|
|
71
|
+
assert_equal 1, recorded.size
|
|
72
|
+
assert_equal :section_title, recorded.first[:attribute]
|
|
73
|
+
assert_equal "Section", recorded.first[:label]
|
|
74
|
+
assert_equal "en", recorded.first[:locale]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
test "preview shows the field at the right position with no migration" do
|
|
78
|
+
post inline_forms_schema_preview_path,
|
|
79
|
+
params: { model_name: "Widget", attribute: "internal_note",
|
|
80
|
+
form_element: "text_field", after: "name" }
|
|
81
|
+
assert_response :success
|
|
82
|
+
assert_includes response.body, "internal_note (new)"
|
|
83
|
+
# rendered live widget for the new field
|
|
84
|
+
assert_includes response.body, %(name="internal_note")
|
|
85
|
+
# placement: internal_note appears after name in the rendered order
|
|
86
|
+
assert response.body.index("name (new)").nil?
|
|
87
|
+
assert response.body.index(">name<") < response.body.index("internal_note (new)")
|
|
88
|
+
|
|
89
|
+
# No schema change happened.
|
|
90
|
+
refute_includes Widget.column_names, "internal_note"
|
|
91
|
+
assert_empty Dir.glob(Rails.root.join("db/migrate/*_inline_forms_add_to_*.rb"))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
test "an unsupported (non-scalar) element is rejected with an error" do
|
|
95
|
+
post inline_forms_schema_preview_path,
|
|
96
|
+
params: { model_name: "Widget", attribute: "vendor", form_element: "dropdown" }
|
|
97
|
+
assert_response :success
|
|
98
|
+
assert_includes response.body, "Unsupported form element"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
test "a value-bearing element previews with a placeholder values hash (no raise)" do
|
|
102
|
+
post inline_forms_schema_preview_path,
|
|
103
|
+
params: { model_name: "Widget", attribute: "rank",
|
|
104
|
+
form_element: "dropdown_with_values_with_stars", after: "name" }
|
|
105
|
+
assert_response :success
|
|
106
|
+
assert_includes response.body, "rank (new)"
|
|
107
|
+
assert_includes response.body, "placeholder values hash"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
test "invalid input re-renders the form with an error" do
|
|
111
|
+
post inline_forms_schema_preview_path,
|
|
112
|
+
params: { model_name: "Widget", attribute: "Bad Name", form_element: "text_field" }
|
|
113
|
+
assert_response :success
|
|
114
|
+
assert_includes response.body, "lowercase letters"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
test "apply invokes the generator (no db:migrate) via the injected executor" do
|
|
118
|
+
recorded = []
|
|
119
|
+
InlineForms::SchemaController.generator_executor = ->(args, _root) { recorded << args }
|
|
120
|
+
|
|
121
|
+
post inline_forms_schema_path,
|
|
122
|
+
params: { model_name: "Widget", attribute: "internal_note",
|
|
123
|
+
form_element: "text_field", after: "name" }
|
|
124
|
+
assert_response :success
|
|
125
|
+
assert_includes response.body, "Applied"
|
|
126
|
+
assert_includes response.body, "db:migrate" # the "you run this" instruction
|
|
127
|
+
assert_equal 1, recorded.size
|
|
128
|
+
assert_equal [ "Widget", "internal_note:text_field", "--after=name" ], recorded.first
|
|
129
|
+
# The generator never wrote a migration (recorder), and we never migrated.
|
|
130
|
+
refute_includes Widget.column_names, "internal_note"
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
test "reachable only outside production" do
|
|
134
|
+
original = Rails.env
|
|
135
|
+
Rails.env = ActiveSupport::StringInquirer.new("production")
|
|
136
|
+
get inline_forms_schema_new_path
|
|
137
|
+
assert_response :not_found
|
|
138
|
+
ensure
|
|
139
|
+
Rails.env = original
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../integration_test_helper"
|
|
4
|
+
|
|
5
|
+
# Cheap preview of a SchemaIntent against the dummy app: a virtual typed
|
|
6
|
+
# attribute on a throwaway subclass + an AttributeList with the proposed row
|
|
7
|
+
# spliced in — no migration, no column, real class/table untouched.
|
|
8
|
+
class SchemaPreviewTest < InlineFormsIntegrationTestCase
|
|
9
|
+
def scalar_intent(**overrides)
|
|
10
|
+
InlineForms::SchemaIntent.new(
|
|
11
|
+
**{ model_name: "Widget", attribute: :internal_note, form_element: :text_field }.merge(overrides)
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "supported? is true for scalar elements, false for relations/uploaders/virtuals" do
|
|
16
|
+
assert InlineForms::SchemaPreview.supported?(scalar_intent(form_element: :text_field))
|
|
17
|
+
assert InlineForms::SchemaPreview.supported?(scalar_intent(form_element: :integer_field))
|
|
18
|
+
assert InlineForms::SchemaPreview.supported?(scalar_intent(form_element: :date_select))
|
|
19
|
+
assert InlineForms::SchemaPreview.supported?(scalar_intent(form_element: :check_box))
|
|
20
|
+
refute InlineForms::SchemaPreview.supported?(scalar_intent(form_element: :dropdown))
|
|
21
|
+
refute InlineForms::SchemaPreview.supported?(scalar_intent(form_element: :rich_text))
|
|
22
|
+
refute InlineForms::SchemaPreview.supported?(scalar_intent(form_element: :image_field))
|
|
23
|
+
refute InlineForms::SchemaPreview.supported?(scalar_intent(form_element: :money_field))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test "preview object carries the proposed attribute as a virtual, no column" do
|
|
27
|
+
object, = InlineForms::SchemaPreview.build(scalar_intent)
|
|
28
|
+
|
|
29
|
+
assert object.respond_to?(:internal_note), "preview should expose the virtual attribute"
|
|
30
|
+
assert_nil object.internal_note, "virtual attribute defaults to nil with no column"
|
|
31
|
+
object.internal_note = "boiler serviced"
|
|
32
|
+
assert_equal "boiler serviced", object.internal_note, "virtual attribute is writable in memory"
|
|
33
|
+
|
|
34
|
+
# The real class/table are untouched.
|
|
35
|
+
refute_includes Widget.column_names, "internal_note"
|
|
36
|
+
assert_equal "Widget", object.class.name, "preview masquerades as the base class"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test "preview attribute_list splices the row at --after" do
|
|
40
|
+
_, list = InlineForms::SchemaPreview.build(scalar_intent(after: :name))
|
|
41
|
+
assert_kind_of InlineForms::AttributeList, list
|
|
42
|
+
assert_equal :internal_note, list.names[list.index_of(:name) + 1]
|
|
43
|
+
# original rows are preserved
|
|
44
|
+
assert list.include_attribute?(:priority)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
test "preview attribute_list appends when no anchor given" do
|
|
48
|
+
_, list = InlineForms::SchemaPreview.build(scalar_intent)
|
|
49
|
+
assert_equal :internal_note, list.names.last
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test "preview seeds existing attributes from a base record" do
|
|
53
|
+
widget = Widget.create!(name: "Base", priority: 2)
|
|
54
|
+
object, = InlineForms::SchemaPreview.build(scalar_intent, widget)
|
|
55
|
+
assert_equal "Base", object.name, "existing data is carried into the preview"
|
|
56
|
+
assert_nil object.internal_note
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test "building a preview does not add a column to the real table" do
|
|
60
|
+
before = Widget.column_names.dup
|
|
61
|
+
InlineForms::SchemaPreview.build(scalar_intent(after: :name))
|
|
62
|
+
Widget.reset_column_information
|
|
63
|
+
assert_equal before, Widget.column_names
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Boots the test/dummy host app for the engine's integration tests. Fast path
|
|
4
|
+
# (seconds) next to the full release gate (build gems -> inline_forms create
|
|
5
|
+
# MyApp --example -> rails test); catches controller/view/Turbo regressions
|
|
6
|
+
# without an install cycle. See stuff/prompt/test-the-example-app.md for the
|
|
7
|
+
# release gate, which remains authoritative.
|
|
8
|
+
ENV["RAILS_ENV"] = "test"
|
|
9
|
+
|
|
10
|
+
require_relative "dummy/config/environment"
|
|
11
|
+
require "rails/test_help"
|
|
12
|
+
require "minitest/autorun"
|
|
13
|
+
|
|
14
|
+
# In-memory SQLite: define the schema on every boot (maintain_test_schema is
|
|
15
|
+
# off; there are no migration files to run).
|
|
16
|
+
ActiveRecord::Schema.verbose = false
|
|
17
|
+
ActiveRecord::Schema.define do
|
|
18
|
+
create_table :widgets, force: true do |t|
|
|
19
|
+
t.string :name
|
|
20
|
+
t.text :notes
|
|
21
|
+
t.date :released_on
|
|
22
|
+
t.time :meeting_at
|
|
23
|
+
t.date :start_month
|
|
24
|
+
t.integer :priority
|
|
25
|
+
t.boolean :active
|
|
26
|
+
t.integer :kind_id
|
|
27
|
+
t.string :kind_other
|
|
28
|
+
t.integer :rating
|
|
29
|
+
t.string :manual
|
|
30
|
+
t.string :accent
|
|
31
|
+
t.timestamps
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
create_table :kinds, force: true do |t|
|
|
35
|
+
t.string :name
|
|
36
|
+
t.timestamps
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Machine has_many :parts with an :associated panel (open-after-create).
|
|
40
|
+
create_table :machines, force: true do |t|
|
|
41
|
+
t.string :name
|
|
42
|
+
t.timestamps
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
create_table :parts, force: true do |t|
|
|
46
|
+
t.string :name
|
|
47
|
+
t.integer :machine_id
|
|
48
|
+
t.timestamps
|
|
49
|
+
end
|
|
50
|
+
add_index :parts, :machine_id
|
|
51
|
+
|
|
52
|
+
# Gizmo intentionally has NO `pending_note` column: its attribute_list
|
|
53
|
+
# references one, modeling the inline_forms_addto pre-migrate window that
|
|
54
|
+
# InlineForms.attribute_pending_migration? gates. See
|
|
55
|
+
# test/integration/pending_migration_gate_test.rb.
|
|
56
|
+
create_table :gizmos, force: true do |t|
|
|
57
|
+
t.string :name
|
|
58
|
+
t.timestamps
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Schema-GUI batch pipeline (inline_forms_schema_edit). Mirrors the gem's
|
|
62
|
+
# install-generator migration.
|
|
63
|
+
create_table :inline_forms_schema_batches, force: true do |t|
|
|
64
|
+
t.string :status, null: false, default: "draft"
|
|
65
|
+
t.string :requested_by
|
|
66
|
+
t.datetime :submitted_at
|
|
67
|
+
t.datetime :window_at
|
|
68
|
+
t.datetime :applied_at
|
|
69
|
+
t.string :git_sha
|
|
70
|
+
t.string :content_digest
|
|
71
|
+
t.text :error
|
|
72
|
+
t.timestamps
|
|
73
|
+
end
|
|
74
|
+
add_index :inline_forms_schema_batches, :status
|
|
75
|
+
|
|
76
|
+
create_table :inline_forms_schema_intents, force: true do |t|
|
|
77
|
+
t.references :batch, null: false, index: true
|
|
78
|
+
t.string :target_model, null: false
|
|
79
|
+
t.string :attr_name, null: false
|
|
80
|
+
t.string :form_element, null: false
|
|
81
|
+
t.string :after_attr
|
|
82
|
+
t.string :before_attr
|
|
83
|
+
t.string :label
|
|
84
|
+
t.string :locale
|
|
85
|
+
t.integer :position
|
|
86
|
+
t.string :migration_version
|
|
87
|
+
t.timestamps
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# PaperTrail (paper_trail 17.x shape).
|
|
91
|
+
create_table :versions, force: true do |t|
|
|
92
|
+
t.string :item_type, null: false
|
|
93
|
+
t.bigint :item_id, null: false
|
|
94
|
+
t.string :event, null: false
|
|
95
|
+
t.string :whodunnit
|
|
96
|
+
t.text :object, limit: 1_073_741_823
|
|
97
|
+
t.text :object_changes, limit: 1_073_741_823
|
|
98
|
+
t.datetime :created_at
|
|
99
|
+
end
|
|
100
|
+
add_index :versions, [ :item_type, :item_id ]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class InlineFormsIntegrationTestCase < ActionDispatch::IntegrationTest
|
|
104
|
+
# The inline UI drives every request through a <turbo-frame>; the frame
|
|
105
|
+
# layout (turbo_rails/frame) also spares the dummy the full chrome (header
|
|
106
|
+
# needs current_user, assets, ...).
|
|
107
|
+
def frame_headers(frame_id)
|
|
108
|
+
{ "Turbo-Frame" => frame_id, "Accept" => "text/html" }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
setup do
|
|
112
|
+
Widget.delete_all
|
|
113
|
+
Kind.delete_all
|
|
114
|
+
Part.delete_all
|
|
115
|
+
Machine.delete_all
|
|
116
|
+
Gizmo.delete_all
|
|
117
|
+
PaperTrail::Version.delete_all
|
|
118
|
+
InlineForms::SchemaIntentRecord.delete_all
|
|
119
|
+
InlineForms::SchemaBatch.delete_all
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -20,7 +20,7 @@ class PlainTextConfigurationTest < Minitest::Test
|
|
|
20
20
|
|
|
21
21
|
def inline_forms_attribute_list
|
|
22
22
|
[
|
|
23
|
-
[:description, :plain_text]
|
|
23
|
+
[ :description, :plain_text ]
|
|
24
24
|
]
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -40,7 +40,7 @@ class PlainTextConfigurationTest < Minitest::Test
|
|
|
40
40
|
|
|
41
41
|
def inline_forms_attribute_list
|
|
42
42
|
[
|
|
43
|
-
[:description, :plain_text]
|
|
43
|
+
[ :description, :plain_text ]
|
|
44
44
|
]
|
|
45
45
|
end
|
|
46
46
|
end
|
|
@@ -56,7 +56,7 @@ class PlainTextConfigurationTest < Minitest::Test
|
|
|
56
56
|
|
|
57
57
|
def inline_forms_attribute_list
|
|
58
58
|
[
|
|
59
|
-
[:description, :rich_text]
|
|
59
|
+
[ :description, :rich_text ]
|
|
60
60
|
]
|
|
61
61
|
end
|
|
62
62
|
end
|