card 1.20.0 → 1.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +1 -1
  4. data/lib/card.rb +7 -3
  5. data/lib/card/act_manager/stage_director.rb +22 -10
  6. data/lib/card/cache/persistent.rb +15 -9
  7. data/lib/card/format/nest.rb +12 -5
  8. data/lib/card/format/nest/fetch.rb +2 -1
  9. data/lib/card/format/render.rb +5 -2
  10. data/lib/card/set/event.rb +7 -1
  11. data/lib/card/subcards.rb +3 -3
  12. data/lib/card/view/cache.rb +1 -1
  13. data/lib/card/view/fetch.rb +17 -5
  14. data/lib/card/view/options.rb +52 -26
  15. data/lib/cardio.rb +2 -1
  16. data/mod/account/spec/set/right/account_spec.rb +17 -3
  17. data/mod/admin/set/self/admin.rb +0 -2
  18. data/mod/admin/spec/set/self/admin_spec.rb +14 -11
  19. data/mod/bootstrap/set/all/bootstrap/helper.rb +27 -29
  20. data/mod/carrierwave/set/type/file.rb +1 -1
  21. data/mod/carrierwave/set/type/image.rb +18 -6
  22. data/mod/core/set/all/collection.rb +33 -7
  23. data/mod/core/set/all/fetch.rb +16 -3
  24. data/mod/core/set/all/permissions.rb +6 -12
  25. data/mod/core/set/all/trash.rb +3 -1
  26. data/mod/core/spec/set/all/collection_spec.rb +9 -8
  27. data/mod/email/set/all/notify.rb +27 -17
  28. data/mod/email/set/right/follow.rb +49 -36
  29. data/mod/email/set/type/email_template.rb +25 -69
  30. data/mod/email/set/type/email_template/email_config.rb +63 -0
  31. data/mod/email/set/type_plus_right/user/follow.rb +3 -3
  32. data/mod/machines/lib/stylesheets/style_cards.scss +292 -0
  33. data/mod/pointer/set/abstract/01_pointer.rb +8 -8
  34. data/mod/pointer/set/abstract/01_pointer/edit.rb +6 -2
  35. data/mod/prosemirror_editor/lib/javascript/script_prosemirror.js +12283 -11605
  36. data/mod/prosemirror_editor/lib/javascript/script_prosemirror_config.js.coffee +1 -1
  37. data/mod/standard/set/abstract/01_search_params.rb +1 -1
  38. data/mod/standard/set/abstract/search/paging.rb +4 -4
  39. data/mod/standard/set/all/comment.rb +67 -47
  40. data/mod/standard/set/all/links.rb +2 -2
  41. data/mod/standard/set/all/rich_html/content.rb +1 -1
  42. data/mod/standard/set/all/rich_html/editing.rb +3 -2
  43. data/mod/standard/set/all/rich_html/form.rb +21 -12
  44. data/mod/standard/set/all/rich_html/header.rb +9 -0
  45. data/mod/standard/set/all/rich_html/menu.rb +16 -12
  46. data/mod/standard/set/all/rich_html/toolbar.rb +140 -130
  47. data/mod/standard/set/all/rich_html/wrapper.rb +11 -1
  48. data/mod/standard/set/rstar/rules_editor.rb +2 -34
  49. data/mod/standard/set/self/search.rb +1 -1
  50. data/mod/standard/set/type/set.rb +4 -4
  51. data/mod/standard/spec/set/type/email_template/email_config_spec.rb +218 -0
  52. data/mod/standard/spec/set/type/email_template_spec.rb +3 -185
  53. data/spec/lib/card/cache_spec.rb +0 -1
  54. data/spec/lib/card/format/render_spec.rb +19 -0
  55. data/spec/lib/card/stage_director_spec.rb +1 -1
  56. data/tmpsets/set/mod001-core/all/actify.rb +5 -6
  57. data/tmpsets/set/mod001-core/all/fetch.rb +14 -12
  58. data/tmpsets/set/mod001-core/all/name.rb +1 -1
  59. data/tmpsets/set/mod001-core/all/permissions.rb +12 -22
  60. data/tmpsets/set/mod001-core/all/tracked_attributes.rb +76 -0
  61. data/tmpsets/set/mod001-core/all/utils.rb +40 -3
  62. data/tmpsets/set/mod002-history/all/history.rb +1 -2
  63. data/tmpsets/set/mod008-solid_cache/abstract/solid_cache.rb +1 -1
  64. data/tmpsets/set/mod013-carrierwave/abstract/attachment.rb +282 -0
  65. data/tmpsets/set/mod013-carrierwave/type/file.rb +155 -0
  66. data/tmpsets/set/mod013-carrierwave/type/image.rb +96 -0
  67. data/tmpsets/set/mod014-admin/self/admin.rb +113 -0
  68. data/tmpsets/set/mod014-admin/self/admin_info.rb +110 -0
  69. data/tmpsets/set/mod014-admin/self/version.rb +15 -0
  70. data/tmpsets/set/mod015-developer/all/event_viz.rb +59 -0
  71. data/tmpsets/set/mod015-developer/all/view_viz.rb +30 -0
  72. data/tmpsets/set/mod015-developer/right/debug.rb +96 -0
  73. metadata +15 -2
@@ -1,5 +1,4 @@
1
1
  format :html do
2
-
3
2
  # Does two main things:
4
3
  # (1) gives CSS classes for styling and
5
4
  # (2) adds card data for javascript - including the "card-slot" class,
@@ -13,6 +12,17 @@ format :html do
13
12
  end
14
13
  end
15
14
 
15
+ def haml_wrap slot=true
16
+ @slot_view = @current_view
17
+ debug_slot do
18
+ haml_tag :div, id: card.cardname.url_key,
19
+ class: wrap_classes(slot),
20
+ data: wrap_data do
21
+ yield
22
+ end
23
+ end
24
+ end
25
+
16
26
  def wrap_data
17
27
  { "card-id" => card.id,
18
28
  "card-name" => h(card.name),
@@ -348,40 +348,8 @@ format :html do
348
348
  end
349
349
  end
350
350
 
351
-
352
-
353
-
354
-
355
-
356
-
357
-
358
-
359
-
360
-
361
- view :edit_single_rule, cache: :never do |args|
362
- %(<div class="edit-single-rule panel-body">#{render_edit_rule args}</div>)
363
- end
364
-
365
- def default_edit_single_rule_args args
366
- args[:remote] ||= false
367
- args[:success] ||= {
368
- card: args[:parent] || card,
369
- id: (args[:parent] && args[:parent].cardname.url_key) ||
370
- card.cardname.url_key,
371
- view: :open,
372
- item: nil
373
- }
374
- default_edit_rule_args args
375
- edit_single_rule_button_args args
376
- end
377
-
378
- def edit_single_rule_button_args args
379
- args[:delete_button] = delete_button args, ".card-slot.related-view"
380
-
381
- args[:cancel_button] =
382
- link_to_card args[:success][:id], "Cancel",
383
- class: "rule-cancel-button btn btn-default",
384
- path: { view: args[:success][:view] }
351
+ view :edit_single_rule, tags: :unknown_ok, cache: :never do
352
+ frame() { render_edit_rule }
385
353
  end
386
354
 
387
355
  private
@@ -21,7 +21,7 @@ format do
21
21
  end
22
22
 
23
23
  format :html do
24
- view :title do
24
+ view :title, cache: :never do
25
25
  vars = root.search_params[:vars]
26
26
  if vars && vars[:keyword]
27
27
  voo.title = %(Search results for: <span class="search-keyword">)\
@@ -5,10 +5,10 @@ format :html do
5
5
  COMMON_RULE_SETTINGS =
6
6
  [:create, :read, :update, :delete, :structure, :default, :style].freeze
7
7
 
8
- view :core do |args|
8
+ view :core, cache: :never do |args|
9
9
  voo.show :set_label, :rule_navbar
10
10
  voo.hide :set_navbar
11
- rule_view = args[:rule_view] || :common_rules
11
+ rule_view = params[:rule_view] || :common_rules
12
12
  _render rule_view
13
13
  end
14
14
 
@@ -186,7 +186,7 @@ format :html do
186
186
  return "" if related_sets.size <= 1
187
187
  navbar id, toggle: 'Rules<span class="caret"></span>', toggle_align: :left,
188
188
  class: "slotter toolbar", navbar_type: "inverse",
189
- collapsed_content: close_link(class: "pull-right visible-xs") do
189
+ collapsed_content: close_link("pull-right visible-xs") do
190
190
  [
191
191
  wrap_with(:span, "Set:", class: "navbar-text hidden-xs"),
192
192
  (wrap_with :ul, class: "nav navbar-nav nav-pills" do
@@ -213,7 +213,7 @@ format :html do
213
213
  navbar "rule-navbar-#{card.cardname.safe_key}-#{voo.home_view}",
214
214
  toggle: 'Rules<span class="caret"></span>', toggle_align: :left,
215
215
  class: "slotter toolbar", navbar_type: "inverse",
216
- collapsed_content: close_link(class: "pull-right visible-xs") do
216
+ collapsed_content: close_link("pull-right visible-xs") do
217
217
  [rule_navbar_heading, rule_navbar_content]
218
218
  end
219
219
  end
@@ -0,0 +1,218 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require "card/mailer"
3
+
4
+ describe Card::Set::Type::EmailTemplate::EmailConfig do
5
+ let(:email_name) { "a mail template" }
6
+ let(:email) { Card.fetch(email_name) }
7
+
8
+ def mailconfig args={}
9
+ Card[email_name].email_config(args)
10
+ end
11
+
12
+ def update_field name, args={}
13
+ Card["#{email_name}+#{name}"].update_attributes! args
14
+ end
15
+
16
+ def create_field name, args={}
17
+ Card.create! args.merge(name: "#{email_name}+#{name}")
18
+ end
19
+
20
+ before do
21
+ Card::Auth.current_id = Card::WagnBotID
22
+ chunk_test = "Url(wagn.org) Link([[http://wagn.org|Wagn]])"\
23
+ " Inclusion({{B|name}}) Card link([[A]])"
24
+ Card.create! name: email_name, type: :email_template, subcards: {
25
+ "+*to" => "joe@user.com",
26
+ "+*from" => "from@user.com",
27
+ "+*subject" => "*subject #{chunk_test}",
28
+ "+*html_message" => "*html message #{chunk_test}",
29
+ "+*text_message" => "*text message #{chunk_test}"
30
+ }
31
+ end
32
+ describe "address fields" do
33
+ it "uses *from field" do
34
+ expect(mailconfig[:from]).to eq "from@user.com"
35
+ end
36
+
37
+ it "uses *to field" do
38
+ expect(mailconfig[:to]).to eq "joe@user.com"
39
+ end
40
+
41
+ it "handles pointer values" do
42
+ create_field "*cc", content: "[[joe@user.com]]", type: "Pointer"
43
+ expect(mailconfig[:cc]).to eq "joe@user.com"
44
+ end
45
+
46
+ # it 'handles email syntax in pointer values' do
47
+ # create_field '*cc', content: "[[Joe User <joe@user.com>]]",
48
+ # type: 'Pointer'
49
+ # expect( mailconfig[:cc] ).to eq 'Joe User <joe@user.com>'
50
+ # end
51
+
52
+ it "handles link to email card" do
53
+ create_field "*cc", content: "[[Joe User+*email]]", type: "Pointer"
54
+ expect(mailconfig[:cc]).to eq "joe@user.com"
55
+ end
56
+
57
+ # it 'handles link with valid email address' do
58
+ # create_field '*cc', content: "[[joe@admin.com|Joe]]", type: 'Phrase'
59
+ # expect( mailconfig[:cc] ).to eq 'Joe<joe@user.com>'
60
+ # end
61
+
62
+ it "handles search card" do
63
+ create_field "*bcc", content: '{"name":"Joe Admin","append":"*email"}',
64
+ type: "Search"
65
+ expect(mailconfig[:bcc]).to eq "joe@admin.com"
66
+ end
67
+ # TODO: not obvious how to deal with that.
68
+ # it 'handles invalid email address' do
69
+ # we can't decided whether a email address like [[_left]] is valid;
70
+ # depends on the context
71
+ # Card.fetch("a mail template+*to").
72
+ # update_attributes(content: "invalid mail address")
73
+ # end
74
+ end
75
+
76
+ describe "subject" do
77
+ subject { mailconfig[:subject] }
78
+
79
+ it "uses *subject field" do
80
+ is_expected.to include "*subject"
81
+ end
82
+ it "does not render url" do
83
+ is_expected.to include "Url(wagn.org)"
84
+ end
85
+ it "does not render link" do
86
+ is_expected.to include "Link(Wagn[http://wagn.org])"
87
+ end
88
+ it "renders nest" do
89
+ is_expected.to include "Inclusion(B)"
90
+ end
91
+ end
92
+
93
+ describe "text message" do
94
+ subject { mailconfig[:text_message] }
95
+
96
+ it "uses *text_message field" do
97
+ is_expected.to include "*text message"
98
+ end
99
+ it "does not render url" do
100
+ is_expected.to include "Url(wagn.org)"
101
+ end
102
+ it "renders link" do
103
+ is_expected.to include "Link(Wagn[http://wagn.org])"
104
+ end
105
+ it "renders nest" do
106
+ is_expected.to include "Inclusion(B)"
107
+ end
108
+ end
109
+
110
+ describe "html message" do
111
+ subject do
112
+ config = mailconfig
113
+ config[:context] = Card[email_name]
114
+ config =
115
+ Card[email_name].process_html_message(config,
116
+ { context: Card[email_name] },
117
+ nil)
118
+ # TODO: very hacky to test this; screams for refactoring
119
+ config[:html_message]
120
+ end
121
+
122
+ it "uses *html_message field" do
123
+ is_expected.to include "*html message"
124
+ end
125
+ it "renders url" do
126
+ is_expected.to include 'Url(<a target="_blank" class="external-link" '\
127
+ 'href="http://wagn.org">wagn.org</a>)'
128
+ end
129
+ it "renders link" do
130
+ is_expected.to include 'Link(<a target="_blank" class="external-link" '\
131
+ 'href="http://wagn.org">Wagn</a>)'
132
+ end
133
+ it "renders nest" do
134
+ is_expected.to include "Inclusion(B)"
135
+ end
136
+ it "renders absolute urls" do
137
+ Card::Env[:protocol] = "http://"
138
+ Card::Env[:host] = "www.fake.com"
139
+ is_expected.to include 'Card link(<a class="known-card" '\
140
+ 'href="http://www.fake.com/A">A</a>)'
141
+ end
142
+ end
143
+
144
+ context "with context card" do
145
+ subject(:config) { mailconfig(context: context_card) }
146
+ let(:context_card) do
147
+ file = File.new(File.join(FIXTURES_PATH, "mao2.jpg"))
148
+ Card.create(
149
+ name: "Banana",
150
+ content: "data content [[A]]",
151
+ subcards: {
152
+ "+email" => { content: "gary@gary.com" },
153
+ "+subject" => { type: "Pointer", content: "[[default subject]]" },
154
+ "+attachment" => { type: "File", file: file }
155
+ }
156
+ )
157
+ end
158
+
159
+ it "handles contextual name in address search" do
160
+ update_field "*from", content: '{"left":"_self", "right":"email"}',
161
+ type: "Search"
162
+ expect(config[:from]).to eq "gary@gary.com"
163
+ end
164
+
165
+ it "handles contextual names and structure rules in subject" do
166
+ Card.create! name: "default subject", content: "a very nutty thang",
167
+ type: "Phrase"
168
+ Card.create! name: "subject search+*right+*structure",
169
+ content: %({"referred_to_by":"_left+subject"}),
170
+ type: "Search"
171
+ update_field "*subject", content: "{{+subject search|core|core}}"
172
+ expect(config[:subject]).to eq("a very nutty thang")
173
+ end
174
+
175
+ it "handles _self in html message" do
176
+ update_field "*html message", content: "Triggered by {{_self|name}}"
177
+ mail = email.format.render_mail context: context_card
178
+ expect(mail.parts[1].body.raw_source).to include("Triggered by Banana")
179
+ end
180
+
181
+ it "handles _left in html message" do
182
+ update_field "*html_message",
183
+ content: "Nobody expects {{_left+surprise|core}}"
184
+ Card.create name: "Banana+surprise", content: "the Spanish Inquisition"
185
+ c = Card.create name: "Banana+emailtest", content: "data content"
186
+ mail = email.format.render_mail context: c
187
+ # c.format.render_mail.parts[1].body.raw_source
188
+ expected = mail.parts[1].body.raw_source
189
+ # expected = mailconfig(context: c)[:html_message]
190
+ expect(expected).to include "Nobody expects the Spanish Inquisition"
191
+ end
192
+
193
+ it "handles image nests in html message" do
194
+ update_field "*html message", content: "Triggered by {{:logo|core}}"
195
+ mail = email.format.render_mail context: context_card
196
+ expect(mail.parts[0].mime_type).to eq "image/png"
197
+ url = mail.parts[0].url
198
+ expect(mail.parts[2].mime_type).to eq "text/html"
199
+ expect(mail.parts[2].body.raw_source).to include('<img src="cid:')
200
+ expect(mail.parts[2].body.raw_source).to include("<img src=\"#{url}\"")
201
+ end
202
+
203
+ it "handles image nests in html message in default view" do
204
+ update_field "*html message", content: "Triggered by {{:logo}}"
205
+ mail = email.format.render_mail context: context_card
206
+ expect(mail.parts[0].mime_type).to eq "image/png"
207
+ url = mail.parts[0].url
208
+ expect(mail.parts[2].mime_type).to eq "text/html"
209
+ expect(mail.parts[2].body.raw_source).to include('<img src="cid:')
210
+ expect(mail.parts[2].body.raw_source).to include("<img src=\"#{url}\"")
211
+ end
212
+
213
+ it "handles contextual name for attachments" do
214
+ create_field "*attach", type: "Pointer", content: "[[_self+attachment]]"
215
+ expect(config[:attach]).to eq ["Banana+attachment".to_name]
216
+ end
217
+ end
218
+ end
@@ -2,38 +2,12 @@
2
2
  require "card/mailer"
3
3
 
4
4
  describe Card::Set::Type::EmailTemplate do
5
- let(:email_name) { "a mail template" }
6
- let(:email) { Card.fetch(email_name) }
7
-
8
- def mailconfig args={}
9
- Card[email_name].email_config(args)
10
- end
11
-
12
- def update_field name, args={}
13
- Card["#{email_name}+#{name}"].update_attributes! args
14
- end
15
-
16
- def create_field name, args={}
17
- Card.create! args.merge(name: "#{email_name}+#{name}")
18
- end
19
-
20
- before do
21
- Card::Auth.current_id = Card::WagnBotID
22
- chunk_test = "Url(wagn.org) Link([[http://wagn.org|Wagn]])"\
23
- " Inclusion({{B|name}}) Card link([[A]])"
24
- Card.create! name: email_name, type: :email_template, subcards: {
25
- "+*to" => "joe@user.com",
26
- "+*from" => "from@user.com",
27
- "+*subject" => "*subject #{chunk_test}",
28
- "+*html_message" => "*html message #{chunk_test}",
29
- "+*text_message" => "*text message #{chunk_test}"
30
- }
31
- end
32
-
33
- describe "mail view" do
5
+ describe "view :mail" do
34
6
  let(:content_type) do
7
+ Card::Auth.current_id = Card::WagnBotID
35
8
  card = Card.create!(name: "content type test", type: :email_template,
36
9
  subcards: @fields)
10
+
37
11
  email = card.format.render_mail
38
12
  email[:content_type].value
39
13
  end
@@ -53,160 +27,4 @@ describe Card::Set::Type::EmailTemplate do
53
27
  expect(content_type).to include "multipart/alternative"
54
28
  end
55
29
  end
56
-
57
- describe "#email_config" do
58
- describe "address fields" do
59
- it "uses *from field" do
60
- expect(mailconfig[:from]).to eq "from@user.com"
61
- end
62
-
63
- it "uses *to field" do
64
- expect(mailconfig[:to]).to eq "joe@user.com"
65
- end
66
-
67
- it "handles pointer values" do
68
- create_field "*cc", content: "[[joe@user.com]]", type: "Pointer"
69
- expect(mailconfig[:cc]).to eq "joe@user.com"
70
- end
71
-
72
- # it 'handles email syntax in pointer values' do
73
- # create_field '*cc', content: "[[Joe User <joe@user.com>]]",
74
- # type: 'Pointer'
75
- # expect( mailconfig[:cc] ).to eq 'Joe User <joe@user.com>'
76
- # end
77
-
78
- it "handles link to email card" do
79
- create_field "*cc", content: "[[Joe User+*email]]", type: "Pointer"
80
- expect(mailconfig[:cc]).to eq "joe@user.com"
81
- end
82
-
83
- # it 'handles link with valid email address' do
84
- # create_field '*cc', content: "[[joe@admin.com|Joe]]", type: 'Phrase'
85
- # expect( mailconfig[:cc] ).to eq 'Joe<joe@user.com>'
86
- # end
87
-
88
- it "handles search card" do
89
- create_field "*bcc", content: '{"name":"Joe Admin","append":"*email"}',
90
- type: "Search"
91
- expect(mailconfig[:bcc]).to eq "joe@admin.com"
92
- end
93
- # TODO: not obvious how to deal with that.
94
- # it 'handles invalid email address' do
95
- # we can't decided whether a email address like [[_left]] is valid;
96
- # depends on the context
97
- # Card.fetch("a mail template+*to").
98
- # update_attributes(content: "invalid mail address")
99
- # end
100
- end
101
-
102
- describe "subject" do
103
- subject { mailconfig[:subject] }
104
-
105
- it "uses *subject field" do
106
- is_expected.to include "*subject"
107
- end
108
- it "does not render url" do
109
- is_expected.to include "Url(wagn.org)"
110
- end
111
- it "does not render link" do
112
- is_expected.to include "Link([[http://wagn.org|Wagn]])"
113
- end
114
- it "renders nest" do
115
- is_expected.to include "Inclusion(B)"
116
- end
117
- end
118
-
119
- describe "text message" do
120
- subject { mailconfig[:text_message] }
121
-
122
- it "uses *text_message field" do
123
- is_expected.to include "*text message"
124
- end
125
- it "does not render url" do
126
- is_expected.to include "Url(wagn.org)"
127
- end
128
- it "renders link" do
129
- is_expected.to include "Link(Wagn[http://wagn.org])"
130
- end
131
- it "renders nest" do
132
- is_expected.to include "Inclusion(B)"
133
- end
134
- end
135
-
136
- describe "html message" do
137
- subject { mailconfig[:html_message] }
138
-
139
- it "uses *html_message field" do
140
- is_expected.to include "*html message"
141
- end
142
- it "renders url" do
143
- is_expected.to include 'Url(<a target="_blank" class="external-link" '\
144
- 'href="http://wagn.org">wagn.org</a>)'
145
- end
146
- it "renders link" do
147
- is_expected.to include 'Link(<a target="_blank" class="external-link" '\
148
- 'href="http://wagn.org">Wagn</a>)'
149
- end
150
- it "renders nest" do
151
- is_expected.to include "Inclusion(B)"
152
- end
153
- it "renders absolute urls" do
154
- Card::Env[:protocol] = "http://"
155
- Card::Env[:host] = "www.fake.com"
156
- is_expected.to include 'Card link(<a class="known-card" '\
157
- 'href="http://www.fake.com/A">A</a>)'
158
- end
159
- end
160
-
161
- context "with context card" do
162
- let(:context_card) do
163
- file = File.new(File.join FIXTURES_PATH, "mao2.jpg")
164
- Card.create(
165
- name: "Banana",
166
- content: "data content [[A]]",
167
- subcards: {
168
- "+email" => { content: "gary@gary.com" },
169
- "+subject" => { type: "Pointer", content: "[[default subject]]" },
170
- "+attachment" => { type: "File", file: file }
171
- }
172
- )
173
- end
174
- subject { mailconfig(context: context_card) }
175
-
176
- it "handles contextual name in address search" do
177
- update_field "*from", content: '{"left":"_self", "right":"email"}',
178
- type: "Search"
179
- expect(subject[:from]).to eq "gary@gary.com"
180
- end
181
-
182
- it "handles contextual names and structure rules in subject" do
183
- Card.create! name: "default subject", content: "a very nutty thang",
184
- type: "Phrase"
185
- Card.create! name: "subject search+*right+*structure",
186
- content: %({"referred_to_by":"_left+subject"}),
187
- type: "Search"
188
- update_field "*subject", content: "{{+subject search|core|core}}"
189
- expect(subject[:subject]).to eq("a very nutty thang")
190
- end
191
-
192
- it "handles _self in html message" do
193
- update_field "*html message", content: "Triggered by {{_self|name}}"
194
- expect(subject[:html_message]).to include("Triggered by Banana")
195
- end
196
-
197
- it "handles _left in html message" do
198
- update_field "*html_message",
199
- content: "Nobody expects {{_left+surprise|core}}"
200
- Card.create name: "Banana+surprise", content: "the Spanish Inquisition"
201
- c = Card.create name: "Banana+emailtest", content: "data content"
202
- expected = mailconfig(context: c)[:html_message]
203
- expect(expected).to include "Nobody expects the Spanish Inquisition"
204
- end
205
-
206
- it "handles contextual name for attachments" do
207
- create_field "*attach", type: "Pointer", content: "[[_self+attachment]]"
208
- expect(subject[:attach]).to eq ["Banana+attachment".to_name]
209
- end
210
- end
211
- end
212
30
  end