activity_notification 2.4.0 → 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 (253) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -29
  3. data/app/jobs/activity_notification/cascading_notification_job.rb +123 -0
  4. data/docs/Functions.md +202 -12
  5. data/docs/Setup.md +34 -2
  6. data/docs/Testing.md +12 -1
  7. data/lib/activity_notification/apis/cascading_notification_api.rb +208 -0
  8. data/lib/activity_notification/apis/notification_api.rb +3 -0
  9. data/lib/activity_notification/config.rb +10 -0
  10. data/lib/activity_notification/mailers/helpers.rb +27 -1
  11. data/lib/activity_notification/models/concerns/swagger/subscription_schema.rb +1 -1
  12. data/lib/activity_notification/version.rb +1 -1
  13. data/lib/generators/templates/activity_notification.rb +8 -0
  14. metadata +45 -481
  15. data/.codeclimate.yml +0 -33
  16. data/.coveralls.yml +0 -1
  17. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -22
  18. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
  19. data/.github/pull_request_template.md +0 -13
  20. data/.github/workflows/build.yml +0 -101
  21. data/.gitignore +0 -74
  22. data/.rspec +0 -3
  23. data/.rubocop.yml +0 -1157
  24. data/.yardopts +0 -6
  25. data/CHANGELOG.md +0 -439
  26. data/Gemfile +0 -31
  27. data/Procfile +0 -2
  28. data/Rakefile +0 -28
  29. data/activity_notification.gemspec +0 -44
  30. data/ai-curated-specs/issues/172/design.md +0 -220
  31. data/ai-curated-specs/issues/172/tasks.md +0 -326
  32. data/ai-curated-specs/issues/188/design.md +0 -227
  33. data/ai-curated-specs/issues/188/requirements.md +0 -78
  34. data/ai-curated-specs/issues/188/tasks.md +0 -203
  35. data/ai-curated-specs/issues/188/upstream-contributions.md +0 -592
  36. data/ai-curated-specs/issues/50/design.md +0 -235
  37. data/ai-curated-specs/issues/50/requirements.md +0 -49
  38. data/ai-curated-specs/issues/50/tasks.md +0 -232
  39. data/bin/_dynamodblocal +0 -4
  40. data/bin/bundle_update.sh +0 -7
  41. data/bin/deploy_on_heroku.sh +0 -16
  42. data/bin/install_dynamodblocal.sh +0 -5
  43. data/bin/start_dynamodblocal.sh +0 -47
  44. data/bin/stop_dynamodblocal.sh +0 -34
  45. data/gemfiles/Gemfile.rails-5.0 +0 -25
  46. data/gemfiles/Gemfile.rails-5.1 +0 -25
  47. data/gemfiles/Gemfile.rails-5.2 +0 -24
  48. data/gemfiles/Gemfile.rails-6.0 +0 -23
  49. data/gemfiles/Gemfile.rails-6.1 +0 -22
  50. data/gemfiles/Gemfile.rails-7.0 +0 -25
  51. data/gemfiles/Gemfile.rails-7.1 +0 -23
  52. data/gemfiles/Gemfile.rails-7.2 +0 -23
  53. data/gemfiles/Gemfile.rails-8.0 +0 -24
  54. data/package.json +0 -8
  55. data/spec/channels/notification_api_channel_shared_examples.rb +0 -59
  56. data/spec/channels/notification_api_channel_spec.rb +0 -49
  57. data/spec/channels/notification_api_with_devise_channel_spec.rb +0 -76
  58. data/spec/channels/notification_channel_shared_examples.rb +0 -59
  59. data/spec/channels/notification_channel_spec.rb +0 -48
  60. data/spec/channels/notification_with_devise_channel_spec.rb +0 -97
  61. data/spec/concerns/apis/notification_api_spec.rb +0 -1627
  62. data/spec/concerns/apis/subscription_api_spec.rb +0 -474
  63. data/spec/concerns/common_spec.rb +0 -213
  64. data/spec/concerns/models/group_spec.rb +0 -61
  65. data/spec/concerns/models/notifiable_spec.rb +0 -782
  66. data/spec/concerns/models/notifier_spec.rb +0 -71
  67. data/spec/concerns/models/subscriber_spec.rb +0 -800
  68. data/spec/concerns/models/target_spec.rb +0 -1285
  69. data/spec/concerns/renderable_spec.rb +0 -129
  70. data/spec/config_spec.rb +0 -85
  71. data/spec/controllers/common_controller_spec.rb +0 -25
  72. data/spec/controllers/controller_spec_utility.rb +0 -100
  73. data/spec/controllers/dummy_common_controller.rb +0 -5
  74. data/spec/controllers/notifications_api_controller_shared_examples.rb +0 -619
  75. data/spec/controllers/notifications_api_controller_spec.rb +0 -19
  76. data/spec/controllers/notifications_api_with_devise_controller_spec.rb +0 -60
  77. data/spec/controllers/notifications_controller_shared_examples.rb +0 -743
  78. data/spec/controllers/notifications_controller_spec.rb +0 -11
  79. data/spec/controllers/notifications_with_devise_controller_spec.rb +0 -97
  80. data/spec/controllers/subscriptions_api_controller_shared_examples.rb +0 -750
  81. data/spec/controllers/subscriptions_api_controller_spec.rb +0 -19
  82. data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +0 -60
  83. data/spec/controllers/subscriptions_controller_shared_examples.rb +0 -946
  84. data/spec/controllers/subscriptions_controller_spec.rb +0 -11
  85. data/spec/controllers/subscriptions_with_devise_controller_spec.rb +0 -97
  86. data/spec/factories/admins.rb +0 -5
  87. data/spec/factories/articles.rb +0 -5
  88. data/spec/factories/comments.rb +0 -6
  89. data/spec/factories/dummy/dummy_group.rb +0 -4
  90. data/spec/factories/dummy/dummy_notifiable.rb +0 -4
  91. data/spec/factories/dummy/dummy_notifier.rb +0 -4
  92. data/spec/factories/dummy/dummy_subscriber.rb +0 -4
  93. data/spec/factories/dummy/dummy_target.rb +0 -4
  94. data/spec/factories/notifications.rb +0 -7
  95. data/spec/factories/subscriptions.rb +0 -8
  96. data/spec/factories/users.rb +0 -11
  97. data/spec/generators/controllers_generator_spec.rb +0 -85
  98. data/spec/generators/install_generator_spec.rb +0 -43
  99. data/spec/generators/migration/migration_generator_spec.rb +0 -66
  100. data/spec/generators/models_generator_spec.rb +0 -96
  101. data/spec/generators/views_generator_spec.rb +0 -195
  102. data/spec/helpers/polymorphic_helpers_spec.rb +0 -89
  103. data/spec/helpers/view_helpers_spec.rb +0 -547
  104. data/spec/jobs/notification_resilience_job_spec.rb +0 -167
  105. data/spec/jobs/notify_all_job_spec.rb +0 -23
  106. data/spec/jobs/notify_job_spec.rb +0 -23
  107. data/spec/jobs/notify_to_job_spec.rb +0 -23
  108. data/spec/mailers/mailer_spec.rb +0 -214
  109. data/spec/mailers/notification_resilience_spec.rb +0 -263
  110. data/spec/models/dummy/dummy_group_spec.rb +0 -10
  111. data/spec/models/dummy/dummy_notifiable_spec.rb +0 -10
  112. data/spec/models/dummy/dummy_notifier_spec.rb +0 -10
  113. data/spec/models/dummy/dummy_subscriber_spec.rb +0 -8
  114. data/spec/models/dummy/dummy_target_spec.rb +0 -10
  115. data/spec/models/notification_spec.rb +0 -472
  116. data/spec/models/subscription_spec.rb +0 -215
  117. data/spec/optional_targets/action_cable_api_channel_spec.rb +0 -34
  118. data/spec/optional_targets/action_cable_channel_spec.rb +0 -41
  119. data/spec/optional_targets/amazon_sns_spec.rb +0 -47
  120. data/spec/optional_targets/base_spec.rb +0 -45
  121. data/spec/optional_targets/slack_spec.rb +0 -44
  122. data/spec/orm/dynamoid_spec.rb +0 -115
  123. data/spec/rails_app/Rakefile +0 -15
  124. data/spec/rails_app/app/assets/config/manifest.js +0 -3
  125. data/spec/rails_app/app/assets/images/.keep +0 -0
  126. data/spec/rails_app/app/assets/javascripts/application.js +0 -3
  127. data/spec/rails_app/app/assets/javascripts/cable.js +0 -12
  128. data/spec/rails_app/app/assets/stylesheets/application.css +0 -15
  129. data/spec/rails_app/app/assets/stylesheets/reset.css +0 -85
  130. data/spec/rails_app/app/assets/stylesheets/style.css +0 -244
  131. data/spec/rails_app/app/controllers/admins_controller.rb +0 -21
  132. data/spec/rails_app/app/controllers/application_controller.rb +0 -5
  133. data/spec/rails_app/app/controllers/articles_controller.rb +0 -67
  134. data/spec/rails_app/app/controllers/comments_controller.rb +0 -36
  135. data/spec/rails_app/app/controllers/concerns/.keep +0 -0
  136. data/spec/rails_app/app/controllers/spa_controller.rb +0 -7
  137. data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -2
  138. data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -2
  139. data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -2
  140. data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -2
  141. data/spec/rails_app/app/controllers/users_controller.rb +0 -26
  142. data/spec/rails_app/app/helpers/application_helper.rb +0 -2
  143. data/spec/rails_app/app/helpers/devise_helper.rb +0 -2
  144. data/spec/rails_app/app/javascript/App.vue +0 -40
  145. data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +0 -82
  146. data/spec/rails_app/app/javascript/components/Top.vue +0 -98
  147. data/spec/rails_app/app/javascript/components/notifications/Index.vue +0 -200
  148. data/spec/rails_app/app/javascript/components/notifications/Notification.vue +0 -133
  149. data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +0 -122
  150. data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +0 -279
  151. data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +0 -112
  152. data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +0 -141
  153. data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +0 -226
  154. data/spec/rails_app/app/javascript/config/development.js +0 -5
  155. data/spec/rails_app/app/javascript/config/environment.js +0 -7
  156. data/spec/rails_app/app/javascript/config/production.js +0 -5
  157. data/spec/rails_app/app/javascript/config/test.js +0 -5
  158. data/spec/rails_app/app/javascript/packs/application.js +0 -18
  159. data/spec/rails_app/app/javascript/packs/spa.js +0 -14
  160. data/spec/rails_app/app/javascript/router/index.js +0 -73
  161. data/spec/rails_app/app/javascript/store/index.js +0 -37
  162. data/spec/rails_app/app/mailers/.keep +0 -0
  163. data/spec/rails_app/app/mailers/custom_notification_mailer.rb +0 -5
  164. data/spec/rails_app/app/models/admin.rb +0 -35
  165. data/spec/rails_app/app/models/article.rb +0 -54
  166. data/spec/rails_app/app/models/comment.rb +0 -81
  167. data/spec/rails_app/app/models/dummy/dummy_base.rb +0 -11
  168. data/spec/rails_app/app/models/dummy/dummy_group.rb +0 -23
  169. data/spec/rails_app/app/models/dummy/dummy_notifiable.rb +0 -15
  170. data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +0 -27
  171. data/spec/rails_app/app/models/dummy/dummy_notifier.rb +0 -15
  172. data/spec/rails_app/app/models/dummy/dummy_subscriber.rb +0 -14
  173. data/spec/rails_app/app/models/dummy/dummy_target.rb +0 -16
  174. data/spec/rails_app/app/models/user.rb +0 -73
  175. data/spec/rails_app/app/views/activity_notification/mailer/dummy_subscribers/test_key.text.erb +0 -1
  176. data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +0 -146
  177. data/spec/rails_app/app/views/activity_notification/notifications/default/custom/_path_test.html.erb +0 -1
  178. data/spec/rails_app/app/views/activity_notification/notifications/default/custom/_test.html.erb +0 -1
  179. data/spec/rails_app/app/views/activity_notification/notifications/users/_custom_index.html.erb +0 -1
  180. data/spec/rails_app/app/views/activity_notification/notifications/users/custom/_test.html.erb +0 -1
  181. data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +0 -1
  182. data/spec/rails_app/app/views/activity_notification/optional_targets/admins/amazon_sns/comment/_default.text.erb +0 -10
  183. data/spec/rails_app/app/views/articles/_form.html.erb +0 -24
  184. data/spec/rails_app/app/views/articles/edit.html.erb +0 -8
  185. data/spec/rails_app/app/views/articles/index.html.erb +0 -113
  186. data/spec/rails_app/app/views/articles/new.html.erb +0 -7
  187. data/spec/rails_app/app/views/articles/show.html.erb +0 -49
  188. data/spec/rails_app/app/views/layouts/_header.html.erb +0 -46
  189. data/spec/rails_app/app/views/layouts/application.html.erb +0 -15
  190. data/spec/rails_app/app/views/spa/index.html.erb +0 -2
  191. data/spec/rails_app/babel.config.js +0 -72
  192. data/spec/rails_app/bin/bundle +0 -3
  193. data/spec/rails_app/bin/rails +0 -4
  194. data/spec/rails_app/bin/rake +0 -4
  195. data/spec/rails_app/bin/setup +0 -29
  196. data/spec/rails_app/bin/webpack +0 -18
  197. data/spec/rails_app/bin/webpack-dev-server +0 -18
  198. data/spec/rails_app/config/application.rb +0 -54
  199. data/spec/rails_app/config/boot.rb +0 -5
  200. data/spec/rails_app/config/cable.yml +0 -8
  201. data/spec/rails_app/config/database.yml +0 -36
  202. data/spec/rails_app/config/dynamoid.rb +0 -13
  203. data/spec/rails_app/config/environment.rb +0 -26
  204. data/spec/rails_app/config/environments/development.rb +0 -60
  205. data/spec/rails_app/config/environments/production.rb +0 -85
  206. data/spec/rails_app/config/environments/test.rb +0 -53
  207. data/spec/rails_app/config/initializers/activity_notification.rb +0 -104
  208. data/spec/rails_app/config/initializers/assets.rb +0 -11
  209. data/spec/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  210. data/spec/rails_app/config/initializers/cookies_serializer.rb +0 -3
  211. data/spec/rails_app/config/initializers/copy_it.aws.rb.template +0 -6
  212. data/spec/rails_app/config/initializers/devise.rb +0 -278
  213. data/spec/rails_app/config/initializers/devise_token_auth.rb +0 -55
  214. data/spec/rails_app/config/initializers/filter_parameter_logging.rb +0 -4
  215. data/spec/rails_app/config/initializers/inflections.rb +0 -16
  216. data/spec/rails_app/config/initializers/mime_types.rb +0 -4
  217. data/spec/rails_app/config/initializers/mysql.rb +0 -9
  218. data/spec/rails_app/config/initializers/session_store.rb +0 -3
  219. data/spec/rails_app/config/initializers/wrap_parameters.rb +0 -14
  220. data/spec/rails_app/config/initializers/zeitwerk.rb +0 -10
  221. data/spec/rails_app/config/locales/activity_notification.en.yml +0 -26
  222. data/spec/rails_app/config/locales/devise.en.yml +0 -62
  223. data/spec/rails_app/config/mongoid.yml +0 -13
  224. data/spec/rails_app/config/routes.rb +0 -50
  225. data/spec/rails_app/config/secrets.yml +0 -22
  226. data/spec/rails_app/config/webpack/development.js +0 -5
  227. data/spec/rails_app/config/webpack/environment.js +0 -7
  228. data/spec/rails_app/config/webpack/loaders/vue.js +0 -6
  229. data/spec/rails_app/config/webpack/production.js +0 -5
  230. data/spec/rails_app/config/webpack/test.js +0 -5
  231. data/spec/rails_app/config/webpacker.yml +0 -97
  232. data/spec/rails_app/config.ru +0 -4
  233. data/spec/rails_app/db/migrate/20160716000000_create_test_tables.rb +0 -42
  234. data/spec/rails_app/db/migrate/20181209000000_create_activity_notification_tables.rb +0 -33
  235. data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +0 -10
  236. data/spec/rails_app/db/schema.rb +0 -98
  237. data/spec/rails_app/db/seeds.rb +0 -95
  238. data/spec/rails_app/lib/custom_optional_targets/console_output.rb +0 -16
  239. data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +0 -14
  240. data/spec/rails_app/lib/custom_optional_targets/wrong_target.rb +0 -13
  241. data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +0 -29
  242. data/spec/rails_app/package.json +0 -23
  243. data/spec/rails_app/postcss.config.js +0 -12
  244. data/spec/rails_app/public/404.html +0 -67
  245. data/spec/rails_app/public/422.html +0 -67
  246. data/spec/rails_app/public/500.html +0 -66
  247. data/spec/rails_app/public/favicon.ico +0 -0
  248. data/spec/roles/acts_as_group_spec.rb +0 -30
  249. data/spec/roles/acts_as_notifiable_spec.rb +0 -432
  250. data/spec/roles/acts_as_notifier_spec.rb +0 -30
  251. data/spec/roles/acts_as_target_spec.rb +0 -36
  252. data/spec/spec_helper.rb +0 -56
  253. 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