card 1.16.4 → 1.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/20150429090551_search_card_context.rb +34 -0
  4. data/db/migrate_core_cards/20150824135418_update_file_history.rb +10 -5
  5. data/db/migrate_core_cards/20150910085603_remove_performance_log_card.rb +10 -0
  6. data/db/seed/new/card_actions.yml +358 -366
  7. data/db/seed/new/card_acts.yml +1 -1
  8. data/db/seed/new/card_changes.yml +1379 -1399
  9. data/db/seed/new/card_references.yml +1109 -710
  10. data/db/seed/new/cards.yml +1436 -1454
  11. data/db/seed/test/fixtures/card_actions.yml +1031 -1039
  12. data/db/seed/test/fixtures/card_acts.yml +155 -155
  13. data/db/seed/test/fixtures/card_changes.yml +4148 -4168
  14. data/db/seed/test/fixtures/card_references.yml +1577 -1178
  15. data/db/seed/test/fixtures/cards.yml +2259 -2277
  16. data/db/version_core_cards.txt +1 -1
  17. data/lib/card.rb +3 -2
  18. data/lib/card/env.rb +66 -0
  19. data/lib/card/format.rb +3 -38
  20. data/lib/card/loader.rb +0 -4
  21. data/lib/card/location.rb +38 -0
  22. data/lib/card/set.rb +1 -3
  23. data/lib/card/success.rb +2 -3
  24. data/mod/01_core/format/html_format.rb +0 -48
  25. data/mod/01_core/set/all/collection.rb +9 -7
  26. data/mod/01_core/set/all/initialize.rb +5 -0
  27. data/mod/01_core/set/all/location_history.rb +10 -0
  28. data/mod/01_core/set/all/phases.rb +2 -1
  29. data/mod/01_core/set/all/rules.rb +0 -2
  30. data/mod/01_core/set/all/trash.rb +3 -2
  31. data/mod/01_core/set/all/utils.rb +12 -0
  32. data/mod/01_core/spec/set/all/permissions_spec.rb +8 -8
  33. data/mod/01_core/spec/set/all/type_spec.rb +14 -14
  34. data/mod/01_history/set/all/content_history.rb +7 -3
  35. data/mod/01_history/set/all/history.rb +3 -3
  36. data/mod/02_basic_types/set/type/pointer.rb +8 -1
  37. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +39 -0
  38. data/mod/03_machines/lib/stylesheets/style_cards.scss +12 -2
  39. data/mod/03_machines/set/right/machine_output.rb +4 -0
  40. data/mod/03_machines/set/type/css.rb +1 -1
  41. data/mod/04_settings/spec/set/right/structure_spec.rb +1 -1
  42. data/mod/05_email/set/all/observer.rb +5 -5
  43. data/mod/05_email/set/type_plus_right/user/follow.rb +1 -1
  44. data/mod/05_standard/file/favicon/image-icon.png +0 -0
  45. data/mod/05_standard/file/favicon/image-large.png +0 -0
  46. data/mod/05_standard/file/favicon/image-medium.png +0 -0
  47. data/mod/05_standard/file/favicon/image-original.png +0 -0
  48. data/mod/05_standard/file/favicon/image-small.png +0 -0
  49. data/mod/05_standard/lib/carrier_wave/cardmount.rb +8 -2
  50. data/mod/05_standard/lib/file_uploader.rb +47 -35
  51. data/mod/05_standard/set/abstract/attachment.rb +87 -35
  52. data/mod/05_standard/set/all/error.rb +1 -1
  53. data/mod/05_standard/set/all/links.rb +1 -0
  54. data/mod/05_standard/set/self/signin.rb +1 -1
  55. data/mod/05_standard/set/type/file.rb +16 -1
  56. data/mod/05_standard/set/type/image.rb +2 -0
  57. data/mod/05_standard/set/type/search_type.rb +2 -2
  58. data/mod/05_standard/spec/chunk/link_spec.rb +42 -32
  59. data/mod/05_standard/spec/set/all/links_spec.rb +15 -0
  60. data/mod/05_standard/spec/set/self/head_spec.rb +3 -3
  61. data/mod/05_standard/spec/set/type/email_template_spec.rb +39 -39
  62. data/mod/05_standard/spec/set/type/file_spec.rb +0 -12
  63. data/mod/05_standard/spec/set/type/image_spec.rb +26 -2
  64. data/spec/lib/card/content_spec.rb +169 -154
  65. data/spec/lib/card/format_spec.rb +7 -7
  66. data/spec/lib/card/success_spec.rb +1 -1
  67. metadata +7 -6
  68. data/lib/card/log.rb +0 -545
  69. data/mod/05_standard/set/self/performance_log.rb +0 -92
  70. data/spec/lib/card/log_spec.rb +0 -270
@@ -8,19 +8,14 @@ event :select_file_revision, :after=>:select_action do
8
8
  attachment.retrieve_from_store!(attachment.identifier)
9
9
  end
10
10
 
11
- event :determine_store_place, :before=>:prepare, :on=>:update do
12
- @store_place = load_from_mod || :deck
13
- end
14
-
15
11
  event :upload_attachment, :before=>:validate_name, :on=>:save, :when=>proc { |c| c.preliminary_upload? } do
16
12
  save_original_filename # save original filename as comment in action
17
13
  write_identifier # set db_content (needs original filename to determine extension)
18
14
  store_attachment!
19
15
  finalize_action # create Card::Change entry for db_content
20
16
  @current_action.update_attributes! :draft => true, :card_id => (new_card? ? upload_cache_card.id : id)
21
-
22
17
  success << {
23
- :target => (new_card? ? upload_cache_card : '_self'),
18
+ :target => (new_card? ? upload_cache_card : self),
24
19
  :type=> type_name,
25
20
  :view => 'preview_editor',
26
21
  :rev_id => current_action.id
@@ -28,26 +23,25 @@ event :upload_attachment, :before=>:validate_name, :on=>:save, :when=>proc { |c|
28
23
  abort :success
29
24
  end
30
25
 
31
- event :assign_attachment_on_create, :after=>:prepare, :on=>:create do
32
- if save_preliminary_upload? && (action = Card::Action.fetch(Card::Env.params[:cached_upload]))
26
+ event :assign_attachment_on_create, :after=>:prepare, :on=>:create, :when => proc { |c| c.save_preliminary_upload? } do
27
+ if (action = Card::Action.fetch(Card::Env.params[:cached_upload]))
33
28
  upload_cache_card.selected_action_id = action.id
34
29
  upload_cache_card.select_file_revision
35
30
  assign_attachment upload_cache_card.attachment.file, action.comment
36
- action.delete # TODO: delete files too
37
31
  end
38
32
  end
39
33
 
40
- event :assign_attachment_on_update, :after=>:prepare, :on=>:update do
41
- if save_preliminary_upload? && (action = Card::Action.fetch(Card::Env.params[:cached_upload]))
34
+ event :assign_attachment_on_update, :after=>:prepare, :on=>:update, :when => proc { |c| c.save_preliminary_upload? } do
35
+ if (action = Card::Action.fetch(Card::Env.params[:cached_upload]))
42
36
  uploaded_file =
43
37
  with_selected_action_id(action.id) do
44
38
  attachment.file
45
39
  end
46
40
  assign_attachment uploaded_file, action.comment
47
- action.delete
48
41
  end
49
42
  end
50
43
 
44
+
51
45
  def assign_attachment file, original_filename
52
46
  send "#{attachment_name}=", file
53
47
  write_identifier
@@ -60,26 +54,33 @@ event :correct_identifier, :after=>:store, :on=>:create do
60
54
  expire
61
55
  end
62
56
 
63
-
64
57
  event :save_original_filename, :after=>:validate_name, :when => proc {|c| !c.preliminary_upload? && !c.save_preliminary_upload? && c.attachment_changed?} do
65
58
  if @current_action
66
59
  @current_action.update_attributes! :comment=>original_filename
67
60
  end
68
61
  end
69
62
 
70
- event :write_identifier, :after=>:save_original_filename do
71
- self.content = attachment.db_content(:mod=>load_from_mod)
63
+ event :delete_cached_upload_file_on_create, :after=>:extend, :on=>:create, :when => proc { |c| c.save_preliminary_upload? } do
64
+ if (action = Card::Action.fetch(Card::Env.params[:cached_upload]))
65
+ upload_cache_card.delete_files_for_action action
66
+ action.delete
67
+ end
68
+ clear_upload_cache_dir_for_new_cards
72
69
  end
73
70
 
74
-
75
- def upload_cache_card
76
- @upload_cache_card ||= Card["new_#{attachment_name}".to_sym ]
71
+ event :delete_cached_upload_file_on_update, :after=>:extend, :on=>:update, :when => proc { |c| c.save_preliminary_upload? } do
72
+ if (action = Card::Action.fetch(Card::Env.params[:cached_upload]))
73
+ delete_files_for_action action
74
+ action.delete
75
+ end
77
76
  end
78
77
 
79
- def tmp_store_dir action_id=nil
80
- "#{ Card.paths['files'].existent.first }/#{upload_cache_card.id}"
78
+
79
+ event :write_identifier, :after=>:save_original_filename do
80
+ self.content = attachment.db_content(:mod=>load_from_mod)
81
81
  end
82
82
 
83
+
83
84
  def item_names(args={}) # needed for flexmail attachments. hacky.
84
85
  [self.cardname]
85
86
  end
@@ -104,12 +105,18 @@ def create_versions?
104
105
  true
105
106
  end
106
107
 
107
- def store_place
108
- @store_place ||= mod_file? || :deck
108
+ # used for uploads for new cards until the new card is created
109
+ def upload_cache_card
110
+ @upload_cache_card ||= Card["new_#{attachment_name}".to_sym ]
109
111
  end
110
112
 
113
+
111
114
  def load_from_mod= value
112
115
  @mod = value
116
+ write_identifier
117
+ if value
118
+ @store_in_mod = true
119
+ end
113
120
  end
114
121
 
115
122
  def load_from_mod
@@ -117,20 +124,52 @@ def load_from_mod
117
124
  end
118
125
 
119
126
  def store_dir
120
- if (store_place == :deck)
121
- if id
122
- "#{ Card.paths['files'].existent.first }/#{id}"
123
- else
124
- tmp_store_dir
125
- end
127
+ if @store_in_mod
128
+ mod_dir
126
129
  else
127
- "#{ Cardio.gem_root}/mod/#{store_place}/file/#{codename}"
130
+ upload_dir
128
131
  end
129
132
  end
130
133
 
134
+ def retrieve_dir
135
+ if mod_file?
136
+ mod_dir
137
+ else
138
+ upload_dir
139
+ end
140
+ end
141
+
142
+ # place for files of regular file cards
143
+ def upload_dir
144
+ if id
145
+ "#{ Card.paths['files'].existent.first }/#{id}"
146
+ else
147
+ tmp_upload_dir
148
+ end
149
+ end
150
+
151
+ # place for files if card doesn't have an id yet
152
+ def tmp_upload_dir action_id=nil
153
+ "#{ Card.paths['files'].existent.first }/#{upload_cache_card.id}"
154
+ end
155
+
156
+ # place for files of mod file cards
157
+ def mod_dir
158
+ mod = @mod || mod_file?
159
+ Card.paths['mod'].to_a.each do |mod_path|
160
+ dir = File.join(mod_path, mod, 'file', codename )
161
+ if Dir.exist? dir
162
+ return dir
163
+ end
164
+ end
165
+ end
166
+
167
+
131
168
  def mod_file?
169
+ if @store_in_mod
170
+ return @mod
132
171
  # when db_content was changed assume that it's no longer a mod file
133
- if @store_place != :deck && !db_content_changed? && content.present?
172
+ elsif !db_content_changed? && content.present?
134
173
  case content
135
174
  when /^:[^\/]+\/([^.]+)/ ; $1 # current mod_file format
136
175
  when /^\~/ ; false # current id file format
@@ -150,18 +189,31 @@ def assign_set_specific_attributes
150
189
  super
151
190
  end
152
191
 
153
- def clear_upload_tmp_dir
154
- Dir.entries(tmp_store_dir).each do |filename|
192
+ def clear_upload_cache_dir_for_new_cards
193
+ Dir.entries(tmp_upload_dir).each do |filename|
155
194
  if filename =~/^\d+/
156
- path = File.join(tmp_store_dir, filename )
157
- older_than_five_days = ( DateTime.now - File.ctime(path) > 432000)
158
- if older_than_five_days
195
+ path = File.join(tmp_upload_dir, filename )
196
+ if older_than_five_days? File.ctime(path)
159
197
  FileUtils.rm path
160
198
  end
161
199
  end
162
200
  end
163
201
  end
164
202
 
203
+ def older_than_five_days? time
204
+ Time.now - time > 432000
205
+ end
206
+
207
+ def delete_files_for_action action
208
+ with_selected_action_id(action.id) do
209
+ FileUtils.rm attachment.file.path
210
+ attachment.versions.each_value do |version|
211
+ FileUtils.rm version.path
212
+ end
213
+ end
214
+ end
215
+
216
+
165
217
  def symlink_to(prior_action_id) # create filesystem links to files from prior action
166
218
  if prior_action_id != last_action_id
167
219
  save_action_id = selected_action_id
@@ -166,7 +166,7 @@ format :html do
166
166
  or_signup = if Card.new(:type_id=>Card::SignupID).ok? :create
167
167
  "or #{ link_to 'sign up', card_url('new/:signup') }"
168
168
  end
169
- save_interrupted_action(request.env['REQUEST_URI'])
169
+ Env.save_interrupted_action(request.env['REQUEST_URI'])
170
170
  "Please #{ link_to 'sign in', card_url(':signin') } #{or_signup} #{to_task}"
171
171
  end
172
172
 
@@ -45,6 +45,7 @@ format do
45
45
  else
46
46
  return card_link href, opts
47
47
  end
48
+ opts[:target] = "_blank" if new_class == 'external-link'
48
49
  add_class opts, new_class
49
50
  link_to text, href, opts
50
51
  end
@@ -31,7 +31,7 @@ format :html do
31
31
  view :core do |args|
32
32
  account = card.fetch :trait=>:account, :new=>{}
33
33
  form_args = {
34
- :hidden => { :success=>"REDIRECT: #{interrupted_action || '*previous'}" },
34
+ :hidden => { :success=>"REDIRECT: #{Env.interrupted_action || '*previous'}" },
35
35
  :recaptcha => :off
36
36
  }
37
37
 
@@ -1,5 +1,20 @@
1
1
  attachment :file, :uploader=>FileUploader
2
2
 
3
+ module SelectedAction
4
+ def select_action_by_params params
5
+ # skip action table lookups for current revision
6
+ rev_id = params[:rev_id]
7
+ super unless rev_id && rev_id == last_content_action_id
8
+ end
9
+
10
+ def last_content_action_id
11
+ # find action id from content (saves lookups)
12
+ db_content.to_s.split(/[\/\.]/)[1]
13
+ end
14
+
15
+ end
16
+ include SelectedAction
17
+
3
18
  format do
4
19
  view :source do |args|
5
20
  card.attachment.url
@@ -109,7 +124,7 @@ format :html do
109
124
  <span class="btn btn-success fileinput-button">
110
125
  <i class="glyphicon glyphicon-cloud-upload"></i>
111
126
  <span>
112
- #{@slot_view == :edit ? 'Replace' : 'Add'} #{card.attachment_name}...
127
+ #{card.new_card? ? 'Add' : 'Replace'} #{card.attachment_name}...
113
128
  </span>
114
129
  #{file_field card.attachment_name, :class=>'file-upload slotter'}
115
130
  </span>
@@ -1,5 +1,7 @@
1
1
  attachment :image, :uploader=>ImageUploader
2
2
 
3
+ include File::SelectedAction
4
+
3
5
  format do
4
6
 
5
7
  include File::Format
@@ -36,7 +36,7 @@ def get_query params={}
36
36
  if default_limit = query.delete(:default_limit) and !query[:limit]
37
37
  query[:limit] = default_limit
38
38
  end
39
- query[:context] ||= (cardname.junction? ? cardname.left_name : cardname)
39
+ query[:context] ||= cardname
40
40
  query
41
41
  end
42
42
 
@@ -190,7 +190,7 @@ format :rss do
190
190
  case raw_feed_items args
191
191
  when Exception ; @xml.item { render :search_error }
192
192
  when Integer ; @xml.item { render :search_count }
193
- else super
193
+ else super args
194
194
  end
195
195
  end
196
196
 
@@ -1,60 +1,70 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  describe Card::Chunk::Link do
4
+ def assert_link target, args
5
+ text = args.delete(:text)
6
+ format_args = args.delete(:format_args)
7
+ assert_args = ['a']
8
+ args.each_pair do |key,val|
9
+ assert_args[0] << "[#{key}=\"#{val}\"]"
10
+ end
11
+ assert_args << { :text=>text } if text
12
+ assert_view_select render_content(target, (format_args || {})), *assert_args
13
+ end
4
14
 
5
- it "should handle unknown cards" do
6
- expect(render_content('[[Nixon]]')).to eq('<a class="wanted-card" href="/Nixon">Nixon</a>')
15
+ it "handles unknown cards" do
16
+ assert_link '[[Nixon]]', :class=>"wanted-card", :href=>"/Nixon", :text=>'Nixon'
7
17
  end
8
18
 
9
- it 'should handle known cards' do
10
- expect(render_content("[[A]]")).to eq('<a class="known-card" href="/A">A</a>')
19
+ it 'handles known cards' do
20
+ assert_link "[[A]]", :class=>"known-card", :href=>"/A", :text=>'A'
11
21
  end
12
-
13
- it 'should handle custom text' do
14
- expect(render_content('[[Baines|Lyndon]]')).to eq('<a class="wanted-card" href="/Baines">Lyndon</a>')
22
+
23
+
24
+ it 'handles custom text' do
25
+ assert_link '[[Baines|Lyndon]]', :class=>"wanted-card", :href=>"/Baines", :text=>'Lyndon'
15
26
  end
16
27
 
17
- it "should handle relative names" do
28
+ it "handles relative names" do
18
29
  @card = Card.new :name=>'Kennedy'
19
- expect(render_content('[[+Monroe]]' )).to eq('<a class="wanted-card" href="/Kennedy+Monroe">Kennedy+Monroe</a>')
20
- expect(render_content('[[_self+Exner]]' )).to eq('<a class="wanted-card" href="/Kennedy+Exner">Kennedy+Exner</a>')
21
- expect(render_content('[[Onassis+]]' )).to eq('<a class="wanted-card" href="/Onassis+Kennedy">Onassis+Kennedy</a>')
30
+ assert_link '[[+Monroe]]' , :class=>"wanted-card", :href=>"/Kennedy+Monroe", :text=>'Kennedy+Monroe'
31
+ assert_link '[[_self+Exner]]', :class=>"wanted-card", :href=>"/Kennedy+Exner", :text=>'Kennedy+Exner'
32
+ assert_link '[[Onassis+]]' , :class=>"wanted-card", :href=>"/Onassis+Kennedy",:text=>'Onassis+Kennedy'
22
33
  end
23
34
 
24
- it "should handle relative names in context" do
35
+ it "handles relative names in context" do
25
36
  @card = Card.new :name=>'Kennedy'
26
37
  format_args = { :context_names => [ 'Kennedy'.to_name ] }
27
- expect(render_content('[[+Monroe]]' , format_args )).to eq('<a class="wanted-card" href="/Kennedy+Monroe">+Monroe</a>')
28
- expect(render_content('[[_self+Exner]]', format_args )).to eq('<a class="wanted-card" href="/Kennedy+Exner">+Exner</a>')
29
- expect(render_content('[[Onassis+]]' , format_args )).to eq('<a class="wanted-card" href="/Onassis+Kennedy">Onassis</a>')
38
+ assert_link '[[+Monroe]]' , :format_args=>format_args, :class=>"wanted-card", :href=>"/Kennedy+Monroe", :text=>'+Monroe'
39
+ assert_link '[[_self+Exner]]', :format_args=>format_args, :class=>"wanted-card", :href=>"/Kennedy+Exner", :text=>'+Exner'
40
+ assert_link '[[Onassis+]]' , :format_args=>format_args, :class=>"wanted-card", :href=>"/Onassis+Kennedy", :text=>'Onassis'
30
41
  end
31
42
 
32
- it "should handle relative urls" do
33
- expect(render_content('[[/recent]]')).to eq('<a class="internal-link" href="/recent">/recent</a>')
43
+ it "handles relative urls" do
44
+ assert_link '[[/recent]]', :class=>"internal-link", :href=>"/recent", :text=>'/recent'
34
45
  end
35
46
 
36
- it "should handle absolute urls" do
37
- expect(render_content('[[http://google.com]]')).to eq('<a class="external-link" href="http://google.com">http://google.com</a>')
47
+ it "handles absolute urls" do
48
+ assert_link '[[http://google.com]]', :class=>'external-link', :target=>'_blank', :href=>'http://google.com', :text=> 'http://google.com'
38
49
  end
39
50
 
40
51
  it "should escape spaces in cardnames with %20 (not +)" do
41
- expect(render_content('[[Marie "Mad Dog" Deatherage|Marie]]')).to eq(
42
- '<a class="wanted-card" href="/Marie_Mad_Dog_Deatherage?card%5Bname%5D=Marie+%22Mad+Dog%22+Deatherage">Marie</a>'
43
- )
52
+ assert_link '[[Marie "Mad Dog" Deatherage|Marie]]', :class=>"wanted-card", :href=>"/Marie_Mad_Dog_Deatherage?card%5Bname%5D=Marie+%22Mad+Dog%22+Deatherage", :text=>'Marie'
44
53
  end
45
54
 
46
- it "should not escape content outside of link" do
47
- expect(render_content('wgw&nbsp; [[http://www.google.com|google]] &nbsp; <br>')).to eq(
48
- "wgw&nbsp; <a class=\"external-link\" href=\"http://www.google.com\">google</a> &nbsp; <br>"
49
- )
55
+
56
+ it "doesn't escape content outside of link" do
57
+ content = render_content('wgw&nbsp; [[http://www.google.com|google]] &nbsp; <br>')
58
+ expect(content).to eq "wgw&nbsp; <a target=\"_blank\" class=\"external-link\" href=\"http://www.google.com\">google</a> &nbsp; <br>"
50
59
  end
51
-
52
- it "should handle inclusions in link text" do
53
- expect(render_content('[[linkies|{{namies|name}}]]')).to eq('<a class="wanted-card" href="/linkies">namies</a>')
60
+
61
+ it "handles inclusions in link text" do
62
+ assert_link '[[linkies|{{namies|name}}]]', :class=>"wanted-card", :href=>"/linkies", :text=>'namies'
54
63
  end
55
-
56
- it "should handle dot (.) in missing cardlink" do
57
- expect(render_content("[[Wagn 1.10.12]]")).to eq('<a class="wanted-card" href="/Wagn_1_10_12?card%5Bname%5D=Wagn+1.10.12">Wagn 1.10.12</a>')
64
+
65
+ it "handles dot (.) in missing cardlink" do
66
+ assert_link "[[Wagn 1.10.12]]", :class=>"wanted-card", :href=>"/Wagn_1_10_12?card%5Bname%5D=Wagn+1.10.12", :text=>'Wagn 1.10.12'
67
+
58
68
  end
59
69
 
60
70
  end
@@ -0,0 +1,15 @@
1
+ # -*- encoding : utf-8 -*-
2
+ describe Card::Set::All::Links do
3
+ require 'card'
4
+ describe '#web_link' do
5
+ it 'opens external link in new tab' do
6
+ link = Card['Home'].format.web_link("http://example.com")
7
+ assert_view_select link, 'a[class="external-link"][target="_blank"][href="http://example.com"]'
8
+ end
9
+
10
+ it 'opens interal link in same tab' do
11
+ link = Card['Home'].format.web_link("/Home")
12
+ assert_view_select link, 'a[target="_blank"]', false
13
+ end
14
+ end
15
+ end
@@ -4,14 +4,14 @@ describe Card::Set::Self::Head do
4
4
  it "should have a javascript tag" do
5
5
  assert_view_select render_card(:raw, :name=>'*head'), 'script[type="text/javascript"]'
6
6
  end
7
-
7
+
8
8
  context 'tinyMCE config' do
9
9
  before do
10
10
  @tinyMCE = Card[:tiny_mce]
11
11
  end
12
12
  it 'should handle tinyMCE configuration errors' do
13
-
13
+
14
14
  end
15
15
  end
16
-
16
+
17
17
  end
@@ -4,19 +4,19 @@ require 'card/mailer'
4
4
  describe Card::Set::Type::EmailTemplate do
5
5
  let(:email_name) { 'a mail template' }
6
6
  let(:email) {Card.fetch(email_name)}
7
-
7
+
8
8
  def mailconfig args={}
9
9
  Card[email_name].email_config(args)
10
10
  end
11
-
11
+
12
12
  def update_field name, args={}
13
13
  Card["#{email_name}+#{name}"].update_attributes! args
14
14
  end
15
-
15
+
16
16
  def create_field name, args={}
17
17
  Card.create! args.merge(:name=>"#{email_name}+#{name}")
18
18
  end
19
-
19
+
20
20
  before do
21
21
  Card::Auth.current_id = Card::WagnBotID
22
22
  chunk_test = "Url(wagn.org) Link([[http://wagn.org|Wagn]]) Inclusion({{B|name}}) Card link([[A]])"
@@ -28,96 +28,96 @@ describe Card::Set::Type::EmailTemplate do
28
28
  "+*text_message" => "*text message #{chunk_test}"
29
29
  }
30
30
  end
31
-
31
+
32
32
  describe "mail view" do
33
33
  let(:content_type) do
34
34
  card = Card.create!(:name => 'content type test', :type=>:email_template, :subcards=>@fields)
35
35
  email = card.format.render_mail
36
36
  email[:content_type].value
37
37
  end
38
-
38
+
39
39
  it 'renders text email if text message given' do
40
40
  @fields = { "+*text_message" => "text" }
41
41
  expect(content_type).to include 'text/plain'
42
42
  end
43
-
43
+
44
44
  it 'renders html email if html message given' do
45
45
  @fields = { "+*html_message" => "text" }
46
46
  expect(content_type).to include 'text/html'
47
47
  end
48
-
48
+
49
49
  it 'renders multipart email if text and html given' do
50
50
  @fields = {'+*text_message'=>'text', '+*html_message'=>'text'}
51
51
  expect(content_type).to include 'multipart/alternative'
52
52
  end
53
-
53
+
54
54
  end
55
-
56
-
55
+
56
+
57
57
  describe "#email_config" do
58
58
 
59
59
  describe 'address fields' do
60
60
  it 'uses *from field' do
61
61
  expect( mailconfig[:from] ).to eq 'from@user.com'
62
62
  end
63
-
63
+
64
64
  it 'uses *to field' do
65
65
  expect( mailconfig[:to] ).to eq 'joe@user.com'
66
66
  end
67
-
67
+
68
68
  it 'handles pointer values' do
69
69
  create_field '*cc', :content => "[[joe@user.com]]", :type=>'Pointer'
70
70
  expect( mailconfig[:cc] ).to eq 'joe@user.com'
71
71
  end
72
-
72
+
73
73
 
74
74
  #it 'handles email syntax in pointer values' do
75
75
  # create_field '*cc', :content => "[[Joe User <joe@user.com>]]", :type=>'Pointer'
76
76
  # expect( mailconfig[:cc] ).to eq 'Joe User <joe@user.com>'
77
77
  #end
78
-
78
+
79
79
  it 'handles link to email card' do
80
80
  create_field '*cc', :content => "[[Joe User+*email]]", :type=>'Pointer'
81
81
  expect( mailconfig[:cc] ).to eq 'joe@user.com'
82
82
  end
83
-
83
+
84
84
  # it 'handles link with valid email address' do
85
85
  # create_field '*cc', :content => "[[joe@admin.com|Joe]]", :type=>'Phrase'
86
86
  # expect( mailconfig[:cc] ).to eq 'Joe<joe@user.com>'
87
87
  # end
88
-
88
+
89
89
  it 'handles search card' do
90
90
  create_field '*bcc', :content => '{"name":"Joe Admin","append":"*email"}', :type=>'Search'
91
91
  expect( mailconfig[:bcc] ).to eq 'joe@admin.com'
92
92
  end
93
-
93
+
94
94
  # it 'handles invalid email address' do #TODO not obvious how to deal with that.
95
95
  # we can't decided whether a email address like [[_left]] is valid; depends on the context
96
96
  # Card.fetch("a mail template+*to").update_attributes(:content=>"invalid mail address")
97
97
  # end
98
98
  end
99
-
99
+
100
100
 
101
101
  describe 'subject' do
102
102
  subject { mailconfig[:subject] }
103
-
103
+
104
104
  it 'uses *subject field' do
105
105
  is_expected.to include '*subject'
106
- end
106
+ end
107
107
  it 'does not render url' do
108
108
  is_expected.to include 'Url(wagn.org)'
109
- end
109
+ end
110
110
  it 'does not render link' do
111
111
  is_expected.to include 'Link([[http://wagn.org|Wagn]])'
112
- end
112
+ end
113
113
  it 'renders inclusion' do
114
114
  is_expected.to include 'Inclusion(B)'
115
115
  end
116
116
  end
117
-
117
+
118
118
  describe 'text message' do
119
119
  subject { mailconfig[:text_message] }
120
-
120
+
121
121
  it 'uses *text_message field' do
122
122
  is_expected.to include '*text message'
123
123
  end
@@ -126,25 +126,25 @@ describe Card::Set::Type::EmailTemplate do
126
126
  end
127
127
  it 'renders link' do
128
128
  is_expected.to include 'Link(Wagn[http://wagn.org])'
129
- end
129
+ end
130
130
  it 'renders inclusion' do
131
131
  is_expected.to include 'Inclusion(B)'
132
132
  end
133
-
133
+
134
134
  end
135
-
135
+
136
136
  describe 'html message' do
137
137
  subject { mailconfig[:html_message] }
138
-
138
+
139
139
  it 'uses *html_message field' do
140
140
  is_expected.to include '*html message'
141
- end
141
+ end
142
142
  it 'renders url' do
143
- is_expected.to include 'Url(<a class="external-link" href="http://wagn.org">wagn.org</a>)'
144
- end
143
+ is_expected.to include 'Url(<a target="_blank" class="external-link" href="http://wagn.org">wagn.org</a>)'
144
+ end
145
145
  it 'renders link' do
146
- is_expected.to include 'Link(<a class="external-link" href="http://wagn.org">Wagn</a>)'
147
- end
146
+ is_expected.to include 'Link(<a target="_blank" class="external-link" href="http://wagn.org">Wagn</a>)'
147
+ end
148
148
  it 'renders inclusion' do
149
149
  is_expected.to include 'Inclusion(B)'
150
150
  end
@@ -154,8 +154,8 @@ describe Card::Set::Type::EmailTemplate do
154
154
  is_expected.to include 'Card link(<a class="known-card" href="http://www.fake.com/A">A</a>)'
155
155
  end
156
156
  end
157
-
158
-
157
+
158
+
159
159
  context 'with context card' do
160
160
  let(:context_card) do
161
161
  Card.create(
@@ -172,14 +172,14 @@ describe Card::Set::Type::EmailTemplate do
172
172
 
173
173
  it 'handles contextual name in address search' do
174
174
  update_field '*from', :content => '{"left":"_self", "right":"email"}', :type=>'Search'
175
- update_field '*from', :content => '{"left":"_self", "right":"email"}' #FIXME: have to do this twice to get the right content.
175
+ update_field '*from', :content => '{"left":"_self", "right":"email"}' #FIXME: have to do this twice to get the right content.
176
176
  # After the first update the content is empty
177
177
  expect(subject[:from]).to eq "gary@gary.com"
178
178
  end
179
179
 
180
180
  it 'handles contextual names and structure rules in subject' do
181
181
  Card.create! :name => 'default subject', :content=>'a very nutty thang', :type=>'Phrase'
182
- Card.create! :name => "subject search+*right+*structure", :content => %{{"referred_to_by":"_self+subject"}}, :type=>'Search'
182
+ Card.create! :name => "subject search+*right+*structure", :content => %{{"referred_to_by":"_left+subject"}}, :type=>'Search'
183
183
  update_field '*subject', :content => "{{+subject search|core;item:core}}"
184
184
  expect(subject[:subject]).to eq("a very nutty thang")
185
185
  end
@@ -194,7 +194,7 @@ describe Card::Set::Type::EmailTemplate do
194
194
  Card.create :name=>'Banana+surprise', :content=>"the Spanish Inquisition"
195
195
  c = Card.create :name => "Banana+emailtest", :content => "data content"
196
196
  expect( mailconfig( context: c )[:html_message] ).to include 'Nobody expects the Spanish Inquisition'
197
-
197
+
198
198
  end
199
199
 
200
200
  it 'handles contextual name for attachments' do