wagn 1.14.7 → 1.14.8

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/JASMINE_RAILS_TEST.md +16 -0
  3. data/VERSION +1 -1
  4. data/db/bootstrap/card_actions.yml +501 -480
  5. data/db/bootstrap/card_acts.yml +1 -1
  6. data/db/bootstrap/card_changes.yml +1815 -1752
  7. data/db/bootstrap/cards.yml +1500 -1443
  8. data/db/migrate/20141121172918_rename_card_migration_table.rb +8 -1
  9. data/lib/card/chunk.rb +0 -1
  10. data/lib/card/content.rb +1 -1
  11. data/lib/card/format.rb +6 -4
  12. data/lib/card/generators/card_migration/card_migration_generator.rb +1 -2
  13. data/lib/card/loader.rb +4 -0
  14. data/lib/card/set.rb +21 -7
  15. data/lib/card/set_pattern.rb +38 -5
  16. data/lib/wagn.rb +3 -3
  17. data/lib/wagn/core_migration.rb +1 -15
  18. data/lib/wagn/generators/wagn/templates/Rakefile +0 -1
  19. data/lib/wagn/log.rb +297 -94
  20. data/lib/wagn/migration.rb +53 -24
  21. data/lib/wagn/tasks/wagn.rake +17 -19
  22. data/mod/01_core/set/all/collection.rb +1 -1
  23. data/mod/01_core/set/all/content.rb +5 -2
  24. data/mod/01_core/set/all/fetch.rb +35 -35
  25. data/mod/01_core/set/all/trash.rb +3 -3
  26. data/mod/01_core/set/all/type.rb +7 -4
  27. data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +1 -1
  28. data/mod/01_core/spec/set/all/trash_spec.rb +19 -0
  29. data/mod/02_basic_types/spec/set/type/pointer_spec.rb +13 -3
  30. data/mod/03_machines/set/type/coffee_script.rb +5 -3
  31. data/mod/03_machines/set/type/css.rb +4 -2
  32. data/mod/03_machines/set/type/java_script.rb +5 -4
  33. data/mod/04_settings/set/right/style.rb +3 -2
  34. data/mod/05_email/format/email_text_format.rb +4 -0
  35. data/mod/05_email/set/all/email_text.rb +1 -2
  36. data/mod/05_email/set/right/bcc.rb +8 -4
  37. data/mod/05_email/set/type/email_template.rb +20 -20
  38. data/mod/05_standard/set/all/attach.rb +0 -1
  39. data/mod/05_standard/set/type/basic.rb +3 -1
  40. data/mod/05_standard/set/type/html.rb +7 -5
  41. data/mod/05_standard/spec/set/type/email_template_spec.rb +166 -99
  42. data/public/assets/ace/ext-searchbox.js +409 -0
  43. data/spec/lib/card/set_pattern_spec.rb +18 -1
  44. data/spec/lib/wagn/log_spec.rb +217 -56
  45. data/test/fixtures/card_actions.yml +945 -924
  46. data/test/fixtures/card_acts.yml +101 -101
  47. data/test/fixtures/card_changes.yml +3764 -3701
  48. data/test/fixtures/cards.yml +2012 -1955
  49. metadata +4 -2
@@ -3,7 +3,8 @@ include Machine
3
3
 
4
4
  store_machine_output :filetype => "css"
5
5
 
6
- def chunk_list #turn off autodetection of uri's
7
- #TODO with the new format pattern this should be handled in the js format
6
+ format do
7
+ def chunk_list #turn off autodetection of uri's
8
8
  :inclusion_only
9
+ end
9
10
  end
@@ -4,4 +4,8 @@ class Card::EmailTextFormat < Card::TextFormat
4
4
  def internal_url relative_path
5
5
  wagn_url relative_path
6
6
  end
7
+
8
+ def chunk_list
9
+ :references
10
+ end
7
11
  end
@@ -1,6 +1,5 @@
1
1
 
2
-
3
- format :email_text do
2
+ format :email_text do
4
3
  view :missing do |args| '' end
5
4
  view :closed_missing do |args| '' end
6
5
  end
@@ -1,12 +1,16 @@
1
- def chunk_list #turn off autodetection of uri's
2
- :inclusion_and_link
3
- end
4
1
 
5
2
  def process_email_addresses context_card, format_args, args
6
3
  format(format_args).render_email_addresses(args.merge(:context=>context_card))
7
4
  end
8
5
 
9
6
 
7
+ format do
8
+ def chunk_list #turn off autodetection of uri's
9
+ :references
10
+ end
11
+ end
12
+
13
+
10
14
  format :html do
11
15
  view :pointer_items do |args|
12
16
  card.item_names(:context=>:raw).map do |iname|
@@ -18,7 +22,7 @@ end
18
22
  format :email_text do
19
23
  view :email_addresses do |args|
20
24
  context = args[:context] || self
21
- card.item_names.map do |item_name|
25
+ card.item_names(:context=>context.cardname).map do |item_name|
22
26
  item_name = item_name.to_name.to_absolute(context).to_s
23
27
  if item_name.match /.+\@.+\..+/
24
28
  item_name
@@ -32,30 +32,29 @@ end
32
32
  def email_config args={}
33
33
  config = {}
34
34
  context_card = args[:context] || self
35
- [:to, :from, :cc, :bcc].each do |field_name|
36
- config[field_name] = process_email_field( field_name, args ) do |field_card|
37
- field_card.process_email_addresses context_card, {:format=>'email_text'}, args
38
- end
39
- end
40
-
41
- config[:attach] = process_email_field( :attach, args ) do |field_card|
42
- field_card.extended_item_contents context_card
43
- end
44
35
 
45
- [:subject, :text_message].each do |field_name|
46
- config[field_name] = process_email_field( field_name, args ) do |field_card|
47
- field_card.contextual_content context_card, {:format=>'email_text'}, args
48
- end
36
+ [:to, :from, :cc, :bcc].each do |field_name|
37
+ config[field_name] = process_email_field( field_name, args ) do |field_card|
38
+ field_card.process_email_addresses context_card, {:format=>'email_text'}, args
39
+ end
49
40
  end
50
-
41
+ config[:attach] = process_email_field( :attach, args ) do |field_card|
42
+ field_card.extended_item_contents context_card
43
+ end
44
+ config[:subject] = process_email_field( :subject, args ) do |field_card|
45
+ field_card.contextual_content context_card, {:format=>'email_text'},
46
+ args.merge(:content_opts=>{ :chunk_list=>:inclusion_only })
47
+ end
48
+ config[:text_message] = process_email_field( :text_message, args ) do |field_card|
49
+ field_card.contextual_content context_card, {:format=>'email_text'}, args
50
+ end
51
51
  config[:html_message] = process_email_field :html_message, args do |field_card|
52
- field_card.contextual_content context_card, {:format=>'email_html'}, args
53
- end
54
-
55
- config[:html_message] = Card::Mailer.layout(config[:html_message])
52
+ field_card.contextual_content context_card, {:format=>'email_html'}, args
53
+ end
54
+ config[:html_message] = Card::Mailer.layout config[:html_message] if config[:html_message].present?
55
+
56
56
 
57
57
  from_name, from_email = (config[:from] =~ /(.*)\<(.*)>/) ? [$1.strip, $2] : [nil, config[:from]]
58
-
59
58
  if default_from=Card::Mailer.default[:from]
60
59
  config[:from] = from_email ? "#{from_name || from_email} <#{default_from}>" : default_from
61
60
  config[:reply_to] ||= config[:from]
@@ -72,7 +71,7 @@ format do
72
71
  text_message = args.delete(:text_message)
73
72
  html_message = args.delete(:html_message)
74
73
  attachment_list = args.delete(:attach)
75
- alternative = text_message.present? and html_message.present?
74
+ alternative = (text_message.present? && html_message.present?)
76
75
  mail = Card::Mailer.new_mail(args) do
77
76
  if alternative
78
77
  if attachment_list and !attachment_list.empty?
@@ -96,6 +95,7 @@ format do
96
95
  content_type 'text/html; charset=UTF-8'
97
96
  body html_message
98
97
  else
98
+ content_type 'text/plain; charset=UTF-8'
99
99
  text_part { body text_message }
100
100
  end
101
101
 
@@ -4,7 +4,6 @@ def attach_array
4
4
  !c || c =~ /^\s*<img / ? ['','',''] : c.split(/\n/)
5
5
  end
6
6
 
7
- #ask ethan
8
7
  def attach_array_set i, v
9
8
  c = attach_array[0..2] # make sure there is no mod set for uploaded files
10
9
  if c[i] != v
@@ -41,4 +41,6 @@ format :html do
41
41
  end.join("\n")
42
42
  "<ol>" + list + "</ol>"
43
43
  end
44
- end
44
+
45
+ end
46
+
@@ -11,10 +11,12 @@ def clean_html?
11
11
  false
12
12
  end
13
13
 
14
- def chunk_list
15
- :references
16
- end
17
-
18
14
  def diff_args
19
15
  {:format=>:raw}
20
- end
16
+ end
17
+
18
+ format do
19
+ def chunk_list
20
+ :references
21
+ end
22
+ end
@@ -1,132 +1,199 @@
1
1
  describe Card::Set::Type::EmailTemplate do
2
+ let(:email_name) { 'a mail template' }
3
+ let(:email) {Card.fetch(email_name)}
4
+
2
5
  def mailconfig args={}
3
- Card['a mail template'].email_config(args)
6
+ Card[email_name].email_config(args)
7
+ end
8
+
9
+ def update_field name, args={}
10
+ Card["#{email_name}+#{name}"].update_attributes! args
11
+ end
12
+
13
+ def create_field name, args={}
14
+ Card.create! args.merge(:name=>"#{email_name}+#{name}")
4
15
  end
5
16
 
6
17
  before do
7
18
  Card::Auth.current_id = Card::WagnBotID
8
- Card.create! :name => "a mail template", :type=>:email_template, :subcards=>{
9
- "+*to" => { :content => "joe@user.com" },
10
- "+*from" => { :content => "from@user.com" },
11
- "+*subject" => { :content => "Subject of the mail" },
12
- "+*html_message" => { :content => "[[B]]" }
19
+ chunk_test = "Url(wagn.org) Link([[http://wagn.org|Wagn]]) Inclusion({{B|name}}) Card link([[A]])"
20
+ Card.create! :name => email_name, :type=>:email_template, :subcards=>{
21
+ "+*to" => "joe@user.com",
22
+ "+*from" => "from@user.com",
23
+ "+*subject" => "*subject #{chunk_test}",
24
+ "+*html_message" => "*html message #{chunk_test}",
25
+ "+*text_message" => "*text message #{chunk_test}"
13
26
  }
14
27
  end
15
28
 
16
29
  describe "mail view" do
17
- let(:rendered_mail) { Card.fetch("a mail template").format.render_mail }
30
+ let(:content_type) do
31
+ card = Card.create!(:name => 'content type test', :type=>:email_template, :subcards=>@fields)
32
+ email = card.format.render_mail
33
+ email[:content_type].value
34
+ end
18
35
 
19
-
20
- it "renders absolute urls" do
21
- Card::Env[:protocol] = 'http://'
22
- Card::Env[:host] = 'www.fake.com'
23
- expect(rendered_mail.body).to include('<a class="known-card" href="http://www.fake.com/B">B</a>')
36
+ it 'renders text email if text message given' do
37
+ @fields = { "+*text_message" => "text" }
38
+ expect(content_type).to include 'text/plain'
24
39
  end
25
40
 
26
- # it "renders multipart mails" do
27
- # end
41
+ it 'renders html email if html message given' do
42
+ @fields = { "+*html_message" => "text" }
43
+ expect(content_type).to include 'text/html'
44
+ end
28
45
 
29
- it 'renders broken config' do
30
- Card.fetch("a mail template+*to").update_attributes(:content=>"invalid mail address")
46
+ it 'renders multipart email if text and html given' do
47
+ @fields = {'+*text_message'=>'text', '+*html_message'=>'text'}
48
+ expect(content_type).to include 'multipart/alternative'
31
49
  end
50
+
32
51
  end
33
52
 
53
+
34
54
  describe "#email_config" do
35
- it "returns correct hash with email configuration" do
36
- Card['a mail template+*html_message'].update_attributes! :content => "Nobody expects the Spanish Inquisition"
37
- expect(mailconfig).to eq({
38
- :to => "joe@user.com",
39
- :from => "from@user.com",
40
- :subject => "Subject of the mail",
41
- :html_message => Card::Mailer.layout("Nobody expects the Spanish Inquisition"),
42
- })
43
- end
44
-
45
- it "uses context card for email config" do
46
- Card['a mail template+*html_message'].update_attributes! :content => "Nobody expects {{_left+surprise|core}}"
47
- c = Card.create :name=>'Banana+surprise', :content=>"the Spanish Inquisition"
48
- c = Card.create :name => "Banana+emailtest", :content => "data content"
49
- expect( mailconfig( context: c ) ).to eq({
50
- :to => "joe@user.com",
51
- :from => "from@user.com",
52
- :subject => "Subject of the mail",
53
- :html_message => Card::Mailer.layout("Nobody expects the Spanish Inquisition"),
54
- })
55
+
56
+ describe 'address fields' do
57
+ it 'uses *from field' do
58
+ expect( mailconfig[:from] ).to eq 'from@user.com'
59
+ end
60
+
61
+ it 'uses *to field' do
62
+ expect( mailconfig[:to] ).to eq 'joe@user.com'
63
+ end
64
+
65
+ it 'handles pointer values' do
66
+ create_field '*cc', :content => "[[joe@user.com]]", :type=>'Pointer'
67
+ expect( mailconfig[:cc] ).to eq 'joe@user.com'
68
+ end
69
+
70
+ it 'handles link to email card' do
71
+ create_field '*cc', :content => "[[Joe User+*email]]", :type=>'Pointer'
72
+ expect( mailconfig[:cc] ).to eq 'joe@user.com'
73
+ end
74
+
75
+ # it 'handles link with valid email address' do
76
+ # create_field '*cc', :content => "[[joe@admin.com|Joe]]", :type=>'Phrase'
77
+ # expect( mailconfig[:cc] ).to eq 'Joe<joe@user.com>'
78
+ # end
79
+
80
+ it 'handles search card' do
81
+ create_field '*bcc', :content => '{"name":"Joe Admin","append":"*email"}', :type=>'Search'
82
+ expect( mailconfig[:bcc] ).to eq 'joe@admin.com'
83
+ end
84
+
85
+ # it 'handles invalid email address' do #TODO not obvious how to deal with that.
86
+ # we can't decided whether a email address like [[_left]] is valid; depends on the context
87
+ # Card.fetch("a mail template+*to").update_attributes(:content=>"invalid mail address")
88
+ # end
55
89
  end
56
90
 
57
- it "takes Pointer value for address fields" do
58
- Card.create! :name => "a mail template+*cc", :content => "[[joe@user.com]]", :type=>'Pointer'
59
- expect(mailconfig[:cc]).to eq('joe@user.com')
91
+
92
+ describe 'subject' do
93
+ subject { mailconfig[:subject] }
94
+
95
+ it 'uses *subject field' do
96
+ is_expected.to include '*subject'
97
+ end
98
+ it 'does not render url' do
99
+ is_expected.to include 'Url(wagn.org)'
100
+ end
101
+ it 'does not render link' do
102
+ is_expected.to include 'Link([[http://wagn.org|Wagn]])'
103
+ end
104
+ it 'renders inclusion' do
105
+ is_expected.to include 'Inclusion(B)'
106
+ end
60
107
  end
61
108
 
62
- it "handles +*email" do
63
- pending 'need to handle format-specific chunk lists'
64
- Card::Auth.as_bot do
65
- Card.create! :name => "a mail template+*cc", :content => "[[Joe User+*email]]", :type=>'Pointer'
66
- Card.create! :name => "a mail template+*bcc", :content => '{"name":"Joe Admin","append":"*email"}', :type=>'Search'
109
+ describe 'text message' do
110
+ subject { mailconfig[:text_message] }
111
+
112
+ it 'uses *text_message field' do
113
+ is_expected.to include '*text message'
114
+ end
115
+ it 'does not render url' do
116
+ is_expected.to include 'Url(wagn.org)'
67
117
  end
68
- conf = mailconfig
69
- expect(conf[:cc]).to eq('joe@user.com')
70
- expect(conf[:bcc]).to eq('joe@admin.com')
118
+ it 'renders link' do
119
+ is_expected.to include 'Link(Wagn[http://wagn.org])'
120
+ end
121
+ it 'renders inclusion' do
122
+ is_expected.to include 'Inclusion(B)'
123
+ end
124
+
71
125
  end
72
126
 
73
- it 'creates multipart email if text and html given' do
74
- Card.create! :name => "a mail template+*text_message", :content => "Nobody expects the Spanish Inquisition"
75
- email = render_card :mail, {:name=>"a mail template"}, {}
76
- expect(email[:content_type].value).to include('multipart/alternative')
127
+ describe 'html message' do
128
+ subject { mailconfig[:html_message] }
129
+
130
+ it 'uses *html_message field' do
131
+ is_expected.to include '*html message'
132
+ end
133
+ it 'renders url' do
134
+ is_expected.to include 'Url(<a class="external-link" href="http://wagn.org">wagn.org</a>)'
135
+ end
136
+ it 'renders link' do
137
+ is_expected.to include 'Link(<a class="external-link" href="http://wagn.org">Wagn</a>)'
138
+ end
139
+ it 'renders inclusion' do
140
+ is_expected.to include 'Inclusion(B)'
141
+ end
142
+ it "renders absolute urls" do
143
+ Card::Env[:protocol] = 'http://'
144
+ Card::Env[:host] = 'www.fake.com'
145
+ is_expected.to include 'Card link(<a class="known-card" href="http://www.fake.com/A">A</a>)'
146
+ end
77
147
  end
78
- end
148
+
149
+
150
+ context 'with context card' do
151
+ let(:context_card) do
152
+ Card.create(
153
+ :name => "Banana",
154
+ :content => "data content [[A]]",
155
+ :subcards=> {
156
+ '+email' => {:content=>'gary@gary.com'},
157
+ '+subject' => {:type=>'Pointer', :content=>'[[default subject]]'},
158
+ '+attachment' => {:type=>'File', :content=>"notreally.txt" }
159
+ }
160
+ )
161
+ end
162
+ subject { mailconfig( context: context_card ) }
79
163
 
80
- describe "complex config view" do
81
- before do
82
- class ActionView::Base
83
- def params
84
- @controller ? @controller.params : {}
85
- end
86
- end
164
+ it 'handles contextual name in address search' do
165
+ update_field '*from', :content => '{"left":"_self", "right":"email"}', :type=>'Search'
166
+ update_field '*from', :content => '{"left":"_self", "right":"email"}' #FIXME: have to do this twice to get the right content.
167
+ # After the first update the content is empty
168
+ expect(subject[:from]).to eq "gary@gary.com"
169
+ end
87
170
 
88
- Card::Auth.as_bot do
89
- Card.create! :name => 'Bobs addy', :content=>'bob@bob.com', :type=>'Phrase'
90
- Card.create! :name => 'default subject', :content=>'a very nutty thang', :type=>'Phrase'
91
- Card.create! :name => "mailconfig+*to", :content => %{ {"key":"bob_addy"} }, :type=>'Search'
92
- Card.create! :name => "mailconfig+*from", :content => %{ {"left":"_left", "right":"email"} }, :type=>'Search'
93
- Card.create! :name => "subject search+*right+*structure", :content => %{{"referred_to_by":"_self+subject"}}, :type=>'Search'
94
- Card.create! :name => "mailconfig+*subject", :content => "{{+subject search|core;item:core}}"
95
- Card.create! :name => "mailconfig+*html message", :content => "Triggered by {{_self|name}} and its wonderful content: {{_self|core}}"
96
- Card.create! :name => "mailconfig+*attach", :type=>"Pointer", :content => "[[_self+attachment]]"
97
- Card.create! :name=>'Trigger', :type=>'Cardtype'
98
- Card.create! :name=>'Trigger+*type+*create', :type=>'Pointer', :content=>'[[Anonymous]]'
99
- # Card.create! :name => "Trigger+*type+*send", :content => "[[mailconfig]]", :type=>'Pointer'
100
- end
101
- end
171
+ it 'handles contextual names and structure rules in subject' do
172
+ Card.create! :name => 'default subject', :content=>'a very nutty thang', :type=>'Phrase'
173
+ Card.create! :name => "subject search+*right+*structure", :content => %{{"referred_to_by":"_self+subject"}}, :type=>'Search'
174
+ update_field '*subject', :content => "{{+subject search|core;item:core}}"
175
+ expect(subject[:subject]).to eq("a very nutty thang")
176
+ end
102
177
 
103
- it "returns correct hash with email configuration" do
104
- pending 'need to support searches for emails'
105
- Card::Auth.as_bot do
106
- Card::Env[:protocol] = 'http://'
107
- Card::Env[:host] = 'a.com'
178
+ it 'handles _self in html message' do
179
+ update_field '*html message', :content => "Triggered by {{_self|name}}"
180
+ expect(subject[:html_message]).to include("Triggered by Banana")
181
+ end
108
182
 
109
- c = Card.create(
110
- :name => "Banana Trigger",
111
- :content => "data content [[A]]",
112
- :type => 'Trigger',
113
- :subcards=> {
114
- '+email' => {:content=>'gary@gary.com'},
115
- '+subject' => {:type=>'Pointer', :content=>'[[default subject]]'},
116
- # '+attachment' => {:type=>'File', :content=>"notreally.txt" }
117
- }
118
- )
119
- conf = mailconfig( context: c )
183
+ it 'handles _left in html message' do
184
+ update_field '*html_message', :content => "Nobody expects {{_left+surprise|core}}"
185
+ Card.create :name=>'Banana+surprise', :content=>"the Spanish Inquisition"
186
+ c = Card.create :name => "Banana+emailtest", :content => "data content"
187
+ expect( mailconfig( context: c )[:html_message] ).to include 'Nobody expects the Spanish Inquisition'
188
+
189
+ end
190
+
191
+ it 'handles contextual name for attachments' do
192
+ create_field '*attach', :type=>"Pointer", :content => "[[_self+attachment]]"
193
+ expect(subject[:attach]).to eq ['Banana+attachment'.to_name]
194
+ end
195
+ end
120
196
 
121
- expect(conf[:to ]).to eq("bob@bob.com")
122
- expect(conf[:from ]).to eq("gary@gary.com")
123
- expect(conf[:bcc ]).to eq(nil)
124
- expect(conf[:cc ]).to eq(nil)
125
- expect(conf[:subject]).to eq("a very nutty thang")
126
- # conf[:attach ].should == ['Banana Trigger+attachment']
127
- expect(conf[:html_message]).to include("Triggered by Banana Trigger and its wonderful content: data content " +
128
- '<a class="known-card" href="http://a.com/A">A</a>')
129
- end
130
- end
131
197
  end
198
+
132
199
  end