card 1.20.0 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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