activity_notification 2.4.1 → 2.5.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 (250) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -2
  3. data/app/jobs/activity_notification/cascading_notification_job.rb +123 -0
  4. data/docs/Functions.md +197 -1
  5. data/lib/activity_notification/apis/cascading_notification_api.rb +208 -0
  6. data/lib/activity_notification/apis/notification_api.rb +3 -0
  7. data/lib/activity_notification/config.rb +10 -0
  8. data/lib/activity_notification/mailers/helpers.rb +27 -1
  9. data/lib/activity_notification/version.rb +1 -1
  10. data/lib/generators/templates/activity_notification.rb +8 -0
  11. metadata +5 -441
  12. data/.codeclimate.yml +0 -33
  13. data/.coveralls.yml +0 -1
  14. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -22
  15. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
  16. data/.github/pull_request_template.md +0 -13
  17. data/.github/workflows/build.yml +0 -100
  18. data/.gitignore +0 -74
  19. data/.rspec +0 -3
  20. data/.rubocop.yml +0 -1157
  21. data/.yardopts +0 -6
  22. data/CHANGELOG.md +0 -452
  23. data/Gemfile +0 -31
  24. data/Procfile +0 -2
  25. data/Rakefile +0 -28
  26. data/activity_notification.gemspec +0 -44
  27. data/ai-curated-specs/issues/172/design.md +0 -220
  28. data/ai-curated-specs/issues/172/tasks.md +0 -326
  29. data/ai-curated-specs/issues/188/design.md +0 -227
  30. data/ai-curated-specs/issues/188/requirements.md +0 -78
  31. data/ai-curated-specs/issues/188/tasks.md +0 -203
  32. data/ai-curated-specs/issues/188/upstream-contributions.md +0 -592
  33. data/ai-curated-specs/issues/50/design.md +0 -235
  34. data/ai-curated-specs/issues/50/requirements.md +0 -49
  35. data/ai-curated-specs/issues/50/tasks.md +0 -232
  36. data/bin/_dynamodblocal +0 -4
  37. data/bin/bundle_update.sh +0 -7
  38. data/bin/deploy_on_heroku.sh +0 -16
  39. data/bin/install_dynamodblocal.sh +0 -5
  40. data/bin/start_dynamodblocal.sh +0 -47
  41. data/bin/stop_dynamodblocal.sh +0 -34
  42. data/gemfiles/Gemfile.rails-5.0 +0 -25
  43. data/gemfiles/Gemfile.rails-5.1 +0 -25
  44. data/gemfiles/Gemfile.rails-5.2 +0 -24
  45. data/gemfiles/Gemfile.rails-6.0 +0 -23
  46. data/gemfiles/Gemfile.rails-6.1 +0 -22
  47. data/gemfiles/Gemfile.rails-7.0 +0 -25
  48. data/gemfiles/Gemfile.rails-7.1 +0 -23
  49. data/gemfiles/Gemfile.rails-7.2 +0 -23
  50. data/gemfiles/Gemfile.rails-8.0 +0 -24
  51. data/package.json +0 -8
  52. data/spec/channels/notification_api_channel_shared_examples.rb +0 -59
  53. data/spec/channels/notification_api_channel_spec.rb +0 -49
  54. data/spec/channels/notification_api_with_devise_channel_spec.rb +0 -76
  55. data/spec/channels/notification_channel_shared_examples.rb +0 -59
  56. data/spec/channels/notification_channel_spec.rb +0 -48
  57. data/spec/channels/notification_with_devise_channel_spec.rb +0 -97
  58. data/spec/concerns/apis/notification_api_spec.rb +0 -1627
  59. data/spec/concerns/apis/subscription_api_spec.rb +0 -474
  60. data/spec/concerns/common_spec.rb +0 -213
  61. data/spec/concerns/models/group_spec.rb +0 -61
  62. data/spec/concerns/models/notifiable_spec.rb +0 -782
  63. data/spec/concerns/models/notifier_spec.rb +0 -71
  64. data/spec/concerns/models/subscriber_spec.rb +0 -800
  65. data/spec/concerns/models/target_spec.rb +0 -1285
  66. data/spec/concerns/renderable_spec.rb +0 -129
  67. data/spec/config_spec.rb +0 -85
  68. data/spec/controllers/common_controller_spec.rb +0 -25
  69. data/spec/controllers/controller_spec_utility.rb +0 -100
  70. data/spec/controllers/dummy_common_controller.rb +0 -5
  71. data/spec/controllers/notifications_api_controller_shared_examples.rb +0 -619
  72. data/spec/controllers/notifications_api_controller_spec.rb +0 -19
  73. data/spec/controllers/notifications_api_with_devise_controller_spec.rb +0 -60
  74. data/spec/controllers/notifications_controller_shared_examples.rb +0 -743
  75. data/spec/controllers/notifications_controller_spec.rb +0 -11
  76. data/spec/controllers/notifications_with_devise_controller_spec.rb +0 -97
  77. data/spec/controllers/subscriptions_api_controller_shared_examples.rb +0 -750
  78. data/spec/controllers/subscriptions_api_controller_spec.rb +0 -19
  79. data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +0 -60
  80. data/spec/controllers/subscriptions_controller_shared_examples.rb +0 -946
  81. data/spec/controllers/subscriptions_controller_spec.rb +0 -11
  82. data/spec/controllers/subscriptions_with_devise_controller_spec.rb +0 -97
  83. data/spec/factories/admins.rb +0 -5
  84. data/spec/factories/articles.rb +0 -5
  85. data/spec/factories/comments.rb +0 -6
  86. data/spec/factories/dummy/dummy_group.rb +0 -4
  87. data/spec/factories/dummy/dummy_notifiable.rb +0 -4
  88. data/spec/factories/dummy/dummy_notifier.rb +0 -4
  89. data/spec/factories/dummy/dummy_subscriber.rb +0 -4
  90. data/spec/factories/dummy/dummy_target.rb +0 -4
  91. data/spec/factories/notifications.rb +0 -7
  92. data/spec/factories/subscriptions.rb +0 -8
  93. data/spec/factories/users.rb +0 -11
  94. data/spec/generators/controllers_generator_spec.rb +0 -85
  95. data/spec/generators/install_generator_spec.rb +0 -43
  96. data/spec/generators/migration/migration_generator_spec.rb +0 -80
  97. data/spec/generators/models_generator_spec.rb +0 -96
  98. data/spec/generators/views_generator_spec.rb +0 -195
  99. data/spec/helpers/polymorphic_helpers_spec.rb +0 -89
  100. data/spec/helpers/view_helpers_spec.rb +0 -547
  101. data/spec/jobs/notification_resilience_job_spec.rb +0 -167
  102. data/spec/jobs/notify_all_job_spec.rb +0 -23
  103. data/spec/jobs/notify_job_spec.rb +0 -23
  104. data/spec/jobs/notify_to_job_spec.rb +0 -23
  105. data/spec/mailers/mailer_spec.rb +0 -214
  106. data/spec/mailers/notification_resilience_spec.rb +0 -263
  107. data/spec/models/dummy/dummy_group_spec.rb +0 -10
  108. data/spec/models/dummy/dummy_notifiable_spec.rb +0 -10
  109. data/spec/models/dummy/dummy_notifier_spec.rb +0 -10
  110. data/spec/models/dummy/dummy_subscriber_spec.rb +0 -8
  111. data/spec/models/dummy/dummy_target_spec.rb +0 -10
  112. data/spec/models/notification_spec.rb +0 -472
  113. data/spec/models/subscription_spec.rb +0 -215
  114. data/spec/optional_targets/action_cable_api_channel_spec.rb +0 -34
  115. data/spec/optional_targets/action_cable_channel_spec.rb +0 -41
  116. data/spec/optional_targets/amazon_sns_spec.rb +0 -47
  117. data/spec/optional_targets/base_spec.rb +0 -45
  118. data/spec/optional_targets/slack_spec.rb +0 -44
  119. data/spec/orm/dynamoid_spec.rb +0 -115
  120. data/spec/rails_app/Rakefile +0 -15
  121. data/spec/rails_app/app/assets/config/manifest.js +0 -3
  122. data/spec/rails_app/app/assets/images/.keep +0 -0
  123. data/spec/rails_app/app/assets/javascripts/application.js +0 -3
  124. data/spec/rails_app/app/assets/javascripts/cable.js +0 -12
  125. data/spec/rails_app/app/assets/stylesheets/application.css +0 -15
  126. data/spec/rails_app/app/assets/stylesheets/reset.css +0 -85
  127. data/spec/rails_app/app/assets/stylesheets/style.css +0 -244
  128. data/spec/rails_app/app/controllers/admins_controller.rb +0 -21
  129. data/spec/rails_app/app/controllers/application_controller.rb +0 -5
  130. data/spec/rails_app/app/controllers/articles_controller.rb +0 -67
  131. data/spec/rails_app/app/controllers/comments_controller.rb +0 -36
  132. data/spec/rails_app/app/controllers/concerns/.keep +0 -0
  133. data/spec/rails_app/app/controllers/spa_controller.rb +0 -7
  134. data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -2
  135. data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -2
  136. data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -2
  137. data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -2
  138. data/spec/rails_app/app/controllers/users_controller.rb +0 -26
  139. data/spec/rails_app/app/helpers/application_helper.rb +0 -2
  140. data/spec/rails_app/app/helpers/devise_helper.rb +0 -2
  141. data/spec/rails_app/app/javascript/App.vue +0 -40
  142. data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +0 -82
  143. data/spec/rails_app/app/javascript/components/Top.vue +0 -98
  144. data/spec/rails_app/app/javascript/components/notifications/Index.vue +0 -200
  145. data/spec/rails_app/app/javascript/components/notifications/Notification.vue +0 -133
  146. data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +0 -122
  147. data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +0 -279
  148. data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +0 -112
  149. data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +0 -141
  150. data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +0 -226
  151. data/spec/rails_app/app/javascript/config/development.js +0 -5
  152. data/spec/rails_app/app/javascript/config/environment.js +0 -7
  153. data/spec/rails_app/app/javascript/config/production.js +0 -5
  154. data/spec/rails_app/app/javascript/config/test.js +0 -5
  155. data/spec/rails_app/app/javascript/packs/application.js +0 -18
  156. data/spec/rails_app/app/javascript/packs/spa.js +0 -14
  157. data/spec/rails_app/app/javascript/router/index.js +0 -73
  158. data/spec/rails_app/app/javascript/store/index.js +0 -37
  159. data/spec/rails_app/app/mailers/.keep +0 -0
  160. data/spec/rails_app/app/mailers/custom_notification_mailer.rb +0 -5
  161. data/spec/rails_app/app/models/admin.rb +0 -35
  162. data/spec/rails_app/app/models/article.rb +0 -54
  163. data/spec/rails_app/app/models/comment.rb +0 -81
  164. data/spec/rails_app/app/models/dummy/dummy_base.rb +0 -11
  165. data/spec/rails_app/app/models/dummy/dummy_group.rb +0 -23
  166. data/spec/rails_app/app/models/dummy/dummy_notifiable.rb +0 -15
  167. data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +0 -27
  168. data/spec/rails_app/app/models/dummy/dummy_notifier.rb +0 -15
  169. data/spec/rails_app/app/models/dummy/dummy_subscriber.rb +0 -14
  170. data/spec/rails_app/app/models/dummy/dummy_target.rb +0 -16
  171. data/spec/rails_app/app/models/user.rb +0 -73
  172. data/spec/rails_app/app/views/activity_notification/mailer/dummy_subscribers/test_key.text.erb +0 -1
  173. data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +0 -146
  174. data/spec/rails_app/app/views/activity_notification/notifications/default/custom/_path_test.html.erb +0 -1
  175. data/spec/rails_app/app/views/activity_notification/notifications/default/custom/_test.html.erb +0 -1
  176. data/spec/rails_app/app/views/activity_notification/notifications/users/_custom_index.html.erb +0 -1
  177. data/spec/rails_app/app/views/activity_notification/notifications/users/custom/_test.html.erb +0 -1
  178. data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +0 -1
  179. data/spec/rails_app/app/views/activity_notification/optional_targets/admins/amazon_sns/comment/_default.text.erb +0 -10
  180. data/spec/rails_app/app/views/articles/_form.html.erb +0 -24
  181. data/spec/rails_app/app/views/articles/edit.html.erb +0 -8
  182. data/spec/rails_app/app/views/articles/index.html.erb +0 -113
  183. data/spec/rails_app/app/views/articles/new.html.erb +0 -7
  184. data/spec/rails_app/app/views/articles/show.html.erb +0 -49
  185. data/spec/rails_app/app/views/layouts/_header.html.erb +0 -46
  186. data/spec/rails_app/app/views/layouts/application.html.erb +0 -15
  187. data/spec/rails_app/app/views/spa/index.html.erb +0 -2
  188. data/spec/rails_app/babel.config.js +0 -72
  189. data/spec/rails_app/bin/bundle +0 -3
  190. data/spec/rails_app/bin/rails +0 -4
  191. data/spec/rails_app/bin/rake +0 -4
  192. data/spec/rails_app/bin/setup +0 -29
  193. data/spec/rails_app/bin/webpack +0 -18
  194. data/spec/rails_app/bin/webpack-dev-server +0 -18
  195. data/spec/rails_app/config/application.rb +0 -54
  196. data/spec/rails_app/config/boot.rb +0 -5
  197. data/spec/rails_app/config/cable.yml +0 -8
  198. data/spec/rails_app/config/database.yml +0 -36
  199. data/spec/rails_app/config/dynamoid.rb +0 -13
  200. data/spec/rails_app/config/environment.rb +0 -26
  201. data/spec/rails_app/config/environments/development.rb +0 -60
  202. data/spec/rails_app/config/environments/production.rb +0 -85
  203. data/spec/rails_app/config/environments/test.rb +0 -53
  204. data/spec/rails_app/config/initializers/activity_notification.rb +0 -104
  205. data/spec/rails_app/config/initializers/assets.rb +0 -11
  206. data/spec/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  207. data/spec/rails_app/config/initializers/cookies_serializer.rb +0 -3
  208. data/spec/rails_app/config/initializers/copy_it.aws.rb.template +0 -6
  209. data/spec/rails_app/config/initializers/devise.rb +0 -278
  210. data/spec/rails_app/config/initializers/devise_token_auth.rb +0 -55
  211. data/spec/rails_app/config/initializers/filter_parameter_logging.rb +0 -4
  212. data/spec/rails_app/config/initializers/inflections.rb +0 -16
  213. data/spec/rails_app/config/initializers/mime_types.rb +0 -4
  214. data/spec/rails_app/config/initializers/mysql.rb +0 -9
  215. data/spec/rails_app/config/initializers/session_store.rb +0 -3
  216. data/spec/rails_app/config/initializers/wrap_parameters.rb +0 -14
  217. data/spec/rails_app/config/initializers/zeitwerk.rb +0 -10
  218. data/spec/rails_app/config/locales/activity_notification.en.yml +0 -26
  219. data/spec/rails_app/config/locales/devise.en.yml +0 -62
  220. data/spec/rails_app/config/mongoid.yml +0 -13
  221. data/spec/rails_app/config/routes.rb +0 -50
  222. data/spec/rails_app/config/secrets.yml +0 -22
  223. data/spec/rails_app/config/webpack/development.js +0 -5
  224. data/spec/rails_app/config/webpack/environment.js +0 -7
  225. data/spec/rails_app/config/webpack/loaders/vue.js +0 -6
  226. data/spec/rails_app/config/webpack/production.js +0 -5
  227. data/spec/rails_app/config/webpack/test.js +0 -5
  228. data/spec/rails_app/config/webpacker.yml +0 -97
  229. data/spec/rails_app/config.ru +0 -4
  230. data/spec/rails_app/db/migrate/20160716000000_create_test_tables.rb +0 -42
  231. data/spec/rails_app/db/migrate/20181209000000_create_activity_notification_tables.rb +0 -33
  232. data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +0 -10
  233. data/spec/rails_app/db/schema.rb +0 -98
  234. data/spec/rails_app/db/seeds.rb +0 -95
  235. data/spec/rails_app/lib/custom_optional_targets/console_output.rb +0 -16
  236. data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +0 -14
  237. data/spec/rails_app/lib/custom_optional_targets/wrong_target.rb +0 -13
  238. data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +0 -29
  239. data/spec/rails_app/package.json +0 -23
  240. data/spec/rails_app/postcss.config.js +0 -12
  241. data/spec/rails_app/public/404.html +0 -67
  242. data/spec/rails_app/public/422.html +0 -67
  243. data/spec/rails_app/public/500.html +0 -66
  244. data/spec/rails_app/public/favicon.ico +0 -0
  245. data/spec/roles/acts_as_group_spec.rb +0 -30
  246. data/spec/roles/acts_as_notifiable_spec.rb +0 -432
  247. data/spec/roles/acts_as_notifier_spec.rb +0 -30
  248. data/spec/roles/acts_as_target_spec.rb +0 -36
  249. data/spec/spec_helper.rb +0 -56
  250. data/spec/version_spec.rb +0 -31
@@ -1,263 +0,0 @@
1
- describe ActivityNotification::NotificationResilience do
2
- include ActiveJob::TestHelper
3
- let(:notification) { create(:notification) }
4
- let(:test_target) { notification.target }
5
- let(:notifications) { [create(:notification, target: test_target), create(:notification, target: test_target)] }
6
- let(:batch_key) { 'test_batch_key' }
7
-
8
- before do
9
- ActivityNotification::Mailer.deliveries.clear
10
- expect(ActivityNotification::Mailer.deliveries.size).to eq(0)
11
- end
12
-
13
- describe "ORM exception handling" do
14
- describe ".current_orm" do
15
- it "returns the configured ORM" do
16
- expect(ActivityNotification::NotificationResilience.current_orm).to eq(ActivityNotification.config.orm)
17
- end
18
- end
19
-
20
- describe ".record_not_found_exception_class" do
21
- context "with ActiveRecord ORM" do
22
- before { allow(ActivityNotification.config).to receive(:orm).and_return(:active_record) }
23
-
24
- it "returns ActiveRecord::RecordNotFound" do
25
- expect(ActivityNotification::NotificationResilience.record_not_found_exception_class).to eq(ActiveRecord::RecordNotFound)
26
- end
27
- end
28
-
29
- context "with Mongoid ORM" do
30
- before { allow(ActivityNotification.config).to receive(:orm).and_return(:mongoid) }
31
-
32
- it "returns Mongoid exception class if available" do
33
- if defined?(Mongoid::Errors::DocumentNotFound)
34
- expect(ActivityNotification::NotificationResilience.record_not_found_exception_class).to eq(Mongoid::Errors::DocumentNotFound)
35
- else
36
- expect(ActivityNotification::NotificationResilience.record_not_found_exception_class).to be_nil
37
- end
38
- end
39
- end
40
-
41
- context "with Dynamoid ORM" do
42
- before { allow(ActivityNotification.config).to receive(:orm).and_return(:dynamoid) }
43
-
44
- it "returns Dynamoid exception class if available" do
45
- if defined?(Dynamoid::Errors::RecordNotFound)
46
- expect(ActivityNotification::NotificationResilience.record_not_found_exception_class).to eq(Dynamoid::Errors::RecordNotFound)
47
- else
48
- expect(ActivityNotification::NotificationResilience.record_not_found_exception_class).to be_nil
49
- end
50
- end
51
- end
52
-
53
- context "with unavailable ORM exception class" do
54
- around do |example|
55
- # Temporarily modify the ORM_EXCEPTIONS constant
56
- original_exceptions = ActivityNotification::NotificationResilience::ORM_EXCEPTIONS
57
- ActivityNotification::NotificationResilience.send(:remove_const, :ORM_EXCEPTIONS)
58
- ActivityNotification::NotificationResilience.const_set(:ORM_EXCEPTIONS, {
59
- active_record: 'NonExistent::ExceptionClass',
60
- mongoid: 'Mongoid::Errors::DocumentNotFound',
61
- dynamoid: 'Dynamoid::Errors::RecordNotFound'
62
- })
63
-
64
- example.run
65
-
66
- # Restore original constant
67
- ActivityNotification::NotificationResilience.send(:remove_const, :ORM_EXCEPTIONS)
68
- ActivityNotification::NotificationResilience.const_set(:ORM_EXCEPTIONS, original_exceptions)
69
- end
70
-
71
- before { allow(ActivityNotification.config).to receive(:orm).and_return(:active_record) }
72
-
73
- it "returns nil when exception class is not available" do
74
- expect(ActivityNotification::NotificationResilience.record_not_found_exception_class).to be_nil
75
- end
76
- end
77
- end
78
-
79
- describe ".record_not_found_exception?" do
80
- it "returns true for ActiveRecord::RecordNotFound" do
81
- exception = ActiveRecord::RecordNotFound.new("Test error")
82
- expect(ActivityNotification::NotificationResilience.record_not_found_exception?(exception)).to be_truthy
83
- end
84
-
85
- it "returns false for other exceptions" do
86
- exception = StandardError.new("Test error")
87
- expect(ActivityNotification::NotificationResilience.record_not_found_exception?(exception)).to be_falsy
88
- end
89
-
90
- context "when exception class constantize raises NameError" do
91
- around do |example|
92
- # Temporarily modify the ORM_EXCEPTIONS constant
93
- original_exceptions = ActivityNotification::NotificationResilience::ORM_EXCEPTIONS
94
- ActivityNotification::NotificationResilience.send(:remove_const, :ORM_EXCEPTIONS)
95
- ActivityNotification::NotificationResilience.const_set(:ORM_EXCEPTIONS, {
96
- active_record: 'NonExistent::ExceptionClass1',
97
- mongoid: 'NonExistent::ExceptionClass2',
98
- dynamoid: 'NonExistent::ExceptionClass3'
99
- })
100
-
101
- example.run
102
-
103
- # Restore original constant
104
- ActivityNotification::NotificationResilience.send(:remove_const, :ORM_EXCEPTIONS)
105
- ActivityNotification::NotificationResilience.const_set(:ORM_EXCEPTIONS, original_exceptions)
106
- end
107
-
108
- it "returns false when all exception classes are unavailable" do
109
- exception = StandardError.new("Test error")
110
- # Should return false because all exception classes will raise NameError
111
- expect(ActivityNotification::NotificationResilience.record_not_found_exception?(exception)).to be_falsy
112
- end
113
- end
114
- end
115
- end
116
-
117
- describe "Resilient email sending" do
118
- describe "when notification is destroyed before email job executes" do
119
- let(:destroyed_notification) { create(:notification) }
120
-
121
- before do
122
- destroyed_notification_id = destroyed_notification.id
123
- destroyed_notification.destroy
124
-
125
- # Mock the notification to simulate the scenario where the job tries to access a destroyed notification
126
- allow(ActivityNotification::Notification).to receive(:find).with(destroyed_notification_id).and_raise(ActiveRecord::RecordNotFound)
127
- end
128
-
129
- context "with send_notification_email" do
130
- it "handles missing notification gracefully and logs warning" do
131
- expect(Rails.logger).to receive(:warn).with(/ActivityNotification: Notification.*not found for email delivery/)
132
-
133
- # Create a mock notification that will raise RecordNotFound when accessed
134
- mock_notification = double("notification")
135
- allow(mock_notification).to receive(:id).and_return(999)
136
- allow(mock_notification).to receive(:target).and_raise(ActiveRecord::RecordNotFound)
137
-
138
- result = nil
139
- expect {
140
- result = ActivityNotification::Mailer.send_notification_email(mock_notification).deliver_now
141
- }.not_to raise_error
142
-
143
- expect(result).to be_nil
144
- expect(ActivityNotification::Mailer.deliveries.size).to eq(0)
145
- end
146
- end
147
-
148
- context "with send_batch_notification_email" do
149
- it "handles missing notifications gracefully and logs warning" do
150
- expect(Rails.logger).to receive(:warn).with(/ActivityNotification: Notification.*not found for email delivery/)
151
-
152
- # Create mock notifications that will raise RecordNotFound when accessed
153
- mock_notifications = [double("notification")]
154
- allow(mock_notifications.first).to receive(:id).and_return(999)
155
- allow(mock_notifications.first).to receive(:key).and_return("test.key")
156
- allow(mock_notifications.first).to receive(:notifiable).and_raise(ActiveRecord::RecordNotFound)
157
-
158
- result = nil
159
- expect {
160
- result = ActivityNotification::Mailer.send_batch_notification_email(test_target, mock_notifications, batch_key).deliver_now
161
- }.not_to raise_error
162
-
163
- expect(result).to be_nil
164
- expect(ActivityNotification::Mailer.deliveries.size).to eq(0)
165
- end
166
- end
167
- end
168
-
169
- describe "when notification exists" do
170
- context "with send_notification_email" do
171
- it "sends email normally" do
172
- expect(Rails.logger).not_to receive(:warn)
173
-
174
- ActivityNotification::Mailer.send_notification_email(notification).deliver_now
175
-
176
- expect(ActivityNotification::Mailer.deliveries.size).to eq(1)
177
- expect(ActivityNotification::Mailer.deliveries.last.to[0]).to eq(notification.target.email)
178
- end
179
- end
180
-
181
- context "with send_batch_notification_email" do
182
- it "sends batch email normally" do
183
- expect(Rails.logger).not_to receive(:warn)
184
-
185
- ActivityNotification::Mailer.send_batch_notification_email(test_target, notifications, batch_key).deliver_now
186
-
187
- expect(ActivityNotification::Mailer.deliveries.size).to eq(1)
188
- expect(ActivityNotification::Mailer.deliveries.last.to[0]).to eq(test_target.email)
189
- end
190
- end
191
- end
192
- end
193
-
194
- describe "Class methods (when included in a class)" do
195
- let(:test_class) { Class.new { include ActivityNotification::NotificationResilience } }
196
-
197
- describe "class method exception handling with NameError" do
198
- around do |example|
199
- # Temporarily modify the ORM_EXCEPTIONS constant
200
- original_exceptions = ActivityNotification::NotificationResilience::ORM_EXCEPTIONS
201
- ActivityNotification::NotificationResilience.send(:remove_const, :ORM_EXCEPTIONS)
202
- ActivityNotification::NotificationResilience.const_set(:ORM_EXCEPTIONS, {
203
- active_record: 'NonExistent::ClassMethodException',
204
- mongoid: 'Mongoid::Errors::DocumentNotFound',
205
- dynamoid: 'Dynamoid::Errors::RecordNotFound'
206
- })
207
-
208
- example.run
209
-
210
- # Restore original constant
211
- ActivityNotification::NotificationResilience.send(:remove_const, :ORM_EXCEPTIONS)
212
- ActivityNotification::NotificationResilience.const_set(:ORM_EXCEPTIONS, original_exceptions)
213
- end
214
-
215
- before { allow(ActivityNotification.config).to receive(:orm).and_return(:active_record) }
216
-
217
- it "returns nil when exception class is not available (class method)" do
218
- expect(test_class.record_not_found_exception_class).to be_nil
219
- end
220
-
221
- it "returns false when exception class constantize raises NameError (class method)" do
222
- exception = StandardError.new("Test error")
223
- expect(test_class.record_not_found_exception?(exception)).to be_falsy
224
- end
225
- end
226
- end
227
-
228
- describe "Logging behavior" do
229
- let(:mock_notification) { double("notification", id: 123) }
230
- let(:resilience_instance) { Class.new { include ActivityNotification::NotificationResilience }.new }
231
-
232
- it "logs appropriate warning message with notification ID" do
233
- exception = ActiveRecord::RecordNotFound.new("Test error")
234
-
235
- expect(Rails.logger).to receive(:warn).with(
236
- /ActivityNotification: Notification with id 123 not found for email delivery.*likely destroyed before job execution/
237
- )
238
-
239
- resilience_instance.send(:log_missing_notification, 123, exception)
240
- end
241
-
242
- it "logs warning message with context information" do
243
- exception = ActiveRecord::RecordNotFound.new("Test error")
244
- context = { target: "User", key: "comment.create" }
245
-
246
- expect(Rails.logger).to receive(:warn).with(
247
- /ActivityNotification: Notification with id 123 not found for email delivery.*target: User, key: comment\.create/
248
- )
249
-
250
- resilience_instance.send(:log_missing_notification, 123, exception, context)
251
- end
252
-
253
- it "logs warning message without ID when not provided" do
254
- exception = ActiveRecord::RecordNotFound.new("Test error")
255
-
256
- expect(Rails.logger).to receive(:warn).with(
257
- /ActivityNotification: Notification not found for email delivery.*likely destroyed before job execution/
258
- )
259
-
260
- resilience_instance.send(:log_missing_notification, nil, exception)
261
- end
262
- end
263
- end
@@ -1,10 +0,0 @@
1
- # To run as single test for debugging
2
- # require Rails.root.join('../../spec/concerns/models/group_spec.rb').to_s
3
- # require Rails.root.join('../../spec/concerns/common_spec.rb').to_s
4
-
5
- describe Dummy::DummyGroup, type: :model do
6
-
7
- it_behaves_like :group
8
- it_behaves_like :common
9
-
10
- end
@@ -1,10 +0,0 @@
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
-
5
- describe Dummy::DummyNotifiable, type: :model do
6
-
7
- it_behaves_like :notifiable
8
- it_behaves_like :common
9
-
10
- end
@@ -1,10 +0,0 @@
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
-
5
- describe Dummy::DummyNotifier, type: :model do
6
-
7
- it_behaves_like :notifier
8
- it_behaves_like :common
9
-
10
- end
@@ -1,8 +0,0 @@
1
- # To run as single test for debugging
2
- # require Rails.root.join('../../spec/concerns/models/subscriber_spec.rb').to_s
3
-
4
- describe Dummy::DummySubscriber, type: :model do
5
-
6
- it_behaves_like :subscriber
7
-
8
- end
@@ -1,10 +0,0 @@
1
- # To run as single test for debugging
2
- # require Rails.root.join('../../spec/concerns/models/target_spec.rb').to_s
3
- # require Rails.root.join('../../spec/concerns/common_spec.rb').to_s
4
-
5
- describe Dummy::DummyTarget, type: :model do
6
-
7
- it_behaves_like :target
8
- it_behaves_like :common
9
-
10
- end