notify_user 0.1.4 → 0.3.1

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 (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