wagn 1.14.7 → 1.14.8

Sign up to get free protection for your applications and to get access to all the features.
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