wagn 1.16.9 → 1.16.10
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/features/paging.feature +20 -0
- data/features/step_definitions/wagn_steps.rb +114 -82
- data/lib/wagn/generators/wagn/templates/Gemfile +1 -1
- data/lib/wagn/mods_spec_helper.rb +2 -0
- data/rails/controllers/card_controller.rb +99 -85
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 868985bd60371dbdf3eb8985578149faf1d72ca6
|
|
4
|
+
data.tar.gz: b2c87b109129dadd549da40bf355cde451b59df4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba75aef50dee68c139d0fb9d6b068c9cf8c3a2a05d291b0c680f31c2b14cf5e7478466857ce64c15c29c4b813c612ceb24c698591aecfcd21bcd6289b5a1307f
|
|
7
|
+
data.tar.gz: 130c1496e1ed4eefb74658b5b0a8a0337443748ace7f17f45efa04b899403f67a25ac768437770da57c4be545832f9604be7bac6b8c8639e161f3dcc3410a14e
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@javascript
|
|
2
|
+
Feature: paging
|
|
3
|
+
In order to see limited items per page
|
|
4
|
+
As an Viewer
|
|
5
|
+
I want to have paging function
|
|
6
|
+
|
|
7
|
+
Background:
|
|
8
|
+
Given I am signed in as Joe Admin
|
|
9
|
+
And I create Search card "basic card search" with content "{\"type\":\"basic\", \"limit\":2}"
|
|
10
|
+
And I create HTML card "basic item structure" with content "{{_|name}}"
|
|
11
|
+
And I create HTML card "list all basic cards" with content "{{basic card search||content;structure:basic item structure}}"
|
|
12
|
+
|
|
13
|
+
Scenario: jump to pages should keep the item structure
|
|
14
|
+
When I go to card "list all basic cards"
|
|
15
|
+
And I click "2" within ".paging"
|
|
16
|
+
And I wait until ajax response done
|
|
17
|
+
Then I should see css class ".STRUCTURE-basic_item_structure" within ".search-result-item"
|
|
18
|
+
And I click "3" within ".paging"
|
|
19
|
+
And I wait until ajax response done
|
|
20
|
+
Then I should see css class ".STRUCTURE-basic_item_structure" within ".search-result-item"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
|
2
2
|
require 'uri'
|
|
3
3
|
require 'cgi'
|
|
4
|
-
|
|
4
|
+
support_paths_file = File.join File.dirname(__FILE__), '..', 'support', 'paths'
|
|
5
|
+
require File.expand_path support_paths_file
|
|
5
6
|
|
|
6
7
|
if RUBY_VERSION =~ /^2/
|
|
7
8
|
require 'byebug'
|
|
@@ -9,7 +10,6 @@ else
|
|
|
9
10
|
require 'debugger'
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
|
|
13
13
|
Given /^site simulates setup need$/ do
|
|
14
14
|
Card::Auth.simulate_setup_need!
|
|
15
15
|
end
|
|
@@ -21,30 +21,28 @@ end
|
|
|
21
21
|
|
|
22
22
|
Given /^I am signed in as (.+)$/ do |account_name|
|
|
23
23
|
accounted = Card[account_name]
|
|
24
|
-
visit
|
|
25
|
-
|
|
24
|
+
visit '/update/:signin?card[subcards][%2B*email][content]='\
|
|
25
|
+
"#{accounted.account.email}&card[subcards][%2B*password][content]=joe_pass"
|
|
26
|
+
# could optimize by specifying simple text success page
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
Given /^I am signed out$/ do
|
|
29
|
-
visit
|
|
30
|
-
if page.has_content?
|
|
30
|
+
visit '/'
|
|
31
|
+
if page.has_content? 'Sign out'
|
|
31
32
|
step 'I follow "Sign out"'
|
|
32
33
|
end
|
|
33
34
|
end
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
end
|
|
46
|
-
=end
|
|
47
|
-
|
|
36
|
+
# Given /^I sign in as (.+)$/ do |account_name|
|
|
37
|
+
# # FIXME: define a faster simulate method ("I am logged in as")
|
|
38
|
+
# accounted = Card[account_name]
|
|
39
|
+
# @current_id = accounted.id
|
|
40
|
+
# visit "/:signin"
|
|
41
|
+
# fill_in "card[subcards][+*email][content]", with: accounted.account.email
|
|
42
|
+
# fill_in "card[subcards][+*password][content]", with: 'joe_pass'
|
|
43
|
+
# click_button "Sign in"
|
|
44
|
+
# page.should have_content(account_name)
|
|
45
|
+
# end
|
|
48
46
|
|
|
49
47
|
Given /^the card (.*) contains "([^\"]*)"$/ do |cardname, content|
|
|
50
48
|
Card::Auth.as_bot do
|
|
@@ -60,23 +58,26 @@ When /^(.*) edits? "([^\"]*)"$/ do |username, cardname|
|
|
|
60
58
|
end
|
|
61
59
|
end
|
|
62
60
|
|
|
63
|
-
|
|
61
|
+
wysiwyg_re = /^(.*) edits? "([^\"]*)" entering "([^\"]*)" into wysiwyg$/
|
|
62
|
+
When wysiwyg_re do |username, cardname, content|
|
|
64
63
|
signed_in_as(username) do
|
|
65
64
|
visit "/card/edit/#{cardname.to_name.url_key}"
|
|
66
65
|
page.execute_script "$('#main .card-content').val('#{content}')"
|
|
67
|
-
click_button
|
|
66
|
+
click_button 'Submit'
|
|
68
67
|
end
|
|
69
68
|
end
|
|
70
69
|
|
|
71
|
-
|
|
70
|
+
edit_re = /^(.*) edits? "([^\"]*)" setting (.*) to "([^\"]*)"$/
|
|
71
|
+
When edit_re do |username, cardname, _field, content|
|
|
72
72
|
signed_in_as(username) do
|
|
73
73
|
visit "/card/edit/#{cardname.to_name.url_key}"
|
|
74
74
|
fill_in 'card[content]', with: content
|
|
75
|
-
click_button
|
|
75
|
+
click_button 'Submit'
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
filling_re = /^(.*) edits? "([^\"]*)" filling in "([^\"]*)"$/
|
|
80
|
+
When filling_re do |_username, cardname, content|
|
|
80
81
|
visit "/card/edit/#{cardname.to_name.url_key}"
|
|
81
82
|
fill_in 'card[content]', with: content
|
|
82
83
|
end
|
|
@@ -87,27 +88,34 @@ When /^(.*) edits? "([^\"]*)" with plusses:/ do |username, cardname, plusses|
|
|
|
87
88
|
plusses.hashes.first.each do |name, content|
|
|
88
89
|
fill_in "card[subcards][#{cardname}+#{name}][content]", with: content
|
|
89
90
|
end
|
|
90
|
-
click_button
|
|
91
|
+
click_button 'Submit'
|
|
91
92
|
end
|
|
92
93
|
end
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
content_re = /^(.*) creates?\s*a?\s*([^\s]*) card "(.*)" with content "(.*)"$/
|
|
96
|
+
When content_re do |username, cardtype, cardname, content|
|
|
95
97
|
create_card(username, cardtype, cardname, content) do
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
normal_textarea_types = %w(
|
|
99
|
+
JavaScript CoffeeScript HTML CSS SCSS Search
|
|
100
|
+
)
|
|
101
|
+
if !normal_textarea_types.include?(cardtype) ||
|
|
102
|
+
!page.evaluate_script("typeof ace != 'undefined'")
|
|
103
|
+
fill_in('card[content]', with: content)
|
|
99
104
|
else
|
|
100
|
-
page.execute_script
|
|
105
|
+
page.execute_script "ace.edit($('.ace_editor').get(0))"\
|
|
106
|
+
".getSession().setValue('#{content}')"
|
|
101
107
|
end
|
|
102
108
|
end
|
|
103
109
|
end
|
|
104
110
|
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
create_re = /^(.*) creates?\s*([^\s]*) card "([^"]*)"$/
|
|
112
|
+
When create_re do |username, cardtype, cardname|
|
|
113
|
+
create_card username, cardtype, cardname
|
|
107
114
|
end
|
|
108
115
|
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
plus_re = /^(.*) creates?\s*([^\s]*) card "([^"]*)" with plusses:$/
|
|
117
|
+
When plus_re do |username, cardtype, cardname, plusses|
|
|
118
|
+
create_card(username, cardtype, cardname) do
|
|
111
119
|
plusses.hashes.first.each do |name, content|
|
|
112
120
|
fill_in "card[subcards][+#{name}][content]", with: content
|
|
113
121
|
end
|
|
@@ -122,30 +130,30 @@ end
|
|
|
122
130
|
|
|
123
131
|
When /^(?:|I )enter "([^"]*)" into "([^"]*)"$/ do |value, field|
|
|
124
132
|
selector = ".RIGHT-#{field.to_name.safe_key} input.card-content"
|
|
125
|
-
find(
|
|
133
|
+
find(selector).set value
|
|
126
134
|
end
|
|
127
135
|
|
|
128
136
|
When /^(?:|I )upload the (.+) "(.+)"$/ do |attachment_name, filename|
|
|
129
137
|
script = "$('input[type=file]').css('opacity','1');"
|
|
130
138
|
page.driver.browser.execute_script(script)
|
|
131
|
-
|
|
139
|
+
file = File.join Wagn.gem_root, 'features', 'support', filename
|
|
140
|
+
attach_file "card_#{attachment_name}", file
|
|
132
141
|
end
|
|
133
142
|
|
|
134
|
-
Given /^(.*) (is|am) watching "([^\"]+)"$/ do |user,
|
|
135
|
-
user = Card::Auth.current.name if user ==
|
|
143
|
+
Given /^(.*) (is|am) watching "([^\"]+)"$/ do |user, _verb, cardname|
|
|
144
|
+
user = Card::Auth.current.name if user == 'I'
|
|
136
145
|
signed_in_as user do
|
|
137
146
|
step "the card #{cardname}+#{user}+*follow contains \"[[*always]]\""
|
|
138
147
|
end
|
|
139
148
|
end
|
|
140
149
|
|
|
141
|
-
Given /^(.*) (is|am) not watching "([^\"]+)"$/ do |user,
|
|
142
|
-
user = Card::Auth.current.name if user ==
|
|
150
|
+
Given /^(.*) (is|am) not watching "([^\"]+)"$/ do |user, _verb, cardname|
|
|
151
|
+
user = Card::Auth.current.name if user == 'I'
|
|
143
152
|
signed_in_as user do
|
|
144
153
|
step "the card #{cardname}+#{user}+*follow contains \"[[*never]]\""
|
|
145
154
|
end
|
|
146
155
|
end
|
|
147
156
|
|
|
148
|
-
|
|
149
157
|
When /I wait a sec/ do
|
|
150
158
|
sleep 1
|
|
151
159
|
end
|
|
@@ -162,45 +170,49 @@ When /^I wait until ajax response done$/ do
|
|
|
162
170
|
end
|
|
163
171
|
end
|
|
164
172
|
|
|
165
|
-
Then /what/ do
|
|
166
|
-
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
Then /debug/ do
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def create_card
|
|
173
|
+
# Then /what/ do
|
|
174
|
+
# save_and_open_page
|
|
175
|
+
# end
|
|
176
|
+
#
|
|
177
|
+
# Then /debug/ do
|
|
178
|
+
# if RUBY_VERSION =~ /^2/
|
|
179
|
+
# require 'pry'
|
|
180
|
+
# binding.pry
|
|
181
|
+
# else
|
|
182
|
+
# debugger
|
|
183
|
+
# end
|
|
184
|
+
# nil
|
|
185
|
+
# end
|
|
186
|
+
|
|
187
|
+
def create_card username, cardtype, cardname, content=''
|
|
180
188
|
signed_in_as(username) do
|
|
181
|
-
if cardtype=='Pointer'
|
|
189
|
+
if cardtype == 'Pointer'
|
|
182
190
|
Card.create name: cardname, type: cardtype, content: content
|
|
183
191
|
else
|
|
184
192
|
visit "/card/new?card[name]=#{CGI.escape(cardname)}&type=#{cardtype}"
|
|
185
193
|
yield if block_given?
|
|
186
|
-
click_button
|
|
194
|
+
click_button 'Submit'
|
|
187
195
|
end
|
|
188
196
|
end
|
|
189
197
|
end
|
|
190
198
|
|
|
191
199
|
def signed_in_as username
|
|
192
|
-
sameuser = (username ==
|
|
200
|
+
sameuser = (username == 'I')
|
|
201
|
+
sameuser ||= (Card::Auth.current.key == username.to_name.key)
|
|
193
202
|
was_signed_in = Card::Auth.current_id if Card::Auth.signed_in?
|
|
194
203
|
unless sameuser
|
|
195
204
|
step "I am signed in as #{username}"
|
|
196
205
|
end
|
|
197
206
|
yield
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
207
|
+
return if sameuser
|
|
208
|
+
msg = if was_signed_in
|
|
209
|
+
"I am signed in as #{Card[was_signed_in].name}"
|
|
210
|
+
else
|
|
211
|
+
'I follow "Sign out"'
|
|
212
|
+
end
|
|
213
|
+
step msg
|
|
201
214
|
end
|
|
202
215
|
|
|
203
|
-
|
|
204
216
|
When /^In (.*) I follow "([^\"]*)"$/ do |section, link|
|
|
205
217
|
within scope_of(section) do
|
|
206
218
|
click_link link
|
|
@@ -213,7 +225,14 @@ When /^In (.*) I click "(.*)"$/ do |section, link|
|
|
|
213
225
|
end
|
|
214
226
|
end
|
|
215
227
|
|
|
216
|
-
When /^
|
|
228
|
+
When /^I click "(.*)" within "(.*)"$/ do |link, selector|
|
|
229
|
+
within selector do
|
|
230
|
+
click_link link
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
link_re = /^In (.*) I find link with class "(.*)" and click it$/
|
|
235
|
+
When link_re do |section, css_class|
|
|
217
236
|
within scope_of(section) do
|
|
218
237
|
find("a.#{css_class}").click
|
|
219
238
|
end
|
|
@@ -224,6 +243,7 @@ When /^In (.*) I find link with icon "(.*)" and click it$/ do |section, icon|
|
|
|
224
243
|
find("a > span.glyphicon-#{icon}").click
|
|
225
244
|
end
|
|
226
245
|
end
|
|
246
|
+
|
|
227
247
|
When /^In (.*) I find button with icon "(.*)" and click it$/ do |section, icon|
|
|
228
248
|
within scope_of(section) do
|
|
229
249
|
find("button > span.glyphicon-#{icon}").click
|
|
@@ -231,11 +251,12 @@ When /^In (.*) I find button with icon "(.*)" and click it$/ do |section, icon|
|
|
|
231
251
|
end
|
|
232
252
|
|
|
233
253
|
Then /I submit$/ do
|
|
234
|
-
|
|
254
|
+
click_button 'Submit'
|
|
235
255
|
end
|
|
236
256
|
|
|
237
257
|
When /^I open the main card menu$/ do
|
|
238
|
-
|
|
258
|
+
slot = "$('#main .menu-slot .vertical-card-menu.show-on-hover .card-slot')"
|
|
259
|
+
page.execute_script "#{slot}.show()"
|
|
239
260
|
page.find('#main .menu-slot .card-menu a').click
|
|
240
261
|
end
|
|
241
262
|
|
|
@@ -243,43 +264,41 @@ When /^I close the modal window$/ do
|
|
|
243
264
|
page.find('.modal-menu .close-modal').click
|
|
244
265
|
end
|
|
245
266
|
|
|
246
|
-
When /^I pick (.*)$/ do |menu_item|
|
|
247
|
-
end
|
|
267
|
+
# When /^I pick (.*)$/ do |menu_item|
|
|
268
|
+
# end
|
|
248
269
|
|
|
249
270
|
Then /the card (.*) should contain "([^\"]*)"$/ do |cardname, content|
|
|
250
271
|
visit path_to("card #{cardname}")
|
|
251
|
-
within scope_of(
|
|
272
|
+
within scope_of('main card content') do
|
|
252
273
|
expect(page).to have_content(content)
|
|
253
274
|
end
|
|
254
275
|
end
|
|
255
276
|
|
|
256
277
|
Then /the card (.*) should not contain "([^\"]*)"$/ do |cardname, content|
|
|
257
278
|
visit path_to("card #{cardname}")
|
|
258
|
-
within scope_of(
|
|
279
|
+
within scope_of('main card content') do
|
|
259
280
|
expect(page).not_to have_content(content)
|
|
260
281
|
end
|
|
261
282
|
end
|
|
262
283
|
|
|
263
284
|
Then /the card (.*) should point to "([^\"]*)"$/ do |cardname, content|
|
|
264
285
|
visit path_to("card #{cardname}")
|
|
265
|
-
within scope_of(
|
|
286
|
+
within scope_of('pointer card content') do
|
|
266
287
|
expect(page).to have_content(content)
|
|
267
288
|
end
|
|
268
289
|
end
|
|
269
290
|
|
|
270
291
|
Then /the card (.*) should not point to "([^\"]*)"$/ do |cardname, content|
|
|
271
292
|
visit path_to("card #{cardname}")
|
|
272
|
-
within scope_of(
|
|
293
|
+
within scope_of('pointer card content') do
|
|
273
294
|
expect(page).not_to have_content(content)
|
|
274
295
|
end
|
|
275
296
|
end
|
|
276
297
|
|
|
277
|
-
|
|
278
|
-
|
|
279
298
|
Then /^In (.*) I should see "([^\"]*)"$/ do |section, text|
|
|
280
299
|
within scope_of(section) do
|
|
281
300
|
if text.index('|')
|
|
282
|
-
expect(text.split('|').any? {|t| have_content(t)}).to be
|
|
301
|
+
expect(text.split('|').any? { |t| have_content(t) }).to be
|
|
283
302
|
else
|
|
284
303
|
expect(page).to have_content(text)
|
|
285
304
|
end
|
|
@@ -292,19 +311,23 @@ Then /^In (.*) I should not see "([^\"]*)"$/ do |section, text|
|
|
|
292
311
|
end
|
|
293
312
|
end
|
|
294
313
|
|
|
295
|
-
|
|
314
|
+
class_re = /^In (.*) I should (not )?see a ([^\"]*) with class "([^\"]*)"$/
|
|
315
|
+
Then class_re do |selection, neg, element, selector|
|
|
296
316
|
# checks for existence of a element with a class in a selection context
|
|
297
317
|
element = 'a' if element == 'link'
|
|
298
318
|
within scope_of(selection) do
|
|
299
|
-
|
|
319
|
+
verb = neg ? :should_not : :should
|
|
320
|
+
page.send(verb, have_css([element, selector] * '.'))
|
|
300
321
|
end
|
|
301
322
|
end
|
|
302
323
|
|
|
303
|
-
|
|
324
|
+
content_re = /^In (.*) I should (not )?see a ([^\"]*) with content "([^\"]*)"$/
|
|
325
|
+
Then content_re do |selection, neg, element, content|
|
|
304
326
|
# checks for existence of a element with a class in a selection context
|
|
305
327
|
element = 'a' if element == 'link'
|
|
306
328
|
within scope_of(selection) do
|
|
307
|
-
|
|
329
|
+
verb = neg ? :should_not : :should
|
|
330
|
+
page.send(verb, have_css(element, text: content))
|
|
308
331
|
end
|
|
309
332
|
end
|
|
310
333
|
|
|
@@ -313,7 +336,9 @@ Then /^the "([^"]*)" field should contain "([^"]*)"$/ do |field, value|
|
|
|
313
336
|
end
|
|
314
337
|
|
|
315
338
|
Then /^"([^"]*)" should be selected for "([^"]*)"$/ do |value, field|
|
|
316
|
-
|
|
339
|
+
element = field_labeled(field).element
|
|
340
|
+
selected = element.search ".//option[@selected = 'selected']"
|
|
341
|
+
expect(selected.inner_html).to match /#{value}/
|
|
317
342
|
end
|
|
318
343
|
|
|
319
344
|
When /^I press enter to search$/ do
|
|
@@ -333,7 +358,8 @@ Then /^I should see an image of size "(.+)" and type "(.+)"$/ do |size, type|
|
|
|
333
358
|
find("img[src*='#{size}.#{type}']")
|
|
334
359
|
end
|
|
335
360
|
|
|
336
|
-
|
|
361
|
+
img_should = /^I should see a non-mod image of size "(.+)" and type "(.+)"$/
|
|
362
|
+
Then img_should do |size, type|
|
|
337
363
|
element = find("img[src*='#{size}.#{type}']")
|
|
338
364
|
expect(element[:src]).to match(%r(/~\d+/))
|
|
339
365
|
end
|
|
@@ -342,7 +368,13 @@ Then /^I should see "([^\"]*)" in color (.*)$/ do |text, css_class|
|
|
|
342
368
|
page.has_css?(".diff-#{css_class}", text: text)
|
|
343
369
|
end
|
|
344
370
|
|
|
371
|
+
css_should = /^I should see css class "([^\"]*)" within "(.*)"$/
|
|
372
|
+
Then css_should do |css_class, selector|
|
|
373
|
+
within selector do
|
|
374
|
+
find(css_class)
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
345
378
|
When /^I fill in "([^\"]*)" with$/ do |field, value|
|
|
346
379
|
fill_in(field, with: value)
|
|
347
380
|
end
|
|
348
|
-
|
|
@@ -66,7 +66,7 @@ group :test do
|
|
|
66
66
|
gem 'spork', '>=0.9'
|
|
67
67
|
gem 'rr'#, '=1.0.0'
|
|
68
68
|
gem 'simplecov', '~> 0.7.1', :require => false #test coverage
|
|
69
|
-
|
|
69
|
+
gem 'codeclimate-test-reporter', require: nil
|
|
70
70
|
# gem 'guard-rspec', '~> 4.2' # trigger test runs based on file edits,
|
|
71
71
|
# currently not compatible with spring-watcher-listen
|
|
72
72
|
if RUBY_PLATFORM =~ /darwin/
|
|
@@ -3,24 +3,23 @@
|
|
|
3
3
|
require_dependency 'card'
|
|
4
4
|
|
|
5
5
|
require_dependency 'wagn/exceptions'
|
|
6
|
-
require_dependency 'card/mailer' #otherwise Net::SMTPError rescues can cause
|
|
6
|
+
require_dependency 'card/mailer' # otherwise Net::SMTPError rescues can cause
|
|
7
|
+
# problems when error raised comes before Card::Mailer is mentioned
|
|
7
8
|
|
|
8
9
|
class CardController < ActionController::Base
|
|
9
|
-
|
|
10
10
|
include Card::Location
|
|
11
11
|
include Recaptcha::Verify
|
|
12
12
|
|
|
13
13
|
before_filter :per_request_setup, except: [:asset]
|
|
14
|
-
before_filter :load_id, only: [
|
|
14
|
+
before_filter :load_id, only: [:read]
|
|
15
15
|
before_filter :load_card, except: [:asset]
|
|
16
|
-
before_filter :refresh_card, only: [
|
|
16
|
+
before_filter :refresh_card, only: [:create, :update, :delete, :rollback]
|
|
17
17
|
|
|
18
18
|
layout nil
|
|
19
19
|
|
|
20
20
|
attr_reader :card
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
22
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
24
23
|
# CORE METHODS
|
|
25
24
|
|
|
26
25
|
def create
|
|
@@ -40,18 +39,18 @@ class CardController < ActionController::Base
|
|
|
40
39
|
end
|
|
41
40
|
|
|
42
41
|
def asset
|
|
43
|
-
Rails.logger.info
|
|
42
|
+
Rails.logger.info 'Routing assets through Card. Recommend symlink from ' \
|
|
43
|
+
'Deck to Card gem using "rake wagn:update_assets_symlink"'
|
|
44
44
|
asset_path = Decko::Engine.paths['gem-assets'].existent.first
|
|
45
|
-
filename = [
|
|
46
|
-
send_file_inside asset_path, filename
|
|
45
|
+
filename = [params[:filename], params[:format]].join('.')
|
|
46
|
+
send_file_inside asset_path, filename, x_sendfile: true
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
|
|
50
49
|
private
|
|
51
50
|
|
|
52
51
|
# make sure that filename doesn't leave allowed_path using ".."
|
|
53
|
-
def send_file_inside
|
|
54
|
-
if filename.include?
|
|
52
|
+
def send_file_inside allowed_path, filename, options={}
|
|
53
|
+
if filename.include? '../'
|
|
55
54
|
raise Wagn::BadAddress
|
|
56
55
|
else
|
|
57
56
|
send_file File.join(allowed_path, filename), options
|
|
@@ -61,27 +60,29 @@ class CardController < ActionController::Base
|
|
|
61
60
|
#-------( FILTERS )
|
|
62
61
|
|
|
63
62
|
def per_request_setup
|
|
64
|
-
request.format = :html if !params[:format] #is this used??
|
|
63
|
+
request.format = :html if !params[:format] # is this used??
|
|
65
64
|
Card::Cache.renew
|
|
66
65
|
Card::Env.reset controller: self
|
|
67
66
|
Card::Auth.set_current_from_session
|
|
68
67
|
|
|
69
|
-
if params[:id] && !params[:id].valid_encoding?
|
|
70
|
-
|
|
68
|
+
if params[:id] && !params[:id].valid_encoding?
|
|
69
|
+
# slightly better way to handle encoding issues (than the rescue in
|
|
70
|
+
# load_id)
|
|
71
|
+
# we should find the place where we produce these bad urls
|
|
71
72
|
params[:id] = params[:id].force_encoding('ISO-8859-1').encode('UTF-8')
|
|
72
73
|
end
|
|
73
74
|
end
|
|
74
75
|
|
|
75
|
-
|
|
76
76
|
def load_id
|
|
77
|
-
params[:id] ||=
|
|
77
|
+
params[:id] ||=
|
|
78
|
+
case
|
|
78
79
|
when Card::Auth.needs_setup? && Card::Env.html?
|
|
79
80
|
params[:card] = { type_id: Card.default_accounted_type_id }
|
|
80
81
|
params[:view] = 'setup'
|
|
81
82
|
''
|
|
82
83
|
when params[:card] && params[:card][:name]
|
|
83
84
|
params[:card][:name]
|
|
84
|
-
when Card::Format.tagged(
|
|
85
|
+
when Card::Format.tagged(params[:view], :unknown_ok)
|
|
85
86
|
''
|
|
86
87
|
else
|
|
87
88
|
Card.setting(:home) || 'Home'
|
|
@@ -90,25 +91,23 @@ class CardController < ActionController::Base
|
|
|
90
91
|
raise Wagn::BadAddress
|
|
91
92
|
end
|
|
92
93
|
|
|
93
|
-
|
|
94
94
|
def load_card
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
end
|
|
95
|
+
if params[:id] == '*previous'
|
|
96
|
+
return card_redirect(Card::Env.previous_location)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
opts = card_attr_from_params
|
|
100
|
+
@card =
|
|
101
|
+
if params[:action] == 'create'
|
|
102
|
+
# FIXME: we currently need a "new" card to catch duplicates (otherwise
|
|
103
|
+
# save will just act like a normal update)
|
|
104
|
+
# I think we may need to create a "#create" instance method that
|
|
105
|
+
# handles this checking.
|
|
106
|
+
# that would let us get rid of this...
|
|
107
|
+
Card.new opts
|
|
108
|
+
else
|
|
109
|
+
mark = params[:id] || opts[:name]
|
|
110
|
+
Card.fetch mark, new: opts
|
|
112
111
|
end
|
|
113
112
|
raise Card::NotFound unless @card
|
|
114
113
|
|
|
@@ -123,25 +122,16 @@ class CardController < ActionController::Base
|
|
|
123
122
|
@card = card.refresh
|
|
124
123
|
end
|
|
125
124
|
|
|
126
|
-
|
|
127
125
|
protected
|
|
128
126
|
|
|
129
|
-
def ajax?
|
|
130
|
-
Card::Env.ajax?
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def success
|
|
134
|
-
Card::Env[:success]
|
|
135
|
-
end
|
|
136
|
-
|
|
137
127
|
# ----------( rendering methods ) -------------
|
|
138
128
|
|
|
139
129
|
def card_redirect url
|
|
140
|
-
url = card_url url #make sure we have absolute url
|
|
130
|
+
url = card_url url # make sure we have absolute url
|
|
141
131
|
if ajax?
|
|
142
132
|
# lets client reset window location (not just receive redirected response)
|
|
143
133
|
# formerly used 303 response, but that gave IE the fits
|
|
144
|
-
render json: {redirect: url}
|
|
134
|
+
render json: { redirect: url }
|
|
145
135
|
else
|
|
146
136
|
redirect_to url
|
|
147
137
|
end
|
|
@@ -155,58 +145,45 @@ class CardController < ActionController::Base
|
|
|
155
145
|
|
|
156
146
|
def render_success
|
|
157
147
|
success.name_context = @card.cardname
|
|
158
|
-
if !ajax? || success.hard_redirect?
|
|
159
|
-
|
|
160
|
-
elsif String === success.target
|
|
161
|
-
render text: success.target
|
|
162
|
-
else
|
|
163
|
-
if success.soft_redirect?
|
|
164
|
-
self.params = success.params
|
|
165
|
-
else
|
|
166
|
-
self.params.merge! success.params # #need tests. insure we get slot, main...
|
|
167
|
-
end
|
|
168
|
-
@card = success.target
|
|
169
|
-
@card.select_action_by_params params
|
|
170
|
-
show
|
|
171
|
-
end
|
|
172
|
-
end
|
|
148
|
+
return card_redirect success.to_url if !ajax? || success.hard_redirect?
|
|
149
|
+
return render text: success.target if success.target.is_a? String
|
|
173
150
|
|
|
151
|
+
@card = success.target
|
|
152
|
+
update_params_for_success
|
|
153
|
+
@card.select_action_by_params params
|
|
154
|
+
show
|
|
155
|
+
end
|
|
174
156
|
|
|
175
157
|
def render_errors
|
|
176
|
-
#
|
|
158
|
+
# FIXME: should prioritize certain error classes
|
|
177
159
|
code = nil
|
|
178
|
-
card.errors.each do |key,
|
|
179
|
-
break if code = Card.error_codes[
|
|
160
|
+
card.errors.each do |key, _msg|
|
|
161
|
+
break if (code = Card.error_codes[key])
|
|
180
162
|
end
|
|
181
|
-
view, status = code || [
|
|
163
|
+
view, status = code || [:errors, 422]
|
|
182
164
|
show view, status
|
|
183
165
|
end
|
|
184
166
|
|
|
185
|
-
def show view
|
|
186
|
-
# ActiveSupport::Notifications.instrument('card', message: 'CardController#show') do
|
|
167
|
+
def show view=nil, status=200
|
|
187
168
|
card.action = :read
|
|
188
|
-
|
|
189
|
-
format = :file if params[:explicit_file] or !Card::Format.registered.member? format #unknown format
|
|
169
|
+
card.content = card.last_draft_content if use_draft?
|
|
190
170
|
|
|
191
|
-
opts = ( params[:slot] || {} ).deep_symbolize_keys
|
|
192
171
|
view ||= params[:view]
|
|
172
|
+
slot_opts = (params[:slot] || {}).deep_symbolize_keys
|
|
193
173
|
|
|
194
|
-
|
|
195
|
-
card.content = card.drafts.last.card_changes.last.value
|
|
196
|
-
end
|
|
174
|
+
format = format_from_params
|
|
197
175
|
formatter = card.format(format.to_sym)
|
|
198
176
|
result = card.run_callbacks :show do
|
|
199
|
-
formatter.show view,
|
|
177
|
+
formatter.show view, slot_opts
|
|
200
178
|
end
|
|
201
179
|
status = formatter.error_status || status
|
|
202
180
|
|
|
203
181
|
deliver format, result, status
|
|
204
182
|
end
|
|
205
183
|
|
|
206
|
-
|
|
207
184
|
def deliver format, result, status
|
|
208
|
-
if format
|
|
209
|
-
send_file
|
|
185
|
+
if format == :file && status == 200
|
|
186
|
+
send_file(*result)
|
|
210
187
|
elsif status == 302
|
|
211
188
|
card_redirect result
|
|
212
189
|
else
|
|
@@ -222,27 +199,32 @@ class CardController < ActionController::Base
|
|
|
222
199
|
@card ||= Card.new
|
|
223
200
|
Card::Error.current = exception
|
|
224
201
|
|
|
225
|
-
|
|
226
|
-
|
|
202
|
+
view =
|
|
203
|
+
case exception
|
|
227
204
|
## arguably the view and status should be defined in the error class;
|
|
228
205
|
## some are redundantly defined in view
|
|
229
206
|
when Card::Oops, Card::Query
|
|
230
207
|
card.errors.add :exception, exception.message
|
|
231
|
-
# these error messages are visible to end users and are generally not
|
|
208
|
+
# these error messages are visible to end users and are generally not
|
|
209
|
+
# treated as bugs.
|
|
232
210
|
# Probably want to rename accordingly.
|
|
233
211
|
:errors
|
|
234
212
|
when Card::PermissionDenied
|
|
235
213
|
:denial
|
|
236
|
-
when Card::NotFound, ActiveRecord::RecordNotFound,
|
|
214
|
+
when Card::NotFound, ActiveRecord::RecordNotFound,
|
|
215
|
+
ActionController::MissingFile
|
|
237
216
|
:not_found
|
|
238
217
|
when Wagn::BadAddress
|
|
239
218
|
:bad_address
|
|
240
|
-
else
|
|
219
|
+
else
|
|
220
|
+
# the following indicate a code problem and therefore require full
|
|
221
|
+
# logging
|
|
241
222
|
@card.notable_exception_raised
|
|
242
223
|
|
|
243
224
|
if ActiveRecord::RecordInvalid === exception
|
|
244
225
|
:errors
|
|
245
|
-
|
|
226
|
+
# could also just check non-production mode...
|
|
227
|
+
elsif Rails.logger.level == 0
|
|
246
228
|
raise exception
|
|
247
229
|
else
|
|
248
230
|
:server_error
|
|
@@ -252,9 +234,41 @@ class CardController < ActionController::Base
|
|
|
252
234
|
show view
|
|
253
235
|
end
|
|
254
236
|
|
|
237
|
+
def ajax?
|
|
238
|
+
Card::Env.ajax?
|
|
239
|
+
end
|
|
255
240
|
|
|
241
|
+
def success
|
|
242
|
+
Card::Env[:success]
|
|
243
|
+
end
|
|
256
244
|
|
|
257
|
-
|
|
245
|
+
def card_attr_from_params
|
|
246
|
+
# clone so that original params remain unaltered. need deeper clone?
|
|
247
|
+
opts = params[:card] ? params[:card].clone : {}
|
|
248
|
+
# for /new/:type shortcut. we should fix and deprecate this.
|
|
249
|
+
opts[:type] ||= params[:type] if params[:type]
|
|
250
|
+
# move handling to Card::Name?
|
|
251
|
+
opts[:name] ||= params[:id].to_s.gsub('_', ' ')
|
|
252
|
+
opts
|
|
253
|
+
end
|
|
258
254
|
|
|
255
|
+
def format_from_params
|
|
256
|
+
return :file if params[:explicit_file]
|
|
257
|
+
format = request.parameters[:format]
|
|
258
|
+
return :file if !Card::Format.registered.member?(format) # unknown format
|
|
259
|
+
format
|
|
260
|
+
end
|
|
259
261
|
|
|
262
|
+
def update_params_for_success
|
|
263
|
+
if success.soft_redirect?
|
|
264
|
+
self.params = success.params
|
|
265
|
+
else
|
|
266
|
+
# need tests. insure we get slot, main...
|
|
267
|
+
self.params.merge! success.params
|
|
268
|
+
end
|
|
269
|
+
end
|
|
260
270
|
|
|
271
|
+
def use_draft?
|
|
272
|
+
params[:edit_draft] && card.drafts.present?
|
|
273
|
+
end
|
|
274
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wagn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.16.
|
|
4
|
+
version: 1.16.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ethan McCutchen
|
|
@@ -11,7 +11,7 @@ authors:
|
|
|
11
11
|
autorequire:
|
|
12
12
|
bindir: bin
|
|
13
13
|
cert_chain: []
|
|
14
|
-
date: 2015-
|
|
14
|
+
date: 2015-11-04 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: rails
|
|
@@ -33,14 +33,14 @@ dependencies:
|
|
|
33
33
|
requirements:
|
|
34
34
|
- - '='
|
|
35
35
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: 1.16.
|
|
36
|
+
version: 1.16.10
|
|
37
37
|
type: :runtime
|
|
38
38
|
prerelease: false
|
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
40
|
requirements:
|
|
41
41
|
- - '='
|
|
42
42
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: 1.16.
|
|
43
|
+
version: 1.16.10
|
|
44
44
|
description: a wiki approach to stuctured data, dynamic interaction, and web design
|
|
45
45
|
email:
|
|
46
46
|
- info@wagn.org
|
|
@@ -86,6 +86,7 @@ files:
|
|
|
86
86
|
- features/layouts.feature
|
|
87
87
|
- features/navbox.feature
|
|
88
88
|
- features/notifications.feature
|
|
89
|
+
- features/paging.feature
|
|
89
90
|
- features/pointer_inputs.feature
|
|
90
91
|
- features/presetting_content.feature
|
|
91
92
|
- features/reset_password.feature
|
|
@@ -767,6 +768,7 @@ test_files:
|
|
|
767
768
|
- features/layouts.feature
|
|
768
769
|
- features/navbox.feature
|
|
769
770
|
- features/notifications.feature
|
|
771
|
+
- features/paging.feature
|
|
770
772
|
- features/pointer_inputs.feature
|
|
771
773
|
- features/presetting_content.feature
|
|
772
774
|
- features/reset_password.feature
|