card 1.96.6 → 1.96.7

Sign up to get free protection for your applications and to get access to all the features.
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