hyper-mesh 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (469) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +11 -0
  5. data/.travis.yml +4 -0
  6. data/CODE_OF_CONDUCT.md +13 -0
  7. data/Gemfile +5 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +396 -0
  10. data/Rakefile +6 -0
  11. data/app/controllers/reactive_record/application_controller.rb +4 -0
  12. data/app/controllers/reactive_record/reactive_record_controller.rb +49 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +7 -0
  15. data/codeship.database.yml +18 -0
  16. data/config/routes.rb +7 -0
  17. data/docs/action_cable_quickstart.md +151 -0
  18. data/docs/authorization-policies.md +449 -0
  19. data/docs/client_side_scoping.md +103 -0
  20. data/docs/pusher_quickstart.md +0 -0
  21. data/docs/simple_poller_quickstart.md +121 -0
  22. data/docs/todo-example.md +116 -0
  23. data/docs/words-example.md +65 -0
  24. data/examples/action-cable/.gitignore +21 -0
  25. data/examples/action-cable/Gemfile +58 -0
  26. data/examples/action-cable/Gemfile.lock +247 -0
  27. data/examples/action-cable/README.md +24 -0
  28. data/examples/action-cable/Rakefile +6 -0
  29. data/examples/action-cable/app/assets/config/manifest.js +3 -0
  30. data/examples/action-cable/app/assets/javascripts/application.js +18 -0
  31. data/examples/action-cable/app/assets/stylesheets/application.css +15 -0
  32. data/examples/action-cable/app/controllers/application_controller.rb +3 -0
  33. data/examples/action-cable/app/controllers/test_controller.rb +6 -0
  34. data/examples/action-cable/app/models/models.rb +2 -0
  35. data/examples/action-cable/app/models/public/application_record.rb +3 -0
  36. data/examples/action-cable/app/models/public/word.rb +2 -0
  37. data/examples/action-cable/app/policies/application_policy.rb +6 -0
  38. data/examples/action-cable/app/views/components.rb +17 -0
  39. data/examples/action-cable/app/views/components/app.rb +18 -0
  40. data/examples/action-cable/app/views/layouts/application.html.erb +14 -0
  41. data/examples/action-cable/app/views/layouts/mailer.html.erb +13 -0
  42. data/examples/action-cable/app/views/layouts/mailer.text.erb +1 -0
  43. data/examples/action-cable/bin/bundle +3 -0
  44. data/examples/action-cable/bin/rails +9 -0
  45. data/examples/action-cable/bin/rake +9 -0
  46. data/examples/action-cable/bin/setup +34 -0
  47. data/examples/action-cable/bin/spring +15 -0
  48. data/examples/action-cable/bin/update +29 -0
  49. data/examples/action-cable/config.ru +5 -0
  50. data/examples/action-cable/config/application.rb +30 -0
  51. data/examples/action-cable/config/boot.rb +3 -0
  52. data/examples/action-cable/config/cable.yml +9 -0
  53. data/examples/action-cable/config/database.yml +25 -0
  54. data/examples/action-cable/config/environment.rb +5 -0
  55. data/examples/action-cable/config/environments/development.rb +45 -0
  56. data/examples/action-cable/config/environments/production.rb +86 -0
  57. data/examples/action-cable/config/environments/test.rb +42 -0
  58. data/examples/action-cable/config/initializers/application_controller_renderer.rb +6 -0
  59. data/examples/action-cable/config/initializers/assets.rb +11 -0
  60. data/examples/action-cable/config/initializers/backtrace_silencers.rb +7 -0
  61. data/examples/action-cable/config/initializers/cookies_serializer.rb +5 -0
  62. data/examples/action-cable/config/initializers/filter_parameter_logging.rb +4 -0
  63. data/examples/action-cable/config/initializers/inflections.rb +16 -0
  64. data/examples/action-cable/config/initializers/mime_types.rb +4 -0
  65. data/examples/action-cable/config/initializers/new_framework_defaults.rb +24 -0
  66. data/examples/action-cable/config/initializers/session_store.rb +3 -0
  67. data/examples/action-cable/config/initializers/synchromesh.rb +5 -0
  68. data/examples/action-cable/config/initializers/wrap_parameters.rb +14 -0
  69. data/examples/action-cable/config/locales/en.yml +23 -0
  70. data/examples/action-cable/config/puma.rb +47 -0
  71. data/examples/action-cable/config/routes.rb +5 -0
  72. data/examples/action-cable/config/secrets.yml +22 -0
  73. data/examples/action-cable/config/spring.rb +6 -0
  74. data/examples/action-cable/db/migrate/20160921223808_create_words.rb +9 -0
  75. data/examples/action-cable/db/schema.rb +21 -0
  76. data/examples/action-cable/log/.keep +0 -0
  77. data/examples/action-cable/public/404.html +67 -0
  78. data/examples/action-cable/public/422.html +67 -0
  79. data/examples/action-cable/public/500.html +66 -0
  80. data/examples/action-cable/public/apple-touch-icon-precomposed.png +0 -0
  81. data/examples/action-cable/public/apple-touch-icon.png +0 -0
  82. data/examples/action-cable/public/favicon.ico +0 -0
  83. data/examples/action-cable/public/robots.txt +5 -0
  84. data/examples/action-cable/rails_cache_dir2/C91/480/synchromesh_active_connections +0 -0
  85. data/examples/action-cable/tmp/.keep +0 -0
  86. data/examples/action-cable/vendor/assets/javascripts/.keep +0 -0
  87. data/examples/action-cable/vendor/assets/stylesheets/.keep +0 -0
  88. data/examples/simple-poller/.gitignore +21 -0
  89. data/examples/simple-poller/Gemfile +64 -0
  90. data/examples/simple-poller/Gemfile.lock +272 -0
  91. data/examples/simple-poller/README.md +24 -0
  92. data/examples/simple-poller/Rakefile +6 -0
  93. data/examples/simple-poller/app/assets/config/manifest.js +3 -0
  94. data/examples/simple-poller/app/assets/images/.keep +0 -0
  95. data/examples/simple-poller/app/assets/javascripts/application.js +20 -0
  96. data/examples/simple-poller/app/assets/javascripts/channels/.keep +0 -0
  97. data/examples/simple-poller/app/assets/stylesheets/application.css +15 -0
  98. data/examples/simple-poller/app/channels/application_cable/channel.rb +4 -0
  99. data/examples/simple-poller/app/channels/application_cable/connection.rb +4 -0
  100. data/examples/simple-poller/app/controllers/application_controller.rb +3 -0
  101. data/examples/simple-poller/app/controllers/concerns/.keep +0 -0
  102. data/examples/simple-poller/app/controllers/test_controller.rb +6 -0
  103. data/examples/simple-poller/app/helpers/application_helper.rb +2 -0
  104. data/examples/simple-poller/app/jobs/application_job.rb +2 -0
  105. data/examples/simple-poller/app/mailers/application_mailer.rb +4 -0
  106. data/examples/simple-poller/app/models/concerns/.keep +0 -0
  107. data/examples/simple-poller/app/models/models.rb +2 -0
  108. data/examples/simple-poller/app/models/public/.keep +0 -0
  109. data/examples/simple-poller/app/models/public/application_record.rb +3 -0
  110. data/examples/simple-poller/app/models/public/word.rb +2 -0
  111. data/examples/simple-poller/app/policies/application_policy.rb +5 -0
  112. data/examples/simple-poller/app/views/components.rb +18 -0
  113. data/examples/simple-poller/app/views/components/.keep +0 -0
  114. data/examples/simple-poller/app/views/components/app.rb +40 -0
  115. data/examples/simple-poller/app/views/layouts/application.html.erb +14 -0
  116. data/examples/simple-poller/app/views/layouts/mailer.html.erb +13 -0
  117. data/examples/simple-poller/app/views/layouts/mailer.text.erb +1 -0
  118. data/examples/simple-poller/bin/bundle +3 -0
  119. data/examples/simple-poller/bin/rails +9 -0
  120. data/examples/simple-poller/bin/rake +9 -0
  121. data/examples/simple-poller/bin/setup +34 -0
  122. data/examples/simple-poller/bin/spring +16 -0
  123. data/examples/simple-poller/bin/update +29 -0
  124. data/examples/simple-poller/config.ru +5 -0
  125. data/examples/simple-poller/config/application.rb +20 -0
  126. data/examples/simple-poller/config/boot.rb +3 -0
  127. data/examples/simple-poller/config/cable.yml +9 -0
  128. data/examples/simple-poller/config/database.yml +25 -0
  129. data/examples/simple-poller/config/environment.rb +5 -0
  130. data/examples/simple-poller/config/environments/development.rb +44 -0
  131. data/examples/simple-poller/config/environments/production.rb +86 -0
  132. data/examples/simple-poller/config/environments/test.rb +42 -0
  133. data/examples/simple-poller/config/initializers/application_controller_renderer.rb +6 -0
  134. data/examples/simple-poller/config/initializers/assets.rb +11 -0
  135. data/examples/simple-poller/config/initializers/backtrace_silencers.rb +7 -0
  136. data/examples/simple-poller/config/initializers/cookies_serializer.rb +5 -0
  137. data/examples/simple-poller/config/initializers/filter_parameter_logging.rb +4 -0
  138. data/examples/simple-poller/config/initializers/inflections.rb +16 -0
  139. data/examples/simple-poller/config/initializers/mime_types.rb +4 -0
  140. data/examples/simple-poller/config/initializers/new_framework_defaults.rb +24 -0
  141. data/examples/simple-poller/config/initializers/session_store.rb +3 -0
  142. data/examples/simple-poller/config/initializers/synchromesh.rb +15 -0
  143. data/examples/simple-poller/config/initializers/wrap_parameters.rb +14 -0
  144. data/examples/simple-poller/config/locales/en.yml +23 -0
  145. data/examples/simple-poller/config/puma.rb +47 -0
  146. data/examples/simple-poller/config/routes.rb +5 -0
  147. data/examples/simple-poller/config/secrets.yml +22 -0
  148. data/examples/simple-poller/config/spring.rb +6 -0
  149. data/examples/simple-poller/db/migrate/20161013220135_create_words.rb +9 -0
  150. data/examples/simple-poller/db/schema.rb +21 -0
  151. data/examples/simple-poller/db/seeds.rb +7 -0
  152. data/examples/simple-poller/lib/assets/.keep +0 -0
  153. data/examples/simple-poller/lib/tasks/.keep +0 -0
  154. data/examples/simple-poller/log/.keep +0 -0
  155. data/examples/simple-poller/public/404.html +67 -0
  156. data/examples/simple-poller/public/422.html +67 -0
  157. data/examples/simple-poller/public/500.html +66 -0
  158. data/examples/simple-poller/public/apple-touch-icon-precomposed.png +0 -0
  159. data/examples/simple-poller/public/apple-touch-icon.png +0 -0
  160. data/examples/simple-poller/public/favicon.ico +0 -0
  161. data/examples/simple-poller/public/robots.txt +5 -0
  162. data/examples/simple-poller/test/controllers/.keep +0 -0
  163. data/examples/simple-poller/test/fixtures/.keep +0 -0
  164. data/examples/simple-poller/test/fixtures/files/.keep +0 -0
  165. data/examples/simple-poller/test/fixtures/words.yml +7 -0
  166. data/examples/simple-poller/test/helpers/.keep +0 -0
  167. data/examples/simple-poller/test/integration/.keep +0 -0
  168. data/examples/simple-poller/test/mailers/.keep +0 -0
  169. data/examples/simple-poller/test/models/.keep +0 -0
  170. data/examples/simple-poller/test/models/word_test.rb +7 -0
  171. data/examples/simple-poller/test/test_helper.rb +10 -0
  172. data/examples/simple-poller/tmp/.keep +0 -0
  173. data/examples/simple-poller/vendor/assets/javascripts/.keep +0 -0
  174. data/examples/simple-poller/vendor/assets/stylesheets/.keep +0 -0
  175. data/examples/words/.gitignore +21 -0
  176. data/examples/words/Gemfile +58 -0
  177. data/examples/words/Gemfile.lock +247 -0
  178. data/examples/words/README.md +24 -0
  179. data/examples/words/Rakefile +6 -0
  180. data/examples/words/app/assets/config/manifest.js +3 -0
  181. data/examples/words/app/assets/javascripts/application.js +18 -0
  182. data/examples/words/app/assets/stylesheets/application.css +15 -0
  183. data/examples/words/app/controllers/application_controller.rb +3 -0
  184. data/examples/words/app/controllers/test_controller.rb +6 -0
  185. data/examples/words/app/models/models.rb +2 -0
  186. data/examples/words/app/models/public/application_record.rb +3 -0
  187. data/examples/words/app/models/public/word.rb +10 -0
  188. data/examples/words/app/policies/application_policy.rb +6 -0
  189. data/examples/words/app/views/components.rb +16 -0
  190. data/examples/words/app/views/components/app.rb +31 -0
  191. data/examples/words/app/views/layouts/application.html.erb +14 -0
  192. data/examples/words/app/views/layouts/mailer.html.erb +13 -0
  193. data/examples/words/app/views/layouts/mailer.text.erb +1 -0
  194. data/examples/words/bin/bundle +3 -0
  195. data/examples/words/bin/rails +9 -0
  196. data/examples/words/bin/rake +9 -0
  197. data/examples/words/bin/setup +34 -0
  198. data/examples/words/bin/spring +15 -0
  199. data/examples/words/bin/update +29 -0
  200. data/examples/words/config.ru +5 -0
  201. data/examples/words/config/application.rb +30 -0
  202. data/examples/words/config/boot.rb +3 -0
  203. data/examples/words/config/cable.yml +9 -0
  204. data/examples/words/config/database.yml +25 -0
  205. data/examples/words/config/environment.rb +5 -0
  206. data/examples/words/config/environments/development.rb +45 -0
  207. data/examples/words/config/environments/production.rb +86 -0
  208. data/examples/words/config/environments/test.rb +42 -0
  209. data/examples/words/config/initializers/application_controller_renderer.rb +6 -0
  210. data/examples/words/config/initializers/assets.rb +11 -0
  211. data/examples/words/config/initializers/backtrace_silencers.rb +7 -0
  212. data/examples/words/config/initializers/cookies_serializer.rb +5 -0
  213. data/examples/words/config/initializers/filter_parameter_logging.rb +4 -0
  214. data/examples/words/config/initializers/inflections.rb +16 -0
  215. data/examples/words/config/initializers/mime_types.rb +4 -0
  216. data/examples/words/config/initializers/new_framework_defaults.rb +24 -0
  217. data/examples/words/config/initializers/session_store.rb +3 -0
  218. data/examples/words/config/initializers/synchromesh.rb +5 -0
  219. data/examples/words/config/initializers/wrap_parameters.rb +14 -0
  220. data/examples/words/config/locales/en.yml +23 -0
  221. data/examples/words/config/puma.rb +47 -0
  222. data/examples/words/config/routes.rb +5 -0
  223. data/examples/words/config/secrets.yml +22 -0
  224. data/examples/words/config/spring.rb +6 -0
  225. data/examples/words/db/migrate/20160921223808_create_words.rb +9 -0
  226. data/examples/words/db/schema.rb +28 -0
  227. data/examples/words/log/.keep +0 -0
  228. data/examples/words/public/404.html +67 -0
  229. data/examples/words/public/422.html +67 -0
  230. data/examples/words/public/500.html +66 -0
  231. data/examples/words/public/apple-touch-icon-precomposed.png +0 -0
  232. data/examples/words/public/apple-touch-icon.png +0 -0
  233. data/examples/words/public/favicon.ico +0 -0
  234. data/examples/words/public/robots.txt +5 -0
  235. data/examples/words/tmp/.keep +0 -0
  236. data/examples/words/vendor/assets/javascripts/.keep +0 -0
  237. data/examples/words/vendor/assets/stylesheets/.keep +0 -0
  238. data/hyper-mesh.gemspec +82 -0
  239. data/lib/active_record_base.rb +152 -0
  240. data/lib/enumerable/pluck.rb +6 -0
  241. data/lib/hyper-mesh.rb +62 -0
  242. data/lib/hypermesh/version.rb +3 -0
  243. data/lib/opal/equality_patches.rb +15 -0
  244. data/lib/opal/parse_patch.rb +14 -0
  245. data/lib/opal/set_patches.rb +8 -0
  246. data/lib/reactive_record/active_record/aggregations.rb +69 -0
  247. data/lib/reactive_record/active_record/associations.rb +111 -0
  248. data/lib/reactive_record/active_record/base.rb +9 -0
  249. data/lib/reactive_record/active_record/class_methods.rb +177 -0
  250. data/lib/reactive_record/active_record/error.rb +26 -0
  251. data/lib/reactive_record/active_record/instance_methods.rb +129 -0
  252. data/lib/reactive_record/active_record/public_columns_hash.rb +19 -0
  253. data/lib/reactive_record/active_record/reactive_record/base.rb +520 -0
  254. data/lib/reactive_record/active_record/reactive_record/collection.rb +517 -0
  255. data/lib/reactive_record/active_record/reactive_record/column_types.rb +67 -0
  256. data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +218 -0
  257. data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +532 -0
  258. data/lib/reactive_record/active_record/reactive_record/reactive_set_relationship_helpers.rb +189 -0
  259. data/lib/reactive_record/active_record/reactive_record/scoped_collection.rb +62 -0
  260. data/lib/reactive_record/active_record/reactive_record/unscoped_collection.rb +16 -0
  261. data/lib/reactive_record/active_record/reactive_record/while_loading.rb +299 -0
  262. data/lib/reactive_record/engine.rb +13 -0
  263. data/lib/reactive_record/interval.rb +190 -0
  264. data/lib/reactive_record/permissions.rb +102 -0
  265. data/lib/reactive_record/pry.rb +13 -0
  266. data/lib/reactive_record/reactive_scope.rb +18 -0
  267. data/lib/reactive_record/scope_description.rb +108 -0
  268. data/lib/reactive_record/serializers.rb +7 -0
  269. data/lib/reactive_record/server_data_cache.rb +347 -0
  270. data/lib/reactive_record/version.rb +3 -0
  271. data/lib/sources/hyper-mesh/pusher.js +98 -0
  272. data/lib/synchromesh/action_cable.rb +39 -0
  273. data/lib/synchromesh/client_drivers.rb +357 -0
  274. data/lib/synchromesh/configuration.rb +40 -0
  275. data/lib/synchromesh/connection.rb +144 -0
  276. data/lib/synchromesh/policy.rb +504 -0
  277. data/lib/synchromesh/reactive_record/permission_patches.rb +43 -0
  278. data/lib/synchromesh/synchromesh.rb +155 -0
  279. data/lib/synchromesh/synchromesh_controller.rb +154 -0
  280. data/logo.jpg +0 -0
  281. data/path_release_steps.md +0 -0
  282. data/reactive_record_test_app/Gemfile +15 -0
  283. data/reactive_record_test_app/Gemfile.lock +209 -0
  284. data/reactive_record_test_app/README.rdoc +261 -0
  285. data/reactive_record_test_app/Rakefile +7 -0
  286. data/reactive_record_test_app/app/assets/javascripts/application.rb +5 -0
  287. data/reactive_record_test_app/app/assets/javascripts/components/another_component.rb +24 -0
  288. data/reactive_record_test_app/app/assets/javascripts/components/empty_component.rb +6 -0
  289. data/reactive_record_test_app/app/assets/javascripts/components/todo_item_component.js.rb +16 -0
  290. data/reactive_record_test_app/app/assets/javascripts/components/todos_component.js.rb +42 -0
  291. data/reactive_record_test_app/app/assets/javascripts/components/todos_main_component.rb +49 -0
  292. data/reactive_record_test_app/app/assets/javascripts/react_js_test_only.js +21618 -0
  293. data/reactive_record_test_app/app/assets/javascripts/reactive_record_config.js +2 -0
  294. data/reactive_record_test_app/app/assets/javascripts/spec/reactive_record_xspec.js.rb +42 -0
  295. data/reactive_record_test_app/app/assets/stylesheets/application.css +13 -0
  296. data/reactive_record_test_app/app/controllers/application_controller.rb +8 -0
  297. data/reactive_record_test_app/app/controllers/home_controller.rb +7 -0
  298. data/reactive_record_test_app/app/controllers/test_controller.rb +7 -0
  299. data/reactive_record_test_app/app/helpers/application_helper.rb +2 -0
  300. data/reactive_record_test_app/app/mailers/.gitkeep +0 -0
  301. data/reactive_record_test_app/app/models/.gitkeep +0 -0
  302. data/reactive_record_test_app/app/policies/application_policy.rb +5 -0
  303. data/reactive_record_test_app/app/views/components.rb +4 -0
  304. data/reactive_record_test_app/app/views/components/test.rb +18 -0
  305. data/reactive_record_test_app/app/views/home/index.html.erb +1 -0
  306. data/reactive_record_test_app/app/views/layouts/application.html.erb +17 -0
  307. data/reactive_record_test_app/app/views/models.rb +1 -0
  308. data/reactive_record_test_app/app/views/models/address.rb +13 -0
  309. data/reactive_record_test_app/app/views/models/comment.rb +19 -0
  310. data/reactive_record_test_app/app/views/models/todo_item.rb +36 -0
  311. data/reactive_record_test_app/app/views/models/user.rb +78 -0
  312. data/reactive_record_test_app/config.ru +33 -0
  313. data/reactive_record_test_app/config/application.rb +73 -0
  314. data/reactive_record_test_app/config/boot.rb +10 -0
  315. data/reactive_record_test_app/config/database.yml +25 -0
  316. data/reactive_record_test_app/config/environment.rb +5 -0
  317. data/reactive_record_test_app/config/environments/development.rb +43 -0
  318. data/reactive_record_test_app/config/environments/production.rb +70 -0
  319. data/reactive_record_test_app/config/environments/test.rb +41 -0
  320. data/reactive_record_test_app/config/initializers/backtrace_silencers.rb +7 -0
  321. data/reactive_record_test_app/config/initializers/inflections.rb +15 -0
  322. data/reactive_record_test_app/config/initializers/mime_types.rb +5 -0
  323. data/reactive_record_test_app/config/initializers/secret_token.rb +7 -0
  324. data/reactive_record_test_app/config/initializers/session_store.rb +8 -0
  325. data/reactive_record_test_app/config/initializers/wrap_parameters.rb +14 -0
  326. data/reactive_record_test_app/config/locales/en.yml +5 -0
  327. data/reactive_record_test_app/config/routes.rb +7 -0
  328. data/reactive_record_test_app/db/migrate/20150617002932_create_todo_items.rb +11 -0
  329. data/reactive_record_test_app/db/migrate/20150617134028_create_users.rb +14 -0
  330. data/reactive_record_test_app/db/migrate/20150729195556_add_address_to_user.rb +20 -0
  331. data/reactive_record_test_app/db/migrate/20150826142045_create_comments.rb +10 -0
  332. data/reactive_record_test_app/db/migrate/20150828172008_add_single_comment_to_todo_item.rb +5 -0
  333. data/reactive_record_test_app/db/migrate/20150908184118_add_address_id_to_user.rb +5 -0
  334. data/reactive_record_test_app/db/migrate/20150917220236_add_second_address_to_user.rb +10 -0
  335. data/reactive_record_test_app/db/migrate/20151009000111_add_test_data_attributes_to_user.rb +6 -0
  336. data/reactive_record_test_app/db/migrate/20160129182544_add_test_enum_to_user.rb +5 -0
  337. data/reactive_record_test_app/db/schema.rb +63 -0
  338. data/reactive_record_test_app/db/seeds.rb +60 -0
  339. data/reactive_record_test_app/public/404.html +26 -0
  340. data/reactive_record_test_app/public/422.html +26 -0
  341. data/reactive_record_test_app/public/500.html +25 -0
  342. data/reactive_record_test_app/public/favicon.ico +0 -0
  343. data/reactive_record_test_app/script/rails +6 -0
  344. data/reactive_record_test_app/spec-opal/active-record/aggregations_spec.rb +41 -0
  345. data/reactive_record_test_app/spec-opal/active-record/associations_spec.rb +75 -0
  346. data/reactive_record_test_app/spec-opal/active-record/base_spec.rb +126 -0
  347. data/reactive_record_test_app/spec-opal/active-record/dummy_value_spec.rb +27 -0
  348. data/reactive_record_test_app/spec-opal/active-record/edge_cases_spec.rb +116 -0
  349. data/reactive_record_test_app/spec-opal/active-record/enum_spec.rb +43 -0
  350. data/reactive_record_test_app/spec-opal/active-record/instance_methods_spec.rb +53 -0
  351. data/reactive_record_test_app/spec-opal/active-record/non_ar_aggregations_spec.rb +74 -0
  352. data/reactive_record_test_app/spec-opal/active-record/permissions_spec.rb +170 -0
  353. data/reactive_record_test_app/spec-opal/active-record/prerendering_spec.rb +49 -0
  354. data/reactive_record_test_app/spec-opal/active-record/reactive_record_load_spec.rb +23 -0
  355. data/reactive_record_test_app/spec-opal/active-record/rendering_spec.rb +221 -0
  356. data/reactive_record_test_app/spec-opal/active-record/save_spec.rb +125 -0
  357. data/reactive_record_test_app/spec-opal/active-record/scope_spec.rb +85 -0
  358. data/reactive_record_test_app/spec-opal/active-record/update_aggregations_spec.rb +76 -0
  359. data/reactive_record_test_app/spec-opal/active-record/update_attributes_spec.rb +186 -0
  360. data/reactive_record_test_app/spec-opal/active-record/virtual_methods_spec.rb +71 -0
  361. data/reactive_record_test_app/spec-opal/index.html.erb +11 -0
  362. data/reactive_record_test_app/spec-opal/spec_helper.js.rb +268 -0
  363. data/reactive_record_test_app/spec-opal/vendor/es5-shim.min.js +6 -0
  364. data/reactive_record_test_app/spec_dont_run/README.md +26 -0
  365. data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzmany_to_many_spec_moved_to_main_suite.rb +30 -0
  366. data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzrevert_record_spec_moved.rb +78 -0
  367. data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzupdate_associations_spec_moved.rb +142 -0
  368. data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzupdate_scopes_movedspec.rb +48 -0
  369. data/remote.md +115 -0
  370. data/spec/bin/firebug-2.0.13-fx.xpi +0 -0
  371. data/spec/component_helpers_xspec.rb +49 -0
  372. data/spec/factories/child_model.rb +5 -0
  373. data/spec/factories/comment.rb +5 -0
  374. data/spec/factories/test_models.rb +5 -0
  375. data/spec/factories/todo.rb +5 -0
  376. data/spec/factories/user.rb +5 -0
  377. data/spec/reactive_record/edge_cases_spec.rb +31 -0
  378. data/spec/reactive_record/factory.rb +62 -0
  379. data/spec/reactive_record/many_to_many_spec.rb +50 -0
  380. data/spec/reactive_record/play.rb +64 -0
  381. data/spec/reactive_record/pry_rescue_xspec.rb +48 -0
  382. data/spec/reactive_record/revert_spec.rb +112 -0
  383. data/spec/reactive_record/update_associations_spec.rb +189 -0
  384. data/spec/reactive_record/update_scopes_spec.rb +53 -0
  385. data/spec/spec_helper.rb +366 -0
  386. data/spec/support/component_helpers.rb +351 -0
  387. data/spec/synchromesh/column_types/column_type_spec.rb +302 -0
  388. data/spec/synchromesh/connection_spec.rb +144 -0
  389. data/spec/synchromesh/crud_access_regulation/broadcast_controls_access_spec.rb +105 -0
  390. data/spec/synchromesh/crud_access_regulation/model_policies_spec.rb +131 -0
  391. data/spec/synchromesh/examples/dictionary.rb +239 -0
  392. data/spec/synchromesh/examples/dictionary_with_client_scopes.rb +196 -0
  393. data/spec/synchromesh/examples/random_examples.rb +100 -0
  394. data/spec/synchromesh/examples/scoped_todos_spec.rb +167 -0
  395. data/spec/synchromesh/integration/authorization_spec.rb +111 -0
  396. data/spec/synchromesh/integration/default_scope_spec.rb +121 -0
  397. data/spec/synchromesh/integration/has_many_through_spec.rb +173 -0
  398. data/spec/synchromesh/integration/relationships_spec.rb +263 -0
  399. data/spec/synchromesh/integration/scope_spec.rb +553 -0
  400. data/spec/synchromesh/integration/synchromesh_spec.rb +80 -0
  401. data/spec/synchromesh/integration/test_components.rb +18 -0
  402. data/spec/synchromesh/integration/transports_spec.rb +308 -0
  403. data/spec/synchromesh/policies/auto_connect_spec.rb +60 -0
  404. data/spec/synchromesh/policies/auto_loader_spec.rb +34 -0
  405. data/spec/synchromesh/policies/policy_methods_spec.rb +85 -0
  406. data/spec/synchromesh/policies/regulate_all_broadcasts_spec.rb +315 -0
  407. data/spec/synchromesh/policies/regulate_broadcast_spec.rb +370 -0
  408. data/spec/synchromesh/policies/regulate_class_connection_spec.rb +50 -0
  409. data/spec/synchromesh/policies/regulate_instance_connection_spec.rb +66 -0
  410. data/spec/test_app/Gemfile +61 -0
  411. data/spec/test_app/Gemfile.lock +253 -0
  412. data/spec/test_app/Rakefile +6 -0
  413. data/spec/test_app/app/assets/javascripts/application.js +6 -0
  414. data/spec/test_app/app/assets/stylesheets/application.css +15 -0
  415. data/spec/test_app/app/controllers/application_controller.rb +13 -0
  416. data/spec/test_app/app/controllers/test_controller.rb +5 -0
  417. data/spec/test_app/app/models/_react_public_models.rb +2 -0
  418. data/spec/test_app/app/models/public/address.rb +13 -0
  419. data/spec/test_app/app/models/public/child_model.rb +3 -0
  420. data/spec/test_app/app/models/public/comment.rb +25 -0
  421. data/spec/test_app/app/models/public/test_model.rb +5 -0
  422. data/spec/test_app/app/models/public/todo.rb +6 -0
  423. data/spec/test_app/app/models/public/todo_item.rb +36 -0
  424. data/spec/test_app/app/models/public/user.rb +88 -0
  425. data/spec/test_app/app/policies/auto_loader_test_classa_policy.rb +3 -0
  426. data/spec/test_app/app/policies/auto_loader_test_classb_policy.rb +3 -0
  427. data/spec/test_app/app/policies/auto_loader_test_classc_policy.rb +3 -0
  428. data/spec/test_app/app/policies/auto_loader_test_classd_policy.rb +3 -0
  429. data/spec/test_app/app/views/components.rb +14 -0
  430. data/spec/test_app/app/views/components/show.rb +5 -0
  431. data/spec/test_app/app/views/layouts/application.html.erb +14 -0
  432. data/spec/test_app/bin/bundle +3 -0
  433. data/spec/test_app/bin/rails +4 -0
  434. data/spec/test_app/bin/rake +4 -0
  435. data/spec/test_app/bin/setup +29 -0
  436. data/spec/test_app/config.ru +4 -0
  437. data/spec/test_app/config/application.rb +42 -0
  438. data/spec/test_app/config/boot.rb +6 -0
  439. data/spec/test_app/config/cable.yml +10 -0
  440. data/spec/test_app/config/database.yml +47 -0
  441. data/spec/test_app/config/environment.rb +5 -0
  442. data/spec/test_app/config/environments/development.rb +41 -0
  443. data/spec/test_app/config/environments/production.rb +79 -0
  444. data/spec/test_app/config/environments/test.rb +42 -0
  445. data/spec/test_app/config/initializers/assets.rb +11 -0
  446. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  447. data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
  448. data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
  449. data/spec/test_app/config/initializers/inflections.rb +16 -0
  450. data/spec/test_app/config/initializers/mime_types.rb +4 -0
  451. data/spec/test_app/config/initializers/session_store.rb +3 -0
  452. data/spec/test_app/config/initializers/synchromesh.rb +11 -0
  453. data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
  454. data/spec/test_app/config/locales/en.yml +23 -0
  455. data/spec/test_app/config/routes.rb +61 -0
  456. data/spec/test_app/config/secrets.yml +22 -0
  457. data/spec/test_app/db/development.sqlite3 +0 -0
  458. data/spec/test_app/db/migrate/20160731182106_create_test_models.rb +75 -0
  459. data/spec/test_app/db/schema.rb +88 -0
  460. data/spec/test_app/db/seeds.rb +7 -0
  461. data/spec/test_app/lib/assets/.keep +0 -0
  462. data/spec/test_app/log/.keep +0 -0
  463. data/spec/test_app/public/404.html +67 -0
  464. data/spec/test_app/public/422.html +67 -0
  465. data/spec/test_app/public/500.html +66 -0
  466. data/spec/test_app/public/favicon.ico +0 -0
  467. data/spec/vendor/es5-shim.min.js +6 -0
  468. data/terminal.md +66 -0
  469. metadata +1175 -0
@@ -0,0 +1,34 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe 'rails autoloader' do
5
+
6
+ # can't figure out how to get rails to dump class cache between tests so
7
+ # we define two different class policy pairs...
8
+
9
+ context "when using const_set" do
10
+
11
+ it 'will find the policy class file if available' do
12
+ stub_const "AutoLoaderTestClassa", Class.new
13
+ expect(HyperMesh::AutoConnect.channels(0, nil)).to eq(["AutoLoaderTestClassa"])
14
+ end
15
+
16
+ it 'will raise a load error if file does not define the class' do
17
+ expect { stub_const "AutoLoaderTestClassc", Class.new }.to raise_error(LoadError)
18
+ end
19
+ end
20
+
21
+ context "when defining a new class" do
22
+
23
+ it 'will find the policy class if available' do
24
+ class AutoLoaderTestClassb
25
+ end
26
+ expect(HyperMesh::AutoConnect.channels(0, nil)).to eq(["AutoLoaderTestClassb"])
27
+ end
28
+
29
+ it 'will raise a load error if file does not define the class' do
30
+ expect { class AutoLoaderTestClassd; end }.to raise_error(LoadError)
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+ #require 'synchromesh/test_components'
3
+
4
+ describe "including HyperMesh::PolicyMethods" do
5
+
6
+ before(:each) do
7
+ stub_const "TestClass", Class.new
8
+ TestClass.class_eval do
9
+ include HyperMesh::PolicyMethods
10
+ end
11
+ end
12
+
13
+ it "defines the regulate_class_connection method" do
14
+ expect(TestClass).to respond_to(:regulate_class_connection)
15
+ end
16
+
17
+
18
+ it "defines the regulate_instance_connections method" do
19
+ expect(TestClass).to respond_to(:regulate_instance_connections)
20
+ end
21
+
22
+ it "defines the always_allow_connection method" do
23
+ expect(TestClass).to respond_to(:always_allow_connection)
24
+ end
25
+
26
+ it "defines the regulate_all_broadcasts method" do
27
+ expect(TestClass).to respond_to(:regulate_all_broadcasts)
28
+ end
29
+
30
+ it "defines the regulate_broadcast method" do
31
+ expect(TestClass).to respond_to(:regulate_broadcast)
32
+ end
33
+
34
+ it "sets the correct regulated class" do
35
+ expect(TestClass.synchromesh_internal_policy_object.instance_variable_get("@regulated_klass")).to eq("TestClass")
36
+ end
37
+
38
+ it "exposes the underlying regulate_class_connection method" do
39
+ expect(TestClass.synchromesh_internal_policy_object).to respond_to(:regulate_class_connection)
40
+ end
41
+
42
+
43
+ it "exposes the underlying regulate_instance_connections method" do
44
+ expect(TestClass.synchromesh_internal_policy_object).to respond_to(:regulate_instance_connections)
45
+ end
46
+
47
+ it "exposes the underlying always_allow_connection method" do
48
+ expect(TestClass.synchromesh_internal_policy_object).to respond_to(:always_allow_connection)
49
+ end
50
+
51
+ it "exposes the underlying regulate_all_broadcasts method" do
52
+ expect(TestClass.synchromesh_internal_policy_object).to respond_to(:regulate_all_broadcasts)
53
+ end
54
+
55
+ it "exposes the underlying regulate_broadcast method" do
56
+ expect(TestClass.synchromesh_internal_policy_object).to respond_to(:regulate_broadcast)
57
+ end
58
+
59
+ it "defines the send_all instance method" do
60
+ expect(TestClass.new).to respond_to(:send_all)
61
+ end
62
+
63
+ it "defines the send_all_but instance method" do
64
+ expect(TestClass.new).to respond_to(:send_all_but)
65
+ end
66
+
67
+ it "defines the send_only instance method" do
68
+ expect(TestClass.new).to respond_to(:send_only)
69
+ end
70
+
71
+ it "defines the obj instance method" do
72
+ expect(TestClass.new).to respond_to(:obj)
73
+ end
74
+
75
+ it "will automatically create an empty Application class if needed" do
76
+ expect(defined? Application).to be_falsy
77
+ stub_const 'ApplicationPolicy', Class.new
78
+ ApplicationPolicy.class_eval do
79
+ regulate_class_connection { true }
80
+ end
81
+ HyperMesh.configuration {}
82
+ expect(Application).to be_a(Class)
83
+ end
84
+
85
+ end
@@ -0,0 +1,315 @@
1
+ require 'spec_helper'
2
+
3
+ describe "regulate_all_broadcasts" do
4
+
5
+ before(:each) do
6
+ stub_const "TestModel1", Class.new
7
+ TestModel1.class_eval do
8
+ include ActiveModel::Model
9
+ def react_serializer
10
+ as_json # does not include type: xxx as per reactive-record
11
+ end
12
+ def previous_changes
13
+ Hash[*as_json.keys.collect { |attr| [attr, send(attr)] }.flatten(1)]
14
+ end
15
+ def attribute_names
16
+ [:attr1, :attr2, :attr3, :attr4, :attr5]
17
+ end
18
+ attr_accessor :attr1, :attr2, :attr3, :attr4, :attr5
19
+ end
20
+ stub_const "TestModel2", Class.new
21
+ TestModel2.class_eval do
22
+ include ActiveModel::Model
23
+ def react_serializer
24
+ as_json # does not include type: xxx as per reactive-record
25
+ end
26
+ def previous_changes
27
+ Hash[*as_json.keys.collect { |attr| [attr, send(attr)] }.flatten(1)]
28
+ end
29
+ def attribute_names
30
+ [:attrA, :attrB, :attrC, :attrD, :attrE]
31
+ end
32
+ attr_accessor :attrA, :attrB, :attrC, :attrD, :attrE
33
+ end
34
+ allow_any_instance_of(HyperMesh::InternalPolicy).to receive(:id).and_return(:unique_broadcast_id)
35
+ allow(HyperMesh::Connection).to receive(:active).and_return(['Application', 'AnotherApplication', 'Class1', 'Class2'])
36
+ end
37
+
38
+ it "will broadcast to a single channel" do
39
+ stub_const "ApplicationPolicy", Class.new
40
+ ApplicationPolicy.class_eval do
41
+ regulate_all_broadcasts do | policy |
42
+ policy.send_all
43
+ end
44
+ end
45
+ model = TestModel1.new(attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
46
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
47
+ {
48
+ broadcast_id: :unique_broadcast_id,
49
+ channel: 'Application',
50
+ channels: ['Application'],
51
+ klass: 'TestModel1',
52
+ record: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
53
+ previous_changes: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
54
+ }
55
+ )
56
+ end
57
+
58
+ it "will broadcast to a multiple channels" do
59
+ stub_const "ApplicationPolicy", Class.new
60
+ ApplicationPolicy.class_eval do
61
+ regulate_all_broadcasts do | policy |
62
+ policy.send_all
63
+ end
64
+ end
65
+ stub_const "AnotherApplicationPolicy", Class.new
66
+ AnotherApplicationPolicy.class_eval do
67
+ regulate_all_broadcasts do | policy |
68
+ policy.send_all
69
+ end
70
+ end
71
+ model = TestModel1.new(attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
72
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
73
+ {
74
+ broadcast_id: :unique_broadcast_id,
75
+ channel: 'Application',
76
+ channels: ['Application', 'AnotherApplication'],
77
+ klass: 'TestModel1',
78
+ record: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
79
+ previous_changes: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
80
+ },
81
+ {
82
+ broadcast_id: :unique_broadcast_id,
83
+ channel: 'AnotherApplication',
84
+ channels: ['Application', 'AnotherApplication'],
85
+ klass: 'TestModel1',
86
+ record: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
87
+ previous_changes: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
88
+ }
89
+ )
90
+ end
91
+
92
+ it "will broadcast to a multiple channels with different attributes" do
93
+ stub_const "ApplicationPolicy", Class.new
94
+ ApplicationPolicy.class_eval do
95
+ regulate_all_broadcasts do | policy |
96
+ policy.send_only(:attr1)
97
+ end
98
+ end
99
+ stub_const "AnotherApplicationPolicy", Class.new
100
+ AnotherApplicationPolicy.class_eval do
101
+ regulate_all_broadcasts do | policy |
102
+ policy.send_all_but(:attr1)
103
+ end
104
+ end
105
+ model = TestModel1.new(attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
106
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
107
+ {
108
+ broadcast_id: :unique_broadcast_id,
109
+ channel: 'Application',
110
+ channels: ['Application', 'AnotherApplication'],
111
+ klass: 'TestModel1',
112
+ record: {attr1: 1},
113
+ previous_changes: {attr1: 1}
114
+ },
115
+ {
116
+ broadcast_id: :unique_broadcast_id,
117
+ channel: 'AnotherApplication',
118
+ channels: ['Application', 'AnotherApplication'],
119
+ klass: 'TestModel1',
120
+ record: {attr2: 2, attr3: 3, attr4: 4, attr5: 5},
121
+ previous_changes: {attr2: 2, attr3: 3, attr4: 4, attr5: 5}
122
+ }
123
+ )
124
+ end
125
+
126
+ it "can override the default channel using the 'to' method" do
127
+ stub_const "ApplicationPolicy", Class.new
128
+ stub_const "AnotherApplicationPolicy", Class.new
129
+ stub_const "Application", Class.new
130
+ stub_const "AnotherApplication", Class.new
131
+ ApplicationPolicy.class_eval do
132
+ regulate_all_broadcasts do | policy |
133
+ policy.send_only(:attr1).to(AnotherApplication)
134
+ end
135
+ end
136
+ AnotherApplicationPolicy.class_eval do
137
+ regulate_all_broadcasts do | policy |
138
+ policy.send_all_but(:attr1).to(Application)
139
+ end
140
+ end
141
+ model = TestModel1.new(attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
142
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
143
+ {
144
+ broadcast_id: :unique_broadcast_id,
145
+ channel: 'AnotherApplication',
146
+ channels: ['AnotherApplication', 'Application'],
147
+ klass: 'TestModel1',
148
+ record: {attr1: 1},
149
+ previous_changes: {attr1: 1}
150
+ },
151
+ {
152
+ broadcast_id: :unique_broadcast_id,
153
+ channel: 'Application',
154
+ channels: ['AnotherApplication', 'Application'],
155
+ klass: 'TestModel1',
156
+ record: {attr2: 2, attr3: 3, attr4: 4, attr5: 5},
157
+ previous_changes: {attr2: 2, attr3: 3, attr4: 4, attr5: 5}
158
+ }
159
+ )
160
+ end
161
+
162
+ it "can have multiple polcies" do
163
+ stub_const "ApplicationPolicy", Class.new
164
+ stub_const "AnotherApplicationPolicy", Class.new
165
+ stub_const "Application", Class.new
166
+ stub_const "AnotherApplication", Class.new
167
+ ApplicationPolicy.class_eval do
168
+ regulate_all_broadcasts do | policy |
169
+ policy.send_only(:attr1, :attr2, :attr3).to(AnotherApplication)
170
+ end
171
+ end
172
+ AnotherApplicationPolicy.class_eval do
173
+ regulate_all_broadcasts do | policy |
174
+ policy.send_all_but(:attr1).to(AnotherApplication, Application)
175
+ end
176
+ end
177
+ model = TestModel1.new(attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
178
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
179
+ {
180
+ broadcast_id: :unique_broadcast_id,
181
+ channel: 'AnotherApplication',
182
+ channels: ['AnotherApplication', 'Application'],
183
+ klass: 'TestModel1',
184
+ record: {attr2: 2, attr3: 3},
185
+ previous_changes: {attr2: 2, attr3: 3}
186
+ },
187
+ {
188
+ broadcast_id: :unique_broadcast_id,
189
+ channel: 'Application',
190
+ channels: ['AnotherApplication', 'Application'],
191
+ klass: 'TestModel1',
192
+ record: {attr2: 2, attr3: 3, attr4: 4, attr5: 5},
193
+ previous_changes: {attr2: 2, attr3: 3, attr4: 4, attr5: 5}
194
+ }
195
+ )
196
+ end
197
+
198
+ it "can have multiple polcies defined by separate send policies" do
199
+ stub_const "ApplicationPolicy", Class.new
200
+ stub_const "AnotherApplicationPolicy", Class.new
201
+ stub_const "Application", Class.new
202
+ stub_const "AnotherApplication", Class.new
203
+ ApplicationPolicy.class_eval do
204
+ regulate_all_broadcasts do | policy |
205
+ policy.send_only(:attr1, :attr2, :attr3).to(AnotherApplication)
206
+ end
207
+ end
208
+ AnotherApplicationPolicy.class_eval do
209
+ regulate_all_broadcasts do | policy |
210
+ policy.send_all_but(:attr1).to(Application)
211
+ policy.send_all_but(:attr1)
212
+ end
213
+ end
214
+ model = TestModel1.new(attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
215
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
216
+ {
217
+ broadcast_id: :unique_broadcast_id,
218
+ channel: 'AnotherApplication',
219
+ channels: ['AnotherApplication', 'Application'],
220
+ klass: 'TestModel1',
221
+ record: {attr2: 2, attr3: 3},
222
+ previous_changes: {attr2: 2, attr3: 3}
223
+ },
224
+ {
225
+ broadcast_id: :unique_broadcast_id,
226
+ channel: 'Application',
227
+ channels: ['AnotherApplication', 'Application'],
228
+ klass: 'TestModel1',
229
+ record: {attr2: 2, attr3: 3, attr4: 4, attr5: 5},
230
+ previous_changes: {attr2: 2, attr3: 3, attr4: 4, attr5: 5}
231
+ }
232
+ )
233
+ end
234
+
235
+ it "can have multiple policies without any to method and will intersect the results" do
236
+ stub_const "ApplicationPolicy", Class.new
237
+ ApplicationPolicy.class_eval do
238
+ regulate_all_broadcasts do | policy |
239
+ policy.send_only(:attr1, :attr2)
240
+ policy.send_only(:attr2, :attr3)
241
+ end
242
+ end
243
+ model = TestModel1.new(attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
244
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
245
+ {
246
+ broadcast_id: :unique_broadcast_id,
247
+ channel: 'Application',
248
+ channels: ['Application'],
249
+ klass: 'TestModel1',
250
+ record: {attr2: 2},
251
+ previous_changes: {attr2: 2}
252
+ }
253
+ )
254
+ end
255
+
256
+ it "can have apply the same policies to different models" do
257
+ stub_const "ApplicationPolicy", Class.new
258
+ ApplicationPolicy.class_eval do
259
+ regulate_all_broadcasts do | policy |
260
+ policy.send_only(:attr1, :attrA)
261
+ end
262
+ end
263
+ model = TestModel1.new(attr1: 1)
264
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
265
+ {
266
+ broadcast_id: :unique_broadcast_id,
267
+ channel: 'Application',
268
+ channels: ['Application'],
269
+ klass: 'TestModel1',
270
+ record: {attr1: 1},
271
+ previous_changes: {attr1: 1}
272
+ }
273
+ )
274
+ model = TestModel2.new(attrA: "A")
275
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
276
+ {
277
+ broadcast_id: :unique_broadcast_id,
278
+ channel: 'Application',
279
+ channels: ['Application'],
280
+ klass: 'TestModel2',
281
+ record: {attrA: "A"},
282
+ previous_changes: {attrA: "A"}
283
+ }
284
+ )
285
+ end
286
+ it "will accept a list of classes to apply the policy to" do
287
+ stub_const "ApplicationPolicy", Class.new
288
+ stub_const "Class1", Class.new
289
+ stub_const "Class2", Class.new
290
+ ApplicationPolicy.class_eval do
291
+ regulate_all_broadcasts(Class1, Class2) do | policy |
292
+ policy.send_all
293
+ end
294
+ end
295
+ model = TestModel1.new(attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
296
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
297
+ {
298
+ broadcast_id: :unique_broadcast_id,
299
+ channel: 'Class1',
300
+ channels: ['Class1', 'Class2'],
301
+ klass: 'TestModel1',
302
+ record: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
303
+ previous_changes: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
304
+ },
305
+ {
306
+ broadcast_id: :unique_broadcast_id,
307
+ channel: 'Class2',
308
+ channels: ['Class1', 'Class2'],
309
+ klass: 'TestModel1',
310
+ record: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
311
+ previous_changes: {attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
312
+ }
313
+ )
314
+ end
315
+ end
@@ -0,0 +1,370 @@
1
+ require 'spec_helper'
2
+ #require 'synchromesh/test_components'
3
+
4
+ describe "regulate_broadcast" do
5
+
6
+ before(:each) do
7
+ stub_const "TestModel1", Class.new
8
+ TestModel1.class_eval do
9
+ include ActiveModel::Model
10
+ def react_serializer
11
+ as_json # does not include type: xxx as per reactive-record
12
+ end
13
+ def attribute_names
14
+ [:id, :attr1, :attr2, :attr3, :attr4, :attr5]
15
+ end
16
+ def previous_changes
17
+ Hash[*as_json.keys.collect { |attr| [attr, send(attr)] }.flatten(1)]
18
+ end
19
+ attr_accessor :id, :attr1, :attr2, :attr3, :attr4, :attr5
20
+ end
21
+ stub_const "TestModel2", Class.new
22
+ TestModel2.class_eval do
23
+ include ActiveModel::Model
24
+ def react_serializer
25
+ as_json # does not include type: xxx as per reactive-record
26
+ end
27
+ def attribute_names
28
+ [:id, :attrA, :attrB, :attrC, :attrD, :attrE]
29
+ end
30
+ def previous_changes
31
+ Hash[*as_json.keys.collect { |attr| [attr, send(attr)] }.flatten(1)]
32
+ end
33
+ attr_accessor :id, :attrA, :attrB, :attrC, :attrD, :attrE
34
+ end
35
+ allow(HyperMesh::Connection).to receive(:active).and_return(['Application', 'TestModel1-1', 'TestModel1-7', 'TestModel2-8'])
36
+ allow_any_instance_of(HyperMesh::InternalPolicy).to receive(:id).and_return(:unique_broadcast_id)
37
+ end
38
+
39
+ it "will broadcast the instance policies for a model" do
40
+ stub_const "TestModel1Policy", Class.new
41
+ TestModel1Policy.class_eval do
42
+ regulate_broadcast do | policy |
43
+ policy.send_all.to(self)
44
+ end
45
+ end
46
+ model = TestModel1.new(id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
47
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
48
+ {
49
+ broadcast_id: :unique_broadcast_id,
50
+ channel: 'TestModel1-1',
51
+ channels: ['TestModel1-1'],
52
+ klass: 'TestModel1',
53
+ record: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
54
+ previous_changes: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
55
+ }
56
+ )
57
+ end
58
+
59
+ it "will raise an error if the policy is not sent" do
60
+ stub_const "TestModel1Policy", Class.new
61
+ TestModel1Policy.class_eval do
62
+ regulate_broadcast do | policy |
63
+ policy.send_all
64
+ end
65
+ end
66
+ model = TestModel1.new(id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
67
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.
68
+ to raise_error("TestModel1 instance broadcast policy not sent to any channel")
69
+ end
70
+
71
+ it "will intersect all policies for the same channel" do
72
+ stub_const "TestModel1Policy", Class.new
73
+ TestModel1Policy.class_eval do
74
+ regulate_broadcast do | policy |
75
+ policy.send_only(:attr1, :attr2).to(self)
76
+ policy.send_only(:attr2, :attr3).to(self)
77
+ end
78
+ end
79
+ model = TestModel1.new(id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
80
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
81
+ {
82
+ broadcast_id: :unique_broadcast_id,
83
+ channel: 'TestModel1-1',
84
+ channels: ['TestModel1-1'],
85
+ klass: 'TestModel1',
86
+ record: {id: 1, attr2: 2},
87
+ previous_changes: {id: 1, attr2: 2}
88
+ }
89
+ )
90
+ end
91
+
92
+ it "will broadcast the instance policies for a model and on a class channel" do
93
+ stub_const "TestModel1Policy", Class.new
94
+ stub_const "Application", Class.new
95
+ TestModel1Policy.class_eval do
96
+ regulate_broadcast do | policy |
97
+ policy.send_all.to(self, Application)
98
+ end
99
+ end
100
+ model = TestModel1.new(id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
101
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
102
+ {
103
+ broadcast_id: :unique_broadcast_id,
104
+ channel: 'TestModel1-1',
105
+ channels: ['TestModel1-1', 'Application'],
106
+ klass: 'TestModel1',
107
+ record: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
108
+ previous_changes: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
109
+ },
110
+ {
111
+ broadcast_id: :unique_broadcast_id,
112
+ channel: 'Application',
113
+ channels: ['TestModel1-1', 'Application'],
114
+ klass: 'TestModel1',
115
+ record: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
116
+ previous_changes: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
117
+ }
118
+ )
119
+ end
120
+
121
+ it "will handle arrays and falsy values in the to method" do
122
+ stub_const "TestModel1Policy", Class.new
123
+ stub_const "Application", Class.new
124
+ TestModel1Policy.class_eval do
125
+ regulate_broadcast do | policy |
126
+ policy.send_all.to(false, [self, Application], nil)
127
+ end
128
+ end
129
+ model = TestModel1.new(id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
130
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
131
+ {
132
+ broadcast_id: :unique_broadcast_id,
133
+ channel: 'TestModel1-1',
134
+ channels: ['TestModel1-1', 'Application'],
135
+ klass: 'TestModel1',
136
+ record: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
137
+ previous_changes: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
138
+ },
139
+ {
140
+ broadcast_id: :unique_broadcast_id,
141
+ channel: 'Application',
142
+ channels: ['TestModel1-1', 'Application'],
143
+ klass: 'TestModel1',
144
+ record: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
145
+ previous_changes: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
146
+ }
147
+ )
148
+ end
149
+
150
+ it "will broadcast different instance policies on different channels" do
151
+ stub_const "TestModel1Policy", Class.new
152
+ stub_const "Application", Class.new
153
+ TestModel1Policy.class_eval do
154
+ regulate_broadcast do | policy |
155
+ policy.send_all.to(self)
156
+ policy.send_only(:id).to(Application)
157
+ end
158
+ end
159
+ model = TestModel1.new(id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
160
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
161
+ {
162
+ broadcast_id: :unique_broadcast_id,
163
+ channel: 'TestModel1-1',
164
+ channels: ['TestModel1-1', 'Application'],
165
+ klass: 'TestModel1',
166
+ record: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
167
+ previous_changes: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
168
+ },
169
+ {
170
+ broadcast_id: :unique_broadcast_id,
171
+ channel: 'Application',
172
+ channels: ['TestModel1-1', 'Application'],
173
+ klass: 'TestModel1',
174
+ record: {id: 1},
175
+ previous_changes: {id: 1}
176
+ }
177
+ )
178
+ end
179
+
180
+ it "will pass the proper policy object" do
181
+ stub_const "TestModel1Policy", Class.new
182
+ stub_const "Application", Class.new
183
+ TestModel1Policy.class_eval do
184
+ def public_attributes
185
+ [:id]
186
+ end
187
+ regulate_broadcast do | policy |
188
+ policy.send_all.to(self)
189
+ policy.send_only(*policy.public_attributes).to(Application)
190
+ end
191
+ end
192
+ model = TestModel1.new(id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5)
193
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
194
+ {
195
+ broadcast_id: :unique_broadcast_id,
196
+ channel: 'TestModel1-1',
197
+ channels: ['TestModel1-1', 'Application'],
198
+ klass: 'TestModel1',
199
+ record: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5},
200
+ previous_changes: {id: 1, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5}
201
+ },
202
+ {
203
+ broadcast_id: :unique_broadcast_id,
204
+ channel: 'Application',
205
+ channels: ['TestModel1-1', 'Application'],
206
+ klass: 'TestModel1',
207
+ record: {id: 1},
208
+ previous_changes: {id: 1}
209
+ }
210
+ )
211
+ end
212
+
213
+ it "will evaluates the regulation in the context of model being broadcast" do
214
+ stub_const "TestModel1Policy", Class.new
215
+ stub_const "Application", Class.new
216
+ TestModel1Policy.class_eval do
217
+ def public_attributes
218
+ [:id]
219
+ end
220
+ regulate_broadcast do | policy |
221
+ policy.send_all_but(:attr2).to(self) if attr2 == "YES"
222
+ end
223
+ end
224
+ model = TestModel1.new(id: 1, attr1: 1, attr2: "YES", attr3: 3, attr4: 4, attr5: 5)
225
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
226
+ {
227
+ broadcast_id: :unique_broadcast_id,
228
+ channel: 'TestModel1-1',
229
+ channels: ['TestModel1-1'],
230
+ klass: 'TestModel1',
231
+ record: {id: 1, attr1: 1, attr3: 3, attr4: 4, attr5: 5},
232
+ previous_changes: {id: 1, attr1: 1, attr3: 3, attr4: 4, attr5: 5}
233
+ }
234
+ )
235
+ model = TestModel1.new(id: 1, attr1: 1, attr2: "NO", attr3: 3, attr4: 4, attr5: 5)
236
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.not_to yield_control
237
+ end
238
+
239
+ it "will adds the obj method to the policy which points back to the model being broadcast" do
240
+ stub_const "TestModel1Policy", Class.new
241
+ stub_const "Application", Class.new
242
+ TestModel1Policy.class_eval do
243
+ def send?
244
+ obj.attr2 == "YES"
245
+ end
246
+ regulate_broadcast do | policy |
247
+ policy.send_all_but(:attr2).to(self) if policy.send?
248
+ end
249
+ end
250
+ model = TestModel1.new(id: 1, attr1: 1, attr2: "YES", attr3: 3, attr4: 4, attr5: 5)
251
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
252
+ {
253
+ broadcast_id: :unique_broadcast_id,
254
+ channel: 'TestModel1-1',
255
+ channels: ['TestModel1-1'],
256
+ klass: 'TestModel1',
257
+ record: {id: 1, attr1: 1, attr3: 3, attr4: 4, attr5: 5},
258
+ previous_changes: {id: 1, attr1: 1, attr3: 3, attr4: 4, attr5: 5}
259
+ }
260
+ )
261
+ model = TestModel1.new(id: 1, attr1: 1, attr2: "NO", attr3: 3, attr4: 4, attr5: 5)
262
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.not_to yield_control
263
+ end
264
+ it "will not broadcast an empty record" do
265
+ stub_const "TestModel1Policy", Class.new
266
+ stub_const "Application", Class.new
267
+ TestModel1Policy.class_eval do
268
+ def attributes_to_send
269
+ [:attr1] if obj.attr2 == "YES"
270
+ end
271
+ regulate_broadcast do | policy |
272
+ policy.send_only(*policy.attributes_to_send).to(self)
273
+ end
274
+ end
275
+ model = TestModel1.new(id: 1, attr1: 1, attr2: "YES", attr3: 3, attr4: 4, attr5: 5)
276
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
277
+ {
278
+ broadcast_id: :unique_broadcast_id,
279
+ channel: 'TestModel1-1',
280
+ channels: ['TestModel1-1'],
281
+ klass: 'TestModel1',
282
+ record: {id: 1, attr1: 1},
283
+ previous_changes: {id: 1, attr1: 1}
284
+ }
285
+ )
286
+ model = TestModel1.new(id: 1, attr1: 1, attr2: "NO", attr3: 3, attr4: 4, attr5: 5)
287
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.not_to yield_control
288
+ end
289
+ it "will apply the same policy to several models" do
290
+ stub_const "ApplicationPolicy", Class.new
291
+ ApplicationPolicy.class_eval do
292
+ regulate_broadcast(TestModel1, TestModel2) do |policy|
293
+ policy.send_all_but(:attr1).to(self)
294
+ end
295
+ end
296
+ model1 = TestModel1.new(id: 7, attr1: 1)
297
+ model2 = TestModel2.new(id: 8, attrA: 1)
298
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model1, &b) }.to yield_successive_args(
299
+ {
300
+ broadcast_id: :unique_broadcast_id,
301
+ channel: 'TestModel1-7',
302
+ channels: ['TestModel1-7'],
303
+ klass: 'TestModel1',
304
+ record: {id: 7},
305
+ previous_changes: {id: 7}
306
+ }
307
+ )
308
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model2, &b) }.to yield_successive_args(
309
+ {
310
+ broadcast_id: :unique_broadcast_id,
311
+ channel: 'TestModel2-8',
312
+ channels: ['TestModel2-8'],
313
+ klass: 'TestModel2',
314
+ record: {id: 8, attrA: 1},
315
+ previous_changes: {id: 8, attrA: 1}
316
+ }
317
+ )
318
+
319
+ end
320
+
321
+ it "exposes the policy methods on the synchromesh_internal_policy_object" do
322
+ stub_const "TestModel1Policy", Class.new
323
+ stub_const "Application", Class.new
324
+ TestModel1Policy.class_eval do
325
+ regulate_broadcast do | policy |
326
+ case policy.synchromesh_internal_policy_object.obj.attr1
327
+ when "send_all"
328
+ policy.synchromesh_internal_policy_object.send_all.to(self)
329
+ when "send_all_but"
330
+ policy.synchromesh_internal_policy_object.send_all_but(:attr2).to(self)
331
+ when "send_only"
332
+ policy.synchromesh_internal_policy_object.send_only(:attr2).to(self)
333
+ end
334
+ end
335
+ end
336
+ model = TestModel1.new(id: 1, attr1: "send_all", attr2: "YES", attr3: 3, attr4: 4, attr5: 5)
337
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
338
+ {
339
+ broadcast_id: :unique_broadcast_id,
340
+ channel: 'TestModel1-1',
341
+ channels: ['TestModel1-1'],
342
+ klass: 'TestModel1',
343
+ record: {id: 1, attr1: "send_all", attr2: "YES", attr3: 3, attr4: 4, attr5: 5},
344
+ previous_changes: {id: 1, attr1: "send_all", attr2: "YES", attr3: 3, attr4: 4, attr5: 5}
345
+ }
346
+ )
347
+ model = TestModel1.new(id: 1, attr1: "send_all_but", attr2: "YES", attr3: 3, attr4: 4, attr5: 5)
348
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
349
+ {
350
+ broadcast_id: :unique_broadcast_id,
351
+ channel: 'TestModel1-1',
352
+ channels: ['TestModel1-1'],
353
+ klass: 'TestModel1',
354
+ record: {id: 1, attr1: "send_all_but", attr3: 3, attr4: 4, attr5: 5},
355
+ previous_changes: {id: 1, attr1: "send_all_but", attr3: 3, attr4: 4, attr5: 5}
356
+ }
357
+ )
358
+ model = TestModel1.new(id: 1, attr1: "send_only", attr2: "YES", attr3: 3, attr4: 4, attr5: 5)
359
+ expect { |b| HyperMesh::InternalPolicy.regulate_broadcast(model, &b) }.to yield_successive_args(
360
+ {
361
+ broadcast_id: :unique_broadcast_id,
362
+ channel: 'TestModel1-1',
363
+ channels: ['TestModel1-1'],
364
+ klass: 'TestModel1',
365
+ record: {id: 1, attr2: "YES"},
366
+ previous_changes: {id: 1, attr2: "YES"}
367
+ }
368
+ )
369
+ end
370
+ end