activity_notification 2.0.0 → 2.1.4

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +22 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  4. data/.github/pull_request_template.md +13 -0
  5. data/.gitignore +10 -3
  6. data/.travis.yml +6 -5
  7. data/CHANGELOG.md +60 -0
  8. data/Gemfile +8 -3
  9. data/Procfile +1 -1
  10. data/README.md +153 -1510
  11. data/activity_notification.gemspec +4 -1
  12. data/app/channels/activity_notification/notification_api_channel.rb +12 -0
  13. data/app/channels/activity_notification/notification_api_with_devise_channel.rb +46 -0
  14. data/app/channels/activity_notification/notification_channel.rb +2 -2
  15. data/app/channels/activity_notification/notification_with_devise_channel.rb +2 -2
  16. data/app/controllers/activity_notification/apidocs_controller.rb +75 -0
  17. data/app/controllers/activity_notification/notifications_api_controller.rb +143 -0
  18. data/app/controllers/activity_notification/notifications_api_with_devise_controller.rb +7 -0
  19. data/app/controllers/activity_notification/notifications_controller.rb +79 -53
  20. data/app/controllers/activity_notification/subscriptions_api_controller.rb +197 -0
  21. data/app/controllers/activity_notification/subscriptions_api_with_devise_controller.rb +7 -0
  22. data/app/controllers/activity_notification/subscriptions_controller.rb +78 -69
  23. data/app/views/activity_notification/notifications/default/_default.html.erb +18 -18
  24. data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +14 -14
  25. data/app/views/activity_notification/notifications/default/index.html.erb +6 -6
  26. data/app/views/activity_notification/optional_targets/default/action_cable_channel/_default.html.erb +176 -0
  27. data/app/views/activity_notification/subscriptions/default/_form.html.erb +1 -1
  28. data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +3 -31
  29. data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +7 -7
  30. data/app/views/activity_notification/subscriptions/default/index.html.erb +11 -7
  31. data/bin/deploy_on_heroku.sh +3 -1
  32. data/docs/CODE_OF_CONDUCT.md +76 -0
  33. data/docs/CONTRIBUTING.md +36 -0
  34. data/docs/Functions.md +1130 -0
  35. data/docs/Setup.md +801 -0
  36. data/docs/Testing.md +148 -0
  37. data/gemfiles/Gemfile.rails-4.2 +5 -1
  38. data/gemfiles/Gemfile.rails-5.0 +6 -1
  39. data/gemfiles/Gemfile.rails-5.1 +6 -1
  40. data/gemfiles/Gemfile.rails-5.2 +6 -1
  41. data/gemfiles/{Gemfile.rails-6.0.rc → Gemfile.rails-6.0} +6 -5
  42. data/lib/activity_notification.rb +13 -0
  43. data/lib/activity_notification/apis/notification_api.rb +37 -93
  44. data/lib/activity_notification/apis/subscription_api.rb +20 -8
  45. data/lib/activity_notification/apis/swagger.rb +6 -0
  46. data/lib/activity_notification/common.rb +4 -1
  47. data/lib/activity_notification/config.rb +41 -21
  48. data/lib/activity_notification/controllers/common_api_controller.rb +30 -0
  49. data/lib/activity_notification/controllers/common_controller.rb +45 -21
  50. data/lib/activity_notification/controllers/concerns/swagger/error_responses.rb +55 -0
  51. data/lib/activity_notification/controllers/concerns/swagger/notifications_api.rb +273 -0
  52. data/lib/activity_notification/controllers/concerns/swagger/notifications_parameters.rb +92 -0
  53. data/lib/activity_notification/controllers/concerns/swagger/subscriptions_api.rb +405 -0
  54. data/lib/activity_notification/controllers/concerns/swagger/subscriptions_parameters.rb +50 -0
  55. data/lib/activity_notification/controllers/devise_authentication_controller.rb +7 -6
  56. data/lib/activity_notification/gem_version.rb +14 -0
  57. data/lib/activity_notification/helpers/errors.rb +2 -0
  58. data/lib/activity_notification/helpers/view_helpers.rb +4 -0
  59. data/lib/activity_notification/mailers/helpers.rb +17 -10
  60. data/lib/activity_notification/models/concerns/notifiable.rb +31 -15
  61. data/lib/activity_notification/models/concerns/subscriber.rb +12 -1
  62. data/lib/activity_notification/models/concerns/swagger/error_schema.rb +36 -0
  63. data/lib/activity_notification/models/concerns/swagger/notification_schema.rb +209 -0
  64. data/lib/activity_notification/models/concerns/swagger/subscription_schema.rb +162 -0
  65. data/lib/activity_notification/models/concerns/target.rb +36 -10
  66. data/lib/activity_notification/models/notification.rb +1 -0
  67. data/lib/activity_notification/models/subscription.rb +1 -0
  68. data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +69 -0
  69. data/lib/activity_notification/optional_targets/action_cable_channel.rb +68 -0
  70. data/lib/activity_notification/optional_targets/base.rb +7 -13
  71. data/lib/activity_notification/orm/active_record/notification.rb +17 -1
  72. data/lib/activity_notification/orm/active_record/subscription.rb +1 -1
  73. data/lib/activity_notification/orm/dynamoid.rb +38 -3
  74. data/lib/activity_notification/orm/dynamoid/extension.rb +79 -1
  75. data/lib/activity_notification/orm/dynamoid/notification.rb +49 -14
  76. data/lib/activity_notification/orm/dynamoid/subscription.rb +2 -2
  77. data/lib/activity_notification/orm/mongoid.rb +32 -3
  78. data/lib/activity_notification/orm/mongoid/notification.rb +24 -6
  79. data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
  80. data/lib/activity_notification/rails/routes.rb +132 -48
  81. data/lib/activity_notification/renderable.rb +13 -2
  82. data/lib/activity_notification/roles/acts_as_notifiable.rb +39 -20
  83. data/lib/activity_notification/version.rb +1 -1
  84. data/lib/generators/activity_notification/controllers_generator.rb +2 -1
  85. data/lib/generators/templates/activity_notification.rb +8 -0
  86. data/lib/generators/templates/controllers/notifications_api_controller.rb +31 -0
  87. data/lib/generators/templates/controllers/notifications_api_with_devise_controller.rb +31 -0
  88. data/lib/generators/templates/controllers/notifications_controller.rb +1 -37
  89. data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +1 -45
  90. data/lib/generators/templates/controllers/subscriptions_api_controller.rb +61 -0
  91. data/lib/generators/templates/controllers/subscriptions_api_with_devise_controller.rb +61 -0
  92. data/lib/generators/templates/controllers/subscriptions_controller.rb +14 -37
  93. data/lib/generators/templates/controllers/subscriptions_with_devise_controller.rb +14 -45
  94. data/lib/generators/templates/models/README +8 -4
  95. data/lib/generators/templates/models/notification.rb +1 -1
  96. data/lib/generators/templates/models/subscription.rb +1 -1
  97. data/package.json +8 -0
  98. data/spec/channels/notification_api_channel_shared_examples.rb +59 -0
  99. data/spec/channels/notification_api_channel_spec.rb +51 -0
  100. data/spec/channels/notification_api_with_devise_channel_spec.rb +78 -0
  101. data/spec/concerns/apis/notification_api_spec.rb +38 -3
  102. data/spec/concerns/models/notifiable_spec.rb +82 -18
  103. data/spec/concerns/models/subscriber_spec.rb +13 -16
  104. data/spec/concerns/models/target_spec.rb +32 -0
  105. data/spec/concerns/renderable_spec.rb +2 -2
  106. data/spec/config_spec.rb +26 -15
  107. data/spec/controllers/controller_spec_utility.rb +136 -0
  108. data/spec/controllers/notifications_api_controller_shared_examples.rb +506 -0
  109. data/spec/controllers/notifications_api_controller_spec.rb +19 -0
  110. data/spec/controllers/notifications_api_with_devise_controller_spec.rb +60 -0
  111. data/spec/controllers/notifications_controller_shared_examples.rb +54 -79
  112. data/spec/controllers/notifications_controller_spec.rb +1 -2
  113. data/spec/controllers/notifications_with_devise_controller_spec.rb +3 -12
  114. data/spec/controllers/subscriptions_api_controller_shared_examples.rb +750 -0
  115. data/spec/controllers/subscriptions_api_controller_spec.rb +19 -0
  116. data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +60 -0
  117. data/spec/controllers/subscriptions_controller_shared_examples.rb +94 -121
  118. data/spec/controllers/subscriptions_controller_spec.rb +1 -2
  119. data/spec/controllers/subscriptions_with_devise_controller_spec.rb +3 -12
  120. data/spec/helpers/view_helpers_spec.rb +4 -11
  121. data/spec/mailers/mailer_spec.rb +41 -0
  122. data/spec/models/notification_spec.rb +17 -0
  123. data/spec/models/subscription_spec.rb +8 -13
  124. data/spec/optional_targets/action_cable_api_channel_spec.rb +37 -0
  125. data/spec/optional_targets/action_cable_channel_spec.rb +44 -0
  126. data/spec/optional_targets/amazon_sns_spec.rb +0 -2
  127. data/spec/optional_targets/slack_spec.rb +0 -2
  128. data/spec/rails_app/Rakefile +9 -0
  129. data/spec/rails_app/app/assets/config/manifest.js +3 -0
  130. data/spec/rails_app/app/assets/images/.keep +0 -0
  131. data/spec/rails_app/app/controllers/admins_controller.rb +21 -0
  132. data/spec/rails_app/app/controllers/application_controller.rb +1 -1
  133. data/spec/rails_app/app/controllers/articles_controller.rb +6 -3
  134. data/spec/rails_app/app/controllers/spa_controller.rb +7 -0
  135. data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -65
  136. data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -73
  137. data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -77
  138. data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -85
  139. data/spec/rails_app/app/controllers/users_controller.rb +26 -0
  140. data/spec/rails_app/app/javascript/App.vue +40 -0
  141. data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +82 -0
  142. data/spec/rails_app/app/javascript/components/Top.vue +98 -0
  143. data/spec/rails_app/app/javascript/components/notifications/Index.vue +200 -0
  144. data/spec/rails_app/app/javascript/components/notifications/Notification.vue +133 -0
  145. data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +122 -0
  146. data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +279 -0
  147. data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +112 -0
  148. data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +141 -0
  149. data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +226 -0
  150. data/spec/rails_app/app/javascript/config/development.js +5 -0
  151. data/spec/rails_app/app/javascript/config/environment.js +7 -0
  152. data/spec/rails_app/app/javascript/config/production.js +5 -0
  153. data/spec/rails_app/app/javascript/config/test.js +5 -0
  154. data/spec/rails_app/app/javascript/packs/application.js +18 -0
  155. data/spec/rails_app/app/javascript/packs/spa.js +14 -0
  156. data/spec/rails_app/app/javascript/router/index.js +73 -0
  157. data/spec/rails_app/app/javascript/store/index.js +37 -0
  158. data/spec/rails_app/app/models/admin.rb +16 -15
  159. data/spec/rails_app/app/models/article.rb +26 -21
  160. data/spec/rails_app/app/models/comment.rb +24 -71
  161. data/spec/rails_app/app/models/dummy/dummy_group.rb +8 -0
  162. data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +8 -0
  163. data/spec/rails_app/app/models/user.rb +44 -20
  164. data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +146 -0
  165. data/spec/rails_app/app/views/articles/index.html.erb +51 -7
  166. data/spec/rails_app/app/views/articles/show.html.erb +1 -1
  167. data/spec/rails_app/app/views/layouts/_header.html.erb +8 -10
  168. data/spec/rails_app/app/views/spa/index.html.erb +2 -0
  169. data/spec/rails_app/babel.config.js +72 -0
  170. data/spec/rails_app/bin/webpack +18 -0
  171. data/spec/rails_app/bin/webpack-dev-server +18 -0
  172. data/spec/rails_app/config/application.rb +18 -2
  173. data/spec/rails_app/config/dynamoid.rb +11 -3
  174. data/spec/rails_app/config/environment.rb +2 -1
  175. data/spec/rails_app/config/environments/development.rb +5 -0
  176. data/spec/rails_app/config/environments/production.rb +6 -0
  177. data/spec/rails_app/config/environments/test.rb +5 -0
  178. data/spec/rails_app/config/initializers/activity_notification.rb +11 -3
  179. data/spec/rails_app/config/initializers/copy_it.aws.rb.template +6 -0
  180. data/spec/rails_app/config/initializers/devise_token_auth.rb +55 -0
  181. data/spec/rails_app/config/initializers/mysql.rb +9 -0
  182. data/spec/rails_app/config/locales/activity_notification.en.yml +2 -2
  183. data/spec/rails_app/config/routes.rb +37 -1
  184. data/spec/rails_app/config/webpack/development.js +5 -0
  185. data/spec/rails_app/config/webpack/environment.js +7 -0
  186. data/spec/rails_app/config/webpack/loaders/vue.js +6 -0
  187. data/spec/rails_app/config/webpack/production.js +5 -0
  188. data/spec/rails_app/config/webpack/test.js +5 -0
  189. data/spec/rails_app/config/webpacker.yml +97 -0
  190. data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +10 -0
  191. data/spec/rails_app/db/schema.rb +4 -1
  192. data/spec/rails_app/db/seeds.rb +10 -2
  193. data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +14 -0
  194. data/spec/rails_app/package.json +23 -0
  195. data/spec/rails_app/postcss.config.js +12 -0
  196. data/spec/roles/acts_as_group_spec.rb +0 -2
  197. data/spec/roles/acts_as_notifiable_spec.rb +6 -8
  198. data/spec/roles/acts_as_notifier_spec.rb +0 -2
  199. data/spec/roles/acts_as_target_spec.rb +0 -4
  200. data/spec/spec_helper.rb +7 -15
  201. data/spec/version_spec.rb +31 -0
  202. metadata +191 -13
@@ -0,0 +1,19 @@
1
+ require 'controllers/notifications_api_controller_shared_examples'
2
+
3
+ describe ActivityNotification::NotificationsApiController, type: :controller do
4
+ let(:test_target) { create(:user) }
5
+ let(:target_type) { :users }
6
+ let(:typed_target_param) { :user_id }
7
+ let(:extra_params) { {} }
8
+ let(:valid_session) {}
9
+
10
+ it_behaves_like :notifications_api_controller
11
+
12
+ describe "/api/v#{ActivityNotification::GEM_VERSION::MAJOR}", type: :request do
13
+ let(:root_path) { "/api/v#{ActivityNotification::GEM_VERSION::MAJOR}" }
14
+ let(:test_target) { create(:user) }
15
+ let(:target_type) { :users }
16
+
17
+ it_behaves_like :notifications_api_request
18
+ end
19
+ end
@@ -0,0 +1,60 @@
1
+ require 'controllers/notifications_api_controller_shared_examples'
2
+
3
+ context "ActivityNotification::NotificationsApiWithDeviseController" do
4
+ context "test admins API with associated users authentication" do
5
+
6
+ describe "/api/v#{ActivityNotification::GEM_VERSION::MAJOR}", type: :request do
7
+ include ActivityNotification::ControllerSpec::CommitteeUtility
8
+
9
+ let(:root_path) { "/api/v#{ActivityNotification::GEM_VERSION::MAJOR}" }
10
+ let(:test_user) { create(:confirmed_user) }
11
+ let(:unauthenticated_user) { create(:confirmed_user) }
12
+ let(:test_target) { create(:admin, user: test_user) }
13
+ let(:target_type) { :admins }
14
+
15
+ def sign_in_with_devise_token_auth(auth_user, status)
16
+ post_with_compatibility "#{root_path}/auth/sign_in", params: { email: auth_user.email, password: "password" }
17
+ expect(response).to have_http_status(status)
18
+ @headers = response.header.slice("access-token", "client", "uid")
19
+ end
20
+
21
+ context "signed in with devise as authenticated user" do
22
+ before do
23
+ sign_in_with_devise_token_auth(test_user, 200)
24
+ end
25
+
26
+ it_behaves_like :notifications_api_request
27
+ end
28
+
29
+ context "signed in with devise as unauthenticated user" do
30
+ let(:target_params) { { target_type: target_type, devise_type: :users } }
31
+
32
+ describe "GET #index" do
33
+ before do
34
+ sign_in_with_devise_token_auth(unauthenticated_user, 200)
35
+ get_with_compatibility "#{api_path}/notifications", headers: @headers
36
+ end
37
+
38
+ it "returns 403 as http status code" do
39
+ expect(response.status).to eq(403)
40
+ end
41
+ end
42
+ end
43
+
44
+ context "unsigned in with devise" do
45
+ let(:target_params) { { target_type: target_type, devise_type: :users } }
46
+
47
+ describe "GET #index" do
48
+ before do
49
+ get_with_compatibility "#{api_path}/notifications", headers: @headers
50
+ end
51
+
52
+ it "returns 401 as http status code" do
53
+ expect(response.status).to eq(401)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+ end
@@ -1,4 +1,8 @@
1
- shared_examples_for :notification_controller do
1
+ require_relative 'controller_spec_utility'
2
+
3
+ shared_examples_for :notifications_controller do
4
+ include ActivityNotification::ControllerSpec::RequestUtility
5
+
2
6
  let(:target_params) { { target_type: target_type }.merge(extra_params || {}) }
3
7
 
4
8
  describe "GET #index" do
@@ -69,31 +73,6 @@ shared_examples_for :notification_controller do
69
73
  end
70
74
  end
71
75
 
72
- context "with json as format parameter" do
73
- before do
74
- @notification = create(:notification, target: test_target)
75
- get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, format: :json }), valid_session
76
- end
77
-
78
- it "returns 200 as http status code" do
79
- expect(response.status).to eq(200)
80
- end
81
-
82
- it "returns json format" do
83
- case ActivityNotification.config.orm
84
- when :active_record
85
- expect(JSON.parse(response.body).first)
86
- .to include("target_id" => test_target.id, "target_type" => test_target.to_class_name)
87
- when :mongoid
88
- expect(JSON.parse(response.body).first)
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}")
93
- end
94
- end
95
- end
96
-
97
76
  context "with filter parameter" do
98
77
  context "with unopened as filter" do
99
78
  before do
@@ -170,12 +149,10 @@ shared_examples_for :notification_controller do
170
149
  @notifiable = create(:article)
171
150
  @group = create(:article)
172
151
  @key = 'test.key.1'
173
- notification = create(:notification, target: test_target, notifiable: @notifiable)
174
- create(:notification, target: test_target, notifiable: create(:comment), group: @group, created_at: notification.created_at + 10.second)
175
- create(:notification, target: test_target, notifiable: create(:article), key: @key, created_at: notification.created_at + 20.second).open!
176
- @notification1 = test_target.notification_index[0]
177
- @notification2 = test_target.notification_index[1]
178
- @notification3 = test_target.notification_index[2]
152
+ @notification2 = create(:notification, target: test_target, notifiable: @notifiable)
153
+ @notification1 = create(:notification, target: test_target, notifiable: create(:comment), group: @group, created_at: @notification2.created_at + 10.second)
154
+ @notification3 = create(:notification, target: test_target, notifiable: create(:article), key: @key, created_at: @notification2.created_at + 20.second)
155
+ @notification3.open!
179
156
  end
180
157
 
181
158
  context "as default" do
@@ -211,8 +188,8 @@ shared_examples_for :notification_controller do
211
188
  @group = create(:article)
212
189
  @key = 'test.key.1'
213
190
  @notification2 = create(:notification, target: test_target, notifiable: @notifiable)
214
- @notification1 = create(:notification, target: test_target, notifiable: create(:comment), group: @group)
215
- @notification3 = create(:notification, target: test_target, notifiable: create(:article), key: @key)
191
+ @notification1 = create(:notification, target: test_target, notifiable: create(:comment), group: @group, created_at: @notification2.created_at + 10.second)
192
+ @notification3 = create(:notification, target: test_target, notifiable: create(:article), key: @key, created_at: @notification2.created_at + 20.second)
216
193
  @notification3.open!
217
194
  end
218
195
 
@@ -240,6 +217,22 @@ shared_examples_for :notification_controller do
240
217
  expect(assigns(:notifications).size).to eq(1)
241
218
  end
242
219
  end
220
+
221
+ context 'with later_than parameter' do
222
+ it "returns filtered notifications only" do
223
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, later_than: (@notification1.created_at.in_time_zone + 0.001).iso8601(3) }), valid_session
224
+ expect(assigns(:notifications)[0]).to eq(@notification3)
225
+ expect(assigns(:notifications).size).to eq(1)
226
+ end
227
+ end
228
+
229
+ context 'with earlier_than parameter' do
230
+ it "returns filtered notifications only" do
231
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, earlier_than: @notification1.created_at.iso8601(3) }), valid_session
232
+ expect(assigns(:notifications)[0]).to eq(@notification2)
233
+ expect(assigns(:notifications).size).to eq(1)
234
+ end
235
+ end
243
236
  end
244
237
  end
245
238
 
@@ -314,7 +307,7 @@ shared_examples_for :notification_controller do
314
307
  @target_1, @notifiable_1, @group_1, @key_1 = create(:confirmed_user), create(:article), nil, "key.1"
315
308
  @target_2, @notifiable_2, @group_2, @key_2 = create(:confirmed_user), create(:comment), @notifiable_1, "key.2"
316
309
  @notification_1 = create(:notification, target: test_target, notifiable: @notifiable_1, group: @group_1, key: @key_1)
317
- @notification_2 = create(:notification, target: test_target, notifiable: @notifiable_2, group: @group_2, key: @key_2)
310
+ @notification_2 = create(:notification, target: test_target, notifiable: @notifiable_2, group: @group_2, key: @key_2, created_at: @notification_1.created_at + 10.second)
318
311
  expect(@notification_1.opened?).to be_falsey
319
312
  expect(@notification_2.opened?).to be_falsey
320
313
  end
@@ -343,6 +336,22 @@ shared_examples_for :notification_controller do
343
336
  end
344
337
  end
345
338
 
339
+ context 'with later_than parameter' do
340
+ it "opens filtered notifications only" do
341
+ post_with_compatibility :open_all, target_params.merge({ typed_target_param => test_target, later_than: (@notification_1.created_at.in_time_zone + 0.001).iso8601(3) }), valid_session
342
+ expect(@notification_1.reload.opened?).to be_falsey
343
+ expect(@notification_2.reload.opened?).to be_truthy
344
+ end
345
+ end
346
+
347
+ context 'with earlier_than parameter' do
348
+ it "opens filtered notifications only" do
349
+ post_with_compatibility :open_all, target_params.merge({ typed_target_param => test_target, earlier_than: @notification_2.created_at.iso8601(3) }), valid_session
350
+ expect(@notification_1.reload.opened?).to be_truthy
351
+ expect(@notification_2.reload.opened?).to be_falsey
352
+ end
353
+ end
354
+
346
355
  context "with no filter request parameters" do
347
356
  it "opens all notifications of the target" do
348
357
  post_with_compatibility :open_all, target_params.merge({ typed_target_param => test_target}), valid_session
@@ -397,7 +406,7 @@ shared_examples_for :notification_controller do
397
406
  end
398
407
 
399
408
  it "deletes the notification" do
400
- expect(assigns(test_target.notifications.where(id: @notification.id).exists?)).to be_falsey
409
+ expect(test_target.notifications.where(id: @notification.id).exists?).to be_falsey
401
410
  end
402
411
 
403
412
  it "redirects to :index" do
@@ -449,13 +458,13 @@ shared_examples_for :notification_controller do
449
458
  end
450
459
  end
451
460
 
452
- describe "POST #open" do
461
+ describe "PUT #open" do
453
462
  context "without move parameter" do
454
- context "http direct POST request" do
463
+ context "http direct PUT request" do
455
464
  before do
456
465
  @notification = create(:notification, target: test_target)
457
466
  expect(@notification.opened?).to be_falsey
458
- post_with_compatibility :open, target_params.merge({ id: @notification, typed_target_param => test_target }), valid_session
467
+ put_with_compatibility :open, target_params.merge({ id: @notification, typed_target_param => test_target }), valid_session
459
468
  end
460
469
 
461
470
  it "returns 302 as http status code" do
@@ -471,12 +480,12 @@ shared_examples_for :notification_controller do
471
480
  end
472
481
  end
473
482
 
474
- context "http POST request from root_path" do
483
+ context "http PUT request from root_path" do
475
484
  before do
476
485
  @notification = create(:notification, target: test_target)
477
486
  expect(@notification.opened?).to be_falsey
478
487
  request.env["HTTP_REFERER"] = root_path
479
- post_with_compatibility :open, target_params.merge({ id: @notification, typed_target_param => test_target }), valid_session
488
+ put_with_compatibility :open, target_params.merge({ id: @notification, typed_target_param => test_target }), valid_session
480
489
  end
481
490
 
482
491
  it "returns 302 as http status code" do
@@ -492,12 +501,12 @@ shared_examples_for :notification_controller do
492
501
  end
493
502
  end
494
503
 
495
- context "Ajax POST request" do
504
+ context "Ajax PUT request" do
496
505
  before do
497
506
  @notification = create(:notification, target: test_target)
498
507
  expect(@notification.opened?).to be_falsey
499
508
  request.env["HTTP_REFERER"] = root_path
500
- xhr_with_compatibility :post, :open, target_params.merge({ id: @notification, typed_target_param => test_target }), valid_session
509
+ xhr_with_compatibility :put, :open, target_params.merge({ id: @notification, typed_target_param => test_target }), valid_session
501
510
  end
502
511
 
503
512
  it "returns 200 as http status code" do
@@ -519,11 +528,11 @@ shared_examples_for :notification_controller do
519
528
  end
520
529
 
521
530
  context "with true as move parameter" do
522
- context "http direct POST request" do
531
+ context "http direct PUT request" do
523
532
  before do
524
533
  @notification = create(:notification, target: test_target)
525
534
  expect(@notification.opened?).to be_falsey
526
- post_with_compatibility :open, target_params.merge({ id: @notification, typed_target_param => test_target, move: true }), valid_session
535
+ put_with_compatibility :open, target_params.merge({ id: @notification, typed_target_param => test_target, move: true }), valid_session
527
536
  end
528
537
 
529
538
  it "returns 302 as http status code" do
@@ -581,38 +590,4 @@ shared_examples_for :notification_controller do
581
590
  end
582
591
  end
583
592
  end
584
-
585
- private
586
-
587
- def get_with_compatibility action, params, session
588
- if Rails::VERSION::MAJOR <= 4
589
- get action, params, session
590
- else
591
- get action, params: params, session: session
592
- end
593
- end
594
-
595
- def post_with_compatibility action, params, session
596
- if Rails::VERSION::MAJOR <= 4
597
- post action, params, session
598
- else
599
- post action, params: params, session: session
600
- end
601
- end
602
-
603
- def delete_with_compatibility action, params, session
604
- if Rails::VERSION::MAJOR <= 4
605
- delete action, params, session
606
- else
607
- delete action, params: params, session: session
608
- end
609
- end
610
-
611
- def xhr_with_compatibility method, action, params, session
612
- if Rails::VERSION::MAJOR <= 4
613
- xhr method, action, params, session
614
- else
615
- send method.to_s, action, xhr: true, params: params, session: session
616
- end
617
- end
618
593
  end
@@ -7,6 +7,5 @@ describe ActivityNotification::NotificationsController, type: :controller do
7
7
  let(:extra_params) { {} }
8
8
  let(:valid_session) {}
9
9
 
10
- it_behaves_like :notification_controller
11
-
10
+ it_behaves_like :notifications_controller
12
11
  end
@@ -1,6 +1,8 @@
1
1
  require 'controllers/notifications_controller_shared_examples'
2
2
 
3
3
  describe ActivityNotification::NotificationsWithDeviseController, type: :controller do
4
+ include ActivityNotification::ControllerSpec::RequestUtility
5
+
4
6
  let(:test_user) { create(:confirmed_user) }
5
7
  let(:unauthenticated_user) { create(:confirmed_user) }
6
8
  let(:test_target) { create(:admin, user: test_user) }
@@ -14,7 +16,7 @@ describe ActivityNotification::NotificationsWithDeviseController, type: :control
14
16
  sign_in test_user
15
17
  end
16
18
 
17
- it_behaves_like :notification_controller
19
+ it_behaves_like :notifications_controller
18
20
  end
19
21
 
20
22
  context "signed in with devise as unauthenticated user" do
@@ -92,15 +94,4 @@ describe ActivityNotification::NotificationsWithDeviseController, type: :control
92
94
  end
93
95
  end
94
96
  end
95
-
96
- private
97
-
98
- def get_with_compatibility action, params, session
99
- if Rails::VERSION::MAJOR <= 4
100
- get action, params, session
101
- else
102
- get action, params: params, session: session
103
- end
104
- end
105
-
106
97
  end
@@ -0,0 +1,750 @@
1
+ require_relative 'controller_spec_utility'
2
+
3
+ shared_examples_for :subscriptions_api_controller do
4
+ include ActivityNotification::ControllerSpec::RequestUtility
5
+ include ActivityNotification::ControllerSpec::ApiResponseUtility
6
+
7
+ let(:target_params) { { target_type: target_type }.merge(extra_params || {}) }
8
+
9
+ describe "GET #index" do
10
+ context "with target_type and target_id parameters" do
11
+ before do
12
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
13
+ @notification = create(:notification, target: test_target, key: 'test_notification_key')
14
+ get_with_compatibility :index, target_params.merge({ target_id: test_target, typed_target_param => 'dummy' }), valid_session
15
+ end
16
+
17
+ it "returns 200 as http status code" do
18
+ expect(response.status).to eq(200)
19
+ end
20
+
21
+ it "returns configured subscription index as JSON" do
22
+ expect(response_json["configured_count"]).to eq(1)
23
+ assert_json_with_object_array(response_json["subscriptions"], [@subscription])
24
+ end
25
+
26
+ it "returns unconfigured notification keys as JSON" do
27
+ expect(response_json["unconfigured_count"]).to eq(1)
28
+ expect(response_json['unconfigured_notification_keys']).to eq([@notification.key])
29
+ end
30
+ end
31
+
32
+ context "with target_type and (typed_target)_id parameters" do
33
+ before do
34
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
35
+ @notification = create(:notification, target: test_target, key: 'test_notification_key')
36
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target }), valid_session
37
+ end
38
+
39
+ it "returns 200 as http status code" do
40
+ expect(response.status).to eq(200)
41
+ end
42
+
43
+ it "returns subscription index as JSON" do
44
+ expect(response_json["configured_count"]).to eq(1)
45
+ assert_json_with_object_array(response_json["subscriptions"], [@subscription])
46
+ end
47
+
48
+ it "returns unconfigured notification keys as JSON" do
49
+ expect(response_json["unconfigured_count"]).to eq(1)
50
+ expect(response_json['unconfigured_notification_keys']).to eq([@notification.key])
51
+ end
52
+ end
53
+
54
+ context "without target_type parameters" do
55
+ before do
56
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
57
+ @notification = create(:notification, target: test_target, key: 'test_notification_key')
58
+ get_with_compatibility :index, { typed_target_param => test_target }, valid_session
59
+ end
60
+
61
+ it "returns 400 as http status code" do
62
+ expect(response.status).to eq(400)
63
+ end
64
+
65
+ it "returns error JSON response" do
66
+ assert_error_response(400)
67
+ end
68
+ end
69
+
70
+ context "with not found (typed_target)_id parameter" do
71
+ before do
72
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
73
+ @notification = create(:notification, target: test_target, key: 'test_notification_key')
74
+ get_with_compatibility :index, target_params.merge({ typed_target_param => 0 }), valid_session
75
+ end
76
+
77
+ it "returns 404 as http status code" do
78
+ expect(response.status).to eq(404)
79
+ end
80
+
81
+ it "returns error JSON response" do
82
+ assert_error_response(404)
83
+ end
84
+ end
85
+
86
+ context "with filter parameter" do
87
+ context "with configured as filter" do
88
+ before do
89
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
90
+ @notification = create(:notification, target: test_target, key: 'test_notification_key')
91
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, filter: 'configured' }), valid_session
92
+ end
93
+
94
+ it "returns configured subscription index as JSON" do
95
+ expect(response_json["configured_count"]).to eq(1)
96
+ assert_json_with_object_array(response_json["subscriptions"], [@subscription])
97
+ end
98
+
99
+ it "does not return unconfigured notification keys as JSON" do
100
+ expect(response_json['unconfigured_count']).to be_nil
101
+ expect(response_json['unconfigured_notification_keys']).to be_nil
102
+ end
103
+ end
104
+
105
+ context "with unconfigured as filter" do
106
+ before do
107
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
108
+ @notification = create(:notification, target: test_target, key: 'test_notification_key')
109
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, filter: 'unconfigured' }), valid_session
110
+ end
111
+
112
+ it "does not return configured subscription index as JSON" do
113
+ expect(response_json['configured_count']).to be_nil
114
+ expect(response_json['subscriptions']).to be_nil
115
+ end
116
+
117
+ it "returns unconfigured notification keys as JSON" do
118
+ expect(response_json["unconfigured_count"]).to eq(1)
119
+ expect(response_json['unconfigured_notification_keys']).to eq([@notification.key])
120
+ end
121
+ end
122
+ end
123
+
124
+ context "with limit parameter" do
125
+ before do
126
+ create(:subscription, target: test_target, key: 'test_subscription_key_1')
127
+ create(:subscription, target: test_target, key: 'test_subscription_key_2')
128
+ create(:notification, target: test_target, key: 'test_notification_key_1')
129
+ create(:notification, target: test_target, key: 'test_notification_key_2')
130
+ end
131
+ context "with 2 as limit" do
132
+ before do
133
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, limit: 2 }), valid_session
134
+ end
135
+
136
+ it "returns subscription index of size 2 as JSON" do
137
+ assert_json_with_array_size(response_json["subscriptions"], 2)
138
+ end
139
+
140
+ it "returns notification key index of size 2 as JSON" do
141
+ assert_json_with_array_size(response_json["unconfigured_notification_keys"], 2)
142
+ end
143
+ end
144
+
145
+ context "with 1 as limit" do
146
+ before do
147
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, limit: 1 }), valid_session
148
+ end
149
+
150
+ it "returns subscription index of size 1 as JSON" do
151
+ assert_json_with_array_size(response_json["subscriptions"], 1)
152
+ end
153
+
154
+ it "returns notification key index of size 1 as JSON" do
155
+ assert_json_with_array_size(response_json["unconfigured_notification_keys"], 1)
156
+ end
157
+ end
158
+ end
159
+
160
+ context "with options filter parameters" do
161
+ before do
162
+ @subscription1 = create(:subscription, target: test_target, key: 'test_subscription_key_1')
163
+ @subscription2 = create(:subscription, target: test_target, key: 'test_subscription_key_2')
164
+ @notification1 = create(:notification, target: test_target, key: 'test_notification_key_1')
165
+ @notification2 = create(:notification, target: test_target, key: 'test_notification_key_2')
166
+ end
167
+
168
+ context 'with filtered_by_key parameter' do
169
+ it "returns filtered subscriptions only" do
170
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, filtered_by_key: 'test_subscription_key_2' }), valid_session
171
+ assert_json_with_object_array(response_json["subscriptions"], [@subscription2])
172
+ end
173
+
174
+ it "returns filtered notification keys only" do
175
+ get_with_compatibility :index, target_params.merge({ typed_target_param => test_target, filtered_by_key: 'test_notification_key_2' }), valid_session
176
+ expect(response_json['unconfigured_notification_keys']).to eq([@notification2.key])
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ describe "POST #create" do
183
+ before do
184
+ expect(test_target.subscriptions.size).to eq(0)
185
+ end
186
+
187
+ context "http POST request without optional targets" do
188
+ before do
189
+ post_with_compatibility :create, target_params.merge({
190
+ typed_target_param => test_target,
191
+ "subscription" => { "key" => "new_subscription_key",
192
+ "subscribing"=> "true",
193
+ "subscribing_to_email"=>"true"
194
+ }
195
+ }), valid_session
196
+ end
197
+
198
+ it "returns 201 as http status code" do
199
+ expect(response.status).to eq(201)
200
+ end
201
+
202
+ it "creates new subscription of the target" do
203
+ expect(test_target.subscriptions.reload.size).to eq(1)
204
+ expect(test_target.subscriptions.reload.first.key).to eq("new_subscription_key")
205
+ end
206
+
207
+ it "returns created subscription" do
208
+ created_subscription = test_target.subscriptions.reload.first
209
+ assert_json_with_object(response_json, created_subscription)
210
+ end
211
+ end
212
+
213
+ context "http POST request with optional targets" do
214
+ before do
215
+ post_with_compatibility :create, target_params.merge({
216
+ typed_target_param => test_target,
217
+ "subscription" => { "key" => "new_subscription_key",
218
+ "subscribing"=> "true",
219
+ "subscribing_to_email"=>"true",
220
+ "optional_targets" => { "subscribing_to_base1" => "true", "subscribing_to_base2" => "false" }
221
+ }
222
+ }), valid_session
223
+ end
224
+
225
+ it "returns 201 as http status code" do
226
+ expect(response.status).to eq(201)
227
+ end
228
+
229
+ it "creates new subscription of the target" do
230
+ expect(test_target.subscriptions.reload.size).to eq(1)
231
+ created_subscription = test_target.subscriptions.reload.first
232
+ expect(created_subscription.key).to eq("new_subscription_key")
233
+ expect(created_subscription.subscribing_to_optional_target?("base1")).to be_truthy
234
+ expect(created_subscription.subscribing_to_optional_target?("base2")).to be_falsey
235
+ end
236
+
237
+ it "returns created subscription" do
238
+ created_subscription = test_target.subscriptions.reload.first
239
+ assert_json_with_object(response_json, created_subscription)
240
+ end
241
+ end
242
+
243
+ context "without subscription parameter" do
244
+ before do
245
+ put_with_compatibility :create, target_params.merge({
246
+ typed_target_param => test_target
247
+ }), valid_session
248
+ end
249
+
250
+ it "returns 400 as http status code" do
251
+ expect(response.status).to eq(400)
252
+ end
253
+
254
+ it "returns error JSON response" do
255
+ assert_error_response(400)
256
+ end
257
+ end
258
+
259
+ context "unprocessable entity because of duplicate key" do
260
+ before do
261
+ @duplicate_subscription = create(:subscription, target: test_target, key: 'duplicate_subscription_key')
262
+ put_with_compatibility :create, target_params.merge({
263
+ typed_target_param => test_target,
264
+ "subscription" => { "key" => "duplicate_subscription_key",
265
+ "subscribing"=> "true",
266
+ "subscribing_to_email"=>"true"
267
+ }
268
+ }), valid_session
269
+ end
270
+
271
+ it "returns 422 as http status code" do
272
+ expect(response.status).to eq(422)
273
+ end
274
+
275
+ it "returns error JSON response" do
276
+ assert_error_response(422)
277
+ end
278
+ end
279
+ end
280
+
281
+ describe "GET #find" do
282
+ context "with key, target_type and (typed_target)_id parameters" do
283
+ before do
284
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
285
+ get_with_compatibility :find, target_params.merge({ key: 'test_subscription_key', typed_target_param => test_target }), valid_session
286
+ end
287
+
288
+ it "returns 200 as http status code" do
289
+ expect(response.status).to eq(200)
290
+ end
291
+
292
+ it "returns the requested subscription as JSON" do
293
+ assert_json_with_object(response_json, @subscription)
294
+ end
295
+ end
296
+
297
+ context "with wrong id and (typed_target)_id parameters" do
298
+ before do
299
+ @subscription = create(:subscription, target: create(:user))
300
+ get_with_compatibility :find, target_params.merge({ key: 'test_subscription_key', typed_target_param => test_target }), valid_session
301
+ end
302
+
303
+ it "returns 404 as http status code" do
304
+ expect(response.status).to eq(404)
305
+ end
306
+
307
+ it "returns error JSON response" do
308
+ assert_error_response(404)
309
+ end
310
+ end
311
+ end
312
+
313
+ describe "GET #optional_target_names" do
314
+ context "with key, target_type and (typed_target)_id parameters" do
315
+ before do
316
+ @notification = create(:notification, target: test_target, key: 'test_subscription_key')
317
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
318
+ get_with_compatibility :optional_target_names, target_params.merge({ key: 'test_subscription_key', typed_target_param => test_target }), valid_session
319
+ end
320
+
321
+ it "returns 200 as http status code" do
322
+ expect(response.status).to eq(200)
323
+ end
324
+
325
+ it "returns the blank array since configurured optional targets are not configured" do
326
+ expect(JSON.parse(response.body)["optional_target_names"].is_a?(Array)).to be_truthy
327
+ end
328
+ end
329
+
330
+ context "with wrong id and (typed_target)_id parameters" do
331
+ before do
332
+ @subscription = create(:subscription, target: create(:user))
333
+ get_with_compatibility :find, target_params.merge({ key: 'test_subscription_key', typed_target_param => test_target }), valid_session
334
+ end
335
+
336
+ it "returns 404 as http status code" do
337
+ expect(response.status).to eq(404)
338
+ end
339
+
340
+ it "returns error JSON response" do
341
+ assert_error_response(404)
342
+ end
343
+ end
344
+ end
345
+
346
+ describe "GET #show" do
347
+ context "with id, target_type and (typed_target)_id parameters" do
348
+ before do
349
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
350
+ get_with_compatibility :show, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
351
+ end
352
+
353
+ it "returns 200 as http status code" do
354
+ expect(response.status).to eq(200)
355
+ end
356
+
357
+ it "returns the requested subscription as JSON" do
358
+ assert_json_with_object(response_json, @subscription)
359
+ end
360
+ end
361
+
362
+ context "with wrong id and (typed_target)_id parameters" do
363
+ before do
364
+ @subscription = create(:subscription, target: create(:user))
365
+ get_with_compatibility :show, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
366
+ end
367
+
368
+ it "returns 403 as http status code" do
369
+ expect(response.status).to eq(403)
370
+ end
371
+
372
+ it "returns error JSON response" do
373
+ assert_error_response(403)
374
+ end
375
+ end
376
+ end
377
+
378
+ describe "DELETE #destroy" do
379
+ context "http DELETE request" do
380
+ before do
381
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
382
+ delete_with_compatibility :destroy, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
383
+ end
384
+
385
+ it "returns 204 as http status code" do
386
+ expect(response.status).to eq(204)
387
+ end
388
+
389
+ it "deletes the subscription" do
390
+ expect(test_target.subscriptions.where(id: @subscription.id).exists?).to be_falsey
391
+ end
392
+ end
393
+ end
394
+
395
+ describe "PUT #subscribe" do
396
+ context "http PUT request" do
397
+ before do
398
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
399
+ @subscription.unsubscribe
400
+ expect(@subscription.subscribing?).to be_falsey
401
+ put_with_compatibility :subscribe, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
402
+ end
403
+
404
+ it "returns 200 as http status code" do
405
+ expect(response.status).to eq(200)
406
+ end
407
+
408
+ it "updates subscribing to true" do
409
+ expect(@subscription.reload.subscribing?).to be_truthy
410
+ end
411
+
412
+ it "returns JSON response" do
413
+ assert_json_with_object(response_json, @subscription)
414
+ end
415
+ end
416
+ end
417
+
418
+ describe "PUT #unsubscribe" do
419
+ context "http PUT request" do
420
+ before do
421
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
422
+ expect(@subscription.subscribing?).to be_truthy
423
+ put_with_compatibility :unsubscribe, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
424
+ end
425
+
426
+ it "returns 200 as http status code" do
427
+ expect(response.status).to eq(200)
428
+ end
429
+
430
+ it "updates subscribing to false" do
431
+ expect(@subscription.reload.subscribing?).to be_falsey
432
+ end
433
+
434
+ it "returns JSON response" do
435
+ assert_json_with_object(response_json, @subscription)
436
+ end
437
+ end
438
+ end
439
+
440
+ describe "PUT #subscribe_to_email" do
441
+ context "http PUT request" do
442
+ before do
443
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
444
+ @subscription.unsubscribe_to_email
445
+ expect(@subscription.subscribing_to_email?).to be_falsey
446
+ put_with_compatibility :subscribe_to_email, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
447
+ end
448
+
449
+ it "returns 200 as http status code" do
450
+ expect(response.status).to eq(200)
451
+ end
452
+
453
+ it "updates subscribing_to_email to true" do
454
+ expect(@subscription.reload.subscribing_to_email?).to be_truthy
455
+ end
456
+
457
+ it "returns JSON response" do
458
+ assert_json_with_object(response_json, @subscription)
459
+ end
460
+ end
461
+
462
+ context "with unsubscribed target" do
463
+ before do
464
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
465
+ @subscription.unsubscribe
466
+ expect(@subscription.subscribing?).to be_falsey
467
+ expect(@subscription.subscribing_to_email?).to be_falsey
468
+ put_with_compatibility :subscribe_to_email, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
469
+ end
470
+
471
+ it "returns 422 as http status code" do
472
+ expect(response.status).to eq(422)
473
+ end
474
+
475
+ it "cannot update subscribing_to_email to true" do
476
+ expect(@subscription.reload.subscribing_to_email?).to be_falsey
477
+ end
478
+
479
+ it "returns error JSON response" do
480
+ assert_error_response(422)
481
+ end
482
+ end
483
+ end
484
+
485
+ describe "PUT #unsubscribe_to_email" do
486
+ context "http PUT request" do
487
+ before do
488
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
489
+ expect(@subscription.subscribing_to_email?).to be_truthy
490
+ put_with_compatibility :unsubscribe_to_email, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
491
+ end
492
+
493
+ it "returns 200 as http status code" do
494
+ expect(response.status).to eq(200)
495
+ end
496
+
497
+ it "updates subscribing_to_email to false" do
498
+ expect(@subscription.reload.subscribing_to_email?).to be_falsey
499
+ end
500
+
501
+ it "returns JSON response" do
502
+ assert_json_with_object(response_json, @subscription)
503
+ end
504
+ end
505
+ end
506
+
507
+ describe "PUT #subscribe_to_optional_target" do
508
+ context "without optional_target_name param" do
509
+ before do
510
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
511
+ @subscription.unsubscribe_to_optional_target(:base)
512
+ expect(@subscription.subscribing_to_optional_target?(:base)).to be_falsey
513
+ put_with_compatibility :subscribe_to_optional_target, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
514
+ end
515
+
516
+ it "returns 400 as http status code" do
517
+ expect(response.status).to eq(400)
518
+ end
519
+
520
+ it "does not update subscribing_to_optional_target?" do
521
+ expect(@subscription.subscribing_to_optional_target?(:base)).to be_falsey
522
+ end
523
+
524
+ it "returns error JSON response" do
525
+ assert_error_response(400)
526
+ end
527
+ end
528
+
529
+ context "http PUT request" do
530
+ before do
531
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
532
+ @subscription.unsubscribe_to_optional_target(:base)
533
+ expect(@subscription.subscribing_to_optional_target?(:base)).to be_falsey
534
+ put_with_compatibility :subscribe_to_optional_target, target_params.merge({ id: @subscription, optional_target_name: 'base', typed_target_param => test_target }), valid_session
535
+ end
536
+
537
+ it "returns 200 as http status code" do
538
+ expect(response.status).to eq(200)
539
+ end
540
+
541
+ it "updates subscribing_to_optional_target to true" do
542
+ expect(@subscription.reload.subscribing_to_optional_target?(:base)).to be_truthy
543
+ end
544
+
545
+ it "returns JSON response" do
546
+ assert_json_with_object(response_json, @subscription)
547
+ end
548
+ end
549
+
550
+ context "with unsubscribed target" do
551
+ before do
552
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
553
+ @subscription.unsubscribe_to_optional_target(:base)
554
+ @subscription.unsubscribe
555
+ expect(@subscription.subscribing?).to be_falsey
556
+ expect(@subscription.subscribing_to_optional_target?(:base)).to be_falsey
557
+ put_with_compatibility :subscribe_to_optional_target, target_params.merge({ id: @subscription, optional_target_name: 'base', typed_target_param => test_target }), valid_session
558
+ end
559
+
560
+ it "returns 422 as http status code" do
561
+ expect(response.status).to eq(422)
562
+ end
563
+
564
+ it "cannot update subscribing_to_optional_target to true" do
565
+ expect(@subscription.reload.subscribing_to_optional_target?(:base)).to be_falsey
566
+ end
567
+
568
+ it "returns error JSON response" do
569
+ assert_error_response(422)
570
+ end
571
+ end
572
+ end
573
+
574
+ describe "PUT #unsubscribe_to_optional_target" do
575
+ context "without optional_target_name param" do
576
+ before do
577
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
578
+ expect(@subscription.subscribing_to_optional_target?(:base)).to be_truthy
579
+ put_with_compatibility :unsubscribe_to_optional_target, target_params.merge({ id: @subscription, typed_target_param => test_target }), valid_session
580
+ end
581
+
582
+ it "returns 400 as http status code" do
583
+ expect(response.status).to eq(400)
584
+ end
585
+
586
+ it "does not update subscribing_to_optional_target?" do
587
+ expect(@subscription.subscribing_to_optional_target?(:base)).to be_truthy
588
+ end
589
+
590
+ it "returns error JSON response" do
591
+ assert_error_response(400)
592
+ end
593
+ end
594
+
595
+ context "http PUT request" do
596
+ before do
597
+ @subscription = create(:subscription, target: test_target, key: 'test_subscription_key')
598
+ expect(@subscription.subscribing_to_optional_target?(:base)).to be_truthy
599
+ put_with_compatibility :unsubscribe_to_optional_target, target_params.merge({ id: @subscription, optional_target_name: 'base', typed_target_param => test_target }), valid_session
600
+ end
601
+
602
+ it "returns 200 as http status code" do
603
+ expect(response.status).to eq(200)
604
+ end
605
+
606
+ it "updates subscribing_to_optional_target to false" do
607
+ expect(@subscription.reload.subscribing_to_optional_target?(:base)).to be_falsey
608
+ end
609
+
610
+ it "returns JSON response" do
611
+ assert_json_with_object(response_json, @subscription)
612
+ end
613
+ end
614
+ end
615
+ end
616
+
617
+ shared_examples_for :subscriptions_api_request do
618
+ include ActivityNotification::ControllerSpec::CommitteeUtility
619
+
620
+ before do
621
+ @notification = create(:notification, target: test_target, key: "unconfigured_key")
622
+ @subscription = create(:subscription, target: test_target, key: "configured_key")
623
+ end
624
+
625
+ describe "GET /apidocs to test" do
626
+ it "returns API references as OpenAPI Specification JSON schema" do
627
+ get "#{root_path}/apidocs"
628
+ write_schema_file(response.body)
629
+ expect(read_schema_file["openapi"]).to eq("3.0.0")
630
+ end
631
+ end
632
+
633
+ describe "GET /{target_type}/{target_id}/subscriptions", type: :request do
634
+ it "returns response as API references" do
635
+ get_with_compatibility "#{api_path}/subscriptions", headers: @headers
636
+ assert_all_schema_confirm(response, 200)
637
+ end
638
+ end
639
+
640
+ describe "POST /{target_type}/{target_id}/subscriptions", type: :request do
641
+ it "returns response as API references" do
642
+ post_with_compatibility "#{api_path}/subscriptions", params: {
643
+ "subscription" => { "key" => "new_subscription_key",
644
+ "subscribing"=> "true",
645
+ "subscribing_to_email"=>"true",
646
+ "optional_targets"=>{
647
+ "action_cable_channel"=>{
648
+ "subscribing"=>"true",
649
+ },
650
+ "slack"=>{
651
+ "subscribing"=>"false"
652
+ }
653
+ }
654
+ }
655
+ }, headers: @headers
656
+ assert_all_schema_confirm(response, 201)
657
+ end
658
+
659
+ it "returns response as API references when the key is duplicate" do
660
+ post_with_compatibility "#{api_path}/subscriptions", params: {
661
+ "subscription" => { "key" => "configured_key",
662
+ "subscribing"=> "true",
663
+ "subscribing_to_email"=>"true"
664
+ }
665
+ }, headers: @headers
666
+ assert_all_schema_confirm(response, 422)
667
+ end
668
+ end
669
+
670
+ describe "GET /{target_type}/{target_id}/subscriptions/find", type: :request do
671
+ it "returns response as API references" do
672
+ get_with_compatibility "#{api_path}/subscriptions/find?key=#{@subscription.key}", headers: @headers
673
+ assert_all_schema_confirm(response, 200)
674
+ end
675
+ end
676
+
677
+ describe "GET /{target_type}/{target_id}/subscriptions/optional_target_names", type: :request do
678
+ it "returns response as API references" do
679
+ create(:notification, target: test_target, key: @subscription.key)
680
+ get_with_compatibility "#{api_path}/subscriptions/optional_target_names?key=#{@subscription.key}", headers: @headers
681
+ assert_all_schema_confirm(response, 200)
682
+ end
683
+
684
+ it "returns response as API references when any notification with the key is not found" do
685
+ get_with_compatibility "#{api_path}/subscriptions/optional_target_names?key=#{@subscription.key}", headers: @headers
686
+ assert_all_schema_confirm(response, 404)
687
+ end
688
+ end
689
+
690
+ describe "GET /{target_type}/{target_id}/subscriptions/{id}", type: :request do
691
+ it "returns response as API references" do
692
+ get_with_compatibility "#{api_path}/subscriptions/#{@subscription.id}", headers: @headers
693
+ assert_all_schema_confirm(response, 200)
694
+ end
695
+
696
+ it "returns error response as API references" do
697
+ get_with_compatibility "#{api_path}/subscriptions/0", headers: @headers
698
+ assert_all_schema_confirm(response, 404)
699
+ end
700
+ end
701
+
702
+ describe "DELETE /{target_type}/{target_id}/subscriptions/{id}", type: :request do
703
+ it "returns response as API references" do
704
+ delete_with_compatibility "#{api_path}/subscriptions/#{@subscription.id}", headers: @headers
705
+ assert_all_schema_confirm(response, 204)
706
+ end
707
+ end
708
+
709
+ describe "PUT /{target_type}/{target_id}/subscriptions/{id}/subscribe", type: :request do
710
+ it "returns response as API references" do
711
+ put_with_compatibility "#{api_path}/subscriptions/#{@subscription.id}/subscribe", headers: @headers
712
+ assert_all_schema_confirm(response, 200)
713
+ end
714
+ end
715
+
716
+ describe "PUT /{target_type}/{target_id}/subscriptions/{id}/unsubscribe", type: :request do
717
+ it "returns response as API references" do
718
+ put_with_compatibility "#{api_path}/subscriptions/#{@subscription.id}/unsubscribe", headers: @headers
719
+ assert_all_schema_confirm(response, 200)
720
+ end
721
+ end
722
+
723
+ describe "PUT /{target_type}/{target_id}/subscriptions/{id}/subscribe_to_email", type: :request do
724
+ it "returns response as API references" do
725
+ put_with_compatibility "#{api_path}/subscriptions/#{@subscription.id}/subscribe_to_email", headers: @headers
726
+ assert_all_schema_confirm(response, 200)
727
+ end
728
+ end
729
+
730
+ describe "PUT /{target_type}/{target_id}/subscriptions/{id}/unsubscribe_to_email", type: :request do
731
+ it "returns response as API references" do
732
+ put_with_compatibility "#{api_path}/subscriptions/#{@subscription.id}/unsubscribe_to_email", headers: @headers
733
+ assert_all_schema_confirm(response, 200)
734
+ end
735
+ end
736
+
737
+ describe "PUT /{target_type}/{target_id}/subscriptions/{id}/subscribe_to_optional_target", type: :request do
738
+ it "returns response as API references" do
739
+ put_with_compatibility "#{api_path}/subscriptions/#{@subscription.id}/subscribe_to_optional_target?optional_target_name=slack", headers: @headers
740
+ assert_all_schema_confirm(response, 200)
741
+ end
742
+ end
743
+
744
+ describe "PUT /{target_type}/{target_id}/subscriptions/{id}/unsubscribe_to_optional_target", type: :request do
745
+ it "returns response as API references" do
746
+ put_with_compatibility "#{api_path}/subscriptions/#{@subscription.id}/unsubscribe_to_optional_target?optional_target_name=slack", headers: @headers
747
+ assert_all_schema_confirm(response, 200)
748
+ end
749
+ end
750
+ end