render_turbo_stream 0.1.40 → 0.1.42

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: b1d7e23e79f3d7f68a39cd3b9163020515231012283068dd777ed5544f8ad5db
4
- data.tar.gz: 38428bc23917c1c9ea1643381a2034605b5ece0ab69f8768297e2f876e3e6720
3
+ metadata.gz: 262075083599385cfe9bf300a909ae3dd0feee5f7ba32691a3024260307301c5
4
+ data.tar.gz: 71629066a9d7dfd6a2fab896e63011d23a8b735539cda0afb21eec2a4807d571
5
5
  SHA512:
6
- metadata.gz: 5a1f7456bd103ce669d356d8c7abd9af013cd7c38cb25c34d5bd5e3461343ede8ead6f271dfbaec69ef42aaac22f34f481dadac2ce04303cfa8f446ea8bada72
7
- data.tar.gz: d247dd8be9882db553478062ba937757e5e657264f4a49eab8d642c363cc54eeeca1933290548503c7c6a0a4f38a75409c596e7c03f152a4d019a7ec5047f527
6
+ metadata.gz: ae1caa61d33da5504bc562eabd139d1c0566b4ac7a23989603e4225464b7e41a6e423e67e2141255f0488698ca08ac65533cf1e87013a734362b0404f48e0705
7
+ data.tar.gz: e95004ea0010b2c4ee433208b36250ad47fd4dd48646f962bfa4a0cd966deb5421fc95dbb82d6ff8759ed09b5da14dab3808976895bf64270203f6902755a29e
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:
@@ -122,38 +118,24 @@ RSpec.describe "Articles", type: :request do
122
118
 
123
119
  post articles_path(params: invalid_params)
124
120
 
125
- # ----- BASIC -----
126
-
127
- # Exactly which partials were rendered to which ids
128
- expect(
129
- partials_once(
130
- { partial: 'layouts/flash', id: 'flash-box' },
131
- { partial: 'articles/form', id: 'form' })
132
- ).to be_truthy
133
-
134
- # ----- MORE OPTIONS -----
135
-
136
- # 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
137
- r = partial_response(id: 'flash-box')
138
- expect(r.css('div.text-content').first.inner_html).to include('Article could not be created')
139
-
140
- # same, but based on path by which partial is rendered to
141
- r = partial_response(partial: 'layouts/flash')
142
- expect(r.css('div.text-content').first.inner_html).to include('Article could not be created')
143
-
144
- # COUNTS
145
-
146
- # Check how many times a specific ID has been responded to.
147
- expect(partials_responses(id: 'flash-box').length).to eq(1)
148
-
149
- # Same with partials
150
- expect(partials_responses(partial: 'layouts/flash').length).to eq(1)
151
-
152
121
  # partials_log: developer information about what the renderer did, and strings to copy and paste into test commands
153
122
  expect(partials_log.join('')).to include('Article could not be created')
154
123
  expect(partials_log.join('')).to include('layouts/flash')
155
124
 
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)
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
156
137
  end
138
+
157
139
  end
158
140
  ```
159
141
 
@@ -174,29 +156,33 @@ includes the plugin and has tests done by rspec/request and capybara.
174
156
 
175
157
  ## Parameters for turbo_stream_save
176
158
 
177
- `save_action` (first parameter, boolean) true if successful
178
-
179
- `redirect_on_success_to:` path for redirection in case of success, if nil: no redirection.
180
-
181
- `success_message:` custom message if action is successful
182
-
183
- `error_message:` custom message if action has failed
184
-
185
- `object:` default: object (e.g. @customer) is derived from controller name
186
-
187
- `id:` html-ID for the object that is replaced by turbo_stream, if nil: no partial is rendered
188
-
189
- `partial:` default: 'form', assumes `controller_path`/_form
190
-
191
- `locals:` locals for the partial, as hash
192
-
193
- `replace_on_success:` array of hashes: `[{ id: nil, partial: '', locals: {} }]`
194
-
195
- `replace_on_error:` array of hashes: `[{ id: nil, partial: '', locals: {} }]`
196
-
197
- `add_flash_notices:` additional alerts for the case of failure, example: `["custom-success-message"]`
198
-
199
- `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
200
186
 
201
187
  ## Requirements
202
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.40"
2
+ VERSION = "0.1.42"
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.40
4
+ version: 0.1.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - christian
@@ -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
@@ -1,80 +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
- # count of rendered partials
33
- # count rendering different partials (example: «customer/form»)
34
- # doesnt check how often a specific partial is rendered
35
-
36
- def partials_count
37
- partials = []
38
- partials_attributes.each do |p|
39
- unless partials.include?(p[:partial])
40
- partials.push(p[:partial])
41
- end
42
- end
43
- partials.length
44
- end
45
-
46
- # returns an array of hashes with the attributes used to call partials and the response (html as string) from the partial.
47
- def partials_attributes
48
- e = Nokogiri::HTML(response.body).search('#rendered-partials').first
49
- JSON.parse(e.inner_html)
50
- end
51
-
52
- # Returns the path to which turbo_stream.redirect_to would be applied.
53
- def turbo_redirect_to
54
- expect(response.status).to eq(302)
55
- r = JSON.parse(response.body)
56
- r['redirected_to']
57
- end
58
-
59
- # log as helper for the developer to see which flash is set and which partials are rendered to wich ids
60
- def partials_log
61
- r = []
62
- if response.status == 302
63
- r.push("redirect to #{turbo_redirect_to}")
64
- else
65
- partials_attributes.map do |a|
66
- str = [
67
- a['action'],
68
- 'id',
69
- "«#{a['id']}»",
70
- 'by partial',
71
- "«#{a['partial']}»",
72
- (a['locals'].present? ? "locals: «#{a['locals']}»" : nil)
73
- ].compact.join(' ')
74
- r.push(str)
75
- end
76
- end
77
- r
78
- end
79
- end
80
- end