activity_notification 1.1.0 → 1.2.0

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 (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