card 1.16.8 → 1.16.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/{20150611203506_rails_inflection_updates.rb → 20120611203506_rails_inflection_updates.rb} +0 -0
  4. data/db/migrate_core_cards/20150326205655_bootswatch_themes.rb +0 -1
  5. data/db/migrate_core_cards/20150429090551_search_card_context.rb +1 -1
  6. data/db/migrate_core_cards/20150708224756_add_list_cards.rb +22 -0
  7. data/db/seed/new/card_actions.yml +789 -509
  8. data/db/seed/new/card_acts.yml +1 -1
  9. data/db/seed/new/card_changes.yml +2618 -1920
  10. data/db/seed/new/card_references.yml +1034 -901
  11. data/db/seed/new/cards.yml +2303 -1675
  12. data/db/seed/test/fixtures/card_actions.yml +1926 -1606
  13. data/db/seed/test/fixtures/card_acts.yml +354 -324
  14. data/db/seed/test/fixtures/card_changes.yml +5950 -5175
  15. data/db/seed/test/fixtures/card_references.yml +1861 -1630
  16. data/db/seed/test/fixtures/cards.yml +3768 -3048
  17. data/db/seed/test/seed.rb +121 -107
  18. data/lib/card.rb +2 -3
  19. data/lib/card/active_record_helper.rb +44 -0
  20. data/lib/card/auth.rb +51 -47
  21. data/lib/card/cache.rb +7 -3
  22. data/lib/card/codename.rb +7 -7
  23. data/lib/card/format.rb +2 -1
  24. data/lib/card/migration.rb +17 -16
  25. data/lib/card/name.rb +71 -20
  26. data/lib/card/set.rb +202 -166
  27. data/lib/card/simplecov_helper.rb +11 -7
  28. data/lib/card/subcards.rb +249 -0
  29. data/mod/01_core/set/all/collection.rb +1 -2
  30. data/mod/01_core/set/all/fetch.rb +167 -92
  31. data/mod/01_core/set/all/initialize.rb +8 -22
  32. data/mod/01_core/set/all/name.rb +128 -79
  33. data/mod/01_core/set/all/phases.rb +93 -95
  34. data/mod/01_core/set/all/subcards.rb +70 -0
  35. data/mod/01_core/set/all/tracked_attributes.rb +83 -59
  36. data/mod/01_core/set/all/trash.rb +14 -12
  37. data/mod/01_core/set/all/type.rb +3 -24
  38. data/mod/01_core/spec/set/all/initialize_spec.rb +44 -14
  39. data/mod/01_core/spec/set/all/permissions_spec.rb +206 -185
  40. data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +0 -10
  41. data/mod/01_core/spec/set/all/trash_spec.rb +38 -13
  42. data/mod/01_core/spec/set/all/type_spec.rb +0 -19
  43. data/mod/01_history/set/all/content_history.rb +5 -3
  44. data/mod/01_history/set/all/history.rb +117 -82
  45. data/mod/02_basic_types/set/all/base.rb +50 -49
  46. data/mod/03_machines/lib/card/machine.rb +2 -1
  47. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +55 -17
  48. data/mod/03_machines/spec/set/type/javascript_spec.rb +18 -12
  49. data/mod/05_email/set/right/followers.rb +5 -5
  50. data/mod/05_email/set/right/following.rb +1 -1
  51. data/mod/05_email/set/type_plus_right/user/follow.rb +1 -1
  52. data/mod/05_standard/lib/carrier_wave/cardmount.rb +19 -11
  53. data/mod/05_standard/lib/file_uploader.rb +1 -1
  54. data/mod/05_standard/set/abstract/attachment.rb +20 -8
  55. data/mod/05_standard/set/all/list_changes.rb +43 -0
  56. data/mod/05_standard/set/all/rich_html/form.rb +21 -11
  57. data/mod/05_standard/set/all/rich_html/menu.rb +1 -1
  58. data/mod/05_standard/set/right/account.rb +5 -5
  59. data/mod/05_standard/set/self/head.rb +0 -1
  60. data/mod/05_standard/set/self/signin.rb +43 -35
  61. data/mod/05_standard/set/type/file.rb +9 -2
  62. data/mod/05_standard/set/type/list.rb +134 -0
  63. data/mod/05_standard/set/type/listed_by.rb +94 -0
  64. data/mod/05_standard/set/type/search_type.rb +62 -61
  65. data/mod/05_standard/set/type/signup.rb +94 -63
  66. data/mod/05_standard/set/type/user.rb +48 -39
  67. data/mod/05_standard/spec/set/all/account_spec.rb +1 -1
  68. data/mod/05_standard/spec/set/all/rich_html/form_spec.rb +2 -2
  69. data/mod/05_standard/spec/set/self/signin_spec.rb +23 -27
  70. data/mod/05_standard/spec/set/type/email_template_spec.rb +0 -2
  71. data/mod/05_standard/spec/set/type/list_spec.rb +140 -0
  72. data/mod/05_standard/spec/set/type/listed_by_spec.rb +157 -0
  73. data/mod/05_standard/spec/set/type/signup_spec.rb +38 -32
  74. data/spec/lib/card/subcards_spec.rb +126 -0
  75. metadata +14 -3
@@ -0,0 +1,70 @@
1
+ def field tag
2
+ Card[cardname.field(tag)]
3
+ end
4
+
5
+ def subcard card_name
6
+ subcards.card card_name
7
+ end
8
+
9
+ def subfield field_name
10
+ subcards.field field_name
11
+ end
12
+
13
+ phase_method :add_subcard, before: :approve do |name_or_card, args=nil|
14
+ subcards.add name_or_card, args
15
+ end
16
+
17
+ phase_method :add_subfield, before: :approve do |name_or_card, args=nil|
18
+ subcards.add_field name_or_card, args
19
+ end
20
+
21
+ def remove_subcard name_or_card
22
+ subcards.remove name_or_card
23
+ end
24
+
25
+ def remove_subfield name_or_card
26
+ subcards.remove_field name_or_card
27
+ end
28
+
29
+ def clear_subcards
30
+ subcards.clear
31
+ end
32
+
33
+ def unfilled?
34
+ (content.empty? || content.strip.empty?) && !subcards.present?
35
+ end
36
+
37
+ event :reject_empty_subcards, after: :approve, on: :save do
38
+ subcards.each_with_key do |subcard, key|
39
+ if subcard.new? && subcard.unfilled?
40
+ remove_subcard key
41
+ end
42
+ end
43
+ end
44
+
45
+ # deprecated; left for compatibility reasons because other events refer to this
46
+ # especially wikirate
47
+ event :process_subcards, after: :reject_empty_subcards, on: :save do
48
+ end
49
+
50
+ event :approve_subcards, after: :process_subcards do
51
+ subcards.each do |subcard|
52
+ if !subcard.valid_subcard?
53
+ subcard.errors.each do |field, err|
54
+ err = "#{field} #{err}" unless [:content, :abort].member? field
55
+ errors.add subcard.relative_name.s, err
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ event :store_subcards, after: :store do
62
+ subcards.each do |subcard|
63
+ subcard.save! validate: false if subcard != self # unless @draft
64
+ end
65
+
66
+ # ensures that a supercard can access subcards of self
67
+ # eg. <user> creates <user+*account> creates <user+*account+*status>
68
+ # <user> changes <user+*account+*status> in event activate_account
69
+ Card.write_to_local_cache self
70
+ end
@@ -1,4 +1,3 @@
1
- #fixme -this is called by both initialize and update_attributes. really should be optimized for new!
2
1
  def assign_attributes args={}
3
2
  if args
4
3
  args = args.stringify_keys
@@ -8,123 +7,148 @@ def assign_attributes args={}
8
7
  @set_specific[key] = args.delete(key) if args[key]
9
8
  end
10
9
 
11
- if newtype = args.delete('type')
12
- args['type_id'] = Card.fetch_id newtype
13
- end
14
- @subcards = extract_subcard_args! args
10
+ new_type_id = extract_type_id! args unless args.delete('skip_type_lookup')
11
+ subcard_args = extract_subcard_args! args
12
+ args['type_id'] = new_type_id if new_type_id
15
13
  reset_patterns
16
14
  end
17
15
  params = ActionController::Parameters.new(args)
18
16
  params.permit!
19
17
  super params
18
+ return unless args && subcard_args.present?
19
+ # name= must come before process subcards
20
+ subcards.add subcard_args
20
21
  end
21
22
 
22
23
  def assign_set_specific_attributes
23
- if @set_specific && @set_specific.present?
24
- @set_specific.each_pair do |name, value|
25
- self.send "#{name}=", value
26
- end
24
+ return unless @set_specific && @set_specific.present?
25
+ @set_specific.each_pair do |name, value|
26
+ send "#{name}=", value
27
27
  end
28
28
  end
29
29
 
30
- def extract_subcard_args! args={}
31
- extracted_subcards = args.delete('subcards') || {}
30
+ protected
31
+
32
+ def extract_subcard_args! args
33
+ subcards = args.delete('subcards') || {}
32
34
  args.keys.each do |key|
33
35
  if key =~ /^\+/
34
- val = args.delete key
35
- val = { 'content' => val } if String === val
36
- extracted_subcards[key] = val
36
+ subcards[key] = args.delete(key)
37
37
  end
38
38
  end
39
- extracted_subcards
39
+ subcards
40
40
  end
41
41
 
42
+ def extract_type_id! args={}
43
+ type_id =
44
+ case
45
+ when args['type_id']
46
+ id = args.delete('type_id').to_i
47
+ # type_id can come in as 0,'' or nil
48
+ id == 0 ? nil : id
49
+ when args['type_code']
50
+ Card.fetch_id args.delete('type_code').to_sym
51
+ when args['type']
52
+ Card.fetch_id args.delete('type')
53
+ else
54
+ return nil
55
+ end
42
56
 
43
- protected
57
+ if !type_id
58
+ errors.add :type, "#{args[:type] || args[:type_code]} is not a known type."
59
+ end
60
+ type_id
61
+ end
44
62
 
45
63
  event :set_content, before: :store, on: :save do
46
- self.db_content = content || '' #necessary?
47
- self.db_content = Card::Content.clean! self.db_content if clean_html?
64
+ self.db_content = content || '' # necessary?
65
+ self.db_content = Card::Content.clean!(db_content) if clean_html?
48
66
  @selected_action_id = @selected_content = nil
49
67
  clear_drafts
50
68
  reset_patterns_if_rule saving=true
51
69
  end
52
70
 
53
-
54
- #fixme - the following don't really belong here, but they have to come after the reference stuff. we need to organize a bit!
71
+ # FIXME: the following don't really belong here, but they have to come after
72
+ # the reference stuff. we need to organize a bit!
55
73
 
56
74
  event :update_ruled_cards, after: :store do
57
75
  if is_rule?
58
- # warn "updating ruled cards for #{name}"
76
+ # warn "updating ruled cards for #{name}"
59
77
  self.class.clear_rule_cache
60
78
  set = rule_set
61
79
  set.reset_set_patterns
62
80
 
63
- if right_id==Card::ReadID and (name_changed? or trash_changed?)
81
+ if right_id == Card::ReadID && (name_changed? || trash_changed?)
64
82
  self.class.clear_read_rule_cache
65
83
  Card.cache.reset # maybe be more surgical, just Auth.user related
66
- expire #probably shouldn't be necessary,
67
- # but was sometimes getting cached version when card should be in the trash.
68
- # could be related to other bugs?
84
+ expire # probably shouldn't be necessary,
85
+ # but was sometimes getting cached version when card should be in the
86
+ # trash. could be related to other bugs?
69
87
  in_set = {}
70
- if !(self.trash)
71
- if class_id = (set and set_class=set.tag and set_class.id)
88
+ if !trash && set && (set_class = set.tag)
89
+ if (class_id = set_class.id)
72
90
  rule_class_ids = set_patterns.map &:pattern_id
73
- #warn "rule_class_id #{class_id}, #{rule_class_ids.inspect}"
74
-
75
- #first update all cards in set that aren't governed by narrower rule
76
- Auth.as_bot do
77
- cur_index = rule_class_ids.index Card[read_rule_class].id
78
- if rule_class_index = rule_class_ids.index( class_id )
79
- set.item_cards(limit: 0).each do |item_card|
80
- in_set[item_card.key] = true
81
- next if cur_index < rule_class_index
82
- if cur_index >= rule_class_index
83
- item_card.update_read_rule
84
- end
91
+ # warn "rule_class_id #{class_id}, #{rule_class_ids.inspect}"
92
+
93
+ # first update all cards in set that aren't governed by narrower rule
94
+ Auth.as_bot do
95
+ cur_index = rule_class_ids.index Card[read_rule_class].id
96
+ if (rule_class_index = rule_class_ids.index(class_id))
97
+ set.item_cards(limit: 0).each do |item_card|
98
+ in_set[item_card.key] = true
99
+ next if cur_index < rule_class_index
100
+ if cur_index >= rule_class_index
101
+ item_card.update_read_rule
85
102
  end
86
- # elsif rule_class_index = rule_class_ids.index( 0 )
87
- # in_set[trunk.key] = true
88
- # #warn "self rule update: #{trunk.inspect}, #{rule_class_index}, #{cur_index}"
89
- # trunk.update_read_rule if cur_index > rule_class_index
90
- else warn "No current rule index #{class_id}, #{rule_class_ids.inspect}"
91
- end
103
+ end
104
+ # elsif rule_class_index = rule_class_ids.index( 0 )
105
+ # in_set[trunk.key] = true
106
+ # #warn "self rule update: #{trunk.inspect}, #{rule_class_index},
107
+ # #{cur_index}"
108
+ # trunk.update_read_rule if cur_index > rule_class_index
109
+ else warn "No current rule index #{class_id}, " \
110
+ "#{rule_class_ids.inspect}"
111
+ end
92
112
  end
93
113
 
94
114
  end
95
115
  end
96
116
 
97
- #then find all cards with me as read_rule_id that were not just updated and regenerate their read_rules
117
+ # then find all cards with me as read_rule_id that were not just updated
118
+ # and regenerate their read_rules
98
119
  if !new_record?
99
- Card.where( read_rule_id: self.id, trash: false ).reject do |w|
100
- in_set[ w.key ]
101
- end.each &:update_read_rule
120
+ Card.where(read_rule_id: self.id, trash: false).reject do |w|
121
+ in_set[w.key]
122
+ end.each(&:update_read_rule)
102
123
  end
103
124
  end
104
-
105
125
  end
106
126
  end
107
127
 
108
128
  event :process_read_rule_update_queue, after: :store do
109
- Array.wrap(@read_rule_update_queue).each { |card| card.update_read_rule }
129
+ Array.wrap(@read_rule_update_queue).each(&:update_read_rule)
110
130
  @read_rule_update_queue = []
111
131
  end
112
132
 
113
133
  # set_callback :store, :after, :process_read_rule_update_queue, prepend: true
114
134
 
115
135
  event :expire_related, after: :store do
116
- self.expire
136
+ subcards.keys.each do |key|
137
+ Card.cache.delete_local key
138
+ end
139
+ expire true
117
140
 
118
141
  if self.is_structure?
119
- self.structuree_names.each do |name|
120
- Card.expire name
142
+ structuree_names.each do |name|
143
+ Card.expire name, true
121
144
  end
122
145
  end
123
- # FIXME really shouldn't be instantiating all the following bastards. Just need the key.
146
+
147
+ # FIXME: really shouldn't be instantiating all the following bastards.
148
+ # Just need the key.
124
149
  # fix in id_cache branch
125
- self.dependents.each { |c| c.expire }
126
- # self.referencers.each { |c| c.expire }
127
- self.name_referencers.each { |c| c.expire }
150
+ dependents.each { |c| c.expire(true) }
151
+ # self.referencers.each { |c| c.expire(true) }
152
+ name_referencers.each { |c| c.expire(true) }
128
153
  # FIXME: this will need review when we do the new defaults/templating system
129
154
  end
130
-
@@ -6,13 +6,15 @@ def delete!
6
6
  update_attributes! trash: true unless new_card?
7
7
  end
8
8
 
9
-
10
9
  event :pull_from_trash, before: :store, on: :create do
11
- if trashed_card = Card.find_by_key_and_trash(key, true)
12
- # a. (Rails way) tried Card.where(key: 'wagn_bot').select(:id), but it wouldn't work. This #select
13
- # generally breaks on cards. I think our initialization process screws with something
14
- # b. (Wagn way) we could get card directly from fetch if we add :include_trashed (eg).
15
- # likely low ROI, but would be nice to have interface to retrieve cards from trash...
10
+ if (trashed_card = Card.find_by_key_and_trash(key, true))
11
+ # a. (Rails way) tried Card.where(key: 'wagn_bot').select(:id), but it
12
+ # wouldn't work. This #select generally breaks on cards. I think our
13
+ # initialization process screws with something
14
+ # b. (Wagn way) we could get card directly from fetch if we add
15
+ # :include_trashed (eg).
16
+ # likely low ROI, but would be nice to have interface to retrieve cards
17
+ # from trash...m
16
18
  self.id = trashed_card.id
17
19
  @from_trash = true
18
20
  @new_record = false
@@ -27,20 +29,21 @@ event :validate_delete, before: :approve, on: :delete do
27
29
  end
28
30
 
29
31
  undeletable_all_rules_tags = %w{ default style layout create read update delete }
30
- if junction? and l=left and l.codename == 'all' and undeletable_all_rules_tags.member? right.codename
32
+ if junction? && (l = left) && l.codename == 'all' &&
33
+ undeletable_all_rules_tags.member?(right.codename)
31
34
  errors.add :delete, "#{name} is an indestructible rule"
32
35
  end
33
36
 
34
- if account && Card::Act.find_by_actor_id( self.id )
35
- errors.add :delete, "Edits have been made with #{name}'s user account.\nDeleting this card would mess up our history."
37
+ if account && self.has_edits?
38
+ errors.add :delete, "Edits have been made with #{name}'s user account.\n" \
39
+ 'Deleting this card would mess up our history.'
36
40
  end
37
41
  end
38
42
 
39
43
  event :validate_delete_children, after: :approve, on: :delete do
40
44
  children.each do |child|
41
- child.supercard = self
42
- subcards[child.name]=child
43
45
  child.trash = true
46
+ add_subcard child
44
47
  unless child.valid?
45
48
  child.errors.each do |field, message|
46
49
  errors.add field, "can't delete #{child.name}: #{message}"
@@ -48,4 +51,3 @@ event :validate_delete_children, after: :approve, on: :delete do
48
51
  end
49
52
  end
50
53
  end
51
-
@@ -26,34 +26,13 @@ def type= type_name
26
26
  self.type_id = Card.fetch_id type_name
27
27
  end
28
28
 
29
- def get_type_id args={}
30
- return if args[:type_id] # type_id was set explicitly. no need to set again.
31
-
32
- type_id = case
33
- when args[:type_code]
34
- if code=args[:type_code]
35
- Card::Codename[code] || ( c=Card[code] and c.id)
36
- end
37
- when args[:type]
38
- Card.fetch_id args[:type]
39
- else :noop
40
- end
41
-
42
- case type_id
43
- when :noop
44
- when false, nil
45
- errors.add :type, "#{args[:type] || args[:type_code]} is not a known type."
46
- else
47
- return type_id
48
- end
49
-
50
- if name && t=template
51
- reset_patterns #still necessary even with new template handling?
29
+ def get_type_id_from_structure
30
+ if name && (t = template)
31
+ reset_patterns # still necessary even with new template handling?
52
32
  t.type_id
53
33
  end
54
34
  end
55
35
 
56
-
57
36
  event :validate_type_change, before: :approve, on: :update, changed: :type_id do
58
37
  if c = dup and c.action == :create and !c.valid?
59
38
  errors.add :type, "of #{ name } can't be changed; errors creating new #{ type_id }: #{ c.errors.full_messages * ', ' }"
@@ -1,14 +1,14 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  describe Card::Set::All::Initialize do
4
- describe "new" do
5
- it "handles explicit nil as parameters" do
4
+ describe 'new' do
5
+ it 'handles explicit nil as parameters' do
6
6
  c = Card.new nil
7
7
  expect(c).to be_instance_of(Card)
8
8
  expect(c.name).to eq('')
9
9
  end
10
10
 
11
- it "handles nil name" do
11
+ it 'handles nil name' do
12
12
  c = Card.new name: nil
13
13
  expect(c).to be_instance_of(Card)
14
14
  expect(c.name).to eq('')
@@ -19,38 +19,68 @@ describe Card::Set::All::Initialize do
19
19
  expect(c).to be_instance_of(Card)
20
20
  expect(c.name).to eq('Ceee')
21
21
  end
22
- end
23
22
 
23
+ it 'handles no type' do
24
+ c = Card.new
25
+ expect(c.type_id).to eq(Card::BasicID)
26
+ end
27
+
28
+ it 'handles nil type_id' do
29
+ c = Card.new name: 'Ceee', type_id: nil
30
+ expect(c.type_id).to eq(Card::BasicID)
31
+ end
32
+
33
+ it 'handles empty string type_id' do
34
+ c = Card.new type_id: ''
35
+ expect(c.type_id).to eq(Card::BasicID)
36
+ end
37
+
38
+ it 'handles cardtype name and casespace variant as type' do
39
+ expect(Card.new(type: 'Phrase').type_id).to eq(Card::PhraseID)
40
+ expect(Card.new(type: 'PHRASE').type_id).to eq(Card::PhraseID)
41
+ expect(Card.new(type: 'phrase').type_id).to eq(Card::PhraseID)
42
+ expect(Card.new(type: 'phrase??').type_id).to eq(Card::PhraseID)
43
+ end
44
+
45
+ it 'handles type_code' do
46
+ expect(Card.new(type_code: 'phrase').type_id).to eq(Card::PhraseID)
47
+ expect(Card.new(type_code: :phrase).type_id).to eq(Card::PhraseID)
48
+ end
49
+
50
+ it 'handles type_id' do
51
+ expect(Card.new(type_id: Card::PhraseID).type_code).to eq(:phrase)
52
+ end
53
+ end
24
54
 
25
- describe "module inclusion" do
55
+ describe 'module inclusion' do
26
56
  context '(search)' do
27
57
  before do
28
58
  @c = Card.new type: 'Search', name: 'Module Inclusion Test Card'
29
59
  end
30
60
 
31
- it "happens after new" do
32
- expect(@c.respond_to?( :get_query )).to be_truthy
61
+ it 'happens after new' do
62
+ expect(@c.respond_to?(:get_query)).to be_truthy
33
63
  end
34
64
 
35
- it "happens after save" do
36
- expect(@c.respond_to?( :get_query )).to be_truthy
65
+ it 'happens after save' do
66
+ expect(@c.respond_to?(:get_query)).to be_truthy
37
67
  @c.save!
38
- expect(@c.respond_to?( :get_query )).to be_truthy
68
+ expect(@c.respond_to?(:get_query)).to be_truthy
39
69
  end
40
70
 
41
- it "happens after fetch" do
71
+ it 'happens after fetch' do
42
72
  @c.save!
43
73
  c = Card.fetch(@c.name)
44
- expect(c.respond_to?( :get_query )).to be_truthy
74
+ expect(c.respond_to?(:get_query)).to be_truthy
45
75
  end
46
76
  end
47
77
 
48
78
  context '(pointer)' do
49
- it "happens with explicit pointer setting" do
79
+ it 'happens with explicit pointer setting' do
50
80
  expect(Card.new(type: 'Pointer').respond_to?(:add_item)).to be_truthy
51
81
  end
52
82
 
53
- it "happens with implicit pointer setting (from template)" do
83
+ it 'happens with implicit pointer setting (from template)' do
54
84
  expect(Card.new(name: 'Home+*cc').respond_to?(:add_item)).to be_truthy
55
85
  end
56
86
  end