render_turbo_stream 0.1.25 → 0.1.27
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/README.md +25 -28
- data/app/views/render_turbo_stream_partials.html.erb +3 -24
- data/lib/render_turbo_stream/test_helpers.rb +34 -35
- data/lib/render_turbo_stream/version.rb +1 -1
- data/lib/render_turbo_stream.rb +6 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 71ca68293cace6bf25ae1983f0c710669d00b624173185da8d22377094a5ec09
|
|
4
|
+
data.tar.gz: 83f6948953c0bae73584aacb28e23785e8bf1308ca8c0f326488dbe1b70c6e4e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 37f7dfac016b98ca2cb9b66f92b34bd534de52e285d1de7a44cd4b3ec8efeef5c0203178ffeef28ee77dd3e66029a76cb2714b7b1b0a398e15f6c774ec1df259
|
|
7
|
+
data.tar.gz: 3a4059c7f942fedc218b716822b8cf9ef854cae5c6ee4e6e40e68a464938568984d290e85d9a915be83993640cb4c5d9cb8237ed7ef869659aedfc11fc6efca4
|
data/README.md
CHANGED
|
@@ -6,6 +6,8 @@ Working consistently with turbo_stream means shooting lots of partials from the
|
|
|
6
6
|
|
|
7
7
|
It sets the status, generates a flash message, handles redirection, pushes it all to the front and comes with predefined helpers for enabling request-specs.
|
|
8
8
|
|
|
9
|
+
An overview of how we design a rails-7 application with turbo is [published on dev.to](https://dev.to/chmich/rails-7-vite-wrapping-up-1pia).
|
|
10
|
+
|
|
9
11
|
## Installation
|
|
10
12
|
|
|
11
13
|
```ruby
|
|
@@ -83,9 +85,9 @@ stream_partial(
|
|
|
83
85
|
|
|
84
86
|
## Testing
|
|
85
87
|
|
|
86
|
-
For system testing we have Capybara. This works great and is necessary, but it is good practice to break tests into smaller pieces.
|
|
88
|
+
For system testing we have Capybara. This works great and is necessary for javascript and backend combined apps, but it is good practice to break tests into smaller pieces.
|
|
87
89
|
|
|
88
|
-
For request-level tests, there are some helpers:
|
|
90
|
+
For the much faster request-level tests, there are some helpers:
|
|
89
91
|
|
|
90
92
|
If the request format is not `turbo_stream`, which is the case on request specs, the method responds in a special html that contains the medadata that is interesting for our tests and is parsed by included test helpers. So tests could look like this:
|
|
91
93
|
|
|
@@ -100,30 +102,25 @@ RSpec.describe "Articles", type: :request do
|
|
|
100
102
|
it 'create failed' do
|
|
101
103
|
post articles_path(params: invalid_params)
|
|
102
104
|
|
|
103
|
-
#
|
|
104
|
-
expect(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
expect(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
expect(
|
|
116
|
-
|
|
117
|
-
#
|
|
118
|
-
|
|
119
|
-
expect(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
expect(partials_params_by_path['layouts/flash'].length).to eq(1)
|
|
123
|
-
expect(partials_params_by_path['layouts/flash'].first['partial']).to eq('layouts/flash')
|
|
124
|
-
|
|
125
|
-
expect(partials_html_by_path['layouts/flash'].length).to eq(1)
|
|
126
|
-
expect(partials_html_by_path['layouts/flash'].first).to include('Article could not be created')
|
|
105
|
+
# to which html-ids turbo-stream would point
|
|
106
|
+
expect(partials_ids).to include('flash-box', 'form')
|
|
107
|
+
|
|
108
|
+
# which partials where rendered
|
|
109
|
+
expect(partials_paths).to include('layouts/flash', 'articles/form')
|
|
110
|
+
|
|
111
|
+
# partial_response (singular) returns false unless partial responded exactly one time, otherwise the content in nokogiri format: https://nokogiri.org/tutorials/searching_a_xml_html_document.html#basic-searching
|
|
112
|
+
r = partial_response(id: 'flash-box')
|
|
113
|
+
expect(r.css('div.text-content').first.inner_html).to include('Article could not be created')
|
|
114
|
+
|
|
115
|
+
# partials_responses (plural) returns a array
|
|
116
|
+
r2 = partials_responses(id: 'flash-box')
|
|
117
|
+
expect(r2.length).to eq(1)
|
|
118
|
+
|
|
119
|
+
# same, based on path by which partial is rendered to
|
|
120
|
+
r = partial_response(partial: 'layouts/flash')
|
|
121
|
+
expect(r.css('div.text-content').first.inner_html).to include('Article could not be created')
|
|
122
|
+
r2 = partials_responses(partial: 'layouts/flash')
|
|
123
|
+
expect(r2.length).to eq(1)
|
|
127
124
|
end
|
|
128
125
|
end
|
|
129
126
|
```
|
|
@@ -134,7 +131,7 @@ The test for a redirection might look something like this:
|
|
|
134
131
|
it 'update success' do
|
|
135
132
|
a = FactoryBot.create(:article)
|
|
136
133
|
patch article_path(a, params: valid_params)
|
|
137
|
-
expect(turbo_redirected_to).to eq(articles_path)
|
|
134
|
+
expect(turbo_redirected_to).to eq(articles_path)
|
|
138
135
|
end
|
|
139
136
|
```
|
|
140
137
|
|
|
@@ -142,7 +139,7 @@ P.S.:
|
|
|
142
139
|
|
|
143
140
|
Testing the plugin itself: There is a [quick-and-dirty app](https://gitlab.com/sedl/renderturbostream_railsapp) which includes the plugin and has tests done by rspec/request and capybara.
|
|
144
141
|
|
|
145
|
-
## Parameters
|
|
142
|
+
## Parameters for turbo_stream_save
|
|
146
143
|
|
|
147
144
|
`save_action` (first parameter, boolean) true if successful
|
|
148
145
|
|
|
@@ -1,33 +1,12 @@
|
|
|
1
|
-
<% partials_count = 0 %>
|
|
2
1
|
<% rendered_partials = [] %>
|
|
3
|
-
<% htmls_by_id = {} %>
|
|
4
|
-
<% params_by_id = {} %>
|
|
5
|
-
<% htmls_by_path = {} %>
|
|
6
|
-
<% params_by_path = {} %>
|
|
7
2
|
|
|
8
3
|
<% streams.each do |s| %>
|
|
9
4
|
|
|
10
|
-
<% html = (render s[:partial], locals: s[:locals], formats: [:html
|
|
11
|
-
<% htmls_by_id[s[:id]] ||= [] %>
|
|
12
|
-
<% htmls_by_id[s[:id]].push(html) %>
|
|
13
|
-
<% params_by_id[s[:id]] ||= [] %>
|
|
14
|
-
<% params_by_id[s[:id]].push(s) %>
|
|
5
|
+
<% html = (render s[:partial], locals: s[:locals], formats: [:html]) %>
|
|
15
6
|
|
|
16
|
-
<%
|
|
17
|
-
<% htmls_by_path[s[:partial]].push(html) %>
|
|
18
|
-
<% params_by_path[s[:partial]] ||= [] %>
|
|
19
|
-
<% params_by_path[s[:partial]].push(s) %>
|
|
20
|
-
|
|
21
|
-
<% partials_count += 1 %>
|
|
22
|
-
<% rendered_partials.push(s[:partial]) %>
|
|
7
|
+
<% rendered_partials.push({ html_response: html }.merge(s)) %>
|
|
23
8
|
|
|
24
9
|
<% end %>
|
|
25
10
|
|
|
26
|
-
<%= content_tag :div, htmls_by_id.to_json, id: 'htmls_by_id' %>
|
|
27
|
-
<%= content_tag :div, params_by_id.to_json, id: 'params_by_id' %>
|
|
28
|
-
|
|
29
|
-
<%= content_tag :div, htmls_by_path.to_json, id: 'htmls_by_path' %>
|
|
30
|
-
<%= content_tag :div, params_by_path.to_json, id: 'params_by_path' %>
|
|
31
|
-
|
|
32
|
-
<%= content_tag :div, check.to_json, id: 'check-json' %>
|
|
33
11
|
<%= content_tag :div, rendered_partials.to_json, id: 'rendered-partials' %>
|
|
12
|
+
|
|
@@ -1,57 +1,56 @@
|
|
|
1
1
|
module RenderTurboStream
|
|
2
2
|
module TestHelpers
|
|
3
3
|
|
|
4
|
-
# returns
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# returns false if id is cero or multiple times rendered to
|
|
11
|
-
def partial_html_by_id(id)
|
|
12
|
-
p = partials_html_by_id[id]
|
|
13
|
-
if p.length != 1
|
|
4
|
+
# returns false if partial is rendered cero or multiple times
|
|
5
|
+
# response can be searched by nokogiri https://nokogiri.org/tutorials/searching_a_xml_html_document.html#basic-searching
|
|
6
|
+
def partial_response(id: nil, partial: nil)
|
|
7
|
+
res = partials_responses(id: id, partial: partial)
|
|
8
|
+
if res.length != 1
|
|
14
9
|
false
|
|
15
10
|
else
|
|
16
|
-
|
|
11
|
+
res.first
|
|
17
12
|
end
|
|
18
13
|
end
|
|
19
14
|
|
|
20
|
-
|
|
21
|
-
e = Nokogiri::HTML(response.body).search('#params_by_id').first
|
|
22
|
-
JSON.parse(e.inner_html)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# returns hash of arrays with responded html(as string) contents by partial-path
|
|
26
|
-
def partials_html_by_path
|
|
27
|
-
e = Nokogiri::HTML(response.body).search('#htmls_by_path').first
|
|
28
|
-
JSON.parse(e.inner_html)
|
|
29
|
-
end
|
|
15
|
+
# like partial_response, but returns an array with length of how many times partial was rendered
|
|
30
16
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
17
|
+
def partials_responses(id: nil, partial: nil)
|
|
18
|
+
ary = partials_attributes
|
|
19
|
+
if id && partial
|
|
20
|
+
res = ary.select { |a| a['partial'] == partial && a['id'] == id }
|
|
21
|
+
elsif id
|
|
22
|
+
res = ary.select { |a| a['id'] == id }
|
|
23
|
+
elsif partial
|
|
24
|
+
res = ary.select { |a| a['partial'] == partial }
|
|
25
|
+
else
|
|
26
|
+
raise 'missing parameter'
|
|
27
|
+
end
|
|
28
|
+
res.map{|r| Nokogiri::HTML(r['html_response']) }
|
|
40
29
|
end
|
|
41
30
|
|
|
42
|
-
# array of strings of rendered
|
|
31
|
+
# array of strings of ids of rendered partials that turbo_stream pointed to
|
|
43
32
|
def partials_ids
|
|
44
|
-
|
|
45
|
-
|
|
33
|
+
ary = partials_attributes
|
|
34
|
+
ids = []
|
|
35
|
+
ary.each {|a| ids.push(a['id']) unless ids.include?(a['id']) }
|
|
36
|
+
ids
|
|
46
37
|
end
|
|
47
38
|
|
|
48
|
-
# array of strings of paths by
|
|
39
|
+
# array of strings of paths by which partials are rendered, for example: ['articles/form'].
|
|
49
40
|
def partials_paths
|
|
41
|
+
ary = partials_attributes
|
|
42
|
+
paths = []
|
|
43
|
+
ary.each {|a| paths.push(a['partial']) unless paths.include?(a['partial']) }
|
|
44
|
+
paths
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# returns an array of hashes with the attributes used to call partials and the response (html as string) from the partial.
|
|
48
|
+
def partials_attributes
|
|
50
49
|
e = Nokogiri::HTML(response.body).search('#rendered-partials').first
|
|
51
50
|
JSON.parse(e.inner_html)
|
|
52
51
|
end
|
|
53
52
|
|
|
54
|
-
#
|
|
53
|
+
# Returns the path to which turbo_stream.redirect_to would be applied.
|
|
55
54
|
def turbo_redirected_to
|
|
56
55
|
expect(response.status).to eq(302)
|
|
57
56
|
r = JSON.parse(response.body)
|
data/lib/render_turbo_stream.rb
CHANGED
|
@@ -8,11 +8,11 @@ module RenderTurboStream
|
|
|
8
8
|
def turbo_stream_save(
|
|
9
9
|
save_action,
|
|
10
10
|
redirect_on_success_to: nil,
|
|
11
|
-
object: nil,
|
|
11
|
+
object: nil, # object used in save_action, example: @customer
|
|
12
12
|
id: 'form', # if nil: no partial is rendered
|
|
13
|
-
partial: nil, #
|
|
14
|
-
action: 'replace',
|
|
15
|
-
locals: {},
|
|
13
|
+
partial: nil, # example: 'customers/form' default: "#{controller_path}/#{id}"
|
|
14
|
+
action: 'replace', # options: append, prepend
|
|
15
|
+
locals: {}, # locals used by the partial
|
|
16
16
|
streams_on_success: [
|
|
17
17
|
{
|
|
18
18
|
id: nil,
|
|
@@ -20,7 +20,7 @@ module RenderTurboStream
|
|
|
20
20
|
locals: {},
|
|
21
21
|
action: 'replace'
|
|
22
22
|
}
|
|
23
|
-
],
|
|
23
|
+
], # additional partials that should be rendered if save_action succeeded
|
|
24
24
|
streams_on_error: [
|
|
25
25
|
{
|
|
26
26
|
id: nil,
|
|
@@ -28,7 +28,7 @@ module RenderTurboStream
|
|
|
28
28
|
locals: {},
|
|
29
29
|
action: 'replace'
|
|
30
30
|
}
|
|
31
|
-
],
|
|
31
|
+
], # additional partials that should be rendered if save_action failed
|
|
32
32
|
add_flash_alerts: [], #=> array of strings
|
|
33
33
|
add_flash_notices: [], #=> array of strings
|
|
34
34
|
flashes_on_success: [], #=> array of strings
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: render_turbo_stream
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.27
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- christian
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-04-
|
|
11
|
+
date: 2023-04-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|