activity_notification 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +23 -11
  5. data/Gemfile.lock +52 -40
  6. data/README.md +177 -14
  7. data/activity_notification.gemspec +3 -1
  8. data/app/controllers/activity_notification/subscriptions_controller.rb +48 -2
  9. data/app/views/activity_notification/optional_targets/default/base/_default.text.erb +10 -0
  10. data/app/views/activity_notification/optional_targets/default/slack/_default.text.erb +6 -0
  11. data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +19 -0
  12. data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +32 -3
  13. data/app/views/activity_notification/subscriptions/default/index.html.erb +4 -0
  14. data/app/views/activity_notification/subscriptions/default/show.html.erb +5 -0
  15. data/app/views/activity_notification/subscriptions/default/subscribe_to_optional_target.js.erb +6 -0
  16. data/app/views/activity_notification/subscriptions/default/unsubscribe_to_optional_target.js.erb +6 -0
  17. data/gemfiles/Gemfile.rails-4.2.lock +15 -3
  18. data/gemfiles/Gemfile.rails-5.0.lock +47 -35
  19. data/lib/activity_notification.rb +1 -0
  20. data/lib/activity_notification/apis/notification_api.rb +83 -26
  21. data/lib/activity_notification/apis/subscription_api.rb +93 -8
  22. data/lib/activity_notification/common.rb +6 -2
  23. data/lib/activity_notification/helpers/view_helpers.rb +43 -0
  24. data/lib/activity_notification/models/concerns/notifiable.rb +73 -28
  25. data/lib/activity_notification/models/concerns/subscriber.rb +34 -7
  26. data/lib/activity_notification/models/concerns/target.rb +25 -13
  27. data/lib/activity_notification/models/subscription.rb +13 -2
  28. data/lib/activity_notification/optional_targets/amazon_sns.rb +42 -0
  29. data/lib/activity_notification/optional_targets/base.rb +79 -0
  30. data/lib/activity_notification/optional_targets/slack.rb +33 -0
  31. data/lib/activity_notification/rails/routes.rb +30 -20
  32. data/lib/activity_notification/roles/acts_as_notifiable.rb +70 -11
  33. data/lib/activity_notification/version.rb +1 -1
  34. data/lib/generators/activity_notification/views_generator.rb +2 -2
  35. data/lib/generators/templates/migrations/migration.rb +2 -2
  36. data/spec/concerns/apis/notification_api_spec.rb +97 -0
  37. data/spec/concerns/apis/subscription_api_spec.rb +206 -41
  38. data/spec/concerns/common_spec.rb +7 -2
  39. data/spec/concerns/models/notifiable_spec.rb +88 -2
  40. data/spec/concerns/models/subscriber_spec.rb +114 -13
  41. data/spec/concerns/models/target_spec.rb +17 -0
  42. data/spec/controllers/subscriptions_controller_shared_examples.rb +251 -28
  43. data/spec/helpers/view_helpers_spec.rb +56 -0
  44. data/spec/optional_targets/amazon_sns_spec.rb +46 -0
  45. data/spec/optional_targets/base_spec.rb +43 -0
  46. data/spec/optional_targets/slack_spec.rb +46 -0
  47. data/spec/rails_app/app/controllers/comments_controller.rb +1 -0
  48. data/spec/rails_app/app/models/admin.rb +1 -2
  49. data/spec/rails_app/app/models/article.rb +2 -3
  50. data/spec/rails_app/app/models/comment.rb +19 -7
  51. data/spec/rails_app/app/views/activity_notification/optional_targets/admins/amazon_sns/comment/_default.text.erb +8 -0
  52. data/spec/rails_app/db/migrate/20160715050420_create_activity_notification_tables.rb +1 -1
  53. data/spec/rails_app/db/migrate/20160715050433_create_test_tables.rb +2 -0
  54. data/spec/rails_app/db/schema.rb +3 -1
  55. data/spec/rails_app/db/seeds.rb +1 -1
  56. data/spec/rails_app/lib/custom_optional_targets/console_output.rb +13 -0
  57. data/spec/rails_app/lib/custom_optional_targets/wrong_target.rb +10 -0
  58. data/spec/roles/acts_as_notifiable_spec.rb +124 -2
  59. metadata +49 -4
  60. data/spec/rails_app/app/models/notification.rb +0 -6
@@ -377,6 +377,34 @@ describe ActivityNotification::ViewHelpers, type: :helper do
377
377
  end
378
378
  end
379
379
 
380
+ describe '#subscribe_to_optional_target_subscription_path_for' do
381
+ it "returns path for the subscription target" do
382
+ expect(subscribe_to_optional_target_subscription_path_for(subscription))
383
+ .to eq(subscribe_to_optional_target_user_subscription_path(target_user, subscription))
384
+ end
385
+ end
386
+
387
+ describe '#subscribe_to_optional_target_path_for' do
388
+ it "returns path for the subscription target" do
389
+ expect(subscribe_to_optional_target_path_for(subscription))
390
+ .to eq(subscribe_to_optional_target_user_subscription_path(target_user, subscription))
391
+ end
392
+ end
393
+
394
+ describe '#unsubscribe_to_optional_target_subscription_path_for' do
395
+ it "returns path for the subscription target" do
396
+ expect(unsubscribe_to_optional_target_subscription_path_for(subscription))
397
+ .to eq(unsubscribe_to_optional_target_user_subscription_path(target_user, subscription))
398
+ end
399
+ end
400
+
401
+ describe '#unsubscribe_to_optional_target_path_for' do
402
+ it "returns path for the subscription target" do
403
+ expect(unsubscribe_to_optional_target_path_for(subscription))
404
+ .to eq(unsubscribe_to_optional_target_user_subscription_path(target_user, subscription))
405
+ end
406
+ end
407
+
380
408
  describe '#subscriptions_url_for' do
381
409
  it "returns url for the subscription target" do
382
410
  expect(subscriptions_url_for(target_user))
@@ -447,4 +475,32 @@ describe ActivityNotification::ViewHelpers, type: :helper do
447
475
  end
448
476
  end
449
477
 
478
+ describe '#subscribe_to_optional_target_subscription_url_for' do
479
+ it "returns url for the subscription target" do
480
+ expect(subscribe_to_optional_target_subscription_url_for(subscription))
481
+ .to eq(subscribe_to_optional_target_user_subscription_url(target_user, subscription))
482
+ end
483
+ end
484
+
485
+ describe '#subscribe_to_optional_target_url_for' do
486
+ it "returns url for the subscription target" do
487
+ expect(subscribe_to_optional_target_url_for(subscription))
488
+ .to eq(subscribe_to_optional_target_user_subscription_url(target_user, subscription))
489
+ end
490
+ end
491
+
492
+ describe '#unsubscribe_to_optional_target_subscription_url_for' do
493
+ it "returns url for the subscription target" do
494
+ expect(unsubscribe_to_optional_target_subscription_url_for(subscription))
495
+ .to eq(unsubscribe_to_optional_target_user_subscription_url(target_user, subscription))
496
+ end
497
+ end
498
+
499
+ describe '#unsubscribe_to_optional_target_url_for' do
500
+ it "returns url for the subscription target" do
501
+ expect(unsubscribe_to_optional_target_url_for(subscription))
502
+ .to eq(unsubscribe_to_optional_target_user_subscription_url(target_user, subscription))
503
+ end
504
+ end
505
+
450
506
  end
@@ -0,0 +1,46 @@
1
+ require 'activity_notification/optional_targets/amazon_sns'
2
+ describe ActivityNotification::OptionalTarget::AmazonSNS do
3
+ let(:test_instance) { ActivityNotification::OptionalTarget::AmazonSNS.new }
4
+
5
+ describe "as public instance methods" do
6
+ describe "#to_optional_target_name" do
7
+ it "is return demodulized symbol class name" do
8
+ expect(test_instance.to_optional_target_name).to eq(:amazon_sns)
9
+ end
10
+ end
11
+
12
+ describe "#initialize_target" do
13
+ #TODO
14
+ it "does not raise NotImplementedError" do
15
+ expect { test_instance.initialize_target }
16
+ .not_to raise_error(NotImplementedError)
17
+ end
18
+ end
19
+
20
+ describe "#notify" do
21
+ #TODO
22
+ it "raises NotImplementedError" do
23
+ expect { test_instance.notify(create(:notification)) }
24
+ .not_to raise_error(NotImplementedError)
25
+ end
26
+ end
27
+ end
28
+
29
+ describe "as protected instance methods" do
30
+ describe "#render_notification_message" do
31
+ context "as default" do
32
+ it "renders notification message with default template" do
33
+ expect(test_instance.send(:render_notification_message, create(:notification))).to be_include("Move to notified")
34
+ end
35
+ end
36
+
37
+ context "with unexisting template as fallback option" do
38
+ it "raise ActionView::MissingTemplate" do
39
+ expect { expect(test_instance.send(:render_notification_message, create(:notification), fallback: :hoge)) }
40
+ .to raise_error(ActionView::MissingTemplate)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,43 @@
1
+ describe ActivityNotification::OptionalTarget::Base do
2
+ let(:test_instance) { ActivityNotification::OptionalTarget::Base.new }
3
+
4
+ describe "as public instance methods" do
5
+ describe "#to_optional_target_name" do
6
+ it "is return demodulized symbol class name" do
7
+ expect(test_instance.to_optional_target_name).to eq(:base)
8
+ end
9
+ end
10
+
11
+ describe "#initialize_target" do
12
+ it "raises NotImplementedError" do
13
+ expect { test_instance.initialize_target }
14
+ .to raise_error(NotImplementedError, /You have to implement ActivityNotification::OptionalTarget::Base#initialize_target/)
15
+ end
16
+ end
17
+
18
+ describe "#notify" do
19
+ it "raises NotImplementedError" do
20
+ expect { test_instance.notify(create(:notification)) }
21
+ .to raise_error(NotImplementedError, /You have to implement ActivityNotification::OptionalTarget::Base#notify/)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "as protected instance methods" do
27
+ describe "#render_notification_message" do
28
+ context "as default" do
29
+ it "renders notification message with default template" do
30
+ expect(test_instance.send(:render_notification_message, create(:notification))).to be_include("Move to notified")
31
+ end
32
+ end
33
+
34
+ context "with unexisting template as fallback option" do
35
+ it "raise ActionView::MissingTemplate" do
36
+ expect { expect(test_instance.send(:render_notification_message, create(:notification), fallback: :hoge)) }
37
+ .to raise_error(ActionView::MissingTemplate)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,46 @@
1
+ require 'activity_notification/optional_targets/slack'
2
+ describe ActivityNotification::OptionalTarget::Slack do
3
+ let(:test_instance) { ActivityNotification::OptionalTarget::Slack.new }
4
+
5
+ describe "as public instance methods" do
6
+ describe "#to_optional_target_name" do
7
+ it "is return demodulized symbol class name" do
8
+ expect(test_instance.to_optional_target_name).to eq(:slack)
9
+ end
10
+ end
11
+
12
+ describe "#initialize_target" do
13
+ #TODO
14
+ it "does not raise NotImplementedError" do
15
+ expect { test_instance.initialize_target }
16
+ .not_to raise_error(NotImplementedError)
17
+ end
18
+ end
19
+
20
+ describe "#notify" do
21
+ #TODO
22
+ it "raises NotImplementedError" do
23
+ expect { test_instance.notify(create(:notification)) }
24
+ .not_to raise_error(NotImplementedError)
25
+ end
26
+ end
27
+ end
28
+
29
+ describe "as protected instance methods" do
30
+ describe "#render_notification_message" do
31
+ context "as default" do
32
+ it "renders notification message with slack default template" do
33
+ expect(test_instance.send(:render_notification_message, create(:notification))).to be_include("<!channel>")
34
+ end
35
+ end
36
+
37
+ context "with unexisting template as fallback option" do
38
+ it "raise ActionView::MissingTemplate" do
39
+ expect { expect(test_instance.send(:render_notification_message, create(:notification), fallback: :hoge)) }
40
+ .to raise_error(ActionView::MissingTemplate)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ end
@@ -8,6 +8,7 @@ class CommentsController < ApplicationController
8
8
 
9
9
  if @comment.save
10
10
  @comment.notify :users
11
+ @comment.notify :admins
11
12
  redirect_to @comment.article, notice: 'Comment was successfully created.'
12
13
  else
13
14
  redirect_to @comment.article
@@ -2,8 +2,7 @@ class Admin < ActiveRecord::Base
2
2
  belongs_to :user
3
3
  validates :user, presence: true
4
4
 
5
- acts_as_notification_target email: :email,
6
- email_allowed: ->(admin, key) { admin.user.confirmed_at.present? },
5
+ acts_as_notification_target email_allowed: false,
7
6
  subscription_allowed: true,
8
7
  devise_resource: :user,
9
8
  printable_name: ->(admin) { "admin (#{admin.user.name})" }
@@ -5,9 +5,8 @@ class Article < ActiveRecord::Base
5
5
  validates :user, presence: true
6
6
 
7
7
  acts_as_notifiable :users,
8
- targets: ->(article, key) { User.all.to_a - [article.user] },
9
- notifier: :user,
10
- email_allowed: true,
8
+ targets: ->(article) { User.all.to_a - [article.user] },
9
+ notifier: :user, email_allowed: true,
11
10
  printable_name: ->(article) { "new article \"#{article.title}\"" },
12
11
  dependent_notifications: :delete_all
13
12
  acts_as_notification_group printable_name: ->(article) { "article \"#{article.title}\"" }
@@ -5,16 +5,28 @@ class Comment < ActiveRecord::Base
5
5
  validates :user, presence: true
6
6
 
7
7
  acts_as_notifiable :users,
8
- targets: ->(comment, key) {
9
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
10
- },
11
- group: :article,
12
- notifier: :user,
13
- email_allowed: true,
8
+ targets: ->(comment, key) { ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq },
9
+ group: :article, notifier: :user, email_allowed: true,
14
10
  parameters: { test_default_param: '1' },
15
11
  notifiable_path: :article_notifiable_path,
16
12
  printable_name: ->(comment) { "comment \"#{comment.body}\"" },
17
- dependent_notifications: :delete_all
13
+ dependent_notifications: :update_group_and_delete_all
14
+
15
+ # require 'activity_notification/optional_targets/amazon_sns'
16
+ # require 'activity_notification/optional_targets/slack'
17
+ require 'custom_optional_targets/console_output'
18
+ acts_as_notifiable :admins, targets: Admin.all,
19
+ group: :article, notifier: :user, notifiable_path: :article_notifiable_path,
20
+ printable_name: ->(comment) { "comment \"#{comment.body}\"" }, dependent_notifications: :delete_all,
21
+ optional_targets: {
22
+ # ActivityNotification::OptionalTarget::AmazonSNS => { topic_arn: 'arn:aws:sns:XXXXX:XXXXXXXXXXXX:XXXXX' },
23
+ # # ActivityNotification::OptionalTarget::AmazonSNS => { phone_number: :phone_number },
24
+ # ActivityNotification::OptionalTarget::Slack => {
25
+ # webhook_url: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX',
26
+ # slack_name: :slack_name, channel: 'activity_notification', username: 'ActivityNotification', icon_emoji: ":ghost:"
27
+ # },
28
+ CustomOptionalTarget::ConsoleOutput => {}
29
+ }
18
30
 
19
31
  def article_notifiable_path
20
32
  article_path(article)
@@ -0,0 +1,8 @@
1
+ [This notification is delivered by ActivityNotification with Amazon SNS]
2
+
3
+ Dear <%= @target.printable_target_name %>
4
+
5
+ <%= @notification.notifier.present? ? @notification.notifier.printable_notifier_name : 'Someone' %> notified you of <%= @notification.notifiable.printable_notifiable_name(@notification.target) %><%= " in #{@notification.group.printable_group_name}" if @notification.group.present? %>.
6
+
7
+ <%= "Move to notified #{@notification.notifiable.printable_type.downcase}:" %>
8
+ <%= move_notification_url_for(@notification, open: true) %>
@@ -24,7 +24,7 @@ class CreateActivityNotificationTables < ActiveRecord::Migration
24
24
  t.datetime :unsubscribed_at
25
25
  t.datetime :subscribed_to_email_at
26
26
  t.datetime :unsubscribed_to_email_at
27
- t.text :parameters
27
+ t.text :optional_targets
28
28
 
29
29
  t.timestamps
30
30
  end
@@ -17,6 +17,8 @@ class CreateTestTables < ActiveRecord::Migration
17
17
 
18
18
  create_table :admins do |t|
19
19
  t.references :user, index: true
20
+ t.string :phone_number
21
+ t.string :slack_name
20
22
 
21
23
  t.timestamps
22
24
  end
@@ -14,6 +14,8 @@ ActiveRecord::Schema.define(version: 20160715050433) do
14
14
 
15
15
  create_table "admins", force: :cascade do |t|
16
16
  t.integer "user_id"
17
+ t.string "phone_number"
18
+ t.string "slack_name"
17
19
  t.datetime "created_at"
18
20
  t.datetime "updated_at"
19
21
  t.index ["user_id"], name: "index_admins_on_user_id"
@@ -70,7 +72,7 @@ ActiveRecord::Schema.define(version: 20160715050433) do
70
72
  t.datetime "unsubscribed_at"
71
73
  t.datetime "subscribed_to_email_at"
72
74
  t.datetime "unsubscribed_to_email_at"
73
- t.text "parameters"
75
+ t.text "optional_targets"
74
76
  t.datetime "created_at"
75
77
  t.datetime "updated_at"
76
78
  t.index ["key"], name: "index_subscriptions_on_key"
@@ -21,7 +21,7 @@ end
21
21
 
22
22
  ['Ichiro'].each do |name|
23
23
  user = User.find_by_name(name)
24
- Admin.create(user: user)
24
+ Admin.create(user: user, slack_name: name.downcase)
25
25
  end
26
26
 
27
27
  User.all.each do |user|
@@ -0,0 +1,13 @@
1
+ module CustomOptionalTarget
2
+ # Optional target implementation for mobile push notification or SMS using AWS SNS.
3
+ class ConsoleOutput < ActivityNotification::OptionalTarget::Base
4
+ def initialize_target(options = {})
5
+ end
6
+
7
+ def notify(notification, options = {})
8
+ puts "----- Optional targets: #{self.class.name} -----"
9
+ puts render_notification_message(notification, options)
10
+ puts "-----------------------------------------------------------------"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module CustomOptionalTarget
2
+ # Wrong optional target implementation for tests.
3
+ class WrongTarget
4
+ def initialize_target(options = {})
5
+ end
6
+
7
+ def notify(notification, options = {})
8
+ end
9
+ end
10
+ end
@@ -1,8 +1,15 @@
1
1
  describe ActivityNotification::ActsAsNotifiable do
2
- let(:dummy_model_class) { Dummy::DummyBase }
2
+ let(:dummy_model_class) { Dummy::DummyBase }
3
+ let(:dummy_notifiable_class) { Dummy::DummyNotifiable }
4
+ let(:dummy_target) { create(:dummy_target) }
3
5
 
4
6
  describe "as public class methods" do
5
7
  describe ".acts_as_notifiable" do
8
+ before do
9
+ dummy_notifiable_class.set_notifiable_class_defaults
10
+ @notifiable = dummy_notifiable_class.create
11
+ end
12
+
6
13
  it "have not included Notifiable before calling" do
7
14
  expect(dummy_model_class.respond_to?(:available_as_notifiable?)).to be_falsey
8
15
  end
@@ -19,13 +26,128 @@ describe ActivityNotification::ActsAsNotifiable do
19
26
  end
20
27
  end
21
28
 
29
+ context "with :dependent_notifications option" do
30
+ before do
31
+ dummy_notifiable_class.reset_callbacks :destroy
32
+ @notifiable_1, @notifiable_2, @notifiable_3 = dummy_notifiable_class.create, dummy_notifiable_class.create, dummy_notifiable_class.create
33
+ @group_owner = create(:notification, target: dummy_target, notifiable: @notifiable_1, group: @notifiable_1)
34
+ @group_member = create(:notification, target: dummy_target, notifiable: @notifiable_2, group: @notifiable_1, group_owner: @group_owner)
35
+ create(:notification, target: dummy_target, notifiable: @notifiable_3, group: @notifiable_1, group_owner: @group_owner)
36
+ expect(@group_owner.group_member_count).to eq(2)
37
+ end
38
+
39
+ it "returns hash of :dependent_notifications option" do
40
+ expect(dummy_notifiable_class.acts_as_notifiable :users, dependent_notifications: :restrict_with_exception)
41
+ .to eq({ dependent_notifications: :restrict_with_exception })
42
+ end
43
+
44
+ context "without option" do
45
+ it "does not deletes any notifications when notifiable is deleted" do
46
+ dummy_notifiable_class.acts_as_notifiable :users
47
+ expect(dummy_target.notifications.reload.size).to eq(3)
48
+ expect { @notifiable_1.destroy }.to change(dummy_notifiable_class, :count).by(-1)
49
+ expect(dummy_target.notifications.reload.size).to eq(3)
50
+ end
51
+ end
52
+
53
+ context ":delete_all" do
54
+ it "deletes all notifications when notifiable is deleted" do
55
+ dummy_notifiable_class.acts_as_notifiable :users, dependent_notifications: :delete_all
56
+ expect(dummy_target.notifications.reload.size).to eq(3)
57
+ expect { @notifiable_1.destroy }.to change(dummy_notifiable_class, :count).by(-1)
58
+ expect(dummy_target.notifications.reload.size).to eq(2)
59
+ expect(@group_member.reload.group_owner?).to be_falsey
60
+ end
61
+ end
62
+
63
+ context ":destroy" do
64
+ it "destroies all notifications when notifiable is deleted" do
65
+ dummy_notifiable_class.acts_as_notifiable :users, dependent_notifications: :destroy
66
+ expect(dummy_target.notifications.reload.size).to eq(3)
67
+ expect { @notifiable_1.destroy }.to change(dummy_notifiable_class, :count).by(-1)
68
+ expect(dummy_target.notifications.reload.size).to eq(2)
69
+ expect(@group_member.reload.group_owner?).to be_falsey
70
+ end
71
+ end
72
+
73
+ context ":restrict_with_exception" do
74
+ it "can not be deleted when it has generated notifications" do
75
+ dummy_notifiable_class.acts_as_notifiable :users, dependent_notifications: :restrict_with_exception
76
+ expect(dummy_target.notifications.reload.size).to eq(3)
77
+ expect { @notifiable_1.destroy }.to raise_error(ActiveRecord::DeleteRestrictionError)
78
+ end
79
+ end
80
+
81
+ context ":update_group_and_delete_all" do
82
+ it "deletes all notifications and update notification group when notifiable is deleted" do
83
+ dummy_notifiable_class.acts_as_notifiable :users, dependent_notifications: :update_group_and_delete_all
84
+ expect(dummy_target.notifications.reload.size).to eq(3)
85
+ expect { @notifiable_1.destroy }.to change(dummy_notifiable_class, :count).by(-1)
86
+ expect(dummy_target.notifications.reload.size).to eq(2)
87
+ expect(@group_member.reload.group_owner?).to be_truthy
88
+ end
89
+ end
90
+
91
+ context ":update_group_and_destroy" do
92
+ it "destroies all notifications and update notification group when notifiable is deleted" do
93
+ dummy_notifiable_class.acts_as_notifiable :users, dependent_notifications: :update_group_and_destroy
94
+ expect(dummy_target.notifications.reload.size).to eq(3)
95
+ expect { @notifiable_1.destroy }.to change(dummy_notifiable_class, :count).by(-1)
96
+ expect(dummy_target.notifications.reload.size).to eq(2)
97
+ expect(@group_member.reload.group_owner?).to be_truthy
98
+ end
99
+ end
100
+ end
101
+
102
+ context "with :optional_targets option" do
103
+ require 'custom_optional_targets/console_output'
104
+ require 'custom_optional_targets/wrong_target'
105
+
106
+ it "returns hash of :optional_targets option" do
107
+ result_hash = dummy_notifiable_class.acts_as_notifiable :users, optional_targets: { CustomOptionalTarget::ConsoleOutput => {} }
108
+ expect(result_hash).to be_a(Hash)
109
+ expect(result_hash[:optional_targets]).to be_a(Array)
110
+ expect(result_hash[:optional_targets].first).to be_a(CustomOptionalTarget::ConsoleOutput)
111
+ end
112
+
113
+ context "without option" do
114
+ it "does not configure optional_targets and notifiable#optional_targets returns empty array" do
115
+ dummy_notifiable_class.acts_as_notifiable :users
116
+ expect(@notifiable.optional_targets(:users)).to eq([])
117
+ end
118
+ end
119
+
120
+ context "with hash configuration" do
121
+ it "configure optional_targets and notifiable#optional_targets returns optional_target array" do
122
+ dummy_notifiable_class.acts_as_notifiable :users, optional_targets: { CustomOptionalTarget::ConsoleOutput => {} }
123
+ expect(@notifiable.optional_targets(:users)).to be_a(Array)
124
+ expect(@notifiable.optional_targets(:users).first).to be_a(CustomOptionalTarget::ConsoleOutput)
125
+ end
126
+ end
127
+
128
+ context "with hash configuration but specified class does not extends ActivityNotification::OptionalTarget::Base" do
129
+ it "raise TypeError" do
130
+ expect { dummy_notifiable_class.acts_as_notifiable :users, optional_targets: { CustomOptionalTarget::WrongTarget => {} } }
131
+ .to raise_error(TypeError, /.+ is not a kind of ActivityNotification::OptionalTarget::Base/)
132
+ end
133
+ end
134
+
135
+ context "with lambda function configuration" do
136
+ it "configure optional_targets and notifiable#optional_targets returns optional_target array" do
137
+ dummy_notifiable_class.acts_as_notifiable :users, optional_targets: ->(notifiable, key){ key == 'dummy_key' ? [ActivityNotification::OptionalTarget::Base.new] : [] }
138
+ expect(@notifiable.optional_targets(:users)).to eq([])
139
+ expect(@notifiable.optional_targets(:users, 'dummy_key').first).to be_a(ActivityNotification::OptionalTarget::Base)
140
+ end
141
+ end
142
+ end
143
+
22
144
  #TODO test other options
23
145
  end
24
146
 
25
147
  describe ".available_notifiable_options" do
26
148
  it "returns list of available options in acts_as_notifiable" do
27
149
  expect(dummy_model_class.available_notifiable_options)
28
- .to eq([:targets, :group, :group_expiry_delay, :notifier, :parameters, :email_allowed, :notifiable_path, :printable_notifiable_name, :printable_name, :dependent_notifications])
150
+ .to eq([:targets, :group, :group_expiry_delay, :notifier, :parameters, :email_allowed, :notifiable_path, :printable_notifiable_name, :printable_name, :dependent_notifications, :optional_targets])
29
151
  end
30
152
  end
31
153
  end