maily_herald 0.8.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +0 -2
  5. data/Gemfile.lock +5 -13
  6. data/README.md +186 -69
  7. data/app/mailers/maily_herald/mailer.rb +44 -26
  8. data/app/models/maily_herald/ad_hoc_mailing.rb +109 -0
  9. data/app/models/maily_herald/dispatch.rb +97 -4
  10. data/app/models/maily_herald/list.rb +36 -7
  11. data/app/models/maily_herald/log.rb +79 -0
  12. data/app/models/maily_herald/mailing.rb +149 -24
  13. data/app/models/maily_herald/one_time_mailing.rb +114 -9
  14. data/app/models/maily_herald/periodical_mailing.rb +76 -47
  15. data/app/models/maily_herald/sequence.rb +57 -18
  16. data/app/models/maily_herald/sequence_mailing.rb +29 -20
  17. data/app/models/maily_herald/subscription.rb +23 -2
  18. data/config/routes.rb +2 -2
  19. data/lib/maily_herald.rb +57 -18
  20. data/lib/maily_herald/autonaming.rb +8 -0
  21. data/lib/maily_herald/context.rb +6 -2
  22. data/lib/maily_herald/logging.rb +2 -0
  23. data/lib/maily_herald/manager.rb +15 -31
  24. data/lib/maily_herald/utils.rb +65 -24
  25. data/lib/maily_herald/version.rb +1 -1
  26. data/maily_herald.gemspec +1 -1
  27. data/spec/controllers/maily_herald/tokens_controller_spec.rb +13 -13
  28. data/spec/dummy/app/mailers/ad_hoc_mailer.rb +11 -0
  29. data/spec/dummy/app/mailers/custom_one_time_mailer.rb +11 -0
  30. data/spec/dummy/config/application.rb +1 -1
  31. data/spec/dummy/config/environments/test.rb +1 -1
  32. data/spec/dummy/config/initializers/maily_herald.rb +3 -69
  33. data/spec/dummy/config/maily_herald.yml +3 -0
  34. data/spec/dummy/db/seeds.rb +73 -0
  35. data/spec/lib/context_spec.rb +7 -7
  36. data/spec/lib/maily_herald_spec.rb +7 -8
  37. data/spec/lib/utils_spec.rb +65 -25
  38. data/spec/mailers/maily_herald/mailer_spec.rb +20 -13
  39. data/spec/models/maily_herald/ad_hoc_mailing_spec.rb +169 -0
  40. data/spec/models/maily_herald/list_spec.rb +2 -1
  41. data/spec/models/maily_herald/log_spec.rb +10 -10
  42. data/spec/models/maily_herald/mailing_spec.rb +9 -8
  43. data/spec/models/maily_herald/one_time_mailing_spec.rb +212 -39
  44. data/spec/models/maily_herald/periodical_mailing_spec.rb +158 -92
  45. data/spec/models/maily_herald/sequence_mailing_spec.rb +2 -2
  46. data/spec/models/maily_herald/sequence_spec.rb +152 -139
  47. data/spec/models/maily_herald/subscription_spec.rb +21 -4
  48. metadata +17 -8
  49. data/lib/maily_herald/condition_evaluator.rb +0 -82
  50. data/lib/maily_herald/config.rb +0 -5
  51. data/spec/dummy/app/mailers/test_mailer.rb +0 -11
@@ -16,16 +16,16 @@ describe MailyHerald::TokensController do
16
16
  describe "when regular subscription" do
17
17
  pending "should deactivate only one subscription" do
18
18
  get :get, token: @subscription.token, use_route: :maily_herald
19
- response.should redirect_to("/")
19
+ expect(response).to redirect_to("/")
20
20
  @subscription.reload
21
21
 
22
- @subscription.active?.should_not be_true
22
+ expect(@subscription.active?).not_to be_true
23
23
 
24
24
  @user.maily_herald_subscriptions.each do |s|
25
25
  next unless s.target.subscription_group == @subscription.target.subscription_group
26
26
  next if s == @subscription
27
27
 
28
- s.active?.should be_true
28
+ expect(s.active?).to be_true
29
29
  end
30
30
  end
31
31
  end
@@ -43,17 +43,17 @@ describe MailyHerald::TokensController do
43
43
 
44
44
  pending "should deactivate subscription group" do
45
45
  get :get, token: @subscription.token, use_route: :maily_herald
46
- response.should redirect_to("/")
46
+ expect(response).to redirect_to("/")
47
47
  @subscription.reload
48
48
 
49
- @subscription.active?.should_not be_true
50
- @subscription.aggregate.should_not be_nil
51
- @subscription.aggregate.active?.should_not be_true
49
+ expect(@subscription.active?).not_to be_true
50
+ expect(@subscription.aggregate).not_to be_nil
51
+ expect(@subscription.aggregate.active?).not_to be_true
52
52
 
53
53
  @user.maily_herald_subscriptions.each do |s|
54
54
  next unless s.target.subscription_group == @subscription.target.subscription_group
55
55
 
56
- s.active?.should be_false
56
+ expect(s.active?).to be_false
57
57
  end
58
58
  end
59
59
  end
@@ -62,20 +62,20 @@ describe MailyHerald::TokensController do
62
62
  pending "Custom action" do
63
63
  before(:each) do
64
64
  @mailing.token_action = :custom
65
- @mailing.should be_valid
65
+ expect(@mailing).to be_valid
66
66
  @mailing.save
67
- @mailing.token_custom_action.should_not be_nil
67
+ expect(@mailing.token_custom_action).not_to be_nil
68
68
  end
69
69
 
70
70
  pending "should perform custom action" do
71
71
  @subscription.reload
72
- @subscription.target.token_action.should eq(:custom)
72
+ expect(@subscription.target.token_action).to eq(:custom)
73
73
  get :get, token: @subscription.token, use_route: :maily_herald
74
- response.should redirect_to("/custom")
74
+ expect(response).to redirect_to("/custom")
75
75
  @subscription.reload
76
76
  @user.reload
77
77
 
78
- @user.name.should eq("changed")
78
+ expect(@user.name).to eq("changed")
79
79
  end
80
80
  end
81
81
  end
@@ -0,0 +1,11 @@
1
+ class AdHocMailer < MailyHerald::Mailer
2
+ default from: "no-reply@mailyherald.org"
3
+
4
+ def ad_hoc_mail user
5
+ mail to: user.email, subject: "Test"
6
+ end
7
+
8
+ def missing_mailing_mail user
9
+ mail to: user.email, subject: "Test", from: "foo@bar.com"
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CustomOneTimeMailer < MailyHerald::Mailer
2
+ default from: "no-reply@mailyherald.org"
3
+
4
+ def one_time_mail user
5
+ mail to: user.email, subject: "Test"
6
+ end
7
+
8
+ def mail_with_error user
9
+ raise "This error comes from CustomOneTimeMailer#mail_with_error"
10
+ end
11
+ end
@@ -29,7 +29,7 @@ module Dummy
29
29
 
30
30
  # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
31
31
  # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
32
- # config.time_zone = 'Central Time (US & Canada)'
32
+ config.time_zone = 'Europe/Warsaw'
33
33
 
34
34
  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
35
35
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
@@ -28,7 +28,7 @@ Dummy::Application.configure do
28
28
  # The :test delivery method accumulates sent emails in the
29
29
  # ActionMailer::Base.deliveries array.
30
30
  config.action_mailer.delivery_method = :test
31
- ActionMailer::Base.default :from => "no-reply@foo.com>"
31
+ ActionMailer::Base.default from: "no-reply@foo.com>"
32
32
 
33
33
  # Raise exception on mass assignment protection for Active Record models
34
34
  config.active_record.mass_assignment_sanitizer = :strict
@@ -18,86 +18,20 @@ MailyHerald.setup do |config|
18
18
  end
19
19
  end
20
20
 
21
- config.list :generic_list do |list|
21
+ config.list :locked_list do |list|
22
22
  list.context_name = :all_users
23
23
  end
24
24
 
25
- config.list :locked_list, locked: true do |list|
25
+ config.list :generic_list do |list|
26
26
  list.context_name = :all_users
27
27
  end
28
28
 
29
- config.one_time_mailing :locked_mailing, locked: true do |mailing|
29
+ config.one_time_mailing :locked_mailing do |mailing|
30
30
  mailing.enable
31
31
  mailing.title = "Test mailing"
32
32
  mailing.subject = "Test mailing"
33
33
  mailing.list = :generic_list
34
- mailing.template = "User name: {{user.name}}."
35
- end
36
-
37
- config.one_time_mailing :test_mailing do |mailing|
38
- mailing.enable
39
- mailing.title = "Test mailing"
40
- mailing.subject = "Test mailing"
41
- mailing.list = :generic_list
42
- mailing.template = "User name: {{user.name}}."
43
- end
44
-
45
- config.one_time_mailing :sample_mail do |mailing|
46
- mailing.enable
47
- mailing.title = "Sample mailing"
48
- mailing.list = :generic_list
49
- mailing.mailer_name = "TestMailer"
50
- end
51
-
52
- config.sequence :newsletters do |seq|
53
- seq.enable
54
- seq.title = "Newsletters"
55
- seq.list = :generic_list
56
- seq.start_at = "user.created_at"
57
- seq.mailing :initial_mail do |mailing|
58
- mailing.title = "Test mailing #1"
59
- mailing.subject = "Test mailing #1"
60
- mailing.template = "User name: {{user.name}}."
61
- mailing.absolute_delay = 1.hour
62
- mailing.enable
63
- end
64
- seq.mailing :second_mail do |mailing|
65
- mailing.title = "Test mailing #2"
66
- mailing.subject = "Test mailing #2"
67
- mailing.template = "User name: {{user.name}}."
68
- mailing.absolute_delay = 3.hours
69
- mailing.enable
70
- end
71
- seq.mailing :third_mail do |mailing|
72
- mailing.title = "Test mailing #3"
73
- mailing.subject = "Test mailing #3"
74
- mailing.template = "User name: {{user.name}}."
75
- mailing.absolute_delay = 6.hours
76
- mailing.enable
77
- end
78
- end
79
-
80
- config.periodical_mailing :weekly_summary do |mailing|
81
- mailing.enable
82
- mailing.title = "Weekly summary"
83
- mailing.subject = "Weekly summary"
84
34
  mailing.start_at = "user.created_at"
85
- mailing.list = :generic_list
86
- mailing.title = "Test periodical mailing"
87
- mailing.template = "User name: {{user.name}}."
88
- mailing.period = 7.days
89
- mailing.conditions = "user.weekly_notifications"
90
- end
91
-
92
- config.periodical_mailing :weekly_summary_sg do |mailing|
93
- mailing.enable
94
- mailing.title = "Weekly summary"
95
- mailing.subject = "Weekly summary"
96
- mailing.start_at = "user.created_at"
97
- mailing.list = :generic_list
98
- mailing.title = "Test periodical mailing"
99
35
  mailing.template = "User name: {{user.name}}."
100
- mailing.period = 7.days
101
- mailing.conditions = "user.weekly_notifications"
102
36
  end
103
37
  end
@@ -0,0 +1,3 @@
1
+ ---
2
+ :verbose: true
3
+ :logfile: "log/maily_herald.log"
@@ -0,0 +1,73 @@
1
+ load "#{Rails.root}/config/initializers/maily_herald.rb" if MailyHerald.schema_loaded? && !MailyHerald::List.any?
2
+
3
+ MailyHerald.one_time_mailing :test_mailing do |mailing|
4
+ mailing.enable
5
+ mailing.title = "Test mailing"
6
+ mailing.subject = "Test mailing"
7
+ mailing.list = :generic_list
8
+ mailing.start_at = "user.created_at"
9
+ mailing.template = "User name: {{user.name}}."
10
+ end
11
+
12
+ MailyHerald.one_time_mailing :one_time_mail do |mailing|
13
+ mailing.enable
14
+ mailing.title = "One time mailing"
15
+ mailing.list = :generic_list
16
+ mailing.mailer_name = "CustomOneTimeMailer"
17
+ mailing.start_at = "user.created_at"
18
+ end
19
+
20
+ MailyHerald.one_time_mailing :mail_with_error do |mailing|
21
+ mailing.enable
22
+ mailing.title = "Mail with error"
23
+ mailing.list = :generic_list
24
+ mailing.mailer_name = "CustomOneTimeMailer"
25
+ mailing.start_at = "user.created_at"
26
+ end
27
+
28
+ MailyHerald.ad_hoc_mailing :ad_hoc_mail do |mailing|
29
+ mailing.enable
30
+ mailing.title = "Ad hoc mailing"
31
+ mailing.list = :generic_list
32
+ mailing.mailer_name = "AdHocMailer"
33
+ end
34
+
35
+ MailyHerald.sequence :newsletters do |seq|
36
+ seq.enable
37
+ seq.title = "Newsletters"
38
+ seq.list = :generic_list
39
+ seq.start_at = "user.created_at"
40
+ seq.mailing :initial_mail do |mailing|
41
+ mailing.title = "Test mailing #1"
42
+ mailing.subject = "Test mailing #1"
43
+ mailing.template = "User name: {{user.name}}."
44
+ mailing.absolute_delay = 1.hour
45
+ mailing.enable
46
+ end
47
+ seq.mailing :second_mail do |mailing|
48
+ mailing.title = "Test mailing #2"
49
+ mailing.subject = "Test mailing #2"
50
+ mailing.template = "User name: {{user.name}}."
51
+ mailing.absolute_delay = 3.hours
52
+ mailing.enable
53
+ end
54
+ seq.mailing :third_mail do |mailing|
55
+ mailing.title = "Test mailing #3"
56
+ mailing.subject = "Test mailing #3"
57
+ mailing.template = "User name: {{user.name}}."
58
+ mailing.absolute_delay = 6.hours
59
+ mailing.enable
60
+ end
61
+ end
62
+
63
+ MailyHerald.periodical_mailing :weekly_summary do |mailing|
64
+ mailing.enable
65
+ mailing.title = "Weekly summary"
66
+ mailing.subject = "Weekly summary"
67
+ mailing.start_at = "user.created_at"
68
+ mailing.list = :generic_list
69
+ mailing.title = "Test periodical mailing"
70
+ mailing.template = "User name: {{user.name}}."
71
+ mailing.period = 7.days
72
+ mailing.conditions = "user.weekly_notifications == true"
73
+ end
@@ -17,17 +17,17 @@ describe MailyHerald::Context do
17
17
  end
18
18
 
19
19
  it "should get valid context" do
20
- @context.should be_a(MailyHerald::Context)
20
+ expect(@context).to be_kind_of(MailyHerald::Context)
21
21
  end
22
22
 
23
23
  it "should resolve attributes properly" do
24
- @drop["user"].should be_a(MailyHerald::Context::Drop)
25
- @drop["user"]["name"].should eq(@user.name)
26
- @drop["user"]["properties"]["prop1"].should eq(@user.name[0])
24
+ expect(@drop["user"]).to be_kind_of(MailyHerald::Context::Drop)
25
+ expect(@drop["user"]["name"]).to eq(@user.name)
26
+ expect(@drop["user"]["properties"]["prop1"]).to eq(@user.name[0])
27
27
  end
28
28
 
29
29
  it "should resolve subscription attributes properly" do
30
- @drop["subscription"].should be_a(MailyHerald::Subscription)
30
+ expect(@drop["subscription"]).to be_kind_of(MailyHerald::Subscription)
31
31
  end
32
32
  end
33
33
  end
@@ -35,7 +35,7 @@ describe MailyHerald::Context do
35
35
  it "should handle both destination procs and strings" do
36
36
  @user = FactoryGirl.create :user
37
37
  context = MailyHerald.context :all_users
38
- context.destination_for(@user).should eq(@user.email)
39
- context.destination_attribute.should be_nil
38
+ expect(context.destination_for(@user)).to eq(@user.email)
39
+ expect(context.destination_attribute).to be_nil
40
40
  end
41
41
  end
@@ -10,23 +10,22 @@ describe MailyHerald do
10
10
  MailyHerald.context(:all_users).model.name.should eq(User.name)
11
11
  User.included_modules.should include(MailyHerald::ModelExtensions)
12
12
 
13
- @user.should respond_to(:maily_herald_subscriptions)
14
-
15
- @user.maily_herald_subscriptions.length.should be_zero
13
+ expect(@user).to respond_to(:maily_herald_subscriptions)
14
+ expect(@user.maily_herald_subscriptions.length).to eq(0)
16
15
  end
17
16
 
18
17
  it "should create mailings from initializer" do
19
18
  mailing = MailyHerald.one_time_mailing(:test_mailing)
20
- mailing.should be_a MailyHerald::Mailing
21
- mailing.should_not be_a_new_record
19
+ expect(mailing).to be_kind_of(MailyHerald::Mailing)
20
+ expect(mailing).not_to be_a_new_record
22
21
  end
23
22
 
24
23
  it "should create sequences from initializer" do
25
24
  sequence = MailyHerald.sequence(:newsletters)
26
- sequence.should be_a MailyHerald::Sequence
27
- sequence.should_not be_a_new_record
25
+ expect(sequence).to be_kind_of(MailyHerald::Sequence)
26
+ expect(sequence).not_to be_a_new_record
28
27
 
29
- sequence.mailings.length.should eq(3)
28
+ expect(sequence.mailings.length).to eq(3)
30
29
  end
31
30
  end
32
31
  end
@@ -11,38 +11,78 @@ describe MailyHerald::Utils do
11
11
  @evaluator = MailyHerald::Utils::MarkupEvaluator.new(@list.context.drop_for(@user, @subscription))
12
12
  end
13
13
 
14
- it "should validate syntax" do
15
- @mailing.conditions = "foo bar"
16
- expect {@evaluator.evaluate_conditions(@mailing.conditions)}.to raise_error(Liquid::Error)
17
- expect {MailyHerald::Utils::MarkupEvaluator.test_conditions(@mailing.conditions)}.to raise_error(Liquid::Error)
18
- end
14
+ describe "conditions" do
15
+ it "should validate syntax" do
16
+ expect(@mailing).to be_valid
17
+ @mailing.conditions = "foo bar"
18
+ #expect {@evaluator.evaluate_conditions(@mailing.conditions)}.to raise_error(Liquid::Error)
19
+ expect(MailyHerald::Utils::MarkupEvaluator.test_conditions(@mailing.conditions)).to be_falsy
20
+ expect(@mailing).not_to be_valid
21
+ expect(@mailing.errors).to include(:conditions)
22
+ end
19
23
 
20
- pending "should validate numerical conditions" do
21
- @mailing.conditions = "(2 * 3) - 1"
22
- @evaluator.evaluate_conditions(@mailing.conditions).should be_falsy
23
- expect {@mailing.test_conditions}.not_to raise_error(Liquid::Error)
24
+ it "should validate numerical conditions" do
25
+ @mailing.conditions = "2"
26
+ expect {@mailing.conditions_met?(@user)}.to raise_error
24
27
 
25
- @mailing.conditions = "2 == 3"
26
- @evaluator.evaluate_conditions(@mailing.conditions).should be_falsy
27
- expect {@mailing.test_conditions}.not_to raise_error(Liquid::Error)
28
+ @mailing.conditions = "5 == 5"
29
+ @evaluator.evaluate_conditions(@mailing.conditions).should be_truthy
30
+ expect {@mailing.conditions_met?(@user)}.not_to raise_error
28
31
 
29
- @mailing.conditions = "1 * 2 + 3"
30
- @evaluator.evaluate_conditions(@mailing.conditions).should be_truthy
31
- expect {@mailing.test_conditions}.not_to raise_error(Liquid::Error)
32
- end
32
+ @mailing.conditions = "2 == 3"
33
+ @evaluator.evaluate_conditions(@mailing.conditions).should be_falsy
34
+ expect {@mailing.conditions_met?(@user)}.not_to raise_error
35
+ end
33
36
 
34
- it "should provide model conditions syntax validation" do
35
- @mailing.conditions = "foo bar"
36
- @mailing.should_not be_valid
37
- end
37
+ it "should evaluate more complex conditions" do
38
+ expect(@user.weekly_notifications).to be_truthy
39
+
40
+ @mailing.conditions = "user.weekly_notifications == true"
41
+ @evaluator.evaluate_conditions(@mailing.conditions).should be_truthy
42
+ expect {@mailing.conditions_met?(@user)}.not_to raise_error
43
+
44
+ @mailing.conditions = "user.weekly_notifications == false"
45
+ @evaluator.evaluate_conditions(@mailing.conditions).should be_falsy
46
+ expect {@mailing.conditions_met?(@user)}.not_to raise_error
47
+
48
+ @user.weekly_notifications = false
49
+ expect(@user.weekly_notifications).to be_falsy
38
50
 
39
- it "should evaluate attributes" do
40
- expect(@evaluator.evaluate_variable("user.created_at")).to eq(@user.created_at)
51
+ @mailing.conditions = "user.weekly_notifications == true"
52
+ @evaluator.evaluate_conditions(@mailing.conditions).should be_falsy
53
+ expect {@mailing.conditions_met?(@user)}.not_to raise_error
54
+ end
55
+
56
+ it "should provide model conditions syntax validation" do
57
+ @mailing.should be_valid
58
+ @mailing.conditions = "foo bar"
59
+ @mailing.should_not be_valid
60
+ end
41
61
  end
42
62
 
43
- it "should evaluate attributes without subscription" do
44
- @evaluator = MailyHerald::Utils::MarkupEvaluator.new(@list.context.drop_for(@user, nil))
45
- expect(@evaluator.evaluate_variable("user.created_at")).to eq(@user.created_at)
63
+ describe "start at" do
64
+ it "should validate syntax" do
65
+ expect(@mailing).to be_valid
66
+ @mailing.start_at = "- foo bar | ddd"
67
+ expect(MailyHerald::Utils::MarkupEvaluator.test_start_at(@mailing.start_at)).to be_falsy
68
+ expect(@mailing).not_to be_valid
69
+ expect(@mailing.errors).to include(:start_at)
70
+ end
71
+
72
+ it "should evaluate attributes" do
73
+ expect(@evaluator.evaluate_start_at("user.created_at")).to eq(@user.created_at)
74
+ end
75
+
76
+ it "should evaluate attributes with filters" do
77
+ expect(@evaluator.evaluate_start_at("user.created_at | minus: 1, 'day'")).to eq(@user.created_at - 1.day)
78
+
79
+ expect(@evaluator.evaluate_start_at("user.created_at | plus: 2, 'minutes'")).to eq(@user.created_at + 2.minutes)
80
+ end
81
+
82
+ it "should evaluate attributes without subscription" do
83
+ @evaluator = MailyHerald::Utils::MarkupEvaluator.new(@list.context.drop_for(@user, nil))
84
+ expect(@evaluator.evaluate_start_at("user.created_at")).to eq(@user.created_at)
85
+ end
46
86
  end
47
87
  end
48
88
  end