render_turbo_stream 0.1.41 → 0.1.43

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9094ebe69f34f4acb61696aff5741b6d1eecaf934b17662bd81d6e5dda8533f9
4
- data.tar.gz: b2a90bca1d9489b59a2de3cc4522b35f9ea81298f55472582adfa597a2a5a553
3
+ metadata.gz: b7105e78e4f7d96782d8bb94cdddefdb3698c68855cd16155dd575660095fa83
4
+ data.tar.gz: ff253ad1317fe42d6c3c617c7c2bb23933c5101330bcf9d3710cd06d6ae09a97
5
5
  SHA512:
6
- metadata.gz: c486823d9469018277398ee19ab7b95291ad0ed607e0abc6e01d1c1497358e2befca6f4ded2e6272ec86005e07c8eef9de2c66078a3c301300eaafb3d18ed0cb
7
- data.tar.gz: a4e3e4cb03a640d6f64b4c4efee892e539c0c5dfd34074be5ee5d0fc6dc259f5707a86cca36fd5e7cfcfdf93cddba91cc4e96b9e209c084eec1d3ab806fcf257
6
+ metadata.gz: df9dd9941005c649c125778ca0c2d35ba4672f5bb742457040fe16513db1078ab34bc140b859400336aa79cce70e4695ba5a8f91bbd185209535867a2cd9da23
7
+ data.tar.gz: 6ef0ec59e35da7fcac18c697bc06c70ca3247107891a9ce02c1ba2f3987d34c439ef97cc18fa5591b7dae441a435a7a0c275e8e4e9ab7d62b548d9da41570762
data/README.md CHANGED
@@ -58,19 +58,15 @@ look like this:
58
58
 
59
59
  ```ruby
60
60
 
61
- def create
62
- @customer = Customer.new(customer_params)
63
-
61
+ def update
64
62
  turbo_stream_save(
65
- @customer.save,
63
+ @customer.update(customer_params),
66
64
  redirect_on_success_to: edit_customer_path(@customer)
67
65
  )
68
-
69
66
  end
70
67
  ```
71
68
 
72
- This will set a status, generate a flash message and perform `stream_partials`, which could result in something like
73
- this:
69
+ This will set a status, generate a flash message and perform `stream_partials`, which could result in something like this:
74
70
 
75
71
  ```ruby
76
72
  stream_partials(
@@ -101,7 +97,7 @@ stream_partial(
101
97
 
102
98
  ## Testing
103
99
 
104
- For system testing we have Capybara. This works great and is necessary for javascript and backend combined apps, but it
100
+ For system testing there is Capybara. This works great and is necessary for javascript and backend combined apps, but it
105
101
  is good practice to break tests into smaller pieces.
106
102
 
107
103
  For the much faster request-level tests, there are some helpers:
@@ -126,11 +122,20 @@ RSpec.describe "Articles", type: :request do
126
122
  expect(partials_log.join('')).to include('Article could not be created')
127
123
  expect(partials_log.join('')).to include('layouts/flash')
128
124
 
129
- expect(partials_count).to eq(2) #=> 2 partials (form and a flash) are rendered
130
- expect(assert_partials('layouts/flash', id: 'flash-box')).to be_truthy #=> expect flash to render exact one time to html-id 'flash-box' by turbo-stream
131
- expect(assert_partials('articles/form', id: 'form')).to be_truthy #=> expect flash to render exact one time to html-id 'form' by turbo-stream
125
+ expect(partials_count).to eq(2)
126
+ #=> 2 partials in total: form, flash, no matter how many times each is rendered (example «flash»: a flash partial can be rendered several times)
132
127
 
128
+ expect(partial_response('form')).to eq(true)
129
+ expect(partial_response('layouts/flash')).to eq(true)
130
+ expect(partial_response('flash', id: 'flash-wrapper', count: 1)).to eq(true)
131
+ #=> id is the ID that turbo-stream pointed to (for replace/append/... an item)
132
+
133
+ expect(partial_response('flash'){|r|r.inner_html.include?('Article could not be created')}).to eq(true)
134
+ expect(partial_response('flash'){|r|r.css('div').inner_html.include?('Article could not be created')}).to eq(true)
135
+ #=> you can use the validators of nokogiri, check: https://nokogiri.org/tutorials/parsing_an_html_xml_document.html
136
+ #=> if a partial was rendered more than once: at least one response must match
133
137
  end
138
+
134
139
  end
135
140
  ```
136
141
 
@@ -151,29 +156,33 @@ includes the plugin and has tests done by rspec/request and capybara.
151
156
 
152
157
  ## Parameters for turbo_stream_save
153
158
 
154
- `save_action` (first parameter, boolean) true if successful
155
-
156
- `redirect_on_success_to:` path for redirection in case of success, if nil: no redirection.
157
-
158
- `success_message:` custom message if action is successful
159
-
160
- `error_message:` custom message if action has failed
161
-
162
- `object:` default: object (e.g. @customer) is derived from controller name
163
-
164
- `id:` html-ID for the object that is replaced by turbo_stream, if nil: no partial is rendered
165
-
166
- `partial:` default: 'form', assumes `controller_path`/_form
167
-
168
- `locals:` locals for the partial, as hash
169
-
170
- `replace_on_success:` array of hashes: `[{ id: nil, partial: '', locals: {} }]`
171
-
172
- `replace_on_error:` array of hashes: `[{ id: nil, partial: '', locals: {} }]`
173
-
174
- `add_flash_notices:` additional alerts for the case of failure, example: `["custom-success-message"]`
175
-
176
- `add_flash_alerts:` additional alerts for the case of success, example: `["custom-error-message"]`
159
+ save_action,
160
+ redirect_on_success_to: nil,
161
+ object: nil, # object used in save_action, example: @customer
162
+ id: 'form', # if nil: no partial is rendered
163
+ partial: nil, # example: 'customers/form' default: "#{controller_path}/#{id}"
164
+ action: 'replace', # options: append, prepend
165
+ locals: {}, # locals used by the partial
166
+ streams_on_success: [
167
+ {
168
+ id: nil,
169
+ partial: 'form',
170
+ locals: {},
171
+ action: 'replace'
172
+ }
173
+ ], # additional partials that should be rendered if save_action succeeded
174
+ streams_on_error: [
175
+ {
176
+ id: nil,
177
+ partial: 'form',
178
+ locals: {},
179
+ action: 'replace'
180
+ }
181
+ ], # additional partials that should be rendered if save_action failed
182
+ add_flash_alerts: [], #=> array of strings
183
+ add_flash_notices: [], #=> array of strings
184
+ flashes_on_success: [], #=> array of strings
185
+ flashes_on_error: [] #=> array of strings
177
186
 
178
187
  ## Requirements
179
188
 
@@ -0,0 +1,52 @@
1
+ module RenderTurboStream
2
+ module Test
3
+ module RequestHelpers
4
+
5
+ # count of rendered partials
6
+ # count rendering different partials (example: «customer/form»)
7
+ # doesnt check how often a specific partial is rendered
8
+
9
+ def partials_count
10
+ RenderTurboStream::Libs.partials_count(response)
11
+ end
12
+
13
+
14
+
15
+ # log as helper for the developer to see which flash is set and which partials are rendered to wich ids
16
+ def partials_log
17
+ all_responses = RenderTurboStream::Libs.all_responses(response)
18
+ r = []
19
+ if response.status == 302
20
+ r.push("redirect to #{turbo_redirect_to}")
21
+ else
22
+ all_responses.map do |a|
23
+ str = [
24
+ a['action'],
25
+ 'id',
26
+ "«#{a['id']}»",
27
+ 'by partial',
28
+ "«#{a['partial']}»",
29
+ (a['locals'].present? ? "locals: «#{a['locals']}»" : nil)
30
+ ].compact.join(' ')
31
+ r.push(str)
32
+ end
33
+ end
34
+ r
35
+ end
36
+
37
+
38
+ # Returns the path to which turbo_stream.redirect_to would be applied.
39
+ def turbo_redirect_to
40
+ expect(response.status).to eq(302)
41
+ r = JSON.parse(response.body)
42
+ r['redirected_to']
43
+ end
44
+
45
+
46
+ def partial_response(partial, id: nil, count: 1, &block)
47
+ RenderTurboStream::Libs.partial_response(response, partial, id, count, &block )
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module RenderTurboStream
2
- VERSION = "0.1.41"
2
+ VERSION = "0.1.43"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require "render_turbo_stream/version"
2
2
  require "render_turbo_stream/railtie"
3
3
  require 'render_turbo_stream/engine'
4
- require 'render_turbo_stream/request_test_helpers'
4
+ require 'render_turbo_stream/test/request_helpers'
5
5
 
6
6
  module RenderTurboStream
7
7
 
@@ -191,4 +191,69 @@ module RenderTurboStream
191
191
  ]
192
192
  )
193
193
  end
194
+
195
+ class Libs
196
+ def self.all_responses(response)
197
+ e = Nokogiri::HTML(response.body).search('#rendered-partials').first
198
+ JSON.parse(e.inner_html)
199
+ end
200
+
201
+ # if partial is one word, its checked against the last behind the slash, example: 'articles/form' matches 'form'
202
+
203
+ def self.select_responses(response, partial, id)
204
+ all = all_responses(response)
205
+
206
+ all.select do |a|
207
+ partial_matched = if !partial.present?
208
+ false
209
+ elsif partial.include?('/')
210
+ a['partial'] == partial
211
+ else
212
+ a['partial'].split('/').last == partial
213
+ end
214
+ id_matched = if !id.present?
215
+ false
216
+ else
217
+ a['id'] == id
218
+ end
219
+ partial_matched || id_matched
220
+ end
221
+
222
+ end
223
+
224
+ def self.partials_count(response)
225
+ all = all_responses(response)
226
+ part = []
227
+ all.each do |p|
228
+ _p = p['partial']
229
+ unless part.include?(_p)
230
+ part.push(_p)
231
+ end
232
+ end
233
+ part.length
234
+ end
235
+
236
+ def self.partial_response(response, partial, id, count, &block)
237
+ responses = select_responses(response, partial, id)
238
+ if block_given?
239
+
240
+ success = false
241
+
242
+ responses.each do |r|
243
+ parsed = Nokogiri::HTML(r['html_response'])
244
+ r = yield parsed
245
+ success = true if r.present?
246
+ end
247
+ success
248
+
249
+ else
250
+ if count
251
+ responses.length == count
252
+ else
253
+ nil
254
+ end
255
+ end
256
+ end
257
+
258
+ end
194
259
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: render_turbo_stream
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.41
4
+ version: 0.1.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - christian
@@ -26,8 +26,8 @@ dependencies:
26
26
  version: 7.0.4.3
27
27
  description: 'Writing views like (create|update).turbo_stream.haml annoyed me. This
28
28
  gem handles translated flash messages, sets status, and renders partials through
29
- turbo-stream. You can control it directly from the controller. It also handles redirection:
30
- turbo_power is included. Comes with predefined test helpers.'
29
+ turbo-stream. You can control them directly from the controller. It also handles
30
+ redirection: turbo_power is included. Includes helpers for enabling request testing.'
31
31
  email:
32
32
  - christian@sedlmair.ch
33
33
  executables: []
@@ -43,7 +43,7 @@ files:
43
43
  - lib/render_turbo_stream.rb
44
44
  - lib/render_turbo_stream/engine.rb
45
45
  - lib/render_turbo_stream/railtie.rb
46
- - lib/render_turbo_stream/request_test_helpers.rb
46
+ - lib/render_turbo_stream/test/request_helpers.rb
47
47
  - lib/render_turbo_stream/version.rb
48
48
  - lib/tasks/render_turbo_stream_tasks.rake
49
49
  homepage: https://gitlab.com/sedl/renderturbostream
@@ -71,5 +71,6 @@ requirements: []
71
71
  rubygems_version: 3.4.12
72
72
  signing_key:
73
73
  specification_version: 4
74
- summary: Render turbo-stream partials directly from the controller
74
+ summary: Render turbo-stream partials directly from the controller, including test
75
+ helpers
75
76
  test_files: []
@@ -1,107 +0,0 @@
1
- module RenderTurboStream
2
- module RequestTestHelpers
3
-
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
9
- false
10
- else
11
- res.first
12
- end
13
- end
14
-
15
- # like partial_response, but returns an array with length of how many times partial was rendered
16
- #
17
-
18
- # def partials_responses(id: nil, partial: nil)
19
- # ary = partials_attributes
20
- # if id && partial
21
- # res = ary.select { |a| a['partial'] == partial && a['id'] == id }
22
- # elsif id
23
- # res = ary.select { |a| a['id'] == id }
24
- # elsif partial
25
- # res = ary.select { |a| a['partial'] == partial }
26
- # else
27
- # raise 'missing parameter'
28
- # end
29
- # res.map { |r| Nokogiri::HTML(r['html_response']) }
30
- # end
31
-
32
- # if no count given: expects exactly one match
33
-
34
- def assert_partials(partial, id: nil, count: 1, &block)
35
- partials = partials_attributes
36
- if id && partial
37
- part = partials.select { |a| a['partial'] == partial && a['id'] == id }
38
- elsif id
39
- part = partials.select { |a| a['id'] == id }
40
- elsif partial
41
- part = partials.select { |a| a['partial'] == partial }
42
- else
43
- raise 'missing parameter'
44
- end
45
- if block_given?
46
- part.each do |r|
47
- noko = Nokogiri::HTML(r['html_response'])
48
- end
49
- else
50
- if count
51
- part.length == count
52
- else
53
- part.length
54
- end
55
- end
56
- end
57
-
58
- # count of rendered partials
59
- # count rendering different partials (example: «customer/form»)
60
- # doesnt check how often a specific partial is rendered
61
-
62
- def partials_count
63
- part = []
64
- partials_attributes.each do |p|
65
- _p = p['partial']
66
- unless part.include?(_p)
67
- part.push(_p)
68
- end
69
- end
70
- part.length
71
- end
72
-
73
- # returns an array of hashes with the attributes used to call partials and the response (html as string) from the partial.
74
- def partials_attributes
75
- e = Nokogiri::HTML(response.body).search('#rendered-partials').first
76
- JSON.parse(e.inner_html)
77
- end
78
-
79
- # Returns the path to which turbo_stream.redirect_to would be applied.
80
- def turbo_redirect_to
81
- expect(response.status).to eq(302)
82
- r = JSON.parse(response.body)
83
- r['redirected_to']
84
- end
85
-
86
- # log as helper for the developer to see which flash is set and which partials are rendered to wich ids
87
- def partials_log
88
- r = []
89
- if response.status == 302
90
- r.push("redirect to #{turbo_redirect_to}")
91
- else
92
- partials_attributes.map do |a|
93
- str = [
94
- a['action'],
95
- 'id',
96
- "«#{a['id']}»",
97
- 'by partial',
98
- "«#{a['partial']}»",
99
- (a['locals'].present? ? "locals: «#{a['locals']}»" : nil)
100
- ].compact.join(' ')
101
- r.push(str)
102
- end
103
- end
104
- r
105
- end
106
- end
107
- end