notify_user 0.1.4 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (238) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -0
  3. data/Rakefile +7 -1
  4. data/app/controllers/notify_user/base_notifications_controller.rb +36 -35
  5. data/app/mailers/notify_user/notification_mailer.rb +1 -1
  6. data/app/models/notify_user/apn_connection.rb +35 -17
  7. data/app/models/notify_user/apns.rb +124 -14
  8. data/app/models/notify_user/base_notification.rb +172 -35
  9. data/app/models/notify_user/gcm.rb +58 -0
  10. data/app/models/notify_user/push.rb +37 -0
  11. data/app/models/notify_user/unsubscribe.rb +26 -9
  12. data/app/models/notify_user/urban_airship.rb +1 -1
  13. data/app/serializers/notify_user/notification_serializer.rb +1 -4
  14. data/config/routes.rb +2 -2
  15. data/lib/generators/notify_user/aggr_interval_update/USAGE +5 -0
  16. data/lib/generators/notify_user/aggr_interval_update/aggr_interval_update_generator.rb +36 -0
  17. data/lib/generators/notify_user/aggr_interval_update/templates/add_sent_time_to_notifications.rb +10 -0
  18. data/lib/generators/notify_user/aggr_interval_update/templates/update_unsubscribe.rb +6 -0
  19. data/lib/generators/notify_user/install/install_generator.rb +2 -5
  20. data/lib/generators/notify_user/install/templates/create_notify_user_notifications.rb +8 -0
  21. data/lib/generators/notify_user/install/templates/create_notify_user_unsubscribes.rb +5 -0
  22. data/lib/generators/notify_user/notification/notification_generator.rb +1 -0
  23. data/lib/notify_user/channels/action_mailer/action_mailer_channel.rb +1 -1
  24. data/lib/notify_user/channels/apns/apns_channel.rb +23 -23
  25. data/lib/notify_user/engine.rb +0 -1
  26. data/lib/notify_user/version.rb +1 -1
  27. data/spec/controllers/notify_user/notifications_controller_spec.rb +130 -108
  28. data/spec/dummy/rails-4.1.0/Gemfile +1 -1
  29. data/spec/dummy/rails-4.1.0/app/notifications/new_post_notification.rb +2 -6
  30. data/spec/dummy/{rails-4.0.4/app/views/notify_user/new_post_notification/mobile_sdk/notification.html.erb → rails-4.1.0/app/views/notify_user/new_post_notification/mobile_sdk/aggregate_notifications.html.erb} +0 -0
  31. data/spec/dummy/rails-4.1.0/app/views/notify_user/new_post_notification/mobile_sdk/notification.html.erb +1 -0
  32. data/spec/dummy/rails-4.1.0/config/environments/production.rb +1 -6
  33. data/spec/dummy/rails-4.1.0/config/initializers/assets.rb +8 -0
  34. data/spec/dummy/rails-4.1.0/config/initializers/notify_user.rb +10 -0
  35. data/spec/dummy/rails-4.1.0/config/secrets.yml +2 -2
  36. data/spec/dummy/{rails-3.2.17/db/migrate/20141102231350_create_users.rb → rails-4.1.0/db/migrate/20150907004705_create_users.rb} +0 -0
  37. data/spec/dummy/{rails-4.0.4/db/migrate/20141102231413669669843000_create_notify_user_notifications.rb → rails-4.1.0/db/migrate/20150907004707_create_notify_user_notifications.rb} +8 -0
  38. data/spec/dummy/rails-4.1.0/db/migrate/{20141102231434013013078000_create_notify_user_unsubscribes.rb → 20150907004708_create_notify_user_unsubscribes.rb} +5 -0
  39. data/spec/dummy/{rails-3.2.17/db/migrate/20141102231353651651843000_create_notify_user_user_hashes.rb → rails-4.1.0/db/migrate/20150907004709_create_notify_user_user_hashes.rb} +0 -0
  40. data/spec/dummy/rails-4.1.0/db/schema.rb +12 -1
  41. data/spec/dummy/rails-4.1.0/log/test.log +55083 -8099
  42. data/spec/dummy/rails-4.1.0/test/test_helper.rb +0 -3
  43. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/2iFf6DF21eHswaXamThRpysQhZa4HHhfXSwW0I26I_Q.cache +3 -0
  44. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/56gcPUZsFk_z-NC4BqxyzJ2fHeG-wa2DVNUK5iFQico.cache +0 -0
  45. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/8DepzOh5SIwaxC825zft8xeBhAi84AFjIkQLBafpfcI.cache +1 -0
  46. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/DFBSCnNmEyoM8roYdJ4CwzgAxnyRtTG3S2qD1ryqXxw.cache +1 -0
  47. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/DcdyyraxoBKSYh1m6Spmfn5Qtn0V2X2t8aO3dmAi0Po.cache +3 -0
  48. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/IO46kchRzb_wUQ8H3D25_DHv7lZK4CxthkOj6ZKp8mQ.cache +1 -0
  49. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/JTg9Khb4iQ4MkGt2OoYdfz6rYD9ccxMNxCOnVK92fJA.cache +1 -0
  50. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/O8akbUwAbmIKY-AhITimq-JDQ6IgsO3Hvq2v5etufFw.cache +2 -0
  51. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/RJrFPSmoXCFaapGXw1bP4Lg0NLmr9qG2RMuN56UrR7U.cache +0 -0
  52. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/TWJMA4bg5d25falxiw_TLK0GtSXWpfl0vFaFLRpkYKI.cache +1 -0
  53. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/XjnNasrgRd0l5xx4UR4IeE-Tz1EtjiPKwmizcf59P9U.cache +0 -0
  54. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/Y829B5qbE0t7idbBscHZCJxlb-D9S6G_8P6HwwMe7J4.cache +2 -0
  55. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/aXGU_8_bWOQw87gl5m_8fgEUtethSIj95P57d5YuW5k.cache +0 -0
  56. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/cjXxcrFHyMpHUOqA38Yaft85pmxR7gZ4__TFcgJQyKA.cache +1 -0
  57. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/cpoXvFR-s_2VM6kFm4ixeZKjW6en5HiD8B-ttj-iUSI.cache +0 -0
  58. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/hAsOx0KPt1yL2Nh2sDOmOIWrAfoEZo1RxZQkNop9FOU.cache +0 -0
  59. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/j52KuMJNJLJcKPVLf8rk8USLswZAmy6Hi1OW35JjVTo.cache +1 -0
  60. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/mwsAf4xggfO0hGKNns79uKcXG7B5rk8a4Zav3vXyr6M.cache +2 -0
  61. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/tPF6H9NRpGO3whu2y5_e_R_1EACKdCwu5437D83qJT0.cache +3 -0
  62. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/x5V5ICXz753PW9A8l6gpNAh_utfwyXyixuUxtMgJ2Pg.cache +1 -0
  63. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/y8AwtETeMIB25XCoxQDwn3DmMpUFLblIFK4yb18zN4c.cache +1 -0
  64. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/yWa5z3IIFR71QlDOGDwO5IpC9vsVUGFNfficVy0q3zo.cache +1 -0
  65. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/v3.0/zDCAil6tD1zhO-gqs7OG9_zEEdMVEZo_aUkZjLHP53M.cache +0 -0
  66. data/spec/factories/notify_user_notifications.rb +4 -7
  67. data/spec/factories/users.rb +7 -0
  68. data/spec/lib/notify_user/channels/apns_channel_spec.rb +65 -0
  69. data/spec/mailers/notify_user/notification_mailer_spec.rb +24 -24
  70. data/spec/models/notify_user/apn_connection_spec.rb +29 -0
  71. data/spec/models/notify_user/apns_spec.rb +96 -0
  72. data/spec/models/notify_user/gcm_spec.rb +70 -0
  73. data/spec/models/notify_user/notification_spec.rb +456 -64
  74. data/spec/models/notify_user/unsubscribe_spec.rb +59 -16
  75. data/spec/models/notify_user/user_hash_spec.rb +11 -14
  76. data/spec/serializers/notify_user/notification_serializer_spec.rb +24 -6
  77. data/spec/setup_spec.rb +3 -4
  78. data/spec/spec_helper.rb +20 -12
  79. data/spec/support/test_apn_connection.rb +8 -0
  80. data/spec/support/test_gcm_connection.rb +5 -0
  81. metadata +131 -332
  82. data/app/models/notify_user/houston.rb +0 -101
  83. data/spec/dummy/rails-3.2.17/Gemfile +0 -38
  84. data/spec/dummy/rails-3.2.17/README.rdoc +0 -261
  85. data/spec/dummy/rails-3.2.17/Rakefile +0 -7
  86. data/spec/dummy/rails-3.2.17/app/assets/images/rails.png +0 -0
  87. data/spec/dummy/rails-3.2.17/app/assets/javascripts/application.js +0 -15
  88. data/spec/dummy/rails-3.2.17/app/assets/stylesheets/application.css +0 -13
  89. data/spec/dummy/rails-3.2.17/app/controllers/application_controller.rb +0 -3
  90. data/spec/dummy/rails-3.2.17/app/controllers/notify_user/notifications_controller.rb +0 -9
  91. data/spec/dummy/rails-3.2.17/app/helpers/application_helper.rb +0 -2
  92. data/spec/dummy/rails-3.2.17/app/models/user.rb +0 -3
  93. data/spec/dummy/rails-3.2.17/app/notifications/new_post_notification.rb +0 -15
  94. data/spec/dummy/rails-3.2.17/app/views/layouts/application.html.erb +0 -14
  95. data/spec/dummy/rails-3.2.17/app/views/notify_user/layouts/action_mailer.html.erb +0 -39
  96. data/spec/dummy/rails-3.2.17/app/views/notify_user/new_post_notification/action_mailer/notification.html.erb +0 -1
  97. data/spec/dummy/rails-3.2.17/config.ru +0 -4
  98. data/spec/dummy/rails-3.2.17/config/application.rb +0 -62
  99. data/spec/dummy/rails-3.2.17/config/boot.rb +0 -6
  100. data/spec/dummy/rails-3.2.17/config/database.yml +0 -24
  101. data/spec/dummy/rails-3.2.17/config/environment.rb +0 -5
  102. data/spec/dummy/rails-3.2.17/config/environments/development.rb +0 -37
  103. data/spec/dummy/rails-3.2.17/config/environments/production.rb +0 -67
  104. data/spec/dummy/rails-3.2.17/config/environments/test.rb +0 -37
  105. data/spec/dummy/rails-3.2.17/config/initializers/backtrace_silencers.rb +0 -7
  106. data/spec/dummy/rails-3.2.17/config/initializers/inflections.rb +0 -15
  107. data/spec/dummy/rails-3.2.17/config/initializers/mime_types.rb +0 -5
  108. data/spec/dummy/rails-3.2.17/config/initializers/notify_user.rb +0 -14
  109. data/spec/dummy/rails-3.2.17/config/initializers/secret_token.rb +0 -7
  110. data/spec/dummy/rails-3.2.17/config/initializers/session_store.rb +0 -8
  111. data/spec/dummy/rails-3.2.17/config/initializers/wrap_parameters.rb +0 -14
  112. data/spec/dummy/rails-3.2.17/config/keys/development_push.pem +0 -0
  113. data/spec/dummy/rails-3.2.17/config/locales/en.yml +0 -5
  114. data/spec/dummy/rails-3.2.17/config/routes.rb +0 -58
  115. data/spec/dummy/rails-3.2.17/db/migrate/20141102231353649649586000_create_notify_user_notifications.rb +0 -13
  116. data/spec/dummy/rails-3.2.17/db/migrate/20141102231353650650817000_create_notify_user_unsubscribes.rb +0 -10
  117. data/spec/dummy/rails-3.2.17/db/schema.rb +0 -50
  118. data/spec/dummy/rails-3.2.17/db/seeds.rb +0 -7
  119. data/spec/dummy/rails-3.2.17/doc/README_FOR_APP +0 -2
  120. data/spec/dummy/rails-3.2.17/log/test.log +0 -9574
  121. data/spec/dummy/rails-3.2.17/public/404.html +0 -26
  122. data/spec/dummy/rails-3.2.17/public/422.html +0 -26
  123. data/spec/dummy/rails-3.2.17/public/500.html +0 -25
  124. data/spec/dummy/rails-3.2.17/public/favicon.ico +0 -0
  125. data/spec/dummy/rails-3.2.17/public/index.html +0 -241
  126. data/spec/dummy/rails-3.2.17/public/robots.txt +0 -5
  127. data/spec/dummy/rails-3.2.17/script/rails +0 -6
  128. data/spec/dummy/rails-3.2.17/test/fixtures/users.yml +0 -7
  129. data/spec/dummy/rails-3.2.17/test/performance/browsing_test.rb +0 -12
  130. data/spec/dummy/rails-3.2.17/test/test_helper.rb +0 -13
  131. data/spec/dummy/rails-3.2.17/test/unit/user_test.rb +0 -7
  132. data/spec/dummy/rails-4.0.4/Gemfile +0 -45
  133. data/spec/dummy/rails-4.0.4/README.rdoc +0 -28
  134. data/spec/dummy/rails-4.0.4/Rakefile +0 -6
  135. data/spec/dummy/rails-4.0.4/app/assets/javascripts/application.js +0 -16
  136. data/spec/dummy/rails-4.0.4/app/assets/stylesheets/application.css +0 -13
  137. data/spec/dummy/rails-4.0.4/app/controllers/application_controller.rb +0 -5
  138. data/spec/dummy/rails-4.0.4/app/controllers/notify_user/notifications_controller.rb +0 -9
  139. data/spec/dummy/rails-4.0.4/app/helpers/application_helper.rb +0 -2
  140. data/spec/dummy/rails-4.0.4/app/models/user.rb +0 -2
  141. data/spec/dummy/rails-4.0.4/app/notifications/new_post_notification.rb +0 -15
  142. data/spec/dummy/rails-4.0.4/app/views/layouts/application.html.erb +0 -14
  143. data/spec/dummy/rails-4.0.4/app/views/notify_user/layouts/action_mailer.html.erb +0 -39
  144. data/spec/dummy/rails-4.0.4/app/views/notify_user/new_post_notification/action_mailer/notification.html.erb +0 -1
  145. data/spec/dummy/rails-4.0.4/bin/bundle +0 -3
  146. data/spec/dummy/rails-4.0.4/bin/rails +0 -4
  147. data/spec/dummy/rails-4.0.4/bin/rake +0 -4
  148. data/spec/dummy/rails-4.0.4/config.ru +0 -4
  149. data/spec/dummy/rails-4.0.4/config/application.rb +0 -23
  150. data/spec/dummy/rails-4.0.4/config/boot.rb +0 -4
  151. data/spec/dummy/rails-4.0.4/config/database.yml +0 -24
  152. data/spec/dummy/rails-4.0.4/config/environment.rb +0 -5
  153. data/spec/dummy/rails-4.0.4/config/environments/development.rb +0 -29
  154. data/spec/dummy/rails-4.0.4/config/environments/production.rb +0 -80
  155. data/spec/dummy/rails-4.0.4/config/environments/test.rb +0 -36
  156. data/spec/dummy/rails-4.0.4/config/initializers/backtrace_silencers.rb +0 -7
  157. data/spec/dummy/rails-4.0.4/config/initializers/filter_parameter_logging.rb +0 -4
  158. data/spec/dummy/rails-4.0.4/config/initializers/inflections.rb +0 -16
  159. data/spec/dummy/rails-4.0.4/config/initializers/mime_types.rb +0 -5
  160. data/spec/dummy/rails-4.0.4/config/initializers/notify_user.rb +0 -14
  161. data/spec/dummy/rails-4.0.4/config/initializers/secret_token.rb +0 -12
  162. data/spec/dummy/rails-4.0.4/config/initializers/session_store.rb +0 -3
  163. data/spec/dummy/rails-4.0.4/config/initializers/wrap_parameters.rb +0 -14
  164. data/spec/dummy/rails-4.0.4/config/keys/development_push.pem +0 -136
  165. data/spec/dummy/rails-4.0.4/config/locales/en.yml +0 -23
  166. data/spec/dummy/rails-4.0.4/config/routes.rb +0 -56
  167. data/spec/dummy/rails-4.0.4/db/migrate/20141102231412_create_users.rb +0 -9
  168. data/spec/dummy/rails-4.0.4/db/migrate/20141102231413670670945000_create_notify_user_unsubscribes.rb +0 -10
  169. data/spec/dummy/rails-4.0.4/db/migrate/20141102231413671671735000_create_notify_user_user_hashes.rb +0 -12
  170. data/spec/dummy/rails-4.0.4/db/schema.rb +0 -53
  171. data/spec/dummy/rails-4.0.4/db/seeds.rb +0 -7
  172. data/spec/dummy/rails-4.0.4/log/test.log +0 -45689
  173. data/spec/dummy/rails-4.0.4/public/404.html +0 -58
  174. data/spec/dummy/rails-4.0.4/public/422.html +0 -58
  175. data/spec/dummy/rails-4.0.4/public/500.html +0 -57
  176. data/spec/dummy/rails-4.0.4/public/favicon.ico +0 -0
  177. data/spec/dummy/rails-4.0.4/public/robots.txt +0 -5
  178. data/spec/dummy/rails-4.0.4/test/fixtures/users.yml +0 -7
  179. data/spec/dummy/rails-4.0.4/test/models/user_test.rb +0 -7
  180. data/spec/dummy/rails-4.0.4/test/test_helper.rb +0 -15
  181. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/0e8918f38b9bf3fc19fca4efda1600a1 +0 -0
  182. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  183. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/1bded108b40ef13c7e07be129e2cd83c +0 -0
  184. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/1ebdd9dfe7e88e90bee37951e2da1ea2 +0 -0
  185. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/23fe609acece1521082ad6b8249f96b1 +0 -0
  186. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  187. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  188. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/40fd179449501b801f80c852d1635a16 +0 -0
  189. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/4499e16a29d89bdf30304de41c456b43 +0 -0
  190. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/49088e1598df49c63ff7d874c97e958f +0 -0
  191. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/7398a3a743326d3576cbb05a000df04b +0 -0
  192. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/8eedfb1d9aee665c9f5a77df67b64a81 +0 -0
  193. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/91d718eeae4552c702b8eafd9e8bbe76 +0 -0
  194. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/9e2c26ef339b5827a5c296acb284ab99 +0 -0
  195. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/a4f2f445b4f8578493957e4f7b0c76e3 +0 -0
  196. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/af361e697648848dbf0282eba1d15c2f +0 -0
  197. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/af95fe3d35c9fe417700e8c3625329fe +0 -0
  198. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/b89f385c2540cb58f04dbfed561d3902 +0 -0
  199. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/bc1864fd5bfa875243b05071735cbb82 +0 -0
  200. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/bede0f0813e15081ea4ee32b640c92c4 +0 -0
  201. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/c1ba4e65491e8bb9fcdc38b22cb64aa9 +0 -0
  202. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/cb741827a22668ecf975f78242076b6b +0 -0
  203. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  204. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/d3516b65bb025bc333e0f91647a7b119 +0 -0
  205. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  206. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/df7c1d81da90fb0287da1e283291dc81 +0 -0
  207. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/f78ea05f6019d54c3572513ebae03556 +0 -0
  208. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/f7c2f64864ec1995aee8dcead45d7f24 +0 -0
  209. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  210. data/spec/dummy/rails-4.0.4/tmp/cache/assets/test/sprockets/fbbb5b21a4144f5e3efee9eda4fc38e5 +0 -0
  211. data/spec/dummy/rails-4.1.0/db/migrate/20141102231432_create_users.rb +0 -9
  212. data/spec/dummy/rails-4.1.0/db/migrate/20141102231434012012157000_create_notify_user_notifications.rb +0 -13
  213. data/spec/dummy/rails-4.1.0/db/migrate/20141102231434013013847000_create_notify_user_user_hashes.rb +0 -12
  214. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  215. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/1bded108b40ef13c7e07be129e2cd83c +0 -0
  216. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/1ebdd9dfe7e88e90bee37951e2da1ea2 +0 -0
  217. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/23fe609acece1521082ad6b8249f96b1 +0 -0
  218. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  219. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  220. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/3fa5cc1bc06bfb81887b971eb8d36258 +0 -0
  221. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/796287194e2490ae173cabd0f8e0fce7 +0 -0
  222. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/8d2563dcd2d59f9e020fc2623eda3999 +0 -0
  223. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/8ebc0d0c963e18c7c16e6e7f55fd379f +0 -0
  224. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/91d718eeae4552c702b8eafd9e8bbe76 +0 -0
  225. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/9e2c26ef339b5827a5c296acb284ab99 +0 -0
  226. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/a098882f88a8b3ca91d2efaada23dba3 +0 -0
  227. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/af361e697648848dbf0282eba1d15c2f +0 -0
  228. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/b89f385c2540cb58f04dbfed561d3902 +0 -0
  229. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/c1ba4e65491e8bb9fcdc38b22cb64aa9 +0 -0
  230. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/cb741827a22668ecf975f78242076b6b +0 -0
  231. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  232. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  233. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/df7c1d81da90fb0287da1e283291dc81 +0 -0
  234. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/f031b3342a7246183ffa1bb7819f293e +0 -0
  235. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/f78ea05f6019d54c3572513ebae03556 +0 -0
  236. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  237. data/spec/dummy/rails-4.1.0/tmp/cache/assets/test/sprockets/fbbb5b21a4144f5e3efee9eda4fc38e5 +0 -0
  238. data/spec/models/notify_user/houston_spec.rb +0 -33
@@ -4,9 +4,6 @@ require 'rails/test_help'
4
4
 
5
5
  class ActiveSupport::TestCase
6
6
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
7
- #
8
- # Note: You'll currently still have to declare fixtures explicitly in integration tests
9
- # -- they do not yet inherit this setting
10
7
  fixtures :all
11
8
 
12
9
  # Add more helper methods to be used by all tests here...
@@ -0,0 +1,3 @@
1
+ [o:Set:
2
+ @hash{
3
+ I"environment-version:ETTI"environment-paths;TTI"0processors:type=text/css&file_type=text/css;TTI"hfile-digest:///Users/anton/workspace/notify_user/app/assets/stylesheets/notify_user/notify_user.css;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TT
@@ -0,0 +1 @@
1
+ I"�/Users/anton/workspace/notify_user/app/assets/javascripts/notify_user/notification.js?type=application/javascript&id=61149a8231535cdb0802ac42bc4d3dd4fdf7bbf78e0982d49b32ebd61f1b476a:ET
@@ -0,0 +1 @@
1
+ "%cK��P�A��G��D�,_� ��|�aLa�
@@ -0,0 +1,3 @@
1
+ [o:Set:
2
+ @hash{
3
+ I"environment-version:ETTI"environment-paths;TTI"Lprocessors:type=application/javascript&file_type=application/javascript;TTI"hfile-digest:///Users/anton/workspace/notify_user/app/assets/javascripts/notify_user/notification.js;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TT
@@ -0,0 +1 @@
1
+ I"�app/assets/stylesheets/application.css?type=text/css&pipeline=self&id=672f11df0f160c5378abcd1e434ad390158f0454aa8d02baf25e6ecd3efb74aa:ET
@@ -0,0 +1 @@
1
+ I"}app/assets/stylesheets/application.css?type=text/css&id=76743947a4cb49f7dd528768c04b9a6e6672cc40163dcbbc5ed210817e510c9a:ET
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI"0processors:type=text/css&file_type=text/css;TTI"9file-digest://app/assets/stylesheets/application.css;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI")file-digest://app/assets/stylesheets;TT
@@ -0,0 +1 @@
1
+ I"�/Users/anton/workspace/notify_user/app/assets/stylesheets/notify_user/notify_user.css?type=text/css&id=d4136d011f761b73a3eda9c8d266e35003ee1ed5ea674226210259697dc0392f:ET
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"hfile-digest:///Users/anton/workspace/notify_user/app/assets/stylesheets/notify_user/notify_user.css;TT
@@ -0,0 +1 @@
1
+ "%��Rm�v�S3.��O�L���ڹc�ƕq�=_j�
@@ -0,0 +1 @@
1
+ "%]!�K��X�K�֓�ޖ���';�����4x��
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"hfile-digest:///Users/anton/workspace/notify_user/app/assets/javascripts/notify_user/notification.js;TT
@@ -0,0 +1,3 @@
1
+ [o:Set:
2
+ @hash{
3
+ I"environment-version:ETTI"environment-paths;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"9file-digest://app/assets/stylesheets/application.css;TTI")file-digest://app/assets/stylesheets;TT
@@ -0,0 +1 @@
1
+ I"�/Users/anton/workspace/notify_user/app/assets/stylesheets/notify_user/notify_user.css?type=text/css&pipeline=self&id=7b0fca9fe7e02f6095e89c0640e6b1fc71949c6242d7ffbc37bd1e22a2b02f33:ET
@@ -0,0 +1 @@
1
+ "%�p���X|���Q&�L;&�t]� �ZP}O
@@ -0,0 +1 @@
1
+ I"�/Users/anton/workspace/notify_user/app/assets/javascripts/notify_user/notification.js?type=application/javascript&pipeline=self&id=62e64bb794f52761bc30a0a0d7f32de7347579aff22beb3d7483bfea4c2da37b:ET
@@ -1,10 +1,7 @@
1
- # Read about factories at https://github.com/thoughtbot/factory_girl
2
-
3
1
  FactoryGirl.define do
4
- factory :notify_user_notification, :class => 'Notification' do
5
- type ""
6
- target_id 1
7
- target_type "MyString"
8
- params "MyText"
2
+ factory :notify_user_notification, class: 'NewPostNotification' do
3
+ params {{ data: 'My Data' }}
4
+
5
+ association :target, factory: :user
9
6
  end
10
7
  end
@@ -0,0 +1,7 @@
1
+ FactoryGirl.define do
2
+ factory :user do
3
+ sequence :email do |n|
4
+ "#{n}@notifyuser.com"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApnsChannel do
4
+ let(:user) { User.create({email: 'user@example.com' })}
5
+ let(:notification) { NewPostNotification.create({target: user}) }
6
+
7
+ before do
8
+ @android = instance_double('Device', token: 'android_token')
9
+ @ios = instance_double('Device', token: 'ios_token')
10
+
11
+ allow(notification).to receive(:mobile_message) { 'Message' }
12
+
13
+ allow_any_instance_of(NotifyUser::Apns).to receive(:push)
14
+ allow_any_instance_of(NotifyUser::Gcm).to receive(:push)
15
+ end
16
+
17
+ describe 'device spliting' do
18
+ context 'all devices' do
19
+ before do
20
+ devices = double('Device', ios: [@ios], android: [@android])
21
+ allow_any_instance_of(User).to receive(:devices) { devices }
22
+ end
23
+
24
+ it 'routes the notifications via apns' do
25
+ @apns = NotifyUser::Apns.new([notification], [@ios], {})
26
+ expect(NotifyUser::Apns).to receive(:new) { @apns }
27
+
28
+ described_class.deliver(notification)
29
+ end
30
+
31
+ it 'routes the notifications via gcm' do
32
+ @gcm = NotifyUser::Gcm.new([notification], [@android], {})
33
+ expect(NotifyUser::Gcm).to receive(:new) { @gcm }
34
+
35
+ described_class.deliver(notification)
36
+ end
37
+ end
38
+
39
+ context 'only ios' do
40
+ before do
41
+ devices = double('Device', ios: [@ios], android: [])
42
+ allow_any_instance_of(User).to receive(:devices) { devices }
43
+ end
44
+
45
+ it 'doesnt make use of the gcm route' do
46
+ expect(NotifyUser::Gcm).not_to receive(:new)
47
+
48
+ described_class.deliver(notification)
49
+ end
50
+ end
51
+
52
+ context 'only android' do
53
+ before do
54
+ devices = double('Device', ios: [], android: [@android])
55
+ allow_any_instance_of(User).to receive(:devices) { devices }
56
+ end
57
+
58
+ it 'doesnt make use of the gcm route' do
59
+ expect(NotifyUser::Apns).not_to receive(:new)
60
+
61
+ described_class.deliver(notification)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,32 +1,32 @@
1
- require "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
- describe NotifyUser::NotificationMailer do
4
- describe "notification_email" do
3
+ module NotifyUser
4
+ describe NotificationMailer do
5
+ describe 'notification_email' do
6
+ let(:user) { build(:user) }
7
+ let(:notification) { NewPostNotification.new(target: user) }
8
+ let(:mailer) { NotificationMailer.send(:new, 'notification_email', notification, ActionMailerChannel.default_options) }
9
+ let(:mail) { mailer.notification_email(notification, ActionMailerChannel.default_options) }
5
10
 
6
- let(:user) { User.new({email: "user@example.com" })}
7
- let(:notification) { NewPostNotification.new({target: user}) }
8
- let(:mailer) { NotifyUser::NotificationMailer.send(:new, 'notification_email', notification, ActionMailerChannel.default_options) }
9
- let(:mail) { mailer.notification_email(notification, ActionMailerChannel.default_options) }
11
+ before :each do
12
+ allow(BaseNotification).to receive(:find).and_return(notification)
13
+ end
10
14
 
11
- before :each do
12
- NotifyUser::BaseNotification.stub(:find).and_return(notification)
13
- end
15
+ it 'renders the headers' do
16
+ expect(mail.subject).to eq(ActionMailerChannel.default_options[:subject])
17
+ expect(mail.to).to eq([user.email])
18
+ expect(mail.from).to eq([NotifyUser.mailer_sender])
19
+ end
14
20
 
15
- it "renders the headers" do
16
- mail.subject.should eq(ActionMailerChannel.default_options[:subject])
17
- mail.to.should eq([user.email])
18
- mail.from.should eq([NotifyUser.mailer_sender])
19
- end
21
+ it "renders a template to render the notification's template as a partial" do
22
+ mailer_should_render_template(mailer, 'notify_user/action_mailer/notification')
23
+ mail
24
+ end
20
25
 
21
- it "renders a template to render the notification's template as a partial" do
22
- mailer_should_render_template(mailer, "notify_user/action_mailer/notification")
23
- mail
26
+ it 'renders with a layout' do
27
+ allow_any_instance_of(NotificationMailer).to receive(:notification).and_return(notification)
28
+ expect(mail.body.raw_source).to include 'This is the default generated layout'
29
+ end
24
30
  end
25
-
26
- it "renders with a layout" do
27
- NotifyUser::NotificationMailer.any_instance.stub(:notification).and_return(notification)
28
- mail.body.raw_source.should include "This is the default generated layout"
29
- end
30
-
31
31
  end
32
32
  end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ module NotifyUser
4
+ describe APNConnection do
5
+ describe 'pem file paths' do
6
+ before :each do
7
+ @connection = described_class.new
8
+ end
9
+
10
+ it 'has the correct default development path' do
11
+ expect(@connection.send(:development_certificate)).to eq "#{Rails.root}/config/keys/development_push.pem"
12
+ end
13
+
14
+ it 'has the correct default production path' do
15
+ expect(@connection.send(:production_certificate)).to eq "#{Rails.root}/config/keys/production_push.pem"
16
+ end
17
+
18
+ it 'can set a custom path for development' do
19
+ ENV['APN_DEVELOPMENT_PATH'] = 'path/to/key.pem'
20
+ expect(@connection.send(:development_certificate)).to eq "#{Rails.root}/path/to/key.pem"
21
+ end
22
+
23
+ it 'can set a custom path for production' do
24
+ ENV['APN_PRODUCTION_PATH'] = 'path/to/key.pem'
25
+ expect(@connection.send(:production_certificate)).to eq "#{Rails.root}/path/to/key.pem"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+ require 'support/test_apn_connection'
3
+
4
+ module NotifyUser
5
+ describe Apns do
6
+ let(:user) { create(:user, email: 'user@example.com') }
7
+ let(:notification) { create(:notify_user_notification, target: user) }
8
+
9
+ describe 'initialisation' do
10
+ before :each do
11
+ @apns = Apns.new([notification], [], {})
12
+ end
13
+
14
+ describe 'push options' do
15
+ it 'sets the mobile message' do
16
+ expect(@apns.push_options[:alert]).to eq notification.mobile_message
17
+ end
18
+
19
+ it 'sets the badge to 1' do
20
+ expect(@apns.push_options[:badge]).to eq 1
21
+ end
22
+
23
+ it 'sets the notification category' do
24
+ expect(@apns.push_options[:category]).to eq notification.class.name
25
+ end
26
+
27
+ it 'sets the custom data with params' do
28
+ expect(@apns.push_options[:custom_data]).to eq notification.params
29
+ end
30
+
31
+ it 'has a default sound' do
32
+ expect(@apns.push_options[:sound]).to eq 'default'
33
+ end
34
+
35
+ it 'can use custom sounds' do
36
+ apns = Apns.new([notification], [], sound: 'special.wav')
37
+
38
+ expect(apns.push_options[:sound]).to eq 'special.wav'
39
+ end
40
+
41
+ it 'removes the badge key for silent notifications' do
42
+ apns = Apns.new([notification], [], silent: true)
43
+
44
+ expect(apns.push_options).not_to have_key(:badge)
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'push' do
50
+ before :each do
51
+ @apns = Apns.new([notification], [], {})
52
+
53
+ @connection = TestAPNConnection.new
54
+
55
+ allow(@apns).to receive(:connection) { @connection }
56
+ end
57
+
58
+ context 'with no errors' do
59
+ before :each do
60
+ allow(IO).to receive(:select) { [nil, nil] }
61
+ end
62
+
63
+ it 'succeeds if no error' do
64
+ expect(@apns.push).to eq true
65
+ end
66
+
67
+ it 'writes to the connection for each device' do
68
+ devices = []
69
+ 3.times do
70
+ devices << create_device_double
71
+ end
72
+ allow(@apns).to receive(:devices) { devices }
73
+ expect(@connection).to receive(:write).exactly(3).times
74
+ @apns.push
75
+ end
76
+ end
77
+
78
+ context 'with an error' do
79
+ before :each do
80
+ # Return errors first time, no errors on recursion
81
+ allow(IO).to receive(:select).and_return([[true], nil], [nil, nil])
82
+ error_string = "nil, #{status}, #{error_index}"
83
+ allow(@connection).to receive(:read) { error_string }
84
+ end
85
+
86
+ let(:status) { 8 }
87
+ let(:error_index) { 0 }
88
+
89
+ it 'tries again if an error occurs' do
90
+ expect(@apns).to receive(:send_notifications).twice.and_call_original
91
+ @apns.push
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+ require 'support/test_gcm_connection'
3
+
4
+ module NotifyUser
5
+ describe Gcm, type: :model do
6
+ let(:user) { create(:user) }
7
+ let(:notification) { create(:notify_user_notification, target: user) }
8
+ let(:user_tokens) { ['a_token'] }
9
+
10
+ before :each do
11
+ allow_any_instance_of(Gcm).to receive(:device_tokens) { user_tokens }
12
+ @client = TestGCMConnection.new
13
+ allow_any_instance_of(Gcm).to receive(:client).and_return(@client)
14
+ end
15
+
16
+ describe 'initialisation' do
17
+ it 'initialises the correct push options' do
18
+ @gcm = Gcm.new([notification], [], {})
19
+
20
+ expect(@gcm.push_options).to include(
21
+ data: {
22
+ notification_id: notification.id,
23
+ message: notification.mobile_message,
24
+ type: notification.class.name,
25
+ unread_count: 1,
26
+ custom_data: notification.params
27
+ }
28
+ )
29
+ end
30
+ end
31
+
32
+ describe 'push' do
33
+ before :each do
34
+ @gcm = Gcm.new([notification], [], {})
35
+ end
36
+
37
+ context 'without errors' do
38
+ before :each do
39
+ # Stub out send method with a successful response object, or maybe,
40
+ # initialize TestGCMConnection with new(:success)
41
+ # This would keep the spec file clean...
42
+ end
43
+
44
+ it 'returns true if no error' do
45
+ expect(@gcm.push).to eq true
46
+ end
47
+
48
+ it 'sends to the device token of the notification target' do
49
+ expect(@client).to receive(:send).with(user_tokens, kind_of(Hash))
50
+ @gcm.push
51
+ end
52
+
53
+ it 'does not try to send to an empty token' do
54
+ user_tokens = []
55
+ allow_any_instance_of(Gcm).to receive(:device_tokens) { user_tokens }
56
+ expect_any_instance_of(GCM).not_to receive(:send)
57
+ @gcm.push
58
+ end
59
+
60
+ it 'sends multiple notifications' do
61
+ multiple_tokens = %w(token_1 token_2 token_3)
62
+ allow(@gcm).to receive(:device_tokens) { multiple_tokens }
63
+ expect(@client).to receive(:send).once
64
+ .with(multiple_tokens, kind_of(Hash))
65
+ @gcm.push
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -5,172 +5,565 @@ module NotifyUser
5
5
 
6
6
  let(:user) { User.create({email: "user@example.com" })}
7
7
  let(:notification) { NewPostNotification.create({target: user}) }
8
- Rails.application.routes.default_url_options[:host]= 'localhost:5000'
8
+ Rails.application.routes.default_url_options[:host]= 'localhost:5000'
9
9
 
10
10
  before :each do
11
- BaseNotification.any_instance.stub(:mobile_message).and_return("New Notification")
12
- # BaseNotification.channel(:apns, {aggregate_per: false})
11
+ NewPostNotification.class_eval do
12
+ channel :action_mailer
13
+ self.aggregate_grouping = false
14
+ end
15
+
16
+ allow_any_instance_of(BaseNotification).to receive(:mobile_message) { 'New Notification' }
13
17
  end
14
18
 
15
19
  describe "notification count" do
16
20
  it "returns the sent count for a user" do
17
- notification.count_for_target.should eq 1
21
+ expect(notification.count_for_target).to eq 1
18
22
  end
19
23
  end
20
24
 
21
25
  describe "params" do
22
-
23
26
  it "doesn't fail if searching for param variable that doesn't exist" do
24
- notification.params[:unknown].should eq nil
27
+ expect(notification.params[:unknown]).to eq nil
25
28
  end
26
29
 
27
30
  it "doesn't fail if searching for a param that doesn't exist if other params are present" do
28
31
  notification.params = {name: "hello_world"}
29
- notification.params[:unknown].should eq nil
32
+ expect(notification.params[:unknown]).to eq nil
30
33
  end
31
34
 
32
35
  it "can reference params using string when submitted as json" do
33
36
  notification.params = {"listing_id" => 1}
34
37
  notification.save
35
38
 
36
- NewPostNotification.last.params["listing_id"].should eq 1
39
+ expect(NewPostNotification.last.params["listing_id"]).to eq 1
37
40
  end
38
41
 
39
42
  it "can reference params using symbol when submitted as json" do
40
43
  notification.params = {"listing_id" => 1}
41
44
  notification.save
42
45
 
43
- NewPostNotification.last.params[:listing_id].should eq 1
46
+ expect(NewPostNotification.last.params[:listing_id]).to eq 1
44
47
  end
45
48
 
46
49
  it "can reference params using symbol when submitted as hash" do
47
50
  notification.params = {:listing_id => 1}
48
51
  notification.save
49
52
 
50
- NewPostNotification.last.params[:listing_id].should eq 1
53
+ expect(NewPostNotification.last.params[:listing_id]).to eq 1
51
54
  end
52
55
 
53
56
  it "can reference params using string when subbmited as hash" do
54
57
  notification.params = {:listing_id => 1}
55
58
  notification.save
56
59
 
57
- NewPostNotification.last.params["listing_id"].should eq 1
60
+ expect(NewPostNotification.last.params["listing_id"]).to eq 1
58
61
  end
59
62
  end
60
63
 
61
64
  describe "#notify" do
65
+ before do
66
+ @notification = NewPostNotification.create(target: user)
67
+ end
62
68
 
63
69
  it "sets the state to pending" do
64
- notification = NewPostNotification.create({target: user})
65
- notification.notify
66
- notification.state.should eq "pending"
70
+ @notification.notify
71
+ expect(@notification.reload.state).to eq 'pending'
67
72
  end
68
73
 
69
- describe "#deliver" do
74
+ it "passing false marks the notification as sent" do
75
+ @notification.notify(false)
76
+ expect(@notification.reload.state).to eq 'sent'
77
+ end
70
78
 
71
- describe "with aggregation enabled" do
72
- it "schedules a job to wait for more notifications to aggregate if there is not one already" do
73
- NewPostNotification.should_receive(:delay_for)
74
- .with(notification.class.aggregate_per).and_call_original
79
+ context 'using aggregation' do
80
+ before do
81
+ allow(NewPostNotification).to receive(:aggregate_grouping) { true }
82
+ end
75
83
 
76
- notification.deliver
77
- end
84
+ it 'doesnt assign a parent if there arent any' do
85
+ @notification.notify
86
+ expect(@notification.reload.parent_id).to be_nil
87
+ end
78
88
 
79
- it "doesn't schedule a job if a pending notification awaiting aggregation already exists" do
80
- another_notification = NewPostNotification.create({target: user})
81
- NewPostNotification.should_not_receive(:delay_for)
82
- .with(notification.class.aggregate_per).and_call_original
89
+ it 'doesnt assign a parent if one hasnt been created within 24 hours' do
90
+ @t = 25.hours.ago
91
+ @parent = NewPostNotification.create(target: user, created_at: @t)
83
92
 
84
- notification.deliver
85
- end
93
+ @notification.notify
94
+ expect(@notification.reload.parent_id).to be_nil
86
95
  end
87
96
 
88
- describe "with aggregation disabled" do
89
- before :each do
90
- NewPostNotification.channel(:action_mailer, {aggregate_per: false})
91
- end
97
+ it 'assigns a parent if one has been created within 24 hours' do
98
+ @t = 23.hours.ago
99
+ @parent = NewPostNotification.create(target: user, created_at: @t)
92
100
 
93
- it "schedules notification to be sent through channels" do
94
- NewPostNotification.should_receive(:delay).and_call_original
95
- notification.deliver
96
- end
101
+ @notification.notify
102
+ expect(@notification.reload.parent_id).to eq @parent.id
97
103
  end
98
104
  end
99
105
  end
100
106
 
101
- describe "notify!" do
107
+ describe "#deliver" do
108
+ context "with aggregation enabled" do
109
+ it "schedules a job to wait for more notifications to aggregate if there is not one already" do
110
+ expect(NewPostNotification).to(
111
+ receive(:delay_for).with(notification.class.aggregate_per)
112
+ ).and_call_original
113
+
114
+ notification.deliver
115
+ end
116
+
117
+ it "doesn't schedule a job if a pending notification awaiting aggregation already exists" do
118
+ another_notification = NewPostNotification.create({target: user, state: "pending_as_aggregation_parent"})
119
+
120
+ expect(NewPostNotification).not_to(
121
+ receive(:delay_for).with(notification.class.aggregate_per)
122
+ )
123
+
124
+ notification.deliver
125
+ end
126
+ end
127
+
128
+ context "with aggregation disabled" do
129
+ before :each do
130
+ NewPostNotification.channel(:action_mailer, {aggregate_per: false})
131
+ end
132
+
133
+ it "schedules notification to be sent through channels" do
134
+ expect(NewPostNotification).to receive(:delay).and_call_original
135
+ notification.deliver
136
+ end
137
+ end
138
+ end
102
139
 
140
+ describe "notify!" do
103
141
  it "sets the state to pending_no_aggregation" do
104
142
  notification = NewPostNotification.create({target: user})
105
143
  notification.notify!
106
- notification.state.should eq "pending_no_aggregation"
144
+
145
+ expect(notification.state).to eq "pending_no_aggregation"
107
146
  end
108
147
 
109
- describe ".deliver_notification_channel" do
148
+ describe ".deliver_notification_channel" do
149
+ before :each do
150
+ @notification = NewPostNotification.create({target: user})
151
+ end
110
152
 
111
- before :each do
112
- @notification = NewPostNotification.create({target: user})
113
- end
153
+ it "doesn't send if unsubscribed from channel" do
154
+ unsubscribe = NotifyUser::Unsubscribe.create({target: user, type: "action_mailer"})
114
155
 
115
- it "doesn't send if unsubscribed from channel" do
116
- unsubscribe = NotifyUser::Unsubscribe.create({target: user, type: "action_mailer"})
117
- ActionMailerChannel.should_not_receive(:deliver)
118
- BaseNotification.deliver_notification_channel(@notification.id, "action_mailer")
119
- end
156
+ expect(ActionMailerChannel).not_to receive(:deliver)
157
+ BaseNotification.deliver_notification_channel(@notification.id, "action_mailer")
158
+ end
120
159
 
121
- it "does send if subscribed to channel" do
122
- ActionMailerChannel.should_receive(:deliver)
123
- BaseNotification.deliver_notification_channel(@notification.id, "action_mailer")
124
- end
160
+ it "does send if subscribed to channel" do
161
+ expect(ActionMailerChannel).to receive(:deliver)
162
+ BaseNotification.deliver_notification_channel(@notification.id, "action_mailer")
163
+ end
125
164
  end
126
165
 
127
166
  describe "#deliver!" do
128
167
  it "schedules to be delivered to channels" do
129
168
  notification.dont_aggregate
130
- NewPostNotification.should_receive(:deliver_channels)
131
- .with(notification.id)
132
- .and_call_original
133
- notification.deliver!
169
+
170
+ expect(NewPostNotification).to(
171
+ receive(:deliver_channels).with(notification.id)
172
+ ).and_call_original
173
+
174
+ notification.deliver!
134
175
  end
135
176
  end
136
177
 
137
178
  describe "#deliver_channels" do
138
-
139
179
  it "delivers notification to channels" do
140
- ActionMailerChannel.should_receive(:deliver).once
180
+ expect(ActionMailerChannel).to receive(:deliver).once
141
181
  NewPostNotification.deliver_channels(notification.id)
142
182
  end
143
-
144
183
  end
145
184
  end
146
185
 
147
186
  describe "#notify_aggregated_channel" do
148
-
149
187
  it "if only one notification to aggregate hit deliver_notification_channel" do
150
- NewPostNotification.should_receive(:deliver_notification_channel).with(notification.id, :action_mailer).once
188
+ expect(NewPostNotification).to receive(:deliver_notification_channel).with(notification.id, :action_mailer).once
151
189
  NewPostNotification.notify_aggregated_channel(notification.id, :action_mailer)
152
190
  end
153
191
 
154
192
  it "if many notifications to aggregate hit deliver_notifications_channel" do
155
193
  another_notification = NewPostNotification.create({target: user})
156
194
 
157
- NewPostNotification.should_receive(:deliver_notifications_channel).once
195
+ expect(NewPostNotification).to receive(:deliver_notifications_channel).once
196
+ NewPostNotification.notify_aggregated_channel(notification.id, :action_mailer)
197
+ end
198
+
199
+ it "if notification is marked_as_read don't deliver" do
200
+ notification = NewPostNotification.create({target: user, state: "read"})
201
+
202
+ expect(NewPostNotification).not_to receive(:deliver_notification_channel)
203
+ expect(NewPostNotification).not_to receive(:deliver_notifications_channel)
204
+
158
205
  NewPostNotification.notify_aggregated_channel(notification.id, :action_mailer)
159
206
  end
160
207
 
208
+ context "with aggregate grouping enabled" do
209
+ before do
210
+ allow(NewPostNotification).to receive(:aggregate_grouping) { true }
211
+ end
212
+
213
+ it "should receive pending_aggregation_by_group_with" do
214
+ notification = NewPostNotification.create({target: user, group_id: 2})
215
+
216
+ expect(NewPostNotification).to receive(:pending_aggregation_by_group_with).and_call_original
217
+ NewPostNotification.notify_aggregated_channel(notification.id, :action_mailer)
218
+ end
219
+ end
220
+ end
221
+
222
+ describe "interval aggregation" do
223
+ before :each do
224
+ Sidekiq::Testing.fake!
225
+ @aggregate_per = [0, 1, 4, 5]
226
+ NewPostNotification.class_eval do
227
+ channel :action_mailer, aggrregate_per: @aggregate_per
228
+
229
+ self.aggregate_grouping = true
230
+ end
231
+ end
232
+
233
+ it "marking a pending_as_aggregation_parent as sent sets it to sent_as_aggregation_parent" do
234
+ notification = NewPostNotification.create({target: user, group_id: 1, state: "pending_as_aggregation_parent"})
235
+ notification.mark_as_sent!
236
+ expect(notification.reload.state).to eq "sent_as_aggregation_parent"
237
+ end
238
+
239
+ describe "aggregate interval" do
240
+ describe "first notification to be received after a notification was sent" do
241
+ it "includes notifications within 24hours from first notification" do
242
+ end
243
+
244
+ it "first notification returns interval 0" do
245
+ notification = NewPostNotification.create({target: user, group_id: 1})
246
+ expect(notification.aggregation_interval).to eq 0
247
+ end
248
+
249
+ it "second notification returns internal 1" do
250
+ NewPostNotification.create({target: user, group_id: 1, state: "sent_as_aggregation_parent"})
251
+ notification = NewPostNotification.create({target: user, group_id: 1})
252
+ expect(notification.aggregation_interval).to eq 1
253
+ end
254
+
255
+ it "third notification returns interval 2" do
256
+ NewPostNotification.create({target: user, group_id: 1, state: "sent_as_aggregation_parent"})
257
+ NewPostNotification.create({target: user, group_id: 1, state: "sent_as_aggregation_parent"})
258
+
259
+ notification = NewPostNotification.create({target: user, group_id: 1})
260
+ expect(notification.aggregation_interval).to eq 2
261
+ end
262
+
263
+ it "doesn't include sent notifications from another target_id" do
264
+ NewPostNotification.create({target: user, group_id: 3, state: "sent_as_aggregation_parent"})
265
+ NewPostNotification.create({target: user, group_id: 0, state: "sent_as_aggregation_parent"})
266
+
267
+ notification = NewPostNotification.create({target: user, group_id: 1})
268
+ expect(notification.aggregation_interval).to eq 0
269
+ end
270
+
271
+ it "agregation interval should include pending as parent states as well" do
272
+ NewPostNotification.create({target: user, group_id: 1, state: "sent_as_aggregation_parent"})
273
+ NewPostNotification.create({target: user, group_id: 1, state: "pending_as_aggregation_parent"})
274
+
275
+ notification = NewPostNotification.create({target: user, group_id: 1})
276
+ expect(notification.aggregation_interval).to eq 2
277
+ end
278
+ end
279
+ end
280
+
281
+ describe "parent_id" do
282
+ it "sets parent_id if the time between the previous parent_id is less than 24 hours ago" do
283
+ n = NewPostNotification.create({target: user, group_id: 1, state: "sent_as_aggregation_parent", parent_id: nil})
284
+
285
+ Timecop.travel(10.hours.from_now) do
286
+ notification = NewPostNotification.new({target: user, group_id: 1})
287
+ notification.notify
288
+
289
+ expect(notification.parent_id).to eq n.id
290
+ end
291
+ end
292
+
293
+ it "does not set parent_id if time between previous parent_id is more than 24 hours ago" do
294
+ n = NewPostNotification.create({target: user, group_id: 1, state: "sent_as_aggregation_parent", parent_id: nil})
295
+
296
+ Timecop.travel(25.hours.from_now) do
297
+ notification = NewPostNotification.new({target: user, group_id: 1})
298
+ notification.notify
299
+
300
+ expect(notification.reload.parent_id).to eq nil
301
+ end
302
+ end
303
+
304
+ it "parent_id gets set to the latest id of the latest parents" do
305
+ NewPostNotification.create({target: user, group_id: 1, parent_id: nil})
306
+
307
+ Timecop.travel(10.hours.from_now) do
308
+ n = NewPostNotification.new({target: user, group_id: 1, parent_id: nil, created_at: 10.hours.ago})
309
+
310
+ Timecop.travel(15.hours.from_now) do
311
+ notification = NewPostNotification.new({target: user, group_id: 1})
312
+ notification.notify
313
+
314
+ expect(notification.reload.parent_id).to eq n.id
315
+ end
316
+ end
317
+ end
318
+ end
319
+
320
+ describe "delay_time" do
321
+
322
+ it "first notification will return Time.now" do
323
+ notification = NewPostNotification.create({target: user, group_id: 1})
324
+ expect(notification.delay_time({aggregate_per: @aggregate_per}).to_s).to eq notification.created_at.to_s
325
+ end
326
+
327
+ it "notification received during first interval returns last time + x.minutes " do
328
+ n = NewPostNotification.create!({target: user, group_id: 1, state: "pending_as_aggregation_parent"})
329
+ n.mark_as_sent!
330
+
331
+ notification = NewPostNotification.create!({target: user, group_id: 1})
332
+ expect(notification.delay_time({aggregate_per: @aggregate_per}).to_s).to eq (n.sent_time + 1.minute).to_s
333
+ end
334
+
335
+ it "notification returned during third interval returns last time + x.minutes" do
336
+ NewPostNotification.create({target: user, group_id: 1, state: "pending_as_aggregation_parent"}).mark_as_sent!
337
+ n = NewPostNotification.create({target: user, group_id: 1, state: "pending_as_aggregation_parent"})
338
+ n.mark_as_sent!
339
+
340
+ notification = NewPostNotification.create({target: user, group_id: 1})
341
+ expect(notification.delay_time({aggregate_per: @aggregate_per}).to_s).to eq (n.sent_time + 4.minute).to_s
342
+ end
343
+
344
+ it "notification received after all intervals have ended just uses the last interval" do
345
+ 10.times do
346
+ NewPostNotification.create({target: user, group_id: 1, state: "pending_as_aggregation_parent"}).mark_as_sent!
347
+ end
348
+ last_n = NewPostNotification.create({target: user, group_id: 1, state: "pending_as_aggregation_parent"})
349
+ last_n.mark_as_sent!
350
+
351
+ notification = NewPostNotification.create({target: user, group_id: 1})
352
+ expect(notification.delay_time({aggregate_per: @aggregate_per}).to_s).to eq (last_n.sent_time + 5.minute).to_s
353
+ end
354
+ end
355
+
356
+ describe "the first notification" do
357
+ before :each do
358
+ @notification = NewPostNotification.create({target: user, group_id: 1})
359
+ end
360
+
361
+ it "should send immediately" do
362
+ expect{
363
+ @notification.deliver
364
+ }.to change(Sidekiq::Extensions::DelayedClass.jobs, :size).by(1)
365
+ end
366
+
367
+ it "should change state to pending_as_aggregation_parent" do
368
+ expect{
369
+ @notification.deliver
370
+ }.to change(@notification, :state).to "pending_as_aggregation_parent"
371
+ end
372
+
373
+ it "parent_id should be nil" do
374
+ @notification.deliver
375
+ expect(@notification.reload.parent_id).to eq nil
376
+ end
377
+ end
378
+
379
+ describe "receive subsequent notifications" do
380
+
381
+ describe "with no pending notifications" do
382
+ before :each do
383
+ @n = NewPostNotification.create({target: user, group_id: 1, state: "sent_as_aggregation_parent"})
384
+ end
385
+
386
+ it "delays notification" do
387
+ notification = NewPostNotification.create({target: user, group_id: 1, created_at: @n.created_at + 2.minutes})
388
+
389
+ expect{
390
+ notification.deliver
391
+ }.to change(Sidekiq::Extensions::DelayedClass.jobs, :size).by(1)
392
+ end
393
+
394
+ it "parent_id gets set to notification at interval 0" do
395
+ notification = NewPostNotification.new({target: user, group_id: 1, created_at: @n.created_at + 2.minutes})
396
+ notification.notify
397
+ expect(notification.reload.parent_id).to eq @n.id
398
+ end
399
+
400
+ end
401
+
402
+ describe "with pending notifications" do
403
+ before :each do
404
+ @n = NewPostNotification.create({target: user, group_id: 1, state: "sent_as_aggregation_parent"})
405
+ @other_notification = NewPostNotification.create({target: user, state: "pending_as_aggregation_parent", group_id: 1})
406
+ @notification = NewPostNotification.create({target: user, group_id: 1})
407
+ end
408
+
409
+ it "dont delay anything" do
410
+ expect{
411
+ @notification.deliver
412
+ }.to change(Sidekiq::Extensions::DelayedClass.jobs, :size).by(0)
413
+ end
414
+
415
+ it "state remains as pending" do
416
+ @notification.deliver
417
+ expect(@notification.reload.pending?).to eq true
418
+ end
419
+
420
+ end
421
+ end
422
+ #we need a way to identify which notification was the one that was delayed conceptually labeled "head" or a special state
423
+ #search how many unread/sent "head" notifications exist and use that as the interval
424
+ end
425
+
426
+ describe "validations" do
427
+ describe "aggregate_grouping false" do
428
+ before :each do
429
+ NewPostNotification.class_eval do
430
+ channel :action_mailer, aggrregate_per: [1, 4, 5]
431
+ end
432
+ end
433
+
434
+ it "doesn't require a group_id" do
435
+ notification = NewPostNotification.new({target: user})
436
+ expect(notification).to be_valid
437
+ end
438
+ end
439
+
440
+ describe "aggregate_grouping true" do
441
+ before :each do
442
+ NewPostNotification.class_eval do
443
+ channel :action_mailer, aggrregate_per: [1, 4, 5]
444
+ self.aggregate_grouping = true
445
+ end
446
+ end
447
+
448
+ it "if group_id present be valid" do
449
+ notification = NewPostNotification.new({target: user, group_id: 1})
450
+ expect(notification).to be_valid
451
+ end
452
+ it "if aggregate_grouping is true require a group_id" do
453
+ notification = NewPostNotification.new({target: user})
454
+ expect(notification).to_not be_valid
455
+ end
456
+ end
457
+ end
458
+
459
+ describe "user_has_unsubscribed?" do
460
+ it "true if unsubscribed from type" do
461
+ notification = NewPostNotification.create({target: user})
462
+ Unsubscribe.create({target: notification.target, type: "NewPostNotification"})
463
+
464
+ expect(notification.user_has_unsubscribed?).to eq true
465
+ end
466
+
467
+ it "false if haven't unsubscribed from type" do
468
+ notification = NewPostNotification.create({target: user})
469
+ expect(notification.user_has_unsubscribed?).to eq false
470
+ end
471
+
472
+ it "true if unsubscribed from channel" do
473
+ notification = NewPostNotification.create({target: user})
474
+ Unsubscribe.create({target: notification.target, type: "action_mailer"})
475
+
476
+ expect(notification.user_has_unsubscribed?(:action_mailer)).to eq true
477
+ end
478
+
479
+ it "false if haven't unsubscribed from channel" do
480
+ notification = NewPostNotification.create({target: user})
481
+
482
+ expect(notification.user_has_unsubscribed?(:action_mailer)).to eq false
483
+ end
484
+
485
+ it "true if unsubscribed from type and group_id" do
486
+ Unsubscribe.create({target: notification.target, type: "NewPostNotification", group_id: 1})
487
+ notification.update_attributes(group_id: 1)
488
+
489
+ expect(notification.user_has_unsubscribed?).to eq true
490
+ end
491
+
492
+ it "true if unsubcribed from type but pass in group_id" do
493
+ Unsubscribe.create({target: notification.target, type: "NewPostNotification"})
494
+ notification.update_attributes(group_id: 1)
495
+
496
+ expect(notification.user_has_unsubscribed?).to eq true
497
+ end
498
+
499
+ it "false if havent unsubscribed from type and group_id" do
500
+ notification.update_attributes(group_id: 1)
501
+ expect(notification.user_has_unsubscribed?).to eq false
502
+ end
503
+ end
504
+
505
+ describe "unsubscribing" do
506
+
507
+ describe "deliver_notification_channel" do
508
+ it "subscribed to type receives deliver" do
509
+ expect(ActionMailerChannel).to receive(:deliver)
510
+ NewPostNotification.deliver_notification_channel(notification.id, :action_mailer)
511
+ end
512
+
513
+ it "unsubscribed from type doesn't receive deliver" do
514
+ expect(ActionMailerChannel).to_not receive(:deliver)
515
+
516
+ Unsubscribe.create({target: notification.target, type: "action_mailer"})
517
+ NewPostNotification.deliver_notification_channel(notification.id, :action_mailer)
518
+ end
519
+
520
+ it "unsubscribed from type and group_id doesn't receive deliver " do
521
+ expect(ActionMailerChannel).to_not receive(:deliver)
522
+ Unsubscribe.create({target: notification.target, type: "NewPostNotification", group_id: 1})
523
+
524
+ notification.update_attributes(group_id: 1)
525
+
526
+ NewPostNotification.deliver_notification_channel(notification.id, :action_mailer)
527
+ end
528
+
529
+ end
530
+
531
+ describe "deliver_notifications_channel" do
532
+
533
+ it "subscribed to type receives deliver_aggregated" do
534
+ expect(ActionMailerChannel).to receive(:deliver_aggregated)
535
+ NewPostNotification.deliver_notifications_channel([notification], :action_mailer)
536
+ end
537
+
538
+ it "unsubscribed from type doesn't receive deliver_aggregated" do
539
+ expect(ActionMailerChannel).to_not receive(:deliver_aggregated)
540
+
541
+ Unsubscribe.create({target: notification.target, type: "action_mailer"})
542
+ NewPostNotification.deliver_notifications_channel([notification], :action_mailer)
543
+ end
544
+
545
+ it "unsubscribed from type and group_id doesn't receive deliver_aggregated " do
546
+ expect(ActionMailerChannel).to_not receive(:deliver_aggregated)
547
+
548
+ Unsubscribe.create({target: notification.target, type: "NewPostNotification", group_id: 1})
549
+ notification.update_attributes(group_id: 1)
550
+
551
+ NewPostNotification.deliver_notifications_channel([notification], :action_mailer)
552
+ end
553
+ end
161
554
  end
162
555
 
163
556
  describe "generate hash" do
164
557
  it "creates a new hash if an active hash doesn't already exist" do
165
558
  user_hash = notification.generate_unsubscribe_hash
166
- user_hash.should_not eq nil
559
+ expect(user_hash).not_to eq nil
167
560
  end
168
561
 
169
562
  it "uses the old hash if an active hash already exists" do
170
563
  user_hash = notification.generate_unsubscribe_hash
171
564
 
172
565
  another_hash = notification.generate_unsubscribe_hash
173
- another_hash.token.should eq user_hash.token
566
+ expect(another_hash.token).to eq user_hash.token
174
567
  end
175
568
 
176
569
  it "creates a new hash if no active hash exists" do
@@ -178,8 +571,7 @@ module NotifyUser
178
571
  user_hash.deactivate
179
572
 
180
573
  another_hash = notification.generate_unsubscribe_hash
181
- another_hash.token.should_not eq user_hash.token
182
-
574
+ expect(another_hash.token).not_to eq user_hash.token
183
575
  end
184
576
  end
185
577
  end