card 1.96.0 → 1.96.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/02_patches/kaminari.rb +2 -2
  4. data/config/locales/de.yml +38 -3
  5. data/config/locales/en.yml +39 -4
  6. data/config/locales/es.yml +606 -0
  7. data/db/migrate_core_cards/data/cards/{*header → Xheader} +0 -0
  8. data/db/migrate_core_cards/data/cards/{*main_menu → Xmain_menu} +0 -0
  9. data/lib/card.rb +2 -2
  10. data/lib/card/act_manager.rb +1 -1
  11. data/lib/card/env/success.rb +26 -13
  12. data/lib/card/format/nest/fetch.rb +6 -1
  13. data/lib/card/migration/import/import_data/card_content.rb +1 -1
  14. data/mod/account/set/right/account.rb +115 -101
  15. data/mod/account/set/self/signin.rb +106 -96
  16. data/mod/account/spec/set/all/account_spec.rb +0 -2
  17. data/mod/account/spec/set/right/account_spec.rb +6 -9
  18. data/mod/account/spec/set/self/signin_spec.rb +2 -5
  19. data/mod/admin/set/self/admin_info.rb +4 -4
  20. data/mod/admin/spec/set/self/admin_info_spec.rb +10 -0
  21. data/mod/admin/spec/set/self/trash_spec.rb +7 -0
  22. data/mod/basic_formats/set/all/json.rb +7 -3
  23. data/mod/basic_formats/spec/set/all/head_spec.rb +33 -0
  24. data/mod/basic_types/set/type/json.rb +1 -1
  25. data/mod/basic_types/spec/set/type/plain_text_spec.rb +6 -0
  26. data/mod/bootstrap/set/type/customized_bootswatch_skin.rb +2 -2
  27. data/mod/bootstrap/spec/set/type/customized_bootswatch_skin/html_views_spec.rb +5 -0
  28. data/mod/bootstrap/spec/set/type_plus_right/customized_bootswatch_skin/colors_spec.rb +8 -0
  29. data/mod/carrierwave/set/abstract/attachment/storage_type.rb +12 -13
  30. data/mod/core/set/all/actify.rb +5 -0
  31. data/mod/core/set/all/codename.rb +2 -2
  32. data/mod/core/set/all/event_conditions.rb +2 -1
  33. data/mod/core/set/all/fetch_helper.rb +2 -2
  34. data/mod/core/set/all/i18n.rb +1 -1
  35. data/mod/core/set/all/item.rb +6 -0
  36. data/mod/core/set/all/location_history.rb +12 -1
  37. data/mod/core/set/all/name_events.rb +8 -9
  38. data/mod/core/set/all/permissions.rb +1 -1
  39. data/mod/core/set/all/rename.rb +3 -5
  40. data/mod/core/set/all/trash.rb +4 -9
  41. data/mod/core/set/all/type.rb +7 -5
  42. data/mod/core/set/all/utils.rb +13 -5
  43. data/mod/core/spec/set/abstract/code_file_spec.rb +8 -0
  44. data/mod/core/spec/set/all/tabs_spec.rb +19 -0
  45. data/mod/developer/spec/set/all/view_viz_spec.rb +9 -0
  46. data/mod/follow/spec/set/all/follow/follow_link_spec.rb +7 -0
  47. data/mod/follow/spec/set/all/notify/html_views_spec.rb +7 -0
  48. data/mod/follow/spec/set/right/follow_spec.rb +0 -0
  49. data/mod/follow/spec/set/right/following_spec.rb +6 -0
  50. data/mod/follow/spec/set/type/notification_template_spec.rb +1 -1
  51. data/mod/history/set/all/content_history.rb +1 -1
  52. data/mod/history/spec/set/all/act_view_spec.rb +16 -0
  53. data/mod/history/spec/set/all/action_view_spec.rb +10 -0
  54. data/mod/history/spec/set/all/history_spec.rb +11 -0
  55. data/mod/item/spec/set/all/bar_spec.rb +41 -0
  56. data/mod/machines/lib/javascript/decko_slot.js.coffee +1 -1
  57. data/mod/pointer/set/abstract/02_pointer/other_views.rb +0 -4
  58. data/mod/recaptcha/set/all/recaptcha.rb +1 -1
  59. data/mod/search/spec/set/abstract/search_spec.rb +8 -0
  60. data/mod/standard/set/all/error.rb +48 -26
  61. data/mod/standard/set/all/rich_html/toolbar.rb +6 -1
  62. data/mod/standard/set/type/list.rb +7 -9
  63. data/mod/standard/set/type/number.rb +1 -1
  64. data/mod/standard/set/type/session.rb +1 -1
  65. data/mod/standard/spec/content/chunk/link_spec.rb +3 -3
  66. data/mod/utility/set/abstract/media.rb +13 -9
  67. data/mod/utility/set/abstract/media/media_snippet.haml +5 -3
  68. metadata +22 -6
@@ -1,5 +1,3 @@
1
- # -*- encoding : utf-8 -*-
2
-
3
1
  RSpec.describe Card::Set::All::Account do
4
2
  describe "accountable?" do
5
3
  it "is false for cards with *accountable rule off" do
@@ -96,8 +96,7 @@ RSpec.describe Card::Set::Right::Account do
96
96
  ["/update/#{@account.left.name.url_key}",
97
97
  "token=#{token}",
98
98
  "live_token=true",
99
- "event=reset_password"].each do |url_part|
100
-
99
+ "card%5Btrigger%5D=reset_password"].each do |url_part|
101
100
  expect(raw_source).to include(url_part)
102
101
  end
103
102
  end
@@ -133,13 +132,14 @@ RSpec.describe Card::Set::Right::Account do
133
132
  @account.send_reset_password_token
134
133
  @token = @account.token
135
134
  Card::Env.params[:token] = @token
136
- Card::Env.params[:event] = "reset_password"
137
135
  Card::Auth.current_id = Card::AnonymousID
138
136
  end
139
137
 
138
+ let(:trigger_reset) { @account.update_attributes! trigger: :reset_password }
139
+
140
140
  it "authenticates with correct token" do
141
141
  expect(Card::Auth.current_id).to eq(Card::AnonymousID)
142
- expect(@account.save).to eq(true)
142
+ trigger_reset
143
143
  expect(Card::Auth.current_id).to eq(@account.left_id)
144
144
  @account = @account.refresh true
145
145
  # expect(@account.fetch(trait: :token)).to be_nil
@@ -149,10 +149,8 @@ RSpec.describe Card::Set::Right::Account do
149
149
  @account.token_card.update_column :updated_at,
150
150
  3.days.ago.strftime("%F %T")
151
151
  @account.token_card.expire
152
- result = @account.save
153
152
 
154
- expect(result).to eq(true)
155
- # successfully completes save
153
+ trigger_reset
156
154
 
157
155
  expect(@account.token).not_to eq(@token)
158
156
  # token gets updated
@@ -163,8 +161,7 @@ RSpec.describe Card::Set::Right::Account do
163
161
 
164
162
  it "does not work if token is wrong" do
165
163
  Card::Env.params[:token] = @token + "xxx"
166
- Card::Env.params[:event] = "reset_password"
167
- @account.save
164
+ trigger_reset
168
165
  expect(@account.errors[:incorrect_token].first).to match(/mismatch/)
169
166
  end
170
167
  end
@@ -51,10 +51,6 @@ RSpec.describe Card::Set::Self::Signin do
51
51
  end
52
52
 
53
53
  context "#reset password" do
54
- before do
55
- Card::Env.params[:reset_password] = true
56
- end
57
-
58
54
  it "is triggered by an update" do
59
55
  # Card['joe admin'].account.token.should be_nil FIXME: this should be t
60
56
  @card.update_attributes! "+*email" => "joe@admin.com"
@@ -62,7 +58,8 @@ RSpec.describe Card::Set::Self::Signin do
62
58
  end
63
59
 
64
60
  it "returns an error if email is not found" do
65
- @card.update_attributes "+*email" => "schmoe@admin.com"
61
+ @card.update_attributes! "+*email" => "schmoe@admin.com",
62
+ trigger: :send_reset_password_token
66
63
  expect(@card.errors[:email].first).to match(/not recognized/)
67
64
  end
68
65
  end
@@ -26,10 +26,10 @@ format :html do
26
26
  end
27
27
 
28
28
  def warning_list_with_auto_scope warnings
29
- # 'ADMINISTRATOR WARNING'
30
- admin_warn = tx(:admin_warn)
31
- "<h5>#{admin_warn}</h5>" + warnings.join("\n")
32
- end
29
+ # 'ADMINISTRATOR WARNING'
30
+ admin_warn = tr(:admin_warn)
31
+ "<h5>#{admin_warn}</h5>" + warnings.join("\n")
32
+ end
33
33
 
34
34
  def email_warning
35
35
  # "Email delivery is turned off."
@@ -0,0 +1,10 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ RSpec.describe Card::Set::Self::AdminInfo do
4
+ specify "view core" do
5
+ expect_view(:core).to have_tag("div.alert.alert-warning.alert-dismissible") do
6
+ with_tag "button.close"
7
+ with_tag "a.external-link"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ describe Card::Set::Self::Trash do
4
+ specify "view core" do
5
+ expect_view(:core).to have_tag("table")
6
+ end
7
+ end
@@ -97,9 +97,7 @@ format :json do
97
97
  end
98
98
 
99
99
  view :items, cache: :never do
100
- item_cards.map do |i_card|
101
- nest i_card
102
- end
100
+ listing item_cards
103
101
  end
104
102
 
105
103
  view :links, cache: :never do
@@ -139,6 +137,12 @@ format :json do
139
137
  }
140
138
  end
141
139
 
140
+ view :export_item do
141
+ item = { name: card.name, type: card.type_name, content: card.content }
142
+ item[:codename] = card.codename if card.codename
143
+ item
144
+ end
145
+
142
146
  view :essentials do
143
147
  if voo.show? :marks
144
148
  render_marks.merge(essentials)
@@ -0,0 +1,33 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ describe Card::Set::All::Head do
4
+ specify "view head" do
5
+ expect_view(:head).to have_tag("title"), "A - WikiRate"
6
+ expect_view(:head).to have_tag("link")
7
+ expect_view(:head).to have_tag("script")
8
+ end
9
+
10
+ specify "view meta_tags" do
11
+ expect_view(:meta_tags).to have_tag("meta")
12
+ end
13
+
14
+ specify "view page_title_tag" do
15
+ expect_view(:page_title_tag).to have_tag("title")
16
+ end
17
+
18
+ specify "view favicon_tag" do
19
+ expect_view(:favicon_tag).to have_tag("link")
20
+ end
21
+
22
+ specify "view universal_edit_button" do
23
+ expect_view(:universal_edit_button).to have_tag("link")
24
+ end
25
+
26
+ specify "view head_stylesheet" do
27
+ expect_view(:head_stylesheet).to have_tag("link")
28
+ end
29
+
30
+ specify "view decko_script_variables" do
31
+ expect_view(:decko_script_variables).to have_tag("script")
32
+ end
33
+ end
@@ -5,7 +5,7 @@ end
5
5
  def check_json_syntax
6
6
  JSON.parse content
7
7
  rescue JSON::ParserError => e
8
- errors.add "invalid json", e.message.sub(/^\d+: /, "").to_s
8
+ errors.add tr(:invalid_json), e.message.sub(/^\d+: /, "").to_s
9
9
  end
10
10
 
11
11
  format :html do
@@ -9,4 +9,10 @@ describe Card::Set::Type::PlainText do
9
9
  expect(render_card(:core, type: "Plain Text", content: "<b></b>"))
10
10
  .to eq "&lt;b&gt;&lt;/b&gt;"
11
11
  end
12
+
13
+ specify "view core" do
14
+ expect_view(:core).to have_tag("a.known-card") do
15
+ with_tag "span.card-title"
16
+ end
17
+ end
12
18
  end
@@ -47,9 +47,9 @@ end
47
47
  event :validate_theme_template, :validate, on: :create do
48
48
  if theme_name
49
49
  if Card.fetch_type_id(theme_card_name) != Card::BootswatchSkinID
50
- errors.add :abort, "not a valid theme: #{theme_name}"
50
+ errors.add :abort, tr(:not_valid_theme, theme_name: theme_name)
51
51
  elsif !Dir.exist?(source_dir)
52
- errors.add :abort, "can't find source for theme \"#{theme_name}\""
52
+ errors.add :abort, tr(:cannot_source_theme, theme_name: theme_name)
53
53
  end
54
54
  end
55
55
  end
@@ -0,0 +1,5 @@
1
+ RSpec.describe Card::Set::Type::CustomizedBootswatchSkin::HtmlViews do
2
+ specify "view core" do
3
+ expect_view(:core).to have_tag("h5")
4
+ end
5
+ end
@@ -15,4 +15,12 @@ RSpec.describe Card::Set::TypePlusRight::CustomizedBootswatchSkin::Colors do
15
15
  expect(card.colors_card.theme_colors)
16
16
  .to include("card-cap-bg": "rgba($black, .03)")
17
17
  end
18
+
19
+ specify "view bar_middle" do
20
+ expect_view(:bar_middle).to have_tag("div.colorpicker-element") do
21
+ with_tag "div.input-group-addon"
22
+ with_tag "span"
23
+ with_tag "i"
24
+ end
25
+ end
18
26
  end
@@ -16,15 +16,14 @@ end
16
16
 
17
17
  event :validate_storage_type, :validate, on: :save do
18
18
  if will_become_coded?
19
- unless mod || @new_mod
20
- errors.add :storage_type, "mod argument needed to save card as coded"
21
- end
22
- if codename.blank?
23
- errors.add :storage_type, "codename needed for storage type coded"
24
- end
19
+ errors.add :storage_type, tr(:mod_argument_needed_to_save) unless mod || @new_mod
20
+ errors.add :storage_type, tr(:codename_needed_for_storage) if codename.blank?
25
21
  end
26
22
  unless known_storage_type? will_be_stored_as
27
- errors.add :storage_type, "unknown storage type: #{@new_storage_type}"
23
+ errors.add :storage_type, tr(
24
+ :unknown_storage_type,
25
+ new_storage_type: @new_storage_type
26
+ )
28
27
  end
29
28
  end
30
29
 
@@ -35,8 +34,7 @@ event :validate_storage_type_update, :validate, on: :update do
35
34
  # i.e. `update_attributes storage_type: :local` fails but
36
35
  # `update_attributes storage_type: :local, file: [file handle]` is ok
37
36
  if cloud? && storage_type_changed? && !attachment_is_changing?
38
- errors.add :storage_type, "moving files from cloud elsewhere "\
39
- "is not supported"
37
+ errors.add :storage_type, tr(:moving_files_is_not_supported)
40
38
  end
41
39
  end
42
40
 
@@ -199,7 +197,7 @@ end
199
197
  def load_bucket_config_from_env config
200
198
  config ||= {}
201
199
  CarrierWave::FileCardUploader::CONFIG_OPTIONS.each do |key|
202
- next if key.in? [:attributes, :credentials]
200
+ next if key.in? %i[attributes credentials]
203
201
  replace_with_env_variable config, key
204
202
  end
205
203
  config[:credentials] ||= {}
@@ -232,7 +230,7 @@ end
232
230
 
233
231
  def bucket_from_config
234
232
  Cardio.config.file_default_bucket ||
235
- (Cardio.config.file_buckets && Cardio.config.file_buckets.keys.first)
233
+ (Cardio.config.file_buckets&.keys&.first)
236
234
  end
237
235
 
238
236
  def storage_type
@@ -308,7 +306,7 @@ end
308
306
  def with_storage_options opts={}
309
307
  old_values = {}
310
308
  validate_temporary_storage_type_change opts[:storage_type]
311
- [:storage_type, :mod, :bucket].each do |opt_name|
309
+ %i[storage_type mod bucket].each do |opt_name|
312
310
  next unless opts[opt_name]
313
311
  old_values[opt_name] = instance_variable_get "@#{opt_name}"
314
312
  instance_variable_set "@#{opt_name}", opts[opt_name]
@@ -330,8 +328,9 @@ def validate_temporary_storage_type_change new_storage_type=nil
330
328
  new_storage_type ||= @new_storage_type
331
329
  return unless new_storage_type
332
330
  unless known_storage_type? new_storage_type
333
- raise Error, "unknown storage type: #{new_storage_type}"
331
+ raise Error, tr(:unknown_storage_type, new_storage_type: new_storage_type)
334
332
  end
333
+
335
334
  if new_storage_type == :coded && codename.blank?
336
335
  raise Error, "codename needed for storage type :coded"
337
336
  end
@@ -19,6 +19,11 @@ def abort status, msg="action canceled"
19
19
  raise Card::Error::Abort.new(status, msg)
20
20
  end
21
21
 
22
+ def aborting
23
+ yield
24
+ errors.any? ? abort(:failure) : abort(:success)
25
+ end
26
+
22
27
  def act opts={}, &block
23
28
  opts ||= {}
24
29
  @action ||= identify_action(opts[:trash])
@@ -15,11 +15,11 @@ private
15
15
 
16
16
  def validate_codename_permission
17
17
  return if Auth.always_ok?
18
- errors.add :codename, "only admins can set codename"
18
+ errors.add :codename, tr(:only_admins_codename)
19
19
  end
20
20
 
21
21
  def validate_codename_uniqueness
22
22
  return (self.codename = nil) if codename.blank?
23
23
  return if errors.present? || !Card.find_by_codename(codename)
24
- errors.add :codename, "codename #{codename} already in use"
24
+ errors.add :codename, tr(:error_code_in_use, codename: codename)
25
25
  end
@@ -20,6 +20,7 @@ def on_condition_applies? _event, actions
20
20
  end
21
21
 
22
22
  def changed_condition_applies? _event, db_columns
23
+ return true unless @action == :update
23
24
  db_columns = Array(db_columns).compact
24
25
  return true if db_columns.empty?
25
26
  db_columns.any? { |col| single_changed_condition_applies? col }
@@ -51,7 +52,7 @@ def single_changed_condition_applies? db_column
51
52
  when :type then "type_id"
52
53
  else db_column.to_s
53
54
  end
54
- @action != :delete && attribute_is_changing?(db_column)
55
+ attribute_is_changing?(db_column)
55
56
  end
56
57
 
57
58
  def wrong_stage opts
@@ -26,7 +26,7 @@ module ClassMethods
26
26
  private
27
27
 
28
28
  def standard_controller_fetch args, card_opts
29
- mark = args[:id] || card_opts[:name]
29
+ mark = args[:mark] || card_opts[:name]
30
30
  card = Card.fetch mark, look_in_trash: args[:look_in_trash], new: card_opts
31
31
  card.assign_attributes card_opts if args[:assign] && card&.real?
32
32
  card
@@ -36,7 +36,7 @@ module ClassMethods
36
36
  opts = safe_param args[:card]
37
37
  opts[:type] ||= args[:type] if args[:type]
38
38
  # for /new/:type shortcut. we should handle in routing and deprecate this
39
- opts[:name] ||= Card::Name.url_key_to_standard(args[:id])
39
+ opts[:name] ||= Card::Name.url_key_to_standard(args[:mark])
40
40
  opts
41
41
  end
42
42
 
@@ -1,6 +1,6 @@
1
1
 
2
2
  def tr key, args={}
3
- ::I18n.t key, args.merge(scope: Card::Set.scope(caller))
3
+ ::I18n.t key, args.reverse_merge(scope: Card::Set.scope(caller))
4
4
  end
5
5
 
6
6
  format do
@@ -102,6 +102,12 @@ format do
102
102
  end
103
103
  end
104
104
 
105
+ def wrap_item item, _args={}
106
+ item # no wrap in base
107
+ end
108
+ end
109
+
110
+ format :html do
105
111
  def wrap_item rendered, item_view
106
112
  %(<div class="item-#{item_view}">#{rendered}</div>)
107
113
  end
@@ -1,8 +1,19 @@
1
1
  event :discard_deleted_locations, in: :finalize, on: :delete do
2
2
  Env.discard_locations_for self
3
- success.target = :previous if success.target == self
3
+ configure_successful_deletion if success.target == self
4
4
  end
5
5
 
6
6
  event :save_current_location, before: :show_page, on: :read do
7
7
  Env.save_location self
8
8
  end
9
+
10
+ # TO DISCUSS: should this default behavior be directly in the controller?
11
+ # Or at least in decko?
12
+ def configure_successful_deletion
13
+ if Env.ajax?
14
+ success.card = self
15
+ success.view = :missing unless success.view
16
+ else
17
+ success.target = :previous
18
+ end
19
+ end
@@ -22,30 +22,29 @@ event :validate_uniqueness_of_name do
22
22
  rel = Card.where key: name.key, trash: false
23
23
  rel = rel.where "id <> ?", id if id
24
24
  if (existing = rel.take)
25
- errors.add :name, "must be unique; '#{existing.name}' already exists."
25
+ errors.add :name, tr(:error_name_exists, name: existing.name)
26
26
  end
27
27
  end
28
28
 
29
29
  event :validate_legality_of_name do
30
30
  if name.length > 255
31
- errors.add :name, "is too long (255 character maximum)"
31
+ errors.add :name, tr(:error_too_long, length: name.length)
32
32
  elsif name.blank?
33
- errors.add :name, "can't be blank"
33
+ errors.add :name, tr(:error_blank_name)
34
34
  elsif name.parts.include? ""
35
- errors.add :name, "is incomplete"
35
+ errors.add :name, tr(:is_incomplete)
36
36
  elsif !name.valid?
37
- errors.add :name, "may not contain any of the following characters: " \
38
- "#{Card::Name.banned_array * ' '}"
37
+ errors.add :name, tr(:error_banned_characters, banned: Card::Name.banned_array * " ")
39
38
  elsif changing_existing_tag_to_junction?
40
- errors.add :name, "#{name} in use as a tag"
39
+ errors.add :name, tr(:error_name_tag, name: name)
41
40
  end
42
41
  end
43
42
 
44
43
  event :validate_key, after: :validate_name, on: :save do
45
44
  if key.empty?
46
- errors.add :key, "cannot be blank" if errors.empty?
45
+ errors.add :key, tr(:error_blank_key) if errors.empty?
47
46
  elsif key != name.key
48
- errors.add :key, "wrong key '#{key}' for name #{name}"
47
+ errors.add :key, tr(:error_wrong_key, key: key, name: name)
49
48
  end
50
49
  end
51
50
 
@@ -95,7 +95,7 @@ def require_permission_rule! rule_id, action
95
95
  return if rule_id
96
96
  # RULE missing. should not be possible.
97
97
  # generalize this to handling of all required rules
98
- errors.add :permission_denied, "No #{action} rule for #{name}"
98
+ errors.add :permission_denied, tr(:error_no_action_rule, action: action, name: name)
99
99
  raise Card::Error::PermissionDenied, self
100
100
  end
101
101