inline_forms 7.10.2 → 7.11.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 +11 -0
- data/Rakefile +18 -1
- data/docs/prompt/test-the-example-app.md +3 -3
- data/inline_forms.gemspec +6 -21
- data/lib/inline_forms/gem_files.rb +39 -0
- data/lib/inline_forms/version.rb +1 -1
- metadata +10 -76
- data/bin/inline_forms +0 -141
- data/bin/inline_forms_app_template.rb +0 -22
- data/bin/inline_forms_installer_core.rb +0 -886
- data/lib/generators/templates/capistrano/Capfile +0 -39
- data/lib/generators/templates/capistrano/deploy.rb +0 -59
- data/lib/generators/templates/capistrano/production.rb +0 -7
- data/lib/generators/templates/unicorn/production.rb +0 -39
- data/lib/installer_templates/dartsass/devise_main.scss +0 -2
- data/lib/installer_templates/dartsass/inline_forms_dartsass_builds.rb +0 -14
- data/lib/installer_templates/dartsass/inline_forms_main.scss +0 -2
- data/lib/installer_templates/example_app_tests/test/example_app/example_integration_test_case.rb +0 -36
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_field_turbo_test.rb +0 -73
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_name_list_test.rb +0 -73
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_name_required_test.rb +0 -21
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_opening_date_test.rb +0 -49
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_photos_pagination_test.rb +0 -440
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_row_turbo_test.rb +0 -103
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_top_level_new_test.rb +0 -70
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_top_level_pagination_test.rb +0 -40
- data/lib/installer_templates/example_app_tests/test/integration/example_app_apartment_versions_turbo_test.rb +0 -120
- data/lib/installer_templates/example_app_tests/test/integration/example_app_guest_access_test.rb +0 -21
- data/lib/installer_templates/example_app_tests/test/integration/example_app_photo_revert_test.rb +0 -94
- data/lib/installer_templates/example_app_tests/test/integration/example_app_photos_test.rb +0 -22
- data/lib/installer_templates/example_app_tests/test/integration/example_app_routing_test.rb +0 -15
- data/lib/installer_templates/example_app_tests/test/integration/example_app_turbo_layout_test.rb +0 -25
- data/lib/installer_templates/example_app_tests/test/integration/example_app_validation_hints_test.rb +0 -40
- data/lib/installer_templates/example_app_tests/test/models/example_app_apartment_name_validation_test.rb +0 -16
- data/lib/installer_templates/example_app_tests/test/models/example_app_apartment_photo_test.rb +0 -26
- data/lib/installer_templates/example_app_tests/test/models/example_app_paper_trail_changeset_test.rb +0 -78
- data/lib/installer_templates/example_app_tests/test/models/example_app_plain_text_rich_text_edge_cases_test.rb +0 -46
- data/lib/installer_templates/example_app_views/apartments/name_list.html.erb +0 -26
- data/lib/installer_templates/example_app_views/inline_forms/_header.html.erb +0 -45
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../example_app/example_integration_test_case"
|
|
4
|
-
|
|
5
|
-
class ExampleAppApartmentVersionsTurboTest < ExampleAppIntegrationTestCase
|
|
6
|
-
setup do
|
|
7
|
-
@apartment = Apartment.first || Apartment.create!(name: "Versions Turbo", title: "T")
|
|
8
|
-
@versions_frame = "apartment_#{@apartment.id}_versions"
|
|
9
|
-
@headers = { "Turbo-Frame" => @versions_frame, "Accept" => "text/html" }
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
test "versions list opens inside matching turbo-frame" do
|
|
13
|
-
get list_versions_apartment_path(@apartment, update: @versions_frame), headers: @headers
|
|
14
|
-
assert_response :success
|
|
15
|
-
assert_includes @response.body, %(<turbo-frame id="#{@versions_frame}">)
|
|
16
|
-
assert_includes @response.body, "Changeset"
|
|
17
|
-
refute_includes @response.body, 'data-remote="true"'
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
test "versions list close returns panel header inside turbo-frame" do
|
|
21
|
-
get list_versions_apartment_path(@apartment, update: @versions_frame, close: true),
|
|
22
|
-
headers: @headers
|
|
23
|
-
assert_response :success
|
|
24
|
-
assert_includes @response.body, %(<turbo-frame id="#{@versions_frame}">)
|
|
25
|
-
refute_includes @response.body, "Changeset"
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
test "expanded row versions open link uses Turbo not UJS remote" do
|
|
29
|
-
row_frame = "apartment_#{@apartment.id}"
|
|
30
|
-
get apartment_path(@apartment, update: row_frame),
|
|
31
|
-
headers: { "Turbo-Frame" => row_frame, "Accept" => "text/html" }
|
|
32
|
-
assert_response :success
|
|
33
|
-
assert_select "turbo-frame##{@versions_frame} a[data-turbo='true'][data-turbo-frame='#{@versions_frame}']", minimum: 1
|
|
34
|
-
refute_select "turbo-frame##{@versions_frame} a[data-remote='true']"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
test "restore link in versions list requests turbo-stream (nested versions frame)" do
|
|
38
|
-
apt = Apartment.create!(name: "Stream Link", title: "T")
|
|
39
|
-
apt.update!(title: "T2")
|
|
40
|
-
vf = "apartment_#{apt.id}_versions"
|
|
41
|
-
get list_versions_apartment_path(apt, update: vf),
|
|
42
|
-
headers: { "Turbo-Frame" => vf, "Accept" => "text/html" }
|
|
43
|
-
assert_response :success
|
|
44
|
-
assert_match(/data-turbo-stream="true"/, @response.body,
|
|
45
|
-
"restore from inside …_versions must use turbo-stream to avoid Turbo-Frame mismatch")
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
test "revert from versions list closes row via turbo-stream when Turbo-Frame is versions" do
|
|
49
|
-
apt = Apartment.create!(name: "Versions Stream Revert", title: "Before")
|
|
50
|
-
apt.update!(title: "After")
|
|
51
|
-
row_frame = "apartment_#{apt.id}"
|
|
52
|
-
versions_frame = "#{row_frame}_versions"
|
|
53
|
-
version = apt.versions.where(event: "update").order(:id).last
|
|
54
|
-
assert version, "expected an update version to revert"
|
|
55
|
-
|
|
56
|
-
post revert_apartment_path(version.id, update: row_frame),
|
|
57
|
-
headers: {
|
|
58
|
-
"Turbo-Frame" => versions_frame,
|
|
59
|
-
"Accept" => "text/vnd.turbo-stream.html"
|
|
60
|
-
}
|
|
61
|
-
assert_response :success
|
|
62
|
-
assert_includes @response.body, %(action="replace")
|
|
63
|
-
assert_includes @response.body, %(target="#{row_frame}")
|
|
64
|
-
assert_includes @response.body, %(target="#{versions_frame}")
|
|
65
|
-
assert_equal "Before", apt.reload.title
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
test "revert from versions list closes row via Turbo POST on row frame" do
|
|
69
|
-
apt = Apartment.create!(name: "Versions Revert", title: "Before")
|
|
70
|
-
apt.update!(title: "After")
|
|
71
|
-
row_frame = "apartment_#{apt.id}"
|
|
72
|
-
versions_frame = "#{row_frame}_versions"
|
|
73
|
-
# 7.9.0 dropped the `format.html` fallback in `revert`; the restore link
|
|
74
|
-
# always requests a turbo-stream now, even when the click happened on
|
|
75
|
-
# the row frame, so the test mirrors that contract.
|
|
76
|
-
row_headers = {
|
|
77
|
-
"Turbo-Frame" => row_frame,
|
|
78
|
-
"Accept" => "text/vnd.turbo-stream.html"
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
version = apt.versions.where(event: "update").order(:id).last
|
|
82
|
-
assert version, "expected an update version to revert"
|
|
83
|
-
|
|
84
|
-
post revert_apartment_path(version.id, update: row_frame), headers: row_headers
|
|
85
|
-
assert_response :success
|
|
86
|
-
assert_includes @response.body, %(action="replace")
|
|
87
|
-
assert_includes @response.body, %(target="#{row_frame}")
|
|
88
|
-
assert_includes @response.body, %(target="#{versions_frame}")
|
|
89
|
-
assert_equal "Before", apt.reload.title
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
test "revert from versions list restores rich_text body via turbo-stream" do
|
|
93
|
-
apt = Apartment.create!(name: "RichText Revert", title: "T")
|
|
94
|
-
apt.update!(description: "<p>old body</p>")
|
|
95
|
-
apt.update!(description: "<p>new body</p>")
|
|
96
|
-
|
|
97
|
-
rich_text = ActionText::RichText.find_by!(
|
|
98
|
-
record_type: Apartment.name, record_id: apt.id, name: "description"
|
|
99
|
-
)
|
|
100
|
-
rich_text_version = rich_text.versions.where(event: "update").order(:id).last
|
|
101
|
-
assert rich_text_version,
|
|
102
|
-
"expected a PaperTrail update version on ActionText::RichText for the description edit"
|
|
103
|
-
|
|
104
|
-
row_frame = "apartment_#{apt.id}"
|
|
105
|
-
versions_frame = "#{row_frame}_versions"
|
|
106
|
-
post revert_apartment_path(rich_text_version.id, update: row_frame),
|
|
107
|
-
headers: {
|
|
108
|
-
"Turbo-Frame" => versions_frame,
|
|
109
|
-
"Accept" => "text/vnd.turbo-stream.html"
|
|
110
|
-
}
|
|
111
|
-
assert_response :success
|
|
112
|
-
assert_includes @response.body, %(action="replace")
|
|
113
|
-
assert_includes @response.body, %(target="#{row_frame}")
|
|
114
|
-
assert_includes @response.body, %(target="#{versions_frame}")
|
|
115
|
-
|
|
116
|
-
apt.reload
|
|
117
|
-
assert_includes apt.description.body.to_html, "old body",
|
|
118
|
-
"rich_text revert should restore the previous body content"
|
|
119
|
-
end
|
|
120
|
-
end
|
data/lib/installer_templates/example_app_tests/test/integration/example_app_guest_access_test.rb
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "test_helper"
|
|
4
|
-
require "devise/test/integration_helpers"
|
|
5
|
-
|
|
6
|
-
class ExampleAppGuestAccessTest < ActionDispatch::IntegrationTest
|
|
7
|
-
include Devise::Test::IntegrationHelpers
|
|
8
|
-
|
|
9
|
-
setup { host!("www.example.com") }
|
|
10
|
-
|
|
11
|
-
test "apartments index redirects when not signed in" do
|
|
12
|
-
get apartments_path
|
|
13
|
-
assert_response :redirect
|
|
14
|
-
assert_match %r{/auth/users/sign_in}, @response.redirect_url
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
test "root redirects when not signed in" do
|
|
18
|
-
get root_path
|
|
19
|
-
assert_response :redirect
|
|
20
|
-
end
|
|
21
|
-
end
|
data/lib/installer_templates/example_app_tests/test/integration/example_app_photo_revert_test.rb
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../example_app/example_integration_test_case"
|
|
4
|
-
|
|
5
|
-
# 7.9.0 regression: revert from the versions panel for a Photo whose
|
|
6
|
-
# `image` column changed must put back the previous CarrierWave file
|
|
7
|
-
# bytes, not just the previous filename string. Relies on the
|
|
8
|
-
# `ImageUploader` knobs the installer ships:
|
|
9
|
-
#
|
|
10
|
-
# * `CarrierWave.configure { config.remove_previously_stored_files_after_update = false }`
|
|
11
|
-
# (config/initializers/carrierwave.rb)
|
|
12
|
-
# * `remove!` no-op
|
|
13
|
-
# * unique per-upload filename prefix
|
|
14
|
-
#
|
|
15
|
-
# See https://stackoverflow.com/questions/9423279/papertrail-and-carrierwave
|
|
16
|
-
class ExampleAppPhotoRevertTest < ExampleAppIntegrationTestCase
|
|
17
|
-
# Mirror the setup of ExampleAppApartmentPhotosPaginationTest: re-seed
|
|
18
|
-
# Konferensha photos from db/seed_images/ so the test asserts against
|
|
19
|
-
# real CarrierWave file mounts without depending on dev DB state.
|
|
20
|
-
setup do
|
|
21
|
-
@apartment = Apartment.find_or_create_by!(name: "Konferensha") do |a|
|
|
22
|
-
a.title = "Konferensha sobre Papiamentu"
|
|
23
|
-
end
|
|
24
|
-
seed_dir = Rails.root.join("db", "seed_images")
|
|
25
|
-
if seed_dir.directory?
|
|
26
|
-
Dir.glob(seed_dir.join("*.{jpg,jpeg,png,gif}"), File::FNM_CASEFOLD).sort.each do |abs|
|
|
27
|
-
base = File.basename(abs)
|
|
28
|
-
next if Photo.exists?(name: base, apartment_id: @apartment.id)
|
|
29
|
-
File.open(abs, "rb") do |io|
|
|
30
|
-
Photo.create!(
|
|
31
|
-
name: base,
|
|
32
|
-
caption: "Konferensha foto #{base}",
|
|
33
|
-
apartment: @apartment,
|
|
34
|
-
image: io
|
|
35
|
-
)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
test "revert restores previous CarrierWave file bytes on disk" do
|
|
42
|
-
photo = @apartment.photos.first!
|
|
43
|
-
original_identifier = photo.image.identifier
|
|
44
|
-
original_path = photo.image.path
|
|
45
|
-
assert File.exist?(original_path), "expected seeded photo file on disk: #{original_path}"
|
|
46
|
-
original_size = File.size(original_path)
|
|
47
|
-
|
|
48
|
-
seed_dir = Rails.root.join("db", "seed_images")
|
|
49
|
-
jpgs = Dir.glob(seed_dir.join("*.{jpg,jpeg}"), File::FNM_CASEFOLD).sort
|
|
50
|
-
replacement = jpgs.find { |abs| File.basename(abs) != photo.name } || jpgs.last
|
|
51
|
-
assert replacement, "need at least one seed jpg different from the photo's current mount"
|
|
52
|
-
refute_equal File.size(replacement), original_size,
|
|
53
|
-
"test needs a replacement file with a different byte length so the assertion is meaningful"
|
|
54
|
-
|
|
55
|
-
frame_id = "apartment_#{@apartment.id}_photo_#{photo.id}_image"
|
|
56
|
-
turbo_headers = { "Turbo-Frame" => frame_id, "Accept" => "text/html" }
|
|
57
|
-
uploaded = Rack::Test::UploadedFile.new(replacement, "image/jpeg")
|
|
58
|
-
put photo_path(
|
|
59
|
-
photo,
|
|
60
|
-
attribute: "image",
|
|
61
|
-
form_element: "image_field",
|
|
62
|
-
update: frame_id
|
|
63
|
-
),
|
|
64
|
-
params: { image: uploaded },
|
|
65
|
-
headers: turbo_headers
|
|
66
|
-
assert_response :success
|
|
67
|
-
photo.reload
|
|
68
|
-
refute_equal original_identifier, photo.image.identifier,
|
|
69
|
-
"update should have changed the image identifier"
|
|
70
|
-
|
|
71
|
-
version = photo.versions.where(event: "update").order(:id).last
|
|
72
|
-
assert version, "expected a Photo update version after the image PUT"
|
|
73
|
-
|
|
74
|
-
row_frame = "apartment_#{@apartment.id}_photo_#{photo.id}"
|
|
75
|
-
versions_frame = "apartment_#{@apartment.id}_photo_#{photo.id}_versions"
|
|
76
|
-
post revert_photo_path(version.id, update: row_frame),
|
|
77
|
-
headers: {
|
|
78
|
-
"Turbo-Frame" => versions_frame,
|
|
79
|
-
"Accept" => "text/vnd.turbo-stream.html"
|
|
80
|
-
}
|
|
81
|
-
assert_response :success
|
|
82
|
-
assert_includes @response.body, %(action="replace")
|
|
83
|
-
assert_includes @response.body, %(target="#{row_frame}")
|
|
84
|
-
assert_includes @response.body, %(target="#{versions_frame}")
|
|
85
|
-
|
|
86
|
-
photo.reload
|
|
87
|
-
assert_equal original_identifier, photo.image.identifier,
|
|
88
|
-
"revert should restore the previous CarrierWave identifier"
|
|
89
|
-
assert File.exist?(photo.image.path),
|
|
90
|
-
"revert should leave the previous file bytes on disk (carrierwave config)"
|
|
91
|
-
assert_equal original_size, File.size(photo.image.path),
|
|
92
|
-
"previous file bytes must be byte-identical to the original"
|
|
93
|
-
end
|
|
94
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../example_app/example_integration_test_case"
|
|
4
|
-
|
|
5
|
-
class ExampleAppPhotosTest < ExampleAppIntegrationTestCase
|
|
6
|
-
setup do
|
|
7
|
-
@apartment = Apartment.create!(name: "Beach", title: "Ocean view")
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
test "photos are not served as standalone html resource" do
|
|
11
|
-
assert Photo.not_accessible_through_html?
|
|
12
|
-
assert_raises(ActionController::UnknownFormat) do
|
|
13
|
-
get photos_path
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
test "can create a photo for an apartment" do
|
|
18
|
-
assert_difference("Photo.count", 1) do
|
|
19
|
-
Photo.create!(name: "Sunset", apartment: @apartment)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../example_app/example_integration_test_case"
|
|
4
|
-
|
|
5
|
-
class ExampleAppRoutingTest < ExampleAppIntegrationTestCase
|
|
6
|
-
test "root routes to apartments index" do
|
|
7
|
-
get root_path
|
|
8
|
-
assert_response :success
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
test "apartments index is reachable when signed in" do
|
|
12
|
-
get apartments_path
|
|
13
|
-
assert_response :success
|
|
14
|
-
end
|
|
15
|
-
end
|
data/lib/installer_templates/example_app_tests/test/integration/example_app_turbo_layout_test.rb
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../example_app/example_integration_test_case"
|
|
4
|
-
|
|
5
|
-
# Smoke test: layouts load Turbo as an ES module (no Sprockets ESM parse error).
|
|
6
|
-
# Step 5 (7.8.0) leaves Turbo Drive at its default (enabled); inline flows use
|
|
7
|
-
# `<turbo-frame>` + HTML, not jquery-ujs.
|
|
8
|
-
class ExampleAppTurboLayoutTest < ExampleAppIntegrationTestCase
|
|
9
|
-
test "inline_forms layout loads turbo.min.js as an ES module" do
|
|
10
|
-
get apartments_path
|
|
11
|
-
assert_response :success
|
|
12
|
-
|
|
13
|
-
assert_match(
|
|
14
|
-
%r{<script\s+type="module">\s*import\s+\{\s*Turbo\s*\}\s+from\s+"[^"]*turbo\.min(?:-[a-f0-9]+)?\.js"}m,
|
|
15
|
-
@response.body,
|
|
16
|
-
"expected the inline_forms layout to import turbo.min.js as a module"
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
refute_match(
|
|
20
|
-
/Turbo\.session\.drive\s*=\s*false/,
|
|
21
|
-
@response.body,
|
|
22
|
-
"Step 5 enables Turbo Drive by default; disabling it would regress full-page Turbo"
|
|
23
|
-
)
|
|
24
|
-
end
|
|
25
|
-
end
|
data/lib/installer_templates/example_app_tests/test/integration/example_app_validation_hints_test.rb
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../example_app/example_integration_test_case"
|
|
4
|
-
|
|
5
|
-
class ExampleAppValidationHintsTest < ExampleAppIntegrationTestCase
|
|
6
|
-
setup do
|
|
7
|
-
@apartment = Apartment.find_or_create_by!(name: "Konferensha") do |a|
|
|
8
|
-
a.title = "Konferensha sobre Papiamentu"
|
|
9
|
-
end
|
|
10
|
-
@row_frame = "apartment_#{@apartment.id}"
|
|
11
|
-
@row_headers = { "Turbo-Frame" => @row_frame, "Accept" => "text/html" }
|
|
12
|
-
@list_frame = "apartments_list"
|
|
13
|
-
@list_headers = { "Turbo-Frame" => @list_frame, "Accept" => "text/html" }
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
test "show panel name label uses hidden HTML source not title attribute" do
|
|
17
|
-
get apartment_path(@apartment, update: @row_frame), headers: @row_headers
|
|
18
|
-
assert_response :success
|
|
19
|
-
|
|
20
|
-
hint_id = "validation_hints_apartment_#{@apartment.id}_name"
|
|
21
|
-
assert_includes @response.body, %(class="validation-hint-trigger has-tip tip-top")
|
|
22
|
-
assert_includes @response.body, %(data-validation-hints-source="#{hint_id}")
|
|
23
|
-
assert_includes @response.body, %(id="#{hint_id}")
|
|
24
|
-
assert_includes @response.body, "Name can't be blank"
|
|
25
|
-
assert_includes @response.body, '<ul class="validation-hints-list">'
|
|
26
|
-
refute_match(%r{title="<ul}, @response.body)
|
|
27
|
-
refute_match(%r{title='<ul}, @response.body)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
test "new apartment form shows validation hint on name" do
|
|
31
|
-
get new_apartment_path(update: @list_frame), headers: @list_headers
|
|
32
|
-
assert_response :success
|
|
33
|
-
|
|
34
|
-
hint_id = "validation_hints_apartment_new_name"
|
|
35
|
-
assert_includes @response.body, %(data-validation-hints-source="#{hint_id}")
|
|
36
|
-
assert_includes @response.body, %(id="#{hint_id}")
|
|
37
|
-
assert_includes @response.body, "Name can't be blank"
|
|
38
|
-
assert_includes @response.body, '<ul class="validation-hints-list">'
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "test_helper"
|
|
4
|
-
|
|
5
|
-
class ExampleAppApartmentNameValidationTest < ActiveSupport::TestCase
|
|
6
|
-
test "apartment requires name" do
|
|
7
|
-
apartment = Apartment.new(title: "No name")
|
|
8
|
-
assert_not apartment.valid?
|
|
9
|
-
assert_includes apartment.errors[:name], "can't be blank"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
test "apartment is valid with name" do
|
|
13
|
-
apartment = Apartment.new(name: "North", title: "Tower")
|
|
14
|
-
assert apartment.valid?
|
|
15
|
-
end
|
|
16
|
-
end
|
data/lib/installer_templates/example_app_tests/test/models/example_app_apartment_photo_test.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "test_helper"
|
|
4
|
-
|
|
5
|
-
class ExampleAppApartmentPhotoTest < ActiveSupport::TestCase
|
|
6
|
-
setup do
|
|
7
|
-
@apartment = Apartment.create!(name: "North", title: "Tower")
|
|
8
|
-
@photo = Photo.create!(name: "Lobby", apartment: @apartment)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
test "photo belongs to apartment" do
|
|
12
|
-
assert_equal @apartment, @photo.apartment
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
test "apartment has many photos" do
|
|
16
|
-
assert_includes @apartment.photos.to_a, @photo
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
test "photo model hides resource from standalone html crud" do
|
|
20
|
-
assert Photo.not_accessible_through_html?
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
test "apartment model allows standalone html crud" do
|
|
24
|
-
assert_not Apartment.not_accessible_through_html?
|
|
25
|
-
end
|
|
26
|
-
end
|
data/lib/installer_templates/example_app_tests/test/models/example_app_paper_trail_changeset_test.rb
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "test_helper"
|
|
4
|
-
|
|
5
|
-
# Regression: PaperTrail (>= 13) deserializes `versions.object_changes` via
|
|
6
|
-
# `YAML.safe_load`, using `ActiveRecord.yaml_column_permitted_classes` as the
|
|
7
|
-
# allow-list. Rails 7's default is `[Symbol]`, so any update that touches
|
|
8
|
-
# `updated_at` (an `ActiveSupport::TimeWithZone`) raises `Psych::DisallowedClass`
|
|
9
|
-
# inside `version.changeset`, and PaperTrail rescues that into `{}`. The
|
|
10
|
-
# inline_forms versions list then renders every changeset as `empty`.
|
|
11
|
-
#
|
|
12
|
-
# The installer ships `config/initializers/paper_trail_yaml_safe_load.rb`,
|
|
13
|
-
# which extends the allow-list. This test fails if that initializer is
|
|
14
|
-
# missing or insufficient.
|
|
15
|
-
class ExampleAppPaperTrailChangesetTest < ActiveSupport::TestCase
|
|
16
|
-
test "version.changeset round-trips a normal update" do
|
|
17
|
-
PaperTrail.request.whodunnit = "test"
|
|
18
|
-
|
|
19
|
-
apartment = Apartment.create!(name: "Original", title: "Old Title")
|
|
20
|
-
apartment.update!(name: "Renamed", title: "New Title")
|
|
21
|
-
|
|
22
|
-
version = apartment.versions.last
|
|
23
|
-
assert_equal "update", version.event,
|
|
24
|
-
"expected an update version to be recorded by paper_trail"
|
|
25
|
-
|
|
26
|
-
changeset = version.changeset
|
|
27
|
-
assert_kind_of Hash, changeset
|
|
28
|
-
refute_empty changeset,
|
|
29
|
-
"version.changeset is empty; PaperTrail's YAML.safe_load probably hit a " \
|
|
30
|
-
"DisallowedClass and returned {}. Check " \
|
|
31
|
-
"config/initializers/paper_trail_yaml_safe_load.rb and the Rails " \
|
|
32
|
-
"ActiveRecord.yaml_column_permitted_classes setting."
|
|
33
|
-
|
|
34
|
-
assert_equal ["Original", "Renamed"], changeset["name"]
|
|
35
|
-
assert_equal ["Old Title", "New Title"], changeset["title"]
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# `has_rich_text :description` lives in the `action_text_rich_texts` table,
|
|
39
|
-
# so `has_paper_trail` on Apartment cannot see body edits. The installer adds
|
|
40
|
-
# `config/initializers/rich_text_paper_trail.rb` (which declares
|
|
41
|
-
# `has_paper_trail` on `ActionText::RichText`), and `inline_forms_versions_for`
|
|
42
|
-
# merges rich-text versions into the parent's history. This test fails if
|
|
43
|
-
# either piece regresses.
|
|
44
|
-
test "rich_text edits surface in the merged versions list for the parent" do
|
|
45
|
-
PaperTrail.request.whodunnit = "test"
|
|
46
|
-
|
|
47
|
-
apartment = Apartment.create!(name: "RT", title: "RT", description: "v1 body")
|
|
48
|
-
apartment.update!(description: "v2 body")
|
|
49
|
-
|
|
50
|
-
rich_text = ActionText::RichText.find_by!(
|
|
51
|
-
record_type: Apartment.name, record_id: apartment.id, name: "description"
|
|
52
|
-
)
|
|
53
|
-
assert rich_text.respond_to?(:versions),
|
|
54
|
-
"ActionText::RichText is missing has_paper_trail; check " \
|
|
55
|
-
"config/initializers/rich_text_paper_trail.rb"
|
|
56
|
-
refute_empty rich_text.versions,
|
|
57
|
-
"no PaperTrail versions on ActionText::RichText; the on_load hook " \
|
|
58
|
-
"in config/initializers/rich_text_paper_trail.rb did not fire or " \
|
|
59
|
-
"has_paper_trail was not applied"
|
|
60
|
-
|
|
61
|
-
helper = Class.new { include InlineFormsHelper }.new
|
|
62
|
-
entries = helper.inline_forms_versions_for(apartment)
|
|
63
|
-
|
|
64
|
-
rich_text_entries = entries.select { |e| e[:kind] == :rich_text }
|
|
65
|
-
refute_empty rich_text_entries,
|
|
66
|
-
"inline_forms_versions_for did not return any rich_text entries"
|
|
67
|
-
|
|
68
|
-
body_changes = rich_text_entries
|
|
69
|
-
.map { |e| e[:version].changeset }
|
|
70
|
-
.select { |cs| cs && cs["body"].is_a?(Array) }
|
|
71
|
-
.map { |cs| cs["body"] }
|
|
72
|
-
|
|
73
|
-
refute_empty body_changes,
|
|
74
|
-
"no body changesets recorded for ActionText::RichText"
|
|
75
|
-
assert body_changes.any? { |old, new_| old.to_s.include?("v1 body") && new_.to_s.include?("v2 body") },
|
|
76
|
-
"expected an entry whose body change moves from 'v1 body' to 'v2 body'; got #{body_changes.inspect}"
|
|
77
|
-
end
|
|
78
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "test_helper"
|
|
4
|
-
|
|
5
|
-
class ExampleAppPlainTextRichTextEdgeCasesTest < ActiveSupport::TestCase
|
|
6
|
-
def with_temporary_inline_forms_attribute_list(klass, temporary_list)
|
|
7
|
-
original = klass.instance_method(:inline_forms_attribute_list)
|
|
8
|
-
klass.define_method(:inline_forms_attribute_list) { temporary_list }
|
|
9
|
-
yield
|
|
10
|
-
ensure
|
|
11
|
-
klass.define_method(:inline_forms_attribute_list, original)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
test "plain_text mapped to actiontext-backed attribute raises configuration error" do
|
|
15
|
-
with_temporary_inline_forms_attribute_list(
|
|
16
|
-
Apartment,
|
|
17
|
-
[[:description, "description", :plain_text]]
|
|
18
|
-
) do
|
|
19
|
-
error = assert_raises(InlineForms::PlainTextColumnMissingError) do
|
|
20
|
-
InlineForms.validate_plain_text_configuration_for!(Apartment)
|
|
21
|
-
end
|
|
22
|
-
assert_includes(error.message, "description")
|
|
23
|
-
assert_includes(error.message, ":rich_text")
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
test "plain_text runtime guard raises before assigning unknown DB attribute" do
|
|
28
|
-
apartment = Apartment.create!(name: "Mismatch", title: "Check")
|
|
29
|
-
assert_raises(InlineForms::PlainTextColumnMissingError) do
|
|
30
|
-
InlineForms.assert_plain_text_column!(
|
|
31
|
-
object: apartment,
|
|
32
|
-
attribute: :description,
|
|
33
|
-
form_element: :plain_text
|
|
34
|
-
)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
test "switching text column field from plain_text to rich_text does not raise" do
|
|
39
|
-
with_temporary_inline_forms_attribute_list(
|
|
40
|
-
Role,
|
|
41
|
-
[[:description, "description", :rich_text]]
|
|
42
|
-
) do
|
|
43
|
-
InlineForms.validate_plain_text_configuration_for!(Role)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<% @inline_forms_turbo_field = true %>
|
|
2
|
-
<div class="row">
|
|
3
|
-
<div class="small-12 columns">
|
|
4
|
-
<h2>Apartment names (first 10)</h2>
|
|
5
|
-
<p>
|
|
6
|
-
<%= link_to "Back to full apartment list", apartments_path %>
|
|
7
|
-
</p>
|
|
8
|
-
<p class="help-text">
|
|
9
|
-
Each name is an inline edit via <code>text_field_show</code> — no stock
|
|
10
|
-
<code>_show</code> panel. Click a name to edit it in place.
|
|
11
|
-
</p>
|
|
12
|
-
</div>
|
|
13
|
-
</div>
|
|
14
|
-
|
|
15
|
-
<% @apartments.each do |apartment| %>
|
|
16
|
-
<div class="row">
|
|
17
|
-
<div class="small-2 columns">
|
|
18
|
-
<%= apartment.id %>
|
|
19
|
-
</div>
|
|
20
|
-
<div class="small-10 columns">
|
|
21
|
-
<turbo-frame id="apartment_<%= apartment.id %>_name">
|
|
22
|
-
<%= text_field_show(apartment, :name) %>
|
|
23
|
-
</turbo-frame>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
<% end %>
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
<div class="contain-to-grid fixed">
|
|
2
|
-
<nav id='inline_forms_application_top_bar' class="top-bar">
|
|
3
|
-
<div class="top-bar-left">
|
|
4
|
-
<ul class="menu">
|
|
5
|
-
<li class="menu-text">
|
|
6
|
-
<h1 style="margin: 0; font-size: inherit;"><a href="/"><%= application_name %> v<%= inline_forms_version %> <%= current_user.name %></a></h1>
|
|
7
|
-
</li>
|
|
8
|
-
</ul>
|
|
9
|
-
</div>
|
|
10
|
-
<div class="top-bar-right">
|
|
11
|
-
<ul class="dropdown menu" data-dropdown-menu>
|
|
12
|
-
<% if current_user.role?(:admin) || current_user.role?(:superadmin) %>
|
|
13
|
-
<li>
|
|
14
|
-
<a href="#"><%= t 'common.more' %></a>
|
|
15
|
-
<ul class="menu">
|
|
16
|
-
<% MODEL_TABS.each do |m| %>
|
|
17
|
-
<% model = m.singularize.camelcase.constantize rescue nil %>
|
|
18
|
-
<% unless model.nil? || model.not_accessible_through_html? %>
|
|
19
|
-
<% if can? :update, model %>
|
|
20
|
-
<li>
|
|
21
|
-
<%= link_to model.model_name.human, '/' + m %>
|
|
22
|
-
</li>
|
|
23
|
-
<% end %>
|
|
24
|
-
<% end %>
|
|
25
|
-
<% end %>
|
|
26
|
-
<% if can? :read, Apartment %>
|
|
27
|
-
<li>
|
|
28
|
-
<%= link_to "Apartment names (first 10)", apartment_name_list_path %>
|
|
29
|
-
</li>
|
|
30
|
-
<% end %>
|
|
31
|
-
</ul>
|
|
32
|
-
</li>
|
|
33
|
-
<% end %>
|
|
34
|
-
<li>
|
|
35
|
-
<a href="#"><%= current_user.name %></a>
|
|
36
|
-
<ul class="menu">
|
|
37
|
-
<li>
|
|
38
|
-
<%= link_to( t("common.logout"), destroy_user_session_path, :method => :delete) if current_user %>
|
|
39
|
-
</li>
|
|
40
|
-
</ul>
|
|
41
|
-
</li>
|
|
42
|
-
</ul>
|
|
43
|
-
</div>
|
|
44
|
-
</nav>
|
|
45
|
-
</div>
|