activity_notification 1.7.1 → 2.0.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.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.travis.yml +16 -2
- data/CHANGELOG.md +22 -2
- data/Gemfile +7 -0
- data/Procfile +2 -0
- data/README.md +366 -32
- data/Rakefile +19 -10
- data/activity_notification.gemspec +5 -3
- data/app/channels/activity_notification/notification_channel.rb +37 -0
- data/app/channels/activity_notification/notification_with_devise_channel.rb +51 -0
- data/app/controllers/activity_notification/notifications_controller.rb +1 -1
- data/app/controllers/activity_notification/subscriptions_controller.rb +1 -1
- data/app/jobs/activity_notification/notify_all_job.rb +16 -0
- data/app/jobs/activity_notification/notify_job.rb +17 -0
- data/app/jobs/activity_notification/notify_to_job.rb +16 -0
- data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +1 -1
- data/app/views/activity_notification/notifications/default/index.html.erb +55 -2
- data/bin/_dynamodblocal +4 -0
- data/{scripts → bin}/bundle_update.sh +1 -0
- data/bin/deploy_on_heroku.sh +14 -0
- data/bin/install_dynamodblocal.sh +5 -0
- data/bin/start_dynamodblocal.sh +47 -0
- data/bin/stop_dynamodblocal.sh +34 -0
- data/gemfiles/Gemfile.rails-4.2 +1 -0
- data/gemfiles/Gemfile.rails-5.0 +2 -0
- data/gemfiles/Gemfile.rails-5.1 +1 -0
- data/gemfiles/Gemfile.rails-5.2 +1 -0
- data/gemfiles/Gemfile.rails-6.0.rc +21 -0
- data/lib/activity_notification.rb +1 -0
- data/lib/activity_notification/apis/notification_api.rb +289 -136
- data/lib/activity_notification/apis/subscription_api.rb +80 -53
- data/lib/activity_notification/common.rb +3 -3
- data/lib/activity_notification/config.rb +89 -33
- data/lib/activity_notification/controllers/common_controller.rb +19 -7
- data/lib/activity_notification/helpers/errors.rb +4 -0
- data/lib/activity_notification/helpers/view_helpers.rb +1 -1
- data/lib/activity_notification/models/concerns/notifiable.rb +61 -53
- data/lib/activity_notification/models/concerns/subscriber.rb +7 -6
- data/lib/activity_notification/models/concerns/target.rb +73 -28
- data/lib/activity_notification/optional_targets/base.rb +2 -2
- data/lib/activity_notification/orm/active_record/notification.rb +4 -23
- data/lib/activity_notification/orm/dynamoid.rb +495 -0
- data/lib/activity_notification/orm/dynamoid/extension.rb +184 -0
- data/lib/activity_notification/orm/dynamoid/notification.rb +189 -0
- data/lib/activity_notification/orm/dynamoid/subscription.rb +82 -0
- data/lib/activity_notification/orm/mongoid.rb +4 -1
- data/lib/activity_notification/orm/mongoid/notification.rb +8 -25
- data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
- data/lib/activity_notification/roles/acts_as_notifiable.rb +33 -5
- data/lib/activity_notification/roles/acts_as_target.rb +62 -9
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/templates/activity_notification.rb +30 -7
- data/lib/tasks/activity_notification_tasks.rake +14 -4
- data/spec/channels/notification_channel_shared_examples.rb +59 -0
- data/spec/channels/notification_channel_spec.rb +50 -0
- data/spec/channels/notification_with_devise_channel_spec.rb +99 -0
- data/spec/concerns/apis/notification_api_spec.rb +2 -2
- data/spec/concerns/apis/subscription_api_spec.rb +2 -2
- data/spec/concerns/models/notifiable_spec.rb +72 -7
- data/spec/concerns/models/subscriber_spec.rb +53 -49
- data/spec/concerns/models/target_spec.rb +135 -13
- data/spec/config_spec.rb +41 -1
- data/spec/controllers/notifications_controller_shared_examples.rb +7 -3
- data/spec/controllers/subscriptions_controller_shared_examples.rb +7 -3
- data/spec/helpers/view_helpers_spec.rb +12 -10
- data/spec/models/dummy/dummy_group_spec.rb +4 -0
- data/spec/models/dummy/dummy_notifiable_spec.rb +4 -0
- data/spec/models/dummy/dummy_notifier_spec.rb +4 -0
- data/spec/models/dummy/dummy_subscriber_spec.rb +3 -0
- data/spec/models/dummy/dummy_target_spec.rb +4 -0
- data/spec/models/notification_spec.rb +164 -45
- data/spec/models/subscription_spec.rb +69 -14
- data/spec/orm/dynamoid_spec.rb +115 -0
- data/spec/rails_app/app/assets/javascripts/application.js +2 -1
- data/spec/rails_app/app/assets/javascripts/cable.js +12 -0
- data/spec/rails_app/app/controllers/comments_controller.rb +3 -4
- data/spec/rails_app/app/models/admin.rb +6 -4
- data/spec/rails_app/app/models/article.rb +2 -2
- data/spec/rails_app/app/models/comment.rb +17 -5
- data/spec/rails_app/app/models/user.rb +5 -3
- data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +1 -0
- data/spec/rails_app/config/application.rb +6 -1
- data/spec/rails_app/config/cable.yml +8 -0
- data/spec/rails_app/config/dynamoid.rb +5 -0
- data/spec/rails_app/config/environment.rb +4 -1
- data/spec/rails_app/config/environments/production.rb +1 -1
- data/spec/rails_app/config/initializers/activity_notification.rb +30 -7
- data/spec/rails_app/config/locales/activity_notification.en.yml +2 -0
- data/spec/rails_app/db/seeds.rb +21 -5
- data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +12 -4
- data/spec/roles/acts_as_notifiable_spec.rb +2 -2
- data/spec/roles/acts_as_target_spec.rb +1 -1
- data/spec/spec_helper.rb +15 -8
- metadata +67 -20
- data/spec/rails_app/app/models/.keep +0 -0
- data/spec/rails_app/app/views/activity_notification/notifications/users/overriden/custom/_test.html.erb +0 -1
|
@@ -10,7 +10,7 @@ shared_examples_for :target do
|
|
|
10
10
|
expect(test_instance.notifications.count).to eq(2)
|
|
11
11
|
expect(test_instance.notifications.earliest).to eq(notification_1)
|
|
12
12
|
expect(test_instance.notifications.latest).to eq(notification_2)
|
|
13
|
-
expect(test_instance.notifications).to
|
|
13
|
+
expect(test_instance.notifications.to_a).to eq(ActivityNotification::Notification.filtered_by_target(test_instance).to_a)
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -24,10 +24,15 @@ shared_examples_for :target do
|
|
|
24
24
|
describe ".set_target_class_defaults" do
|
|
25
25
|
it "set parameter fields as default" do
|
|
26
26
|
described_class.set_target_class_defaults
|
|
27
|
-
expect(described_class._notification_email).to
|
|
28
|
-
expect(described_class._notification_email_allowed).to
|
|
29
|
-
expect(described_class.
|
|
30
|
-
expect(described_class.
|
|
27
|
+
expect(described_class._notification_email).to eq(nil)
|
|
28
|
+
expect(described_class._notification_email_allowed).to eq(ActivityNotification.config.email_enabled)
|
|
29
|
+
expect(described_class._batch_notification_email_allowed).to eq(ActivityNotification.config.email_enabled)
|
|
30
|
+
expect(described_class._notification_subscription_allowed).to eq(ActivityNotification.config.subscription_enabled)
|
|
31
|
+
expect(described_class._notification_action_cable_allowed).to eq(ActivityNotification.config.action_cable_enabled)
|
|
32
|
+
expect(described_class._notification_action_cable_with_devise).to eq(ActivityNotification.config.action_cable_with_devise)
|
|
33
|
+
expect(described_class._notification_devise_resource).to be_a_kind_of(Proc)
|
|
34
|
+
expect(described_class._notification_current_devise_target).to be_a_kind_of(Proc)
|
|
35
|
+
expect(described_class._printable_notification_target_name).to eq(:printable_name)
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
|
|
@@ -264,7 +269,8 @@ shared_examples_for :target do
|
|
|
264
269
|
expect(test_instance.notification_email_allowed?(test_notifiable, 'dummy_key')).to eq(true)
|
|
265
270
|
end
|
|
266
271
|
|
|
267
|
-
it "returns specified symbol with
|
|
272
|
+
it "returns specified symbol with notifiable
|
|
273
|
+
and key arguments" do
|
|
268
274
|
module AdditionalMethods
|
|
269
275
|
def custom_notification_email_allowed?(notifiable, key)
|
|
270
276
|
true
|
|
@@ -391,6 +397,117 @@ shared_examples_for :target do
|
|
|
391
397
|
end
|
|
392
398
|
end
|
|
393
399
|
|
|
400
|
+
describe "#notification_action_cable_allowed?" do
|
|
401
|
+
context "without any configuration" do
|
|
402
|
+
it "returns ActivityNotification.config.action_cable_enabled without arguments" do
|
|
403
|
+
expect(test_instance.notification_action_cable_allowed?)
|
|
404
|
+
.to eq(ActivityNotification.config.action_cable_enabled)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
it "returns ActivityNotification.config.action_cable_enabled with arguments" do
|
|
408
|
+
expect(test_instance.notification_action_cable_allowed?(test_notifiable, 'dummy_key'))
|
|
409
|
+
.to eq(ActivityNotification.config.action_cable_enabled)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
it "returns false as default" do
|
|
413
|
+
expect(test_instance.notification_action_cable_allowed?).to be_falsey
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
context "configured with a field" do
|
|
418
|
+
it "returns specified value" do
|
|
419
|
+
described_class._notification_action_cable_allowed = true
|
|
420
|
+
expect(test_instance.notification_action_cable_allowed?).to eq(true)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
it "returns specified symbol without argument" do
|
|
424
|
+
module AdditionalMethods
|
|
425
|
+
def custom_notification_action_cable_allowed?
|
|
426
|
+
true
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
test_instance.extend(AdditionalMethods)
|
|
430
|
+
described_class._notification_action_cable_allowed = :custom_notification_action_cable_allowed?
|
|
431
|
+
expect(test_instance.notification_action_cable_allowed?).to eq(true)
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
it "returns specified symbol with notifiable and key arguments" do
|
|
435
|
+
module AdditionalMethods
|
|
436
|
+
def custom_notification_action_cable_allowed?(notifiable, key)
|
|
437
|
+
true
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
test_instance.extend(AdditionalMethods)
|
|
441
|
+
described_class._notification_action_cable_allowed = :custom_notification_action_cable_allowed?
|
|
442
|
+
expect(test_instance.notification_action_cable_allowed?(test_notifiable, 'dummy_key')).to eq(true)
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
it "returns specified lambda with single target argument" do
|
|
446
|
+
described_class._notification_action_cable_allowed = ->(target){ true }
|
|
447
|
+
expect(test_instance.notification_action_cable_allowed?(test_notifiable, 'dummy_key')).to eq(true)
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
it "returns specified lambda with target, notifiable and key arguments" do
|
|
451
|
+
described_class._notification_action_cable_allowed = ->(target, notifiable, key){ true }
|
|
452
|
+
expect(test_instance.notification_action_cable_allowed?(test_notifiable, 'dummy_key')).to eq(true)
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
describe "#notification_action_cable_with_devise?" do
|
|
458
|
+
context "without any configuration" do
|
|
459
|
+
it "returns ActivityNotification.config.action_cable_with_devise without arguments" do
|
|
460
|
+
expect(test_instance.notification_action_cable_with_devise?)
|
|
461
|
+
.to eq(ActivityNotification.config.action_cable_with_devise)
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it "returns false as default" do
|
|
465
|
+
expect(test_instance.notification_action_cable_with_devise?).to be_falsey
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
context "configured with a field" do
|
|
470
|
+
it "returns specified value" do
|
|
471
|
+
described_class._notification_action_cable_with_devise = true
|
|
472
|
+
expect(test_instance.notification_action_cable_with_devise?).to eq(true)
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
it "returns specified symbol without argument" do
|
|
476
|
+
module AdditionalMethods
|
|
477
|
+
def custom_notification_action_cable_with_devise?
|
|
478
|
+
true
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
test_instance.extend(AdditionalMethods)
|
|
482
|
+
described_class._notification_action_cable_with_devise = :custom_notification_action_cable_with_devise?
|
|
483
|
+
expect(test_instance.notification_action_cable_with_devise?).to eq(true)
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
it "returns specified lambda with single target argument" do
|
|
487
|
+
described_class._notification_action_cable_with_devise = ->(target){ true }
|
|
488
|
+
expect(test_instance.notification_action_cable_with_devise?).to eq(true)
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
if Rails::VERSION::MAJOR >= 5
|
|
494
|
+
describe "#notification_action_cable_channel_class_name" do
|
|
495
|
+
context "when custom_notification_action_cable_with_devise? returns true" do
|
|
496
|
+
it "returns ActivityNotification::NotificationWithDeviseChannel" do
|
|
497
|
+
described_class._notification_action_cable_with_devise = true
|
|
498
|
+
expect(test_instance.notification_action_cable_channel_class_name).to eq(ActivityNotification::NotificationWithDeviseChannel.name)
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
context "when custom_notification_action_cable_with_devise? returns false" do
|
|
503
|
+
it "returns ActivityNotification::NotificationChannel" do
|
|
504
|
+
described_class._notification_action_cable_with_devise = false
|
|
505
|
+
expect(test_instance.notification_action_cable_channel_class_name).to eq(ActivityNotification::NotificationChannel.name)
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
394
511
|
describe "#authenticated_with_devise?" do
|
|
395
512
|
context "without any configuration" do
|
|
396
513
|
context "when the current devise resource and called target are different class instance" do
|
|
@@ -614,16 +731,21 @@ shared_examples_for :target do
|
|
|
614
731
|
|
|
615
732
|
context 'with custom_filter options' do
|
|
616
733
|
it "returns filtered notifications only" do
|
|
617
|
-
if ActivityNotification.config.orm == :active_record
|
|
618
|
-
options = { custom_filter: ["notifications.key = ?", @key] }
|
|
619
|
-
expect(test_instance.notification_index(options)[0]).to eq(@notification3)
|
|
620
|
-
expect(test_instance.notification_index(options).size).to eq(1)
|
|
621
|
-
end
|
|
622
|
-
|
|
623
734
|
options = { custom_filter: { key: @key } }
|
|
624
735
|
expect(test_instance.notification_index(options)[0]).to eq(@notification3)
|
|
625
736
|
expect(test_instance.notification_index(options).size).to eq(1)
|
|
626
737
|
end
|
|
738
|
+
|
|
739
|
+
it "returns filtered notifications only with filter depending on ORM" do
|
|
740
|
+
options =
|
|
741
|
+
case ActivityNotification.config.orm
|
|
742
|
+
when :active_record then { custom_filter: ["notifications.key = ?", @key] }
|
|
743
|
+
when :mongoid then { custom_filter: { key: {'$eq': @key} } }
|
|
744
|
+
when :dynamoid then { custom_filter: {'key.begins_with': @key} }
|
|
745
|
+
end
|
|
746
|
+
expect(test_instance.notification_index(options)[0]).to eq(@notification3)
|
|
747
|
+
expect(test_instance.notification_index(options).size).to eq(1)
|
|
748
|
+
end
|
|
627
749
|
end
|
|
628
750
|
end
|
|
629
751
|
|
|
@@ -800,7 +922,7 @@ shared_examples_for :target do
|
|
|
800
922
|
end
|
|
801
923
|
|
|
802
924
|
|
|
803
|
-
# Methods to be
|
|
925
|
+
# Methods to be overridden
|
|
804
926
|
|
|
805
927
|
describe "#notification_index_with_attributes" do
|
|
806
928
|
context "when the target has no notifications" do
|
data/spec/config_spec.rb
CHANGED
|
@@ -7,7 +7,7 @@ describe ActivityNotification::Config do
|
|
|
7
7
|
expect(ActivityNotification::Mailer).to receive(:send_notification_email).and_call_original
|
|
8
8
|
notification.send_notification_email send_later: false
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
it "is not configured with CustomNotificationMailer" do
|
|
12
12
|
expect(CustomNotificationMailer).not_to receive(:send_notification_email).and_call_original
|
|
13
13
|
notification.send_notification_email send_later: false
|
|
@@ -31,4 +31,44 @@ describe ActivityNotification::Config do
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
+
|
|
35
|
+
describe "config.store_with_associated_records" do
|
|
36
|
+
let(:target) { create(:confirmed_user) }
|
|
37
|
+
|
|
38
|
+
context "false as default" do
|
|
39
|
+
before do
|
|
40
|
+
@notification = create(:notification, target: target)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "stores notification without associated records" do
|
|
44
|
+
expect(@notification.target).to eq(target)
|
|
45
|
+
expect { @notification.target_record }.to raise_error(NoMethodError)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context "when it is configured as true" do
|
|
50
|
+
if ActivityNotification.config.orm == :active_record
|
|
51
|
+
it "raises ActivityNotification::ConfigError when you use active_record ORM" do
|
|
52
|
+
expect { ActivityNotification.config.store_with_associated_records = true }.to raise_error(ActivityNotification::ConfigError)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
else
|
|
56
|
+
before do
|
|
57
|
+
ActivityNotification.config.store_with_associated_records = true
|
|
58
|
+
load Rails.root.join("../../lib/activity_notification/orm/#{ActivityNotification.config.orm}/notification.rb").to_s
|
|
59
|
+
@notification = create(:notification, target: target)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
after do
|
|
63
|
+
ActivityNotification.config.store_with_associated_records = false
|
|
64
|
+
load Rails.root.join("../../lib/activity_notification/orm/#{ActivityNotification.config.orm}/notification.rb").to_s
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "stores notification without associated records" do
|
|
68
|
+
expect(@notification.target).to eq(target)
|
|
69
|
+
expect(@notification.target_record).to eq(target.to_json)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
34
74
|
end
|
|
@@ -80,12 +80,16 @@ shared_examples_for :notification_controller do
|
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
it "returns json format" do
|
|
83
|
-
|
|
83
|
+
case ActivityNotification.config.orm
|
|
84
|
+
when :active_record
|
|
84
85
|
expect(JSON.parse(response.body).first)
|
|
85
86
|
.to include("target_id" => test_target.id, "target_type" => test_target.to_class_name)
|
|
86
|
-
|
|
87
|
+
when :mongoid
|
|
87
88
|
expect(JSON.parse(response.body).first)
|
|
88
89
|
.to include("target_id" => test_target.id.to_s, "target_type" => test_target.to_class_name)
|
|
90
|
+
when :dynamoid
|
|
91
|
+
expect(JSON.parse(response.body).first)
|
|
92
|
+
.to include("target_key" => "#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
|
89
93
|
end
|
|
90
94
|
end
|
|
91
95
|
end
|
|
@@ -221,7 +225,7 @@ shared_examples_for :notification_controller do
|
|
|
221
225
|
end
|
|
222
226
|
end
|
|
223
227
|
|
|
224
|
-
context 'with filtered_by_group_type and
|
|
228
|
+
context 'with filtered_by_group_type and filtered_by_group_id parameters' do
|
|
225
229
|
it "returns filtered notifications only" do
|
|
226
230
|
get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, filtered_by_group_type: 'Article', filtered_by_group_id: @group.id.to_s }), valid_session
|
|
227
231
|
expect(assigns(:notifications)[0]).to eq(@notification1)
|
|
@@ -93,12 +93,16 @@ shared_examples_for :subscription_controller do
|
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
it "returns json format" do
|
|
96
|
-
|
|
96
|
+
case ActivityNotification.config.orm
|
|
97
|
+
when :active_record
|
|
97
98
|
expect(JSON.parse(response.body)["subscriptions"].first)
|
|
98
99
|
.to include("target_id" => test_target.id, "target_type" => test_target.to_class_name)
|
|
99
|
-
|
|
100
|
+
when :mongoid
|
|
100
101
|
expect(JSON.parse(response.body)["subscriptions"].first)
|
|
101
102
|
.to include("target_id" => test_target.id.to_s, "target_type" => test_target.to_class_name)
|
|
103
|
+
when :dynamoid
|
|
104
|
+
expect(JSON.parse(response.body)["subscriptions"].first)
|
|
105
|
+
.to include("target_key" => "#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
|
102
106
|
end
|
|
103
107
|
expect(JSON.parse(response.body)["unconfigured_notification_keys"].first)
|
|
104
108
|
.to eq('test_notification_key')
|
|
@@ -227,7 +231,7 @@ shared_examples_for :subscription_controller do
|
|
|
227
231
|
|
|
228
232
|
describe "POST #create" do
|
|
229
233
|
before do
|
|
230
|
-
expect(test_target.subscriptions.size).to
|
|
234
|
+
expect(test_target.subscriptions.size).to eq(0)
|
|
231
235
|
end
|
|
232
236
|
|
|
233
237
|
context "http direct POST request without optional targets" do
|
|
@@ -46,12 +46,14 @@ describe ActivityNotification::ViewHelpers, type: :helper do
|
|
|
46
46
|
)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
it 'handles multiple notifications of records' do
|
|
50
|
+
rendered_template = render_notification notifications, fallback: :default
|
|
51
|
+
expect(rendered_template).to start_with(
|
|
52
|
+
render partial: 'activity_notification/notifications/default/default',
|
|
53
|
+
locals: { notification: notifications.to_a.first, parameters: {} })
|
|
54
|
+
expect(rendered_template).to end_with(
|
|
55
|
+
render partial: 'activity_notification/notifications/default/default',
|
|
56
|
+
locals: { notification: notifications.to_a.last , parameters: {} })
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
it 'handles multiple notifications of array' do
|
|
@@ -117,17 +119,17 @@ describe ActivityNotification::ViewHelpers, type: :helper do
|
|
|
117
119
|
end
|
|
118
120
|
|
|
119
121
|
context "with defined overriding_notification_template_key in notifiable model" do
|
|
120
|
-
it "renders
|
|
122
|
+
it "renders overridden custom notification view" do
|
|
121
123
|
notification.key = 'custom.test'
|
|
122
124
|
module AdditionalMethods
|
|
123
125
|
def overriding_notification_template_key(target, key)
|
|
124
|
-
'
|
|
126
|
+
'overridden.custom.test'
|
|
125
127
|
end
|
|
126
128
|
end
|
|
127
129
|
notification.notifiable.extend(AdditionalMethods)
|
|
128
|
-
# render activity_notification/notifications/users/
|
|
130
|
+
# render activity_notification/notifications/users/overridden/custom/test
|
|
129
131
|
expect(render_notification notification, target: :users)
|
|
130
|
-
.to eq("
|
|
132
|
+
.to eq("Overridden custom template root for user target: #{notification.id}")
|
|
131
133
|
end
|
|
132
134
|
end
|
|
133
135
|
end
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# To run as single test for debugging
|
|
2
|
+
# require Rails.root.join('../../spec/concerns/models/notifiable_spec.rb').to_s
|
|
3
|
+
# require Rails.root.join('../../spec/concerns/common_spec.rb').to_s
|
|
4
|
+
|
|
1
5
|
describe Dummy::DummyNotifiable, type: :model do
|
|
2
6
|
|
|
3
7
|
it_behaves_like :notifiable
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# To run as single test for debugging
|
|
2
|
+
# require Rails.root.join('../../spec/concerns/models/notifier_spec.rb').to_s
|
|
3
|
+
# require Rails.root.join('../../spec/concerns/common_spec.rb').to_s
|
|
4
|
+
|
|
1
5
|
describe Dummy::DummyNotifier, type: :model do
|
|
2
6
|
|
|
3
7
|
it_behaves_like :notifier
|
|
@@ -1,13 +1,30 @@
|
|
|
1
|
+
# To run as single test for debugging
|
|
2
|
+
# require Rails.root.join('../../spec/concerns/apis/notification_api_spec.rb').to_s
|
|
3
|
+
# require Rails.root.join('../../spec/concerns/renderable_spec.rb').to_s
|
|
4
|
+
|
|
1
5
|
describe ActivityNotification::Notification, type: :model do
|
|
2
6
|
|
|
3
7
|
it_behaves_like :notification_api
|
|
4
8
|
it_behaves_like :renderable
|
|
5
9
|
|
|
6
10
|
describe "with association" do
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
context "belongs to target" do
|
|
12
|
+
before do
|
|
13
|
+
@target = create(:confirmed_user)
|
|
14
|
+
@notification = create(:notification, target: @target)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "responds to target" do
|
|
18
|
+
expect(@notification.reload.target).to eq(@target)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "responds to target_id" do
|
|
22
|
+
expect(@notification.reload.target_id.to_s).to eq(@target.id.to_s)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "responds to target_type" do
|
|
26
|
+
expect(@notification.reload.target_type).to eq("User")
|
|
27
|
+
end
|
|
11
28
|
end
|
|
12
29
|
|
|
13
30
|
it "belongs to notifiable" do
|
|
@@ -42,18 +59,16 @@ describe ActivityNotification::Notification, type: :model do
|
|
|
42
59
|
end
|
|
43
60
|
|
|
44
61
|
describe "with serializable column" do
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
expect(notification.reload.parameters).to eq(parameters)
|
|
50
|
-
end
|
|
62
|
+
it "has parameters for hash with symbol" do
|
|
63
|
+
parameters = {a: 1, b: 2, c: 3}
|
|
64
|
+
notification = create(:notification, parameters: parameters)
|
|
65
|
+
expect(notification.reload.parameters.symbolize_keys).to eq(parameters)
|
|
51
66
|
end
|
|
52
67
|
|
|
53
68
|
it "has parameters for hash with string" do
|
|
54
69
|
parameters = {'a' => 1, 'b' => 2, 'c' => 3}
|
|
55
70
|
notification = create(:notification, parameters: parameters)
|
|
56
|
-
expect(notification.reload.parameters).to eq(parameters)
|
|
71
|
+
expect(notification.reload.parameters.stringify_keys).to eq(parameters)
|
|
57
72
|
end
|
|
58
73
|
end
|
|
59
74
|
|
|
@@ -67,19 +82,19 @@ describe ActivityNotification::Notification, type: :model do
|
|
|
67
82
|
it "is invalid with blank target" do
|
|
68
83
|
@notification.target = nil
|
|
69
84
|
expect(@notification).to be_invalid
|
|
70
|
-
expect(@notification.errors[:target]
|
|
85
|
+
expect(@notification.errors[:target]).not_to be_empty
|
|
71
86
|
end
|
|
72
87
|
|
|
73
88
|
it "is invalid with blank notifiable" do
|
|
74
89
|
@notification.notifiable = nil
|
|
75
90
|
expect(@notification).to be_invalid
|
|
76
|
-
expect(@notification.errors[:notifiable]
|
|
91
|
+
expect(@notification.errors[:notifiable]).not_to be_empty
|
|
77
92
|
end
|
|
78
93
|
|
|
79
94
|
it "is invalid with blank key" do
|
|
80
95
|
@notification.key = nil
|
|
81
96
|
expect(@notification).to be_invalid
|
|
82
|
-
expect(@notification.errors[:key]
|
|
97
|
+
expect(@notification.errors[:key]).not_to be_empty
|
|
83
98
|
end
|
|
84
99
|
end
|
|
85
100
|
|
|
@@ -99,34 +114,34 @@ describe ActivityNotification::Notification, type: :model do
|
|
|
99
114
|
expect(notifications.unopened_only.first).to eq(@unopened_group_owner)
|
|
100
115
|
expect(notifications.opened_only!.first).to eq(@opened_group_owner)
|
|
101
116
|
end
|
|
102
|
-
|
|
117
|
+
|
|
103
118
|
it "works with group_members_only scope" do
|
|
104
119
|
notifications = ActivityNotification::Notification.group_members_only
|
|
105
120
|
expect(notifications.to_a.size).to eq(2)
|
|
106
121
|
expect(notifications.unopened_only.first).to eq(@unopened_group_member)
|
|
107
122
|
expect(notifications.opened_only!.first).to eq(@opened_group_member)
|
|
108
123
|
end
|
|
109
|
-
|
|
124
|
+
|
|
110
125
|
it "works with unopened_only scope" do
|
|
111
126
|
notifications = ActivityNotification::Notification.unopened_only
|
|
112
127
|
expect(notifications.to_a.size).to eq(2)
|
|
113
128
|
expect(notifications.group_owners_only.first).to eq(@unopened_group_owner)
|
|
114
129
|
expect(notifications.group_members_only.first).to eq(@unopened_group_member)
|
|
115
130
|
end
|
|
116
|
-
|
|
131
|
+
|
|
117
132
|
it "works with unopened_index scope" do
|
|
118
133
|
notifications = ActivityNotification::Notification.unopened_index
|
|
119
134
|
expect(notifications.to_a.size).to eq(1)
|
|
120
135
|
expect(notifications.first).to eq(@unopened_group_owner)
|
|
121
136
|
end
|
|
122
|
-
|
|
137
|
+
|
|
123
138
|
it "works with opened_only! scope" do
|
|
124
139
|
notifications = ActivityNotification::Notification.opened_only!
|
|
125
140
|
expect(notifications.to_a.size).to eq(2)
|
|
126
141
|
expect(notifications.group_owners_only.first).to eq(@opened_group_owner)
|
|
127
142
|
expect(notifications.group_members_only.first).to eq(@opened_group_member)
|
|
128
143
|
end
|
|
129
|
-
|
|
144
|
+
|
|
130
145
|
context "with opened_only scope" do
|
|
131
146
|
it "works" do
|
|
132
147
|
notifications = ActivityNotification::Notification.opened_only(4)
|
|
@@ -134,39 +149,39 @@ describe ActivityNotification::Notification, type: :model do
|
|
|
134
149
|
expect(notifications.group_owners_only.first).to eq(@opened_group_owner)
|
|
135
150
|
expect(notifications.group_members_only.first).to eq(@opened_group_member)
|
|
136
151
|
end
|
|
137
|
-
|
|
152
|
+
|
|
138
153
|
it "works with limit" do
|
|
139
154
|
notifications = ActivityNotification::Notification.opened_only(1)
|
|
140
155
|
expect(notifications.to_a.size).to eq(1)
|
|
141
156
|
end
|
|
142
157
|
end
|
|
143
|
-
|
|
158
|
+
|
|
144
159
|
context "with opened_index scope" do
|
|
145
160
|
it "works" do
|
|
146
161
|
notifications = ActivityNotification::Notification.opened_index(4)
|
|
147
162
|
expect(notifications.to_a.size).to eq(1)
|
|
148
163
|
expect(notifications.first).to eq(@opened_group_owner)
|
|
149
164
|
end
|
|
150
|
-
|
|
165
|
+
|
|
151
166
|
it "works with limit" do
|
|
152
167
|
notifications = ActivityNotification::Notification.opened_index(0)
|
|
153
168
|
expect(notifications.to_a.size).to eq(0)
|
|
154
169
|
end
|
|
155
170
|
end
|
|
156
|
-
|
|
171
|
+
|
|
157
172
|
it "works with unopened_index_group_members_only scope" do
|
|
158
173
|
notifications = ActivityNotification::Notification.unopened_index_group_members_only
|
|
159
174
|
expect(notifications.to_a.size).to eq(1)
|
|
160
175
|
expect(notifications.first).to eq(@unopened_group_member)
|
|
161
176
|
end
|
|
162
|
-
|
|
177
|
+
|
|
163
178
|
context "with opened_index_group_members_only scope" do
|
|
164
179
|
it "works" do
|
|
165
180
|
notifications = ActivityNotification::Notification.opened_index_group_members_only(4)
|
|
166
181
|
expect(notifications.to_a.size).to eq(1)
|
|
167
182
|
expect(notifications.first).to eq(@opened_group_member)
|
|
168
183
|
end
|
|
169
|
-
|
|
184
|
+
|
|
170
185
|
it "works with limit" do
|
|
171
186
|
notifications = ActivityNotification::Notification.opened_index_group_members_only(0)
|
|
172
187
|
expect(notifications.to_a.size).to eq(0)
|
|
@@ -239,7 +254,7 @@ describe ActivityNotification::Notification, type: :model do
|
|
|
239
254
|
expect(notifications.first).to eq(@notification_2)
|
|
240
255
|
end
|
|
241
256
|
end
|
|
242
|
-
|
|
257
|
+
|
|
243
258
|
context 'with filtered_by_group options' do
|
|
244
259
|
it "works with filtered_by_options scope" do
|
|
245
260
|
notifications = ActivityNotification::Notification.filtered_by_options({ filtered_by_group: @group_1 })
|
|
@@ -276,18 +291,24 @@ describe ActivityNotification::Notification, type: :model do
|
|
|
276
291
|
|
|
277
292
|
context 'with custom_filter options' do
|
|
278
293
|
it "works with filtered_by_options scope" do
|
|
279
|
-
if ActivityNotification.config.orm == :active_record
|
|
280
|
-
notifications = ActivityNotification::Notification.filtered_by_options({ custom_filter: ["notifications.key = ?", @key_1] })
|
|
281
|
-
expect(notifications.to_a.size).to eq(1)
|
|
282
|
-
expect(notifications.first).to eq(@notification_1)
|
|
283
|
-
end
|
|
284
|
-
|
|
285
294
|
notifications = ActivityNotification::Notification.filtered_by_options({ custom_filter: { key: @key_2 } })
|
|
286
295
|
expect(notifications.to_a.size).to eq(1)
|
|
287
296
|
expect(notifications.first).to eq(@notification_2)
|
|
288
297
|
end
|
|
298
|
+
|
|
299
|
+
it "works with filtered_by_options scope with filter depending on ORM" do
|
|
300
|
+
options =
|
|
301
|
+
case ActivityNotification.config.orm
|
|
302
|
+
when :active_record then { custom_filter: ["notifications.key = ?", @key_1] }
|
|
303
|
+
when :mongoid then { custom_filter: { key: {'$eq': @key_1} } }
|
|
304
|
+
when :dynamoid then { custom_filter: {'key.begins_with': @key_1} }
|
|
305
|
+
end
|
|
306
|
+
notifications = ActivityNotification::Notification.filtered_by_options(options)
|
|
307
|
+
expect(notifications.to_a.size).to eq(1)
|
|
308
|
+
expect(notifications.first).to eq(@notification_1)
|
|
309
|
+
end
|
|
289
310
|
end
|
|
290
|
-
|
|
311
|
+
|
|
291
312
|
context 'with no options' do
|
|
292
313
|
it "works with filtered_by_options scope" do
|
|
293
314
|
notifications = ActivityNotification::Notification.filtered_by_options
|
|
@@ -300,37 +321,135 @@ describe ActivityNotification::Notification, type: :model do
|
|
|
300
321
|
context "to make order by created_at" do
|
|
301
322
|
before do
|
|
302
323
|
ActivityNotification::Notification.delete_all
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
324
|
+
@target = create(:confirmed_user)
|
|
325
|
+
unopened_group_owner = create(:notification, target: @target, group_owner: nil)
|
|
326
|
+
unopened_group_member = create(:notification, target: @target, group_owner: unopened_group_owner, created_at: unopened_group_owner.created_at + 10.second)
|
|
327
|
+
opened_group_owner = create(:notification, target: @target, group_owner: nil, opened_at: Time.current, created_at: unopened_group_owner.created_at + 20.second)
|
|
328
|
+
opened_group_member = create(:notification, target: @target, group_owner: opened_group_owner, opened_at: Time.current, created_at: unopened_group_owner.created_at + 30.second)
|
|
307
329
|
@earliest_notification = unopened_group_owner
|
|
308
330
|
@latest_notification = opened_group_member
|
|
309
331
|
end
|
|
310
332
|
|
|
311
|
-
|
|
312
|
-
|
|
333
|
+
unless ActivityNotification.config.orm == :dynamoid
|
|
334
|
+
context "using ORM other than dynamoid, you can directly call latest/earliest order method from class objects" do
|
|
335
|
+
|
|
336
|
+
it "works with latest_order scope" do
|
|
337
|
+
notifications = ActivityNotification::Notification.latest_order
|
|
338
|
+
expect(notifications.to_a.size).to eq(4)
|
|
339
|
+
expect(notifications.first).to eq(@latest_notification)
|
|
340
|
+
expect(notifications.last).to eq(@earliest_notification)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
it "works with earliest_order scope" do
|
|
344
|
+
notifications = ActivityNotification::Notification.earliest_order
|
|
345
|
+
expect(notifications.to_a.size).to eq(4)
|
|
346
|
+
expect(notifications.first).to eq(@earliest_notification)
|
|
347
|
+
expect(notifications.last).to eq(@latest_notification)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it "returns the latest notification with latest scope" do
|
|
351
|
+
notification = ActivityNotification::Notification.latest
|
|
352
|
+
expect(notification).to eq(@latest_notification)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it "returns the earliest notification with earliest scope" do
|
|
356
|
+
notification = ActivityNotification::Notification.earliest
|
|
357
|
+
expect(notification).to eq(@earliest_notification)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
end
|
|
361
|
+
else
|
|
362
|
+
context "using dynamoid, you can call latest/earliest order method only with query using partition key of Global Secondary Index" do
|
|
363
|
+
|
|
364
|
+
it "works with latest_order scope" do
|
|
365
|
+
notifications = ActivityNotification::Notification.filtered_by_target(@target).latest_order
|
|
366
|
+
expect(notifications.to_a.size).to eq(4)
|
|
367
|
+
expect(notifications.first).to eq(@latest_notification)
|
|
368
|
+
expect(notifications.last).to eq(@earliest_notification)
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
it "works with earliest_order scope" do
|
|
372
|
+
notifications = ActivityNotification::Notification.filtered_by_target(@target).earliest_order
|
|
373
|
+
expect(notifications.to_a.size).to eq(4)
|
|
374
|
+
expect(notifications.first).to eq(@earliest_notification)
|
|
375
|
+
expect(notifications.last).to eq(@latest_notification)
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it "returns the latest notification with latest scope" do
|
|
379
|
+
notification = ActivityNotification::Notification.filtered_by_target(@target).latest
|
|
380
|
+
expect(notification).to eq(@latest_notification)
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
it "returns the earliest notification with earliest scope" do
|
|
384
|
+
notification = ActivityNotification::Notification.filtered_by_target(@target).earliest
|
|
385
|
+
expect(notification).to eq(@earliest_notification)
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it "works with latest_order! scope" do
|
|
392
|
+
notifications = ActivityNotification::Notification.latest_order!
|
|
313
393
|
expect(notifications.to_a.size).to eq(4)
|
|
314
394
|
expect(notifications.first).to eq(@latest_notification)
|
|
315
395
|
expect(notifications.last).to eq(@earliest_notification)
|
|
316
396
|
end
|
|
317
397
|
|
|
318
|
-
it "works with
|
|
319
|
-
notifications = ActivityNotification::Notification.
|
|
398
|
+
it "works with latest_order!(reverse=true) scope" do
|
|
399
|
+
notifications = ActivityNotification::Notification.latest_order!(true)
|
|
400
|
+
expect(notifications.to_a.size).to eq(4)
|
|
401
|
+
expect(notifications.first).to eq(@earliest_notification)
|
|
402
|
+
expect(notifications.last).to eq(@latest_notification)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it "works with earliest_order! scope" do
|
|
406
|
+
notifications = ActivityNotification::Notification.earliest_order!
|
|
320
407
|
expect(notifications.to_a.size).to eq(4)
|
|
321
408
|
expect(notifications.first).to eq(@earliest_notification)
|
|
322
409
|
expect(notifications.last).to eq(@latest_notification)
|
|
323
410
|
end
|
|
324
411
|
|
|
325
|
-
it "returns the latest notification with latest scope" do
|
|
326
|
-
notification = ActivityNotification::Notification.latest
|
|
412
|
+
it "returns the latest notification with latest! scope" do
|
|
413
|
+
notification = ActivityNotification::Notification.latest!
|
|
327
414
|
expect(notification).to eq(@latest_notification)
|
|
328
415
|
end
|
|
329
416
|
|
|
330
|
-
it "returns the earliest notification with earliest scope" do
|
|
331
|
-
notification = ActivityNotification::Notification.earliest
|
|
417
|
+
it "returns the earliest notification with earliest! scope" do
|
|
418
|
+
notification = ActivityNotification::Notification.earliest!
|
|
332
419
|
expect(notification).to eq(@earliest_notification)
|
|
333
420
|
end
|
|
334
421
|
end
|
|
422
|
+
|
|
423
|
+
context "to include with associated records" do
|
|
424
|
+
before do
|
|
425
|
+
ActivityNotification::Notification.delete_all
|
|
426
|
+
create(:notification)
|
|
427
|
+
@notifications = ActivityNotification::Notification.filtered_by_key("default.default")
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
it "works with_target" do
|
|
431
|
+
expect(@notifications.with_target.count).to eq(1)
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
it "works with_notifiable" do
|
|
435
|
+
expect(@notifications.with_notifiable.count).to eq(1)
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
it "works with_group" do
|
|
439
|
+
expect(@notifications.with_group.count).to eq(1)
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
it "works with_group_owner" do
|
|
443
|
+
expect(@notifications.with_group_owner.count).to eq(1)
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
it "works with_group_members" do
|
|
447
|
+
expect(@notifications.with_group_members.count).to eq(1)
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
it "works with_notifier" do
|
|
451
|
+
expect(@notifications.with_notifier.count).to eq(1)
|
|
452
|
+
end
|
|
453
|
+
end
|
|
335
454
|
end
|
|
336
455
|
end
|