card 1.16.14 → 1.16.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/db/migrate_core_cards/20150903130006_attachment_upload_cards.rb +4 -2
- data/lib/card/auth.rb +15 -10
- data/lib/card/codename.rb +25 -21
- data/lib/card/content.rb +100 -68
- data/lib/card/format.rb +158 -129
- data/lib/card/query.rb +15 -9
- data/lib/card/query/attributes.rb +41 -49
- data/lib/card/set.rb +15 -12
- data/lib/card/set_pattern.rb +4 -5
- data/lib/card/spec_helper.rb +54 -16
- data/lib/cardio.rb +43 -25
- data/mod/01_core/chunk/include.rb +1 -1
- data/mod/01_core/set/all/collection.rb +76 -73
- data/mod/01_core/set/all/content.rb +0 -4
- data/mod/01_core/set/all/fetch.rb +35 -42
- data/mod/01_core/set/all/name.rb +17 -7
- data/mod/01_core/set/all/pattern.rb +12 -11
- data/mod/01_core/set/all/permissions.rb +51 -42
- data/mod/01_core/set/all/phases.rb +2 -1
- data/mod/01_core/set/all/references.rb +2 -2
- data/mod/01_core/set/all/rules.rb +28 -35
- data/mod/01_core/set/all/subcards.rb +12 -12
- data/mod/01_core/set/all/tracked_attributes.rb +1 -1
- data/mod/01_core/set/all/type.rb +11 -11
- data/mod/01_core/set/all/utils.rb +6 -1
- data/mod/01_core/spec/set/all/fetch_spec.rb +6 -6
- data/mod/01_core/spec/set/all/permissions_spec.rb +11 -11
- data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +1 -1
- data/mod/01_history/lib/card/action.rb +52 -47
- data/mod/01_history/set/all/actions.rb +20 -16
- data/mod/01_history/set/all/history.rb +18 -13
- data/mod/02_basic_types/set/all/base.rb +23 -2
- data/mod/02_basic_types/set/type/pointer.rb +45 -36
- data/mod/02_basic_types/spec/set/all/base_spec.rb +40 -24
- data/mod/02_basic_types/spec/set/type/pointer_spec.rb +87 -0
- data/mod/03_machines/set/right/machine_output.rb +10 -6
- data/mod/04_settings/set/abstract/permission.rb +10 -5
- data/mod/04_settings/set/type/setting.rb +4 -1
- data/mod/05_email/set/all/follow.rb +39 -44
- data/mod/05_email/set/all/notify.rb +4 -1
- data/mod/05_email/set/right/followers.rb +16 -14
- data/mod/05_email/set/self/follow_defaults.rb +22 -19
- data/mod/05_standard/lib/carrier_wave/cardmount.rb +1 -0
- data/mod/05_standard/set/abstract/attachment.rb +85 -58
- data/mod/05_standard/set/all/comment.rb +35 -19
- data/mod/05_standard/set/all/error.rb +124 -98
- data/mod/05_standard/set/all/list_changes.rb +27 -22
- data/mod/05_standard/set/all/rich_html/editing.rb +96 -70
- data/mod/05_standard/set/all/rich_html/form.rb +123 -81
- data/mod/05_standard/set/all/rich_html/modal.rb +15 -58
- data/mod/05_standard/set/right/account.rb +2 -2
- data/mod/05_standard/set/right/email.rb +3 -2
- data/mod/05_standard/set/rstar/rules.rb +3 -3
- data/mod/05_standard/set/self/search.rb +45 -22
- data/mod/05_standard/set/type/cardtype.rb +13 -11
- data/mod/05_standard/set/type/listed_by.rb +3 -2
- data/mod/05_standard/set/type/set.rb +17 -13
- data/mod/05_standard/set/type/signup.rb +1 -2
- data/mod/05_standard/set/type/user.rb +1 -1
- data/mod/05_standard/spec/set/all/account_spec.rb +1 -1
- data/mod/05_standard/spec/set/all/history_spec.rb +1 -1
- data/mod/05_standard/spec/set/type/email_template_spec.rb +140 -134
- data/mod/05_standard/spec/set/type/image_spec.rb +2 -1
- data/mod/05_standard/spec/set/type/signup_spec.rb +2 -2
- data/spec/models/card/trash_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- metadata +2 -2
@@ -1,43 +1,66 @@
|
|
1
1
|
|
2
2
|
format :html do
|
3
|
-
|
4
3
|
view :title do |args|
|
5
4
|
vars = root.search_params[:vars]
|
6
5
|
if vars && vars[:keyword]
|
7
|
-
|
6
|
+
args.merge! title: %{Search results for: <span class="search-keyword">}\
|
7
|
+
"#{vars[:keyword]}</span>"
|
8
8
|
end
|
9
9
|
super args
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
13
|
format :json do
|
15
|
-
|
16
|
-
|
17
|
-
term = params['_keyword']
|
18
|
-
if term =~ /^\+/ && main = params['main']
|
19
|
-
term = main+term
|
20
|
-
end
|
21
|
-
|
14
|
+
view :complete do
|
15
|
+
term = complete_term
|
22
16
|
exact = Card.fetch term, new: {}
|
23
|
-
goto_cards = Card.search goto_wql(term)
|
24
|
-
goto_cards.unshift exact.name if exact.known? && !goto_cards.map{|n| n.to_name.key}.include?(exact.key)
|
25
17
|
|
26
18
|
{
|
27
|
-
search: true,
|
28
|
-
add:
|
29
|
-
new:
|
30
|
-
|
31
|
-
[exact.name, exact.cardname.url_key]
|
32
|
-
),
|
33
|
-
goto: goto_cards.map { |name| [name, highlight(name, term), name.to_name.url_key] }
|
19
|
+
search: true,
|
20
|
+
add: add_item(exact),
|
21
|
+
new: new_item_of_type(exact),
|
22
|
+
goto: goto_items(term, exact)
|
34
23
|
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_item exact
|
27
|
+
return unless exact.new_card? &&
|
28
|
+
exact.cardname.valid? &&
|
29
|
+
!exact.virtual? &&
|
30
|
+
exact.ok?(:create)
|
31
|
+
exact.name
|
32
|
+
end
|
35
33
|
|
34
|
+
def new_item_of_type exact
|
35
|
+
return unless (exact.type_id == Card::CardtypeID) &&
|
36
|
+
Card.new(type_id: exact.id).ok?(:create)
|
37
|
+
[exact.name, exact.cardname.url_key]
|
36
38
|
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
def goto_items term, exact
|
41
|
+
goto_names = Card.search goto_wql(term), "goto items for term: #{term}"
|
42
|
+
if add_exact_to_goto_names? exact, goto_names
|
43
|
+
goto_names.unshift exact.name
|
44
|
+
end
|
45
|
+
goto_names.map do |name|
|
46
|
+
[name, highlight(name, term), name.to_name.url_key]
|
47
|
+
end
|
41
48
|
end
|
42
49
|
|
50
|
+
def add_exact_to_goto_names? exact, goto_names
|
51
|
+
exact.known? && !goto_names.find { |n| n.to_name.key == exact.key }
|
52
|
+
end
|
53
|
+
|
54
|
+
def complete_term
|
55
|
+
term = params['_keyword']
|
56
|
+
if (term =~ /^\+/) && (main = params['main'])
|
57
|
+
term = main + term
|
58
|
+
end
|
59
|
+
term
|
60
|
+
end
|
61
|
+
|
62
|
+
# hacky. here for override
|
63
|
+
def goto_wql term
|
64
|
+
{ complete: term, limit: 8, sort: 'name', return: 'name' }
|
65
|
+
end
|
43
66
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
|
2
2
|
format :html do
|
3
|
-
|
4
3
|
view :type do |args|
|
5
4
|
args.merge!(type_class: 'no-edit') if card.cards_of_type_exist?
|
6
5
|
super args
|
@@ -8,7 +7,12 @@ format :html do
|
|
8
7
|
|
9
8
|
view :type_formgroup do |args|
|
10
9
|
if card.cards_of_type_exist?
|
11
|
-
%{
|
10
|
+
%{
|
11
|
+
<div>
|
12
|
+
Sorry, this card must remain a Cardtype so long as there are
|
13
|
+
<strong>#{card.name}</strong> cards.
|
14
|
+
</div>
|
15
|
+
}
|
12
16
|
else
|
13
17
|
super args
|
14
18
|
end
|
@@ -33,36 +37,34 @@ format :html do
|
|
33
37
|
if args[:params]
|
34
38
|
context = ((@parent && @parent.card) || card).name
|
35
39
|
Rack::Utils.parse_nested_query(args[:params]).each do |key, value|
|
36
|
-
|
37
|
-
|
38
|
-
|
40
|
+
value = value.to_name.to_absolute(context) if value
|
41
|
+
key = key.to_name.to_absolute(context)
|
42
|
+
path_args[key] = value
|
39
43
|
end
|
40
44
|
end
|
41
45
|
path_args[:action] = 'new'
|
42
46
|
page_path card.cardname, path_args
|
43
47
|
end
|
44
|
-
|
45
48
|
end
|
46
49
|
|
47
|
-
|
48
50
|
include Basic
|
49
51
|
|
50
|
-
|
51
52
|
def follow_label
|
52
53
|
default_follow_set_card.follow_label
|
53
54
|
end
|
54
55
|
|
55
|
-
def followed_by? user_id
|
56
|
+
def followed_by? user_id=nil
|
56
57
|
default_follow_set_card.all_members_followed_by? user_id
|
57
58
|
end
|
58
59
|
|
59
60
|
def default_follow_set_card
|
61
|
+
# FIXME: use codename
|
60
62
|
Card.fetch("#{name}+*type")
|
61
63
|
end
|
62
64
|
|
63
|
-
|
64
65
|
def cards_of_type_exist?
|
65
|
-
|
66
|
+
# FIXME: faster test than counting all of type?
|
67
|
+
!new_card? && Auth.as_bot { Card.count_by_wql type_id: id } > 0
|
66
68
|
end
|
67
69
|
|
68
70
|
event :check_for_cards_of_type, after: :validate_delete do
|
@@ -59,8 +59,9 @@ end
|
|
59
59
|
|
60
60
|
def listed_by
|
61
61
|
Card.search(
|
62
|
-
type: 'list', right: trunk.type_name,
|
63
|
-
|
62
|
+
{ type: 'list', right: trunk.type_name,
|
63
|
+
left: { type: cardname.tag }, refer_to: cardname.trunk, return: :name
|
64
|
+
}, 'listed_by' # better wql comment would be...better
|
64
65
|
)
|
65
66
|
end
|
66
67
|
|
@@ -1,14 +1,14 @@
|
|
1
1
|
|
2
2
|
format :html do
|
3
|
-
|
4
3
|
view :core do |args|
|
5
4
|
_render args[:rule_view], args
|
6
5
|
end
|
6
|
+
|
7
7
|
def default_core_args args
|
8
8
|
args[:rule_view] ||= :common_rules
|
9
|
-
args[:optional_set_label]
|
9
|
+
args[:optional_set_label] ||= :show
|
10
|
+
args[:optional_set_navbar] ||= :hide
|
10
11
|
args[:optional_rule_navbar] ||= :show
|
11
|
-
args[:optional_set_navbar] ||= :hide
|
12
12
|
end
|
13
13
|
|
14
14
|
def with_label_and_navbars args
|
@@ -24,16 +24,20 @@ format :html do
|
|
24
24
|
|
25
25
|
view :all_rules do |args|
|
26
26
|
with_label_and_navbars args.merge(selected_view: :all_rules) do
|
27
|
-
rules_table
|
27
|
+
rules_table card.visible_setting_codenames.sort, args
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
view :grouped_rules do |args|
|
32
32
|
with_label_and_navbars args.merge(selected_view: :grouped_rules) do
|
33
|
-
content_tag(:div, class: 'panel-group',
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
content_tag(:div, class: 'panel-group',
|
34
|
+
id: 'accordion',
|
35
|
+
role: 'tablist',
|
36
|
+
'aria-multiselectable' => 'true'
|
37
|
+
) do
|
38
|
+
Card::Setting.groups.keys.map do |group_key|
|
39
|
+
_optional_render(group_key, args, :show)
|
40
|
+
end * "\n"
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
@@ -201,20 +205,20 @@ def followed_by? user_id = nil
|
|
201
205
|
all_members_followed_by? user_id
|
202
206
|
end
|
203
207
|
|
204
|
-
|
205
208
|
def default_follow_set_card
|
206
209
|
self
|
207
210
|
end
|
208
211
|
|
209
212
|
def inheritable?
|
210
213
|
return true if junction_only?
|
211
|
-
cardname.trunk_name.junction?
|
214
|
+
cardname.trunk_name.junction? &&
|
215
|
+
cardname.tag_name.key == Card::SelfSet.pattern.key
|
212
216
|
end
|
213
217
|
|
214
218
|
def subclass_for_set
|
215
|
-
|
216
|
-
Card.set_patterns.
|
217
|
-
|
219
|
+
current_set_pattern_code = tag.codename
|
220
|
+
Card.set_patterns.detect do |set|
|
221
|
+
current_set_pattern_code == set.pattern_code
|
218
222
|
end
|
219
223
|
end
|
220
224
|
|
@@ -4,8 +4,7 @@ format :html do
|
|
4
4
|
super args
|
5
5
|
args.merge!(
|
6
6
|
optional_help: :show, # , optional_menu: :never
|
7
|
-
buttons:
|
8
|
-
disable_with: 'Submitting', situation: 'primary'),
|
7
|
+
buttons: submit_button,
|
9
8
|
account: card.fetch(trait: :account, new: {}),
|
10
9
|
title: 'Sign up',
|
11
10
|
hidden: {
|
@@ -126,7 +126,7 @@ describe Card::Set::All::Account do
|
|
126
126
|
|
127
127
|
it "9 more should apply to Joe Admin" do
|
128
128
|
# includes lots of account rules...
|
129
|
-
Card::Auth.as(
|
129
|
+
Card::Auth.as('joe_admin') do
|
130
130
|
ids = Card::Auth.as_card.read_rules
|
131
131
|
expect(ids.length).to eq(@read_rules.size + 9)
|
132
132
|
end
|
@@ -93,7 +93,7 @@ describe Card::Set::All::History do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
it "doesn't create act and actions if subcard fails" do
|
96
|
-
Card::Auth.as(
|
96
|
+
Card::Auth.as('joe_user') do
|
97
97
|
act_count = Card::Act.count
|
98
98
|
action_count = Card::Action.count
|
99
99
|
Card.create name: "crete fail", subcards: {'*all+*create'=>''}
|
@@ -3,7 +3,7 @@ require 'card/mailer'
|
|
3
3
|
|
4
4
|
describe Card::Set::Type::EmailTemplate do
|
5
5
|
let(:email_name) { 'a mail template' }
|
6
|
-
let(:email) {Card.fetch(email_name)}
|
6
|
+
let(:email) { Card.fetch(email_name) }
|
7
7
|
|
8
8
|
def mailconfig args={}
|
9
9
|
Card[email_name].email_config(args)
|
@@ -19,66 +19,65 @@ describe Card::Set::Type::EmailTemplate do
|
|
19
19
|
|
20
20
|
before do
|
21
21
|
Card::Auth.current_id = Card::WagnBotID
|
22
|
-
chunk_test =
|
22
|
+
chunk_test = 'Url(wagn.org) Link([[http://wagn.org|Wagn]])'\
|
23
|
+
' Inclusion({{B|name}}) Card link([[A]])'
|
23
24
|
Card.create! name: email_name, type: :email_template, subcards: {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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}"
|
29
30
|
}
|
30
31
|
end
|
31
32
|
|
32
|
-
describe
|
33
|
+
describe 'mail view' do
|
33
34
|
let(:content_type) do
|
34
|
-
card = Card.create!(name: 'content type test', type: :email_template,
|
35
|
+
card = Card.create!(name: 'content type test', type: :email_template,
|
36
|
+
subcards: @fields)
|
35
37
|
email = card.format.render_mail
|
36
38
|
email[:content_type].value
|
37
39
|
end
|
38
40
|
|
39
41
|
it 'renders text email if text message given' do
|
40
|
-
@fields = {
|
42
|
+
@fields = { '+*text_message' => 'text' }
|
41
43
|
expect(content_type).to include 'text/plain'
|
42
44
|
end
|
43
45
|
|
44
46
|
it 'renders html email if html message given' do
|
45
|
-
@fields = {
|
47
|
+
@fields = { '+*html_message' => 'text' }
|
46
48
|
expect(content_type).to include 'text/html'
|
47
49
|
end
|
48
50
|
|
49
51
|
it 'renders multipart email if text and html given' do
|
50
|
-
@fields = {'+*text_message'=>'text', '+*html_message'=>'text'}
|
52
|
+
@fields = { '+*text_message' => 'text', '+*html_message' => 'text' }
|
51
53
|
expect(content_type).to include 'multipart/alternative'
|
52
54
|
end
|
53
|
-
|
54
55
|
end
|
55
56
|
|
56
|
-
|
57
|
-
describe "#email_config" do
|
58
|
-
|
57
|
+
describe '#email_config' do
|
59
58
|
describe 'address fields' do
|
60
59
|
it 'uses *from field' do
|
61
|
-
expect(
|
60
|
+
expect(mailconfig[:from]).to eq 'from@user.com'
|
62
61
|
end
|
63
62
|
|
64
63
|
it 'uses *to field' do
|
65
|
-
expect(
|
64
|
+
expect(mailconfig[:to]).to eq 'joe@user.com'
|
66
65
|
end
|
67
66
|
|
68
67
|
it 'handles pointer values' do
|
69
|
-
create_field '*cc', content:
|
70
|
-
expect(
|
68
|
+
create_field '*cc', content: '[[joe@user.com]]', type: 'Pointer'
|
69
|
+
expect(mailconfig[:cc]).to eq 'joe@user.com'
|
71
70
|
end
|
72
71
|
|
73
|
-
|
74
|
-
#
|
75
|
-
#
|
72
|
+
# it 'handles email syntax in pointer values' do
|
73
|
+
# create_field '*cc', content: "[[Joe User <joe@user.com>]]",
|
74
|
+
# type: 'Pointer'
|
76
75
|
# expect( mailconfig[:cc] ).to eq 'Joe User <joe@user.com>'
|
77
|
-
#end
|
76
|
+
# end
|
78
77
|
|
79
78
|
it 'handles link to email card' do
|
80
|
-
create_field '*cc', content:
|
81
|
-
expect(
|
79
|
+
create_field '*cc', content: '[[Joe User+*email]]', type: 'Pointer'
|
80
|
+
expect(mailconfig[:cc]).to eq 'joe@user.com'
|
82
81
|
end
|
83
82
|
|
84
83
|
# it 'handles link with valid email address' do
|
@@ -87,120 +86,127 @@ describe Card::Set::Type::EmailTemplate do
|
|
87
86
|
# end
|
88
87
|
|
89
88
|
it 'handles search card' do
|
90
|
-
create_field '*bcc', content: '{"name":"Joe Admin","append":"*email"}',
|
91
|
-
|
89
|
+
create_field '*bcc', content: '{"name":"Joe Admin","append":"*email"}',
|
90
|
+
type: 'Search'
|
91
|
+
expect(mailconfig[:bcc]).to eq 'joe@admin.com'
|
92
92
|
end
|
93
|
-
|
94
|
-
# it 'handles invalid email address' do
|
95
|
-
|
96
|
-
#
|
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")
|
97
99
|
# end
|
98
100
|
end
|
99
101
|
|
102
|
+
describe 'subject' do
|
103
|
+
subject { mailconfig[:subject] }
|
100
104
|
|
101
|
-
|
102
|
-
subject { mailconfig[:subject] }
|
103
|
-
|
104
|
-
it 'uses *subject field' do
|
105
|
+
it 'uses *subject field' do
|
105
106
|
is_expected.to include '*subject'
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
describe 'text message' do
|
119
|
-
subject { mailconfig[:text_message] }
|
120
|
-
|
121
|
-
it 'uses *text_message field' do
|
122
|
-
is_expected.to include '*text message'
|
123
|
-
end
|
124
|
-
it 'does not render url' do
|
125
|
-
is_expected.to include 'Url(wagn.org)'
|
126
|
-
end
|
127
|
-
it 'renders link' do
|
128
|
-
is_expected.to include 'Link(Wagn[http://wagn.org])'
|
129
|
-
end
|
130
|
-
it 'renders inclusion' do
|
131
|
-
is_expected.to include 'Inclusion(B)'
|
132
|
-
end
|
133
|
-
|
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" href="http://wagn.org">wagn.org</a>)'
|
144
|
-
end
|
145
|
-
it 'renders link' do
|
146
|
-
is_expected.to include 'Link(<a target="_blank" class="external-link" href="http://wagn.org">Wagn</a>)'
|
147
|
-
end
|
148
|
-
it 'renders inclusion' do
|
149
|
-
is_expected.to include 'Inclusion(B)'
|
150
|
-
end
|
151
|
-
it "renders absolute urls" do
|
152
|
-
Card::Env[:protocol] = 'http://'
|
153
|
-
Card::Env[:host] = 'www.fake.com'
|
154
|
-
is_expected.to include 'Card link(<a class="known-card" href="http://www.fake.com/A">A</a>)'
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
|
159
|
-
context 'with context card' do
|
160
|
-
let(:context_card) do
|
161
|
-
Card.create(
|
162
|
-
name: "Banana",
|
163
|
-
content: "data content [[A]]",
|
164
|
-
subcards: {
|
165
|
-
'+email' => {content: 'gary@gary.com'},
|
166
|
-
'+subject' => {type: 'Pointer', content: '[[default subject]]'},
|
167
|
-
'+attachment' => {type: 'File', content: "notreally.txt" }
|
168
|
-
}
|
169
|
-
)
|
170
|
-
end
|
171
|
-
subject { mailconfig( context: context_card ) }
|
172
|
-
|
173
|
-
it 'handles contextual name in address search' do
|
174
|
-
update_field '*from', content: '{"left":"_self", "right":"email"}', type: 'Search'
|
175
|
-
expect(subject[:from]).to eq "gary@gary.com"
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'handles contextual names and structure rules in subject' do
|
179
|
-
Card.create! name: 'default subject', content: 'a very nutty thang', type: 'Phrase'
|
180
|
-
Card.create! name: "subject search+*right+*structure", content: %{{"referred_to_by":"_left+subject"}}, type: 'Search'
|
181
|
-
update_field '*subject', content: "{{+subject search|core;item:core}}"
|
182
|
-
expect(subject[:subject]).to eq("a very nutty thang")
|
183
|
-
end
|
184
|
-
|
185
|
-
it 'handles _self in html message' do
|
186
|
-
update_field '*html message', content: "Triggered by {{_self|name}}"
|
187
|
-
expect(subject[:html_message]).to include("Triggered by Banana")
|
188
|
-
end
|
189
|
-
|
190
|
-
it 'handles _left in html message' do
|
191
|
-
update_field '*html_message', content: "Nobody expects {{_left+surprise|core}}"
|
192
|
-
Card.create name: 'Banana+surprise', content: "the Spanish Inquisition"
|
193
|
-
c = Card.create name: "Banana+emailtest", content: "data content"
|
194
|
-
expect( mailconfig( context: c )[:html_message] ).to include 'Nobody expects the Spanish Inquisition'
|
195
|
-
|
196
|
-
end
|
197
|
-
|
198
|
-
it 'handles contextual name for attachments' do
|
199
|
-
create_field '*attach', type: "Pointer", content: "[[_self+attachment]]"
|
200
|
-
expect(subject[:attach]).to eq ['Banana+attachment'.to_name]
|
201
|
-
end
|
202
|
-
end
|
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 inclusion' do
|
115
|
+
is_expected.to include 'Inclusion(B)'
|
116
|
+
end
|
117
|
+
end
|
203
118
|
|
204
|
-
|
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 inclusion' do
|
132
|
+
is_expected.to include 'Inclusion(B)'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe 'html message' do
|
137
|
+
subject { mailconfig[:html_message] }
|
205
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 inclusion' 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;item: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
|
206
212
|
end
|