card 1.96.6 → 1.96.7

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/delayed_job_config.rb +2 -0
  4. data/config/locales/de.yml +0 -5
  5. data/config/locales/en.yml +0 -5
  6. data/config/locales/es.yml +0 -5
  7. data/lib/card/act_manager.rb +3 -1
  8. data/lib/card/act_manager/stage_director.rb +2 -2
  9. data/lib/card/act_manager/stage_director/phases.rb +5 -0
  10. data/lib/card/error.rb +6 -0
  11. data/lib/card/set/event.rb +9 -4
  12. data/lib/cardio.rb +2 -1
  13. data/mod/account/set/right/password.rb +5 -2
  14. data/mod/account/set/right/salt.rb +4 -0
  15. data/mod/basic_formats/spec/set/all/base_spec.rb +1 -1
  16. data/mod/carrierwave/lib/carrier_wave/file_card_uploader.rb +4 -4
  17. data/mod/carrierwave/set/abstract/attachment.rb +1 -1
  18. data/mod/core/chunk/link.rb +7 -8
  19. data/mod/core/set/all/abort.rb +75 -0
  20. data/mod/core/set/all/actify.rb +6 -71
  21. data/mod/core/set/all/event_conditions.rb +19 -8
  22. data/mod/core/set/all/export.rb +1 -1
  23. data/mod/core/set/all/references.rb +8 -10
  24. data/mod/core/set/all/stages.rb +2 -2
  25. data/mod/core/set/all/subcards.rb +5 -0
  26. data/mod/core/spec/set/all/references_spec.rb +7 -0
  27. data/mod/core/spec/set/all/rename_spec.rb +1 -1
  28. data/mod/follow/set/right/follow.rb +6 -2
  29. data/mod/follow/set/type_plus_right/user/follow.rb +4 -0
  30. data/mod/follow/set/type_plus_right/user/follow/follow_editor.haml +1 -1
  31. data/mod/standard/set/all/path.rb +13 -0
  32. data/mod/standard/set/rstar/rules.rb +2 -3
  33. data/mod/standard/set/type/set/html_views.rb +1 -3
  34. data/mod/utility/spec/set/abstract/bs_badge_spec.rb +9 -0
  35. data/mod/utility/spec/set/abstract/media_spec.rb +45 -0
  36. metadata +8 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3cd73df55d95de9043a4d5e3300a76f1111fd933
4
- data.tar.gz: 724ea63e5d8152abe48f81649de53f84c4141dc9
3
+ metadata.gz: dfe773b2796cebb8c834d94c16e8eba012a108db
4
+ data.tar.gz: b946f6dac8f928032af10071185bd8c24f0b4e70
5
5
  SHA512:
6
- metadata.gz: '08e8c8237e2d08c50e383cb8fb0d1779a1c6f869bb4fb4d62d1a0d40a9aa7099d10be14fcb92c7b2270931e456047d9594570abda66d92460c9f46f1e14ef3be'
7
- data.tar.gz: ea9d4c08bbc3b88dd4a8a21f59ea8c151f646ea251c855f4889ec49027101847466530e6ad5c49e25ecab0db936217d634ed4933d1c433481530d74dbc0402a8
6
+ metadata.gz: 243b96583e9ba34479a8150ede0041b4f84cd8e03e6c7ba2a6d0306ee320e9554d7fbb3e8a6d839447e7c303c26849eb7a320f34ee4d4a5e4715bb7666a27cb3
7
+ data.tar.gz: 596d3775d722028dbb4a79f0881b6b1e5f0ee215584b252a7c509722ea55a165e23be45523acf56ba3a8756ed8393866ae24b62acfede690e27bc17b2cc061e7
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.6
1
+ 0.6.7
@@ -0,0 +1,2 @@
1
+ Delayed::Worker.max_attempts = 1
2
+ Delayed::Worker.destroy_failed_jobs = false
@@ -64,11 +64,6 @@ de:
64
64
  set:
65
65
  format:
66
66
  exception_alias_fail: cannot find %{optview} view in %{optmod}; failed to alias %{view} in %{self}
67
- spec:
68
- lib:
69
- card:
70
- stage_director_spec:
71
- dont_do_this: tu das nicht
72
67
  mod:
73
68
  :core:
74
69
  format:
@@ -74,11 +74,6 @@ en:
74
74
  set:
75
75
  format:
76
76
  exception_alias_fail: cannot find %{optview} view in %{optmod}; failed to alias %{view} in %{self}
77
- spec:
78
- lib:
79
- card:
80
- stage_director_spec:
81
- dont_do_this: don't do this
82
77
  mod:
83
78
  :core:
84
79
  format:
@@ -74,11 +74,6 @@ es:
74
74
  set:
75
75
  format:
76
76
  exception_alias_fail: no puede encontrar %{optview} vista en %{optmod}; no se pudo el alias %{view} en %{self}
77
- spec:
78
- lib:
79
- card:
80
- stage_director_spec:
81
- dont_do_this: no hagas esto
82
77
  mod:
83
78
  :core:
84
79
  format:
@@ -91,6 +91,7 @@ class Card
91
91
 
92
92
  def run_act card
93
93
  self.act_card = card
94
+ # add new_director(card)
94
95
  yield
95
96
  ensure
96
97
  clear
@@ -109,12 +110,13 @@ class Card
109
110
  @directors = nil
110
111
  end
111
112
 
113
+ # FIXME: use "parent" instead of opts (it's the only option)
112
114
  def fetch card, opts={}
113
115
  return directors[card] if directors[card]
114
116
  directors.each_key do |dir_card|
115
117
  return dir_card.director if dir_card.name == card.name && dir_card.director
116
118
  end
117
- directors[card] = new_director card, opts
119
+ add new_director(card, opts)
118
120
  end
119
121
 
120
122
  def include? name
@@ -259,6 +259,7 @@ class Card
259
259
  if main? && !block_given?
260
260
  raise Card::Error, "need block to store main card"
261
261
  end
262
+
262
263
  # the block is the ActiveRecord block from the around save callback that
263
264
  # saves the card
264
265
  if block_given?
@@ -300,8 +301,7 @@ class Card
300
301
  # the :store stage and the :finalize stage
301
302
  def trigger_storage_phase_callback
302
303
  @stage = stage_index :prepare_to_store
303
- @card.only_storage_phase = true
304
- @card.save! validate: false
304
+ @card.save_as_subcard!
305
305
  end
306
306
  end
307
307
 
@@ -14,6 +14,11 @@ class Card
14
14
  catch_up_to_stage :prepare_to_store
15
15
  run_single_stage :store, &block
16
16
  run_single_stage :finalize
17
+ if @card.errors.any?
18
+ @card.expire_pieces
19
+ raise ActiveRecord::Rollback,
20
+ "errors added in storage phase: #{@card.errors.full_messages * ','}"
21
+ end
17
22
  ensure
18
23
  @from_trash = nil
19
24
  end
@@ -97,9 +97,15 @@ class Card
97
97
  exception = card_error_class(exception, card).new exception.message
98
98
  end
99
99
  exception.card ||= card
100
+ add_card_errors card, exception if exception.card.errors.empty?
100
101
  exception
101
102
  end
102
103
 
104
+ def add_card_errors card, exception
105
+ label = exception.class.to_s.split("::").last
106
+ card.errors.add label, exception.message
107
+ end
108
+
103
109
  def card_error_class exception, card
104
110
  case exception
105
111
  when ActiveRecord::RecordInvalid
@@ -1,12 +1,17 @@
1
1
  class Card
2
2
  module Set
3
- # Events are the building blocks of the three transformative card actions: _create_, _update_, and _delete_. (The fourth kind of action, _read_, does not transform cards, and is associated with {Card::Format views}, not events).
3
+ # Events are the building blocks of the three transformative card actions: _create_,
4
+ # _update_, and _delete_.
5
+ #
6
+ # (The fourth kind of action, _read_, does not transform cards, and is associated
7
+ # with {Card::Format views}, not events).
4
8
  #
5
9
  # Whenever you create, update, or delete a card, the card goes through three phases:
6
- # * __validation__ makes sure all the data is in order
7
- # * __storage__ puts the data in the database
8
- # * __integration__ deals with any ramifications of those changes
10
+ # * __validate__ makes sure all the data is in order
11
+ # * __store__ puts the data in the database
12
+ # * __integrate__ deals with any ramifications of those changes
9
13
  #
14
+ # Events can be defined on each of these stages
10
15
  #
11
16
  class Event
12
17
  module Api
@@ -72,7 +72,8 @@ module Cardio
72
72
  machine_refresh: :cautious, # options: eager, cautious, never
73
73
 
74
74
  allow_irreversible_admin_tasks: false,
75
- raise_all_rendering_errors: true
75
+ raise_all_rendering_errors: false,
76
+ rescue_all_in_controller: true
76
77
  }
77
78
  end
78
79
 
@@ -1,6 +1,9 @@
1
-
2
1
  include All::Permissions::Accounts
3
2
 
3
+ def history?
4
+ false
5
+ end
6
+
4
7
  def ok_to_read
5
8
  own_account? ? true : super
6
9
  end
@@ -9,7 +12,7 @@ event :encrypt_password, :store,
9
12
  on: :save, changed: :content,
10
13
  when: proc { !Card::Env[:no_password_encryptions] } do
11
14
  # no_password_encryptions = hack for import - fix with api for ignoring events
12
- salt = left && left.salt
15
+ salt = left&.salt
13
16
  # HACK: fix with better ORM handling
14
17
  salt = Card::Env[:salt] unless salt.present?
15
18
  self.content = Auth.encrypt content, salt
@@ -1,5 +1,9 @@
1
1
  include All::Permissions::Accounts
2
2
 
3
+ def history?
4
+ false
5
+ end
6
+
3
7
  view :raw do
4
8
  tr :private_data
5
9
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "rspec-html-matchers"
4
4
 
5
- describe Card::Set::All::Base do
5
+ RSpec.describe Card::Set::All::Base do
6
6
  describe "handles view" do
7
7
  describe "name view" do
8
8
  it("name") { expect(render_card(:name)).to eq("Tempo Rary") }
@@ -173,10 +173,10 @@ module CarrierWave
173
173
 
174
174
  def extension
175
175
  case
176
- when file && file.extension.present? then ".#{file.extension}"
177
- when card_content = model.content then File.extname(card_content)
178
- when orig = original_filename then File.extname(orig)
179
- else ""
176
+ when file&.extension.present? then ".#{file.extension}"
177
+ when card_content = model.content then File.extname(card_content)
178
+ when orig = original_filename then File.extname(orig)
179
+ else ""
180
180
  end.downcase
181
181
  end
182
182
 
@@ -18,7 +18,7 @@ event :correct_identifier, :finalize,
18
18
  expire
19
19
  end
20
20
 
21
- event :save_original_filename, :prepare_to_store, when: :file_ready_to_save? do
21
+ event :save_original_filename, :prepare_to_store, on: :save, when: :file_ready_to_save? do
22
22
  return unless @current_action
23
23
  @current_action.update_attributes! comment: original_filename
24
24
  end
@@ -89,20 +89,19 @@ module Card::Content::Chunk
89
89
 
90
90
  def replace_reference old_name, new_name
91
91
  replace_name_reference old_name, new_name
92
+ replace_link_text old_name, new_name
93
+ @text =
94
+ @link_text.nil? ? "[[#{referee_name}]]" : "[[#{referee_name}|#{@link_text}]]"
95
+ end
92
96
 
97
+ def replace_link_text old_name, new_name
93
98
  if @link_text.is_a?(Card::Content)
94
99
  @link_text.find_chunks(Card::Content::Chunk::Reference).each do |chunk|
95
100
  chunk.replace_reference old_name, new_name
96
101
  end
97
- elsif old_name.to_name == @link_text
98
- @link_text = new_name
102
+ elsif @link_text.present?
103
+ @link_text = old_name.to_name.sub_in(@link_text, with: new_name)
99
104
  end
100
-
101
- @text = if @link_text.nil?
102
- "[[#{referee_name}]]"
103
- else
104
- "[[#{referee_name}|#{@link_text}]]"
105
- end
106
105
  end
107
106
  end
108
107
  end
@@ -0,0 +1,75 @@
1
+
2
+ # The Card#abort method is for cleanly exiting an action without continuing
3
+ # to process any further events.
4
+ #
5
+ # Three statuses are supported:
6
+ #
7
+ # failure: adds an error, returns false on save
8
+ # success: no error, returns true on save
9
+ # triumph: similar to success, but if called on a subcard
10
+ # it causes the entire action to abort (not just the subcard)
11
+ def abort status, msg="action canceled"
12
+ director.abort
13
+ if status == :failure && errors.empty?
14
+ errors.add :abort, msg
15
+ elsif status.is_a?(Hash) && status[:success]
16
+ success << status[:success]
17
+ status = :success
18
+ end
19
+ raise Card::Error::Abort.new(status, msg)
20
+ end
21
+
22
+ def aborting
23
+ yield
24
+ errors.any? ? abort(:failure) : abort(:success)
25
+ end
26
+
27
+ def abortable
28
+ yield
29
+ rescue Card::Error::Abort => e
30
+ handle_abort_error e
31
+ end
32
+
33
+ private
34
+
35
+ def handle_abort_error e
36
+ if e.status == :triumph
37
+ @supercard ? raise(e) : true
38
+ elsif e.status == :success
39
+ abort_success
40
+ end
41
+ end
42
+
43
+ def abort_success
44
+ if @supercard
45
+ @supercard.subcards.delete key
46
+ @supercard.director.subdirectors.delete self
47
+ expire :soft
48
+ end
49
+ true
50
+ end
51
+
52
+ # this is an override of standard rails behavior that rescues abort
53
+ # makes it so that :success abortions do not rollback
54
+ def with_transaction_returning_status
55
+ status = nil
56
+ self.class.transaction do
57
+ add_to_transaction
58
+ status = abortable { yield }
59
+ raise ActiveRecord::Rollback unless status
60
+ end
61
+ status
62
+ end
63
+
64
+ # FIXME: these two do not belong here!
65
+
66
+ public
67
+
68
+ event :notable_exception_raised do
69
+ error = Card::Error.current
70
+ Rails.logger.debug "#{error.message}\n#{error.backtrace * "\n "}"
71
+ end
72
+
73
+ def success
74
+ Env.success(name)
75
+ end
@@ -1,43 +1,15 @@
1
-
2
- # The Card#abort method is for cleanly exiting an action without continuing
3
- # to process any further events.
4
- #
5
- # Three statuses are supported:
6
- #
7
- # failure: adds an error, returns false on save
8
- # success: no error, returns true on save
9
- # triumph: similar to success, but if called on a subcard
10
- # it causes the entire action to abort (not just the subcard)
11
- def abort status, msg="action canceled"
12
- director.abort
13
- if status == :failure && errors.empty?
14
- errors.add :abort, msg
15
- elsif status.is_a?(Hash) && status[:success]
16
- success << status[:success]
17
- status = :success
18
- end
19
- raise Card::Error::Abort.new(status, msg)
20
- end
21
-
22
- def aborting
23
- yield
24
- errors.any? ? abort(:failure) : abort(:success)
25
- end
26
-
27
- def act opts={}, &block
28
- opts ||= {}
29
- @action ||= identify_action(opts[:trash])
1
+ def act &block
2
+ @action ||= identify_action
30
3
  if ActManager.act_card
31
4
  add_to_act &block
32
5
  else
33
- start_new_act opts, &block
6
+ start_new_act &block
34
7
  end
35
8
  end
36
9
 
37
- def start_new_act opts
10
+ def start_new_act
38
11
  self.director = nil
39
12
  ActManager.run_act(self) do
40
- Env.success(name) if opts[:success]
41
13
  run_callbacks(:act) { yield }
42
14
  end
43
15
  end
@@ -82,46 +54,9 @@ def valid?(*)
82
54
  end
83
55
 
84
56
  def update_attributes *args
85
- act(*args) { super }
57
+ act { super }
86
58
  end
87
59
 
88
60
  def update_attributes! *args
89
- act(*args) { super }
90
- end
91
-
92
- def abortable
93
- yield
94
- rescue Card::Error::Abort => e
95
- if e.status == :triumph
96
- @supercard ? raise(e) : true
97
- elsif e.status == :success
98
- if @supercard
99
- @supercard.subcards.delete key
100
- @supercard.director.subdirectors.delete self
101
- expire :soft
102
- end
103
- true
104
- end
105
- end
106
-
107
- # this is an override of standard rails behavior that rescues abort
108
- # makes it so that :success abortions do not rollback
109
- def with_transaction_returning_status
110
- status = nil
111
- self.class.transaction do
112
- add_to_transaction
113
- status = abortable { yield }
114
- raise ActiveRecord::Rollback unless status
115
- end
116
- status
117
- end
118
-
119
- event :notable_exception_raised do
120
- error = Card::Error.current
121
- Rails.logger.debug "#{error.message}\n#{error.backtrace * "\n "}"
122
- end
123
-
124
- def success
125
- Env.success(name)
61
+ act { super }
126
62
  end
127
-
@@ -35,8 +35,9 @@ def when_condition_applies? _event, block
35
35
  end
36
36
 
37
37
  def skip_condition_applies? event, allowed
38
- return true unless allowed == :allowed
39
- !skip_event? event
38
+ return true if skip_events.empty?
39
+ event = event.name.to_s
40
+ !(standard_skip_event?(event, allowed) || force_skip_event?(event))
40
41
  end
41
42
 
42
43
  def trigger_condition_applies? event, required
@@ -69,14 +70,24 @@ def wrong_action action
69
70
  "on: #{action} method #{method} called on #{@action}"
70
71
  end
71
72
 
72
- def skip_event? event
73
- @names_of_skipped_events ||= skipped_events
74
- @names_of_skipped_events.include? event.name
73
+ def standard_skip_event? event, allowed
74
+ return false unless allowed == :allowed
75
+ skip_events.include? event
75
76
  end
76
77
 
77
- def skipped_events
78
- events = Array.wrap(skip_event_in_action) + Array.wrap(act_card.skip_event)
79
- ::Set.new events.map(&:to_sym)
78
+ def force_skip_event? event
79
+ forced_skip_events.include? event
80
+ end
81
+
82
+ def forced_skip_events
83
+ @forced_skip_events ||= ::Set.new(skip_events.find_all { |e| e.last == "!" })
84
+ end
85
+
86
+ def skip_events
87
+ @skip_events ||= begin
88
+ events = Array.wrap(skip_event_in_action) + Array.wrap(act_card.skip_event)
89
+ ::Set.new events.map(&:to_s)
90
+ end
80
91
  end
81
92
 
82
93
  def trigger_event? event
@@ -13,7 +13,7 @@ format :json do
13
13
  # returns an array of Hashes (each in export_item view)
14
14
  view :export_items, cache: :never do
15
15
  exporting_uniques do
16
- export_items_in_view :export_item
16
+ export_items_in_view(:export).flatten
17
17
  end
18
18
  end
19
19
 
@@ -91,7 +91,8 @@ end
91
91
  # }
92
92
  def interpret_reference ref_hash, referee_name, ref_type
93
93
  return unless referee_name # eg commented nest has no referee_name
94
- referee_key = (referee_name = referee_name.to_name).key
94
+ referee_name = referee_name.to_name
95
+ referee_key = referee_name.key
95
96
  return if referee_key == key # don't create self reference
96
97
 
97
98
  referee_id = Card.fetch_id(referee_name)
@@ -162,15 +163,12 @@ end
162
163
 
163
164
  # on rename, update names in cards that refer to self by name (as directed)
164
165
  event :update_referer_content, :finalize,
165
- on: :update, after: :name_change_finalized,
166
- when: :update_referers do
167
- # FIXME: break into correct stages
168
- Auth.as_bot do
169
- referers.each do |card|
170
- next if card == self || card.structure
171
- new_content = card.replace_reference_syntax name_before_last_save, name
172
- card.refresh.update_attributes! content: new_content
173
- end
166
+ on: :update, after: :name_change_finalized, when: :update_referers do
167
+ referers.each do |card|
168
+ next if card.structure
169
+ card.skip = %i[validate_renaming check_permissions!]
170
+ attach_subcard card.name,
171
+ content: card.replace_reference_syntax(name_before_last_save, name)
174
172
  end
175
173
  end
176
174
 
@@ -5,9 +5,9 @@ def director
5
5
  @director ||= Card::ActManager.fetch self
6
6
  end
7
7
 
8
- def identify_action explicit_delete=false
8
+ def identify_action
9
9
  @action =
10
- if explicit_delete || (trash && trash_changed?)
10
+ if trash && trash_changed?
11
11
  :delete
12
12
  elsif new_card?
13
13
  :create
@@ -22,6 +22,11 @@ def expire_subcards
22
22
  subcards.clear
23
23
  end
24
24
 
25
+ def save_as_subcard!
26
+ self.only_storage_phase = true
27
+ save! validate: false
28
+ end
29
+
25
30
  # phase_method :attach_subcard, before: :store do |name_or_card, args=nil|
26
31
  # TODO: handle differently in different stages
27
32
  def attach_subcard name_or_card, args={}
@@ -43,4 +43,11 @@ RSpec.describe Card::Set::All::References do
43
43
  expect(Card["X"].nestees.map(&:name)).to eq([])
44
44
  end
45
45
  end
46
+
47
+ describe "event :update_referer_content" do
48
+ it "handles self references" do
49
+ Card["A"].update_attributes! name: "AAA", update_referers: true
50
+ expect(Card["X"].content).to eq("[[AAA]] [[AAA+B]] [[T]]")
51
+ end
52
+ end
46
53
  end
@@ -18,7 +18,7 @@ module RenameMethods
18
18
  end
19
19
  attrs_before = name_invariant_attributes(card)
20
20
  actions_count_before = card.actions.count
21
- update card.name, name: new_name, update_referers: true
21
+ update! card.name, name: new_name, update_referers: true
22
22
  expect(card.actions.count).to eq(actions_count_before + 1)
23
23
  assert_equal attrs_before, name_invariant_attributes(card)
24
24
  assert_equal new_name, card.name
@@ -35,14 +35,18 @@ def ok_to_delete
35
35
  end
36
36
 
37
37
  def permit action, verb=nil
38
- if %i[create delete update].include?(action) && Auth.signed_in? &&
39
- (user = rule_user) && Auth.current_id == user.id
38
+ if %i[create delete update].include?(action) && allowed_to_change_follow_status?
40
39
  true
41
40
  else
42
41
  super action, verb
43
42
  end
44
43
  end
45
44
 
45
+ def allowed_to_change_follow_status?
46
+ Auth.signed_in? &&
47
+ ((user = rule_user) && Auth.current_id == user.id) || Auth.always_ok?
48
+ end
49
+
46
50
  format :html do
47
51
  # shows a follow item link for each of the current follow options
48
52
  view :follow_status, cache: :never do
@@ -52,6 +52,10 @@ format :html do
52
52
  haml :follow_editor, items_method: :ignoring_rules_and_options
53
53
  end
54
54
 
55
+ def show_button?
56
+ card.current_user? || Auth.always_ok?
57
+ end
58
+
55
59
  def pointer_items args
56
60
  voo.items[:view] ||= :link
57
61
  super(args)
@@ -2,4 +2,4 @@
2
2
  %ul.delete-list.list-group
3
3
  - send items_method do |rule_card, option|
4
4
  %li.list-group-item
5
- = subformat(rule_card).follow_item option, card.current_user?
5
+ = subformat(rule_card).follow_item option, show_button?
@@ -123,6 +123,19 @@ format :json do
123
123
  end
124
124
  end
125
125
 
126
+ format :css do
127
+ def contextualize_path relative_path
128
+ if Card.config.file_storage == :local
129
+ # absolute paths lead to invalid assets path in css for cukes
130
+ card_path relative_path
131
+ else
132
+ # ...but relative paths are problematic when machine output and
133
+ # hard-coded assets (like fonts) are on different servers
134
+ card_url relative_path
135
+ end
136
+ end
137
+ end
138
+
126
139
  format :html do
127
140
  # in HTML, decko paths rendered as relative to the site's root.
128
141
  def contextualize_path relative_path
@@ -1,8 +1,7 @@
1
- event :save_recently_edited_settings, :integrate,
2
- on: :save, when: proc { |c| c.is_rule? } do
1
+ event :save_recently_edited_settings, :integrate, on: :save, when: :is_rule? do
3
2
  if (recent = Card[:recent_settings])
4
3
  recent.insert_item 0, name.right
5
- recent.save
4
+ attach_subcard recent
6
5
  end
7
6
  end
8
7
 
@@ -135,9 +135,7 @@ format :html do
135
135
  def set_navbar_content related_sets
136
136
  wrap_with :ul, class: "nav navbar-nav nav-pills" do
137
137
  related_sets.map do |name, label|
138
- slot_opts = { subheader: title_in_context(name),
139
- subframe: true,
140
- hide: "header set_label rule_navbar",
138
+ slot_opts = { hide: "header set_label rule_navbar",
141
139
  show: "subheader set_navbar" }
142
140
  link = link_to_card name, label, remote: true,
143
141
  path: { view: @slot_view,
@@ -0,0 +1,9 @@
1
+ RSpec.describe Card::Set::Abstract::BsBadge do
2
+ specify "#labeled badge" do
3
+ expect(format_subject.labeled_badge(5, "Cats"))
4
+ .to have_tag "span.labeled-badge" do
5
+ with_tag("span.badge") { "5" }
6
+ with_tag("label.text-muted") { "Cats" }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,45 @@
1
+ RSpec.describe Card::Set::Abstract::Media do
2
+ describe "#image_with_text" do
3
+ let(:html_format) do
4
+ Card["*credit"].format_with_set(described_class, :html)
5
+ end
6
+
7
+ def text_with_image args={}
8
+ html_format.text_with_image args
9
+ end
10
+
11
+ it "uses +image by default" do
12
+ expect(text_with_image)
13
+ .to have_tag :div, with: { class: "media" } do
14
+ with_tag "img[src*='/files/']", with: { alt: "*credit+image" }
15
+ end
16
+ end
17
+
18
+ it "takes image card name as image" do
19
+ expect(text_with_image(image: "*logo"))
20
+ .to have_tag :div, with: { class: "media" } do
21
+ with_tag "img[src*='/files/']", with: { alt: "*logo" }
22
+ end
23
+ end
24
+
25
+ it "takes image card object as image" do
26
+ expect(text_with_image(image: Card["*logo"]))
27
+ .to have_tag :div, with: { class: "media" } do
28
+ with_tag "img[src*='/files/']", with: { alt: "*logo" }
29
+ end
30
+ end
31
+
32
+ it "handles size argument" do
33
+ expect(text_with_image(size: :small))
34
+ .to have_tag :div, with: { class: "media" } do
35
+ with_tag "img[src*='small']"
36
+ end
37
+ end
38
+
39
+ it "doesn't escape a stubbed src argument" do
40
+ stub = "(stub)#{Card::View::Stub.escape '{"mode":"normal"}'}(/stub)"
41
+ allow(html_format).to receive(:nest).and_return stub
42
+ expect(text_with_image).to include %{src='(stub){"mode":"normal"}(/stub)'}
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: card
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.96.6
4
+ version: 1.96.7
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: 2018-11-30 00:00:00.000000000 Z
14
+ date: 2018-12-18 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: cardname
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - '='
21
21
  - !ruby/object:Gem::Version
22
- version: 0.6.6
22
+ version: 0.6.7
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - '='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.6.6
29
+ version: 0.6.7
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: haml
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -308,6 +308,7 @@ files:
308
308
  - config/initializers/02_patches/kaminari.rb
309
309
  - config/initializers/core_extensions.rb
310
310
  - config/initializers/deck_config.rb
311
+ - config/initializers/delayed_job_config.rb
311
312
  - config/initializers/inflections.rb
312
313
  - config/initializers/internationalization.rb
313
314
  - config/initializers/mime_types.rb
@@ -3856,6 +3857,7 @@ files:
3856
3857
  - mod/core/set/abstract/haml_file.rb
3857
3858
  - mod/core/set/abstract/lock.rb
3858
3859
  - mod/core/set/abstract/vendor_code_file.rb
3860
+ - mod/core/set/all/abort.rb
3859
3861
  - mod/core/set/all/actify.rb
3860
3862
  - mod/core/set/all/active_card.rb
3861
3863
  - mod/core/set/all/assign_attributes.rb
@@ -5218,6 +5220,8 @@ files:
5218
5220
  - mod/utility/set/abstract/media.rb
5219
5221
  - mod/utility/set/abstract/media/media_snippet.haml
5220
5222
  - mod/utility/set/abstract/utility.rb
5223
+ - mod/utility/spec/set/abstract/bs_badge_spec.rb
5224
+ - mod/utility/spec/set/abstract/media_spec.rb
5221
5225
  - mod/utility/spec/set/abstract/utility_spec.rb
5222
5226
  - mod/virtual/lib/card/virtual.rb
5223
5227
  - mod/virtual/set/abstract/virtual_cache.rb