releaf-core 0.2.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 (288) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +24 -0
  3. data/app/assets/fonts/releaf/RobotoRegular_normal_400.ttf +0 -0
  4. data/app/assets/fonts/releaf/RobotoRegular_normal_400.woff +0 -0
  5. data/app/assets/fonts/releaf/RobotoRegular_normal_400.woff2 +0 -0
  6. data/app/assets/images/releaf/icons/apple-touch-icon-114x114-precomposed.png +0 -0
  7. data/app/assets/images/releaf/icons/apple-touch-icon-152x152-precomposed.png +0 -0
  8. data/app/assets/images/releaf/icons/apple-touch-icon-72x72-precomposed.png +0 -0
  9. data/app/assets/images/releaf/icons/favicon.ico +0 -0
  10. data/app/assets/images/releaf/icons/favicon.png +0 -0
  11. data/app/assets/images/releaf/icons/msapplication-tile-144x144.png +0 -0
  12. data/app/assets/images/releaf/logo-login.png +0 -0
  13. data/app/assets/images/releaf/logo.png +0 -0
  14. data/app/assets/javascripts/ckeditor/plugins/mediaembed/icons/hidpi/mediaembed.png +0 -0
  15. data/app/assets/javascripts/ckeditor/plugins/mediaembed/icons/mediaembed.png +0 -0
  16. data/app/assets/javascripts/ckeditor/plugins/mediaembed/lang/en.js +12 -0
  17. data/app/assets/javascripts/ckeditor/plugins/mediaembed/lang/es.js +12 -0
  18. data/app/assets/javascripts/ckeditor/plugins/mediaembed/plugin.js +63 -0
  19. data/app/assets/javascripts/releaf/3rd_party/jquery-ui-timepicker-addon.js +1882 -0
  20. data/app/assets/javascripts/releaf/3rd_party/jquery.magnific-popup.min.js +4 -0
  21. data/app/assets/javascripts/releaf/application.js +13 -0
  22. data/app/assets/javascripts/releaf/include/ajax.js +66 -0
  23. data/app/assets/javascripts/releaf/include/ajaxbox.js +179 -0
  24. data/app/assets/javascripts/releaf/include/dialogs.js +13 -0
  25. data/app/assets/javascripts/releaf/include/field.type_associated_set.js +32 -0
  26. data/app/assets/javascripts/releaf/include/field.type_date_or_datetime_or_time.js +73 -0
  27. data/app/assets/javascripts/releaf/include/field.type_richtext.js +188 -0
  28. data/app/assets/javascripts/releaf/include/loader.js +45 -0
  29. data/app/assets/javascripts/releaf/include/localization.js +213 -0
  30. data/app/assets/javascripts/releaf/include/nested_fields.js +295 -0
  31. data/app/assets/javascripts/releaf/include/notifications.js +267 -0
  32. data/app/assets/javascripts/releaf/include/pagination.js +19 -0
  33. data/app/assets/javascripts/releaf/include/profile_settings.js +28 -0
  34. data/app/assets/javascripts/releaf/include/remote_validator.js +437 -0
  35. data/app/assets/javascripts/releaf/include/search.js +140 -0
  36. data/app/assets/javascripts/releaf/include/sidebar.js +149 -0
  37. data/app/assets/javascripts/releaf/include/sortable.js +69 -0
  38. data/app/assets/javascripts/releaf/include/toolbox.js +221 -0
  39. data/app/assets/javascripts/releaf/include/url_builder.js +193 -0
  40. data/app/assets/stylesheets/releaf/application.scss +9 -0
  41. data/app/assets/stylesheets/releaf/environment/extras.scss +11 -0
  42. data/app/assets/stylesheets/releaf/environment/functions/units.scss +12 -0
  43. data/app/assets/stylesheets/releaf/environment/functions.scss +1 -0
  44. data/app/assets/stylesheets/releaf/environment/mixins/blocks.scss +133 -0
  45. data/app/assets/stylesheets/releaf/environment/mixins/elements.scss +64 -0
  46. data/app/assets/stylesheets/releaf/environment/mixins/text.scss +61 -0
  47. data/app/assets/stylesheets/releaf/environment/mixins.scss +3 -0
  48. data/app/assets/stylesheets/releaf/environment/variables/colors.scss +93 -0
  49. data/app/assets/stylesheets/releaf/environment/variables/dimensions.scss +0 -0
  50. data/app/assets/stylesheets/releaf/environment/variables/magnific-popup.scss +6 -0
  51. data/app/assets/stylesheets/releaf/environment/variables.scss +5 -0
  52. data/app/assets/stylesheets/releaf/environment.scss +4 -0
  53. data/app/assets/stylesheets/releaf/layout/base.scss +32 -0
  54. data/app/assets/stylesheets/releaf/layout/breadcrumbs.scss +47 -0
  55. data/app/assets/stylesheets/releaf/layout/buttons.scss +107 -0
  56. data/app/assets/stylesheets/releaf/layout/deprecated.scss +29 -0
  57. data/app/assets/stylesheets/releaf/layout/dialogs.scss +138 -0
  58. data/app/assets/stylesheets/releaf/layout/errors.scss +28 -0
  59. data/app/assets/stylesheets/releaf/layout/extras.scss +10 -0
  60. data/app/assets/stylesheets/releaf/layout/fields.scss +305 -0
  61. data/app/assets/stylesheets/releaf/layout/fonts.scss +16 -0
  62. data/app/assets/stylesheets/releaf/layout/footer.scss +80 -0
  63. data/app/assets/stylesheets/releaf/layout/forms.scss +23 -0
  64. data/app/assets/stylesheets/releaf/layout/header.scss +55 -0
  65. data/app/assets/stylesheets/releaf/layout/icons.scss +4 -0
  66. data/app/assets/stylesheets/releaf/layout/images.scss +4 -0
  67. data/app/assets/stylesheets/releaf/layout/links.scss +7 -0
  68. data/app/assets/stylesheets/releaf/layout/localization.scss +79 -0
  69. data/app/assets/stylesheets/releaf/layout/main.scss +43 -0
  70. data/app/assets/stylesheets/releaf/layout/notifications.scss +67 -0
  71. data/app/assets/stylesheets/releaf/layout/pagination.scss +18 -0
  72. data/app/assets/stylesheets/releaf/layout/search.scss +70 -0
  73. data/app/assets/stylesheets/releaf/layout/sections.scss +138 -0
  74. data/app/assets/stylesheets/releaf/layout/sidebar.scss +306 -0
  75. data/app/assets/stylesheets/releaf/layout/tables.scss +99 -0
  76. data/app/assets/stylesheets/releaf/layout/text.scss +31 -0
  77. data/app/assets/stylesheets/releaf/layout/toolboxes.scss +69 -0
  78. data/app/assets/stylesheets/releaf/layout.scss +35 -0
  79. data/app/assets/stylesheets/releaf/vendor/magnific-popup/main.scss +596 -0
  80. data/app/assets/stylesheets/releaf/vendor/magnific-popup/settings.scss +45 -0
  81. data/app/builders/releaf/builders/association_reflector.rb +58 -0
  82. data/app/builders/releaf/builders/base.rb +80 -0
  83. data/app/builders/releaf/builders/collection.rb +8 -0
  84. data/app/builders/releaf/builders/confirm_destroy_dialog_builder.rb +25 -0
  85. data/app/builders/releaf/builders/confirm_dialog_builder.rb +54 -0
  86. data/app/builders/releaf/builders/edit_builder.rb +66 -0
  87. data/app/builders/releaf/builders/form_builder.rb +594 -0
  88. data/app/builders/releaf/builders/index_builder.rb +118 -0
  89. data/app/builders/releaf/builders/orderer.rb +5 -0
  90. data/app/builders/releaf/builders/page/header_builder.rb +70 -0
  91. data/app/builders/releaf/builders/page/layout_builder.rb +155 -0
  92. data/app/builders/releaf/builders/page/menu_builder.rb +140 -0
  93. data/app/builders/releaf/builders/pagination_builder.rb +107 -0
  94. data/app/builders/releaf/builders/refused_destroy_dialog_builder.rb +68 -0
  95. data/app/builders/releaf/builders/resource.rb +9 -0
  96. data/app/builders/releaf/builders/resource_dialog.rb +8 -0
  97. data/app/builders/releaf/builders/resource_view.rb +54 -0
  98. data/app/builders/releaf/builders/show_builder.rb +3 -0
  99. data/app/builders/releaf/builders/table_builder.rb +280 -0
  100. data/app/builders/releaf/builders/tags/releaf_associated_set_field.rb +40 -0
  101. data/app/builders/releaf/builders/template.rb +8 -0
  102. data/app/builders/releaf/builders/toolbox.rb +23 -0
  103. data/app/builders/releaf/builders/toolbox_builder.rb +27 -0
  104. data/app/builders/releaf/builders/view.rb +132 -0
  105. data/app/builders/releaf/builders.rb +38 -0
  106. data/app/builders/releaf/core/settings/form_builder.rb +21 -0
  107. data/app/builders/releaf/core/settings/table_builder.rb +11 -0
  108. data/app/controllers/concerns/releaf/breadcrumbs.rb +42 -0
  109. data/app/controllers/concerns/releaf/richtext_attachments.rb +20 -0
  110. data/app/controllers/releaf/base_controller.rb +458 -0
  111. data/app/controllers/releaf/core/errors_controller.rb +5 -0
  112. data/app/controllers/releaf/core/settings_controller.rb +50 -0
  113. data/app/helpers/releaf/application_helper.rb +53 -0
  114. data/app/helpers/releaf/button_helper.rb +50 -0
  115. data/app/helpers/releaf/javascript_helper.rb +75 -0
  116. data/app/lib/releaf/core/assets_resolver.rb +58 -0
  117. data/app/lib/releaf/core/default_searchable_fields.rb +43 -0
  118. data/app/lib/releaf/core/error_formatter.rb +103 -0
  119. data/app/lib/releaf/core/item_orderer.rb +102 -0
  120. data/app/lib/releaf/core/resource_base.rb +66 -0
  121. data/app/lib/releaf/core/resource_fields.rb +6 -0
  122. data/app/lib/releaf/core/resource_params.rb +47 -0
  123. data/app/lib/releaf/core/resource_table_fields.rb +10 -0
  124. data/app/lib/releaf/core/resource_utilities.rb +36 -0
  125. data/app/lib/releaf/core/responders/access_denied_responder.rb +9 -0
  126. data/app/lib/releaf/core/responders/after_save_responder.rb +28 -0
  127. data/app/lib/releaf/core/responders/confirm_destroy_responder.rb +13 -0
  128. data/app/lib/releaf/core/responders/destroy_responder.rb +10 -0
  129. data/app/lib/releaf/core/responders/error_responder.rb +9 -0
  130. data/app/lib/releaf/core/responders/feature_disabled_responder.rb +9 -0
  131. data/app/lib/releaf/core/responders/page_not_found_responder.rb +9 -0
  132. data/app/lib/releaf/core/responders.rb +31 -0
  133. data/app/lib/releaf/core/search.rb +147 -0
  134. data/app/lib/releaf/core/template_field_type_mapper.rb +127 -0
  135. data/app/models/releaf/richtext_attachment.rb +6 -0
  136. data/app/models/releaf/settings.rb +27 -0
  137. data/app/views/layouts/releaf/admin.html.erb +1 -0
  138. data/app/views/releaf/base/confirm_destroy.ruby +1 -0
  139. data/app/views/releaf/base/create_releaf_richtext_attachment.haml +1 -0
  140. data/app/views/releaf/base/edit.ruby +1 -0
  141. data/app/views/releaf/base/index.ruby +1 -0
  142. data/app/views/releaf/base/new.ruby +1 -0
  143. data/app/views/releaf/base/refused_destroy.ruby +1 -0
  144. data/app/views/releaf/base/show.ruby +1 -0
  145. data/app/views/releaf/base/toolbox.ruby +1 -0
  146. data/app/views/releaf/error_pages/_error.html.haml +10 -0
  147. data/app/views/releaf/error_pages/access_denied.html.haml +1 -0
  148. data/app/views/releaf/error_pages/feature_disabled.html.haml +1 -0
  149. data/app/views/releaf/error_pages/page_not_found.html.haml +2 -0
  150. data/lib/generators/dummy/install_generator.rb +18 -0
  151. data/lib/generators/dummy/templates/builders/admin/books/form_builder.rb +13 -0
  152. data/lib/generators/dummy/templates/builders/admin/books/index_builder.rb +30 -0
  153. data/lib/generators/dummy/templates/builders/admin/books/table_builder.rb +7 -0
  154. data/lib/generators/dummy/templates/builders/admin/nodes/form_builder.rb +7 -0
  155. data/lib/generators/dummy/templates/config/routes.rb +19 -0
  156. data/lib/generators/dummy/templates/controllers/admin/authors_controller.rb +12 -0
  157. data/lib/generators/dummy/templates/controllers/admin/books_controller.rb +17 -0
  158. data/lib/generators/dummy/templates/controllers/admin/chapters_controller.rb +3 -0
  159. data/lib/generators/dummy/templates/controllers/admin/publishers_controller.rb +3 -0
  160. data/lib/generators/dummy/templates/controllers/application_controller.rb +39 -0
  161. data/lib/generators/dummy/templates/controllers/concerns/.keep +0 -0
  162. data/lib/generators/dummy/templates/controllers/concerns/node_controller.rb +37 -0
  163. data/lib/generators/dummy/templates/controllers/contacts_controller.rb +3 -0
  164. data/lib/generators/dummy/templates/controllers/home_pages_controller.rb +3 -0
  165. data/lib/generators/dummy/templates/controllers/text_pages_controller.rb +3 -0
  166. data/lib/generators/dummy/templates/initializers/releaf.rb +35 -0
  167. data/lib/generators/dummy/templates/migrations/create_authors.rb +14 -0
  168. data/lib/generators/dummy/templates/migrations/create_banners.rb +11 -0
  169. data/lib/generators/dummy/templates/migrations/create_book_sequels.rb +14 -0
  170. data/lib/generators/dummy/templates/migrations/create_books.rb +27 -0
  171. data/lib/generators/dummy/templates/migrations/create_bundles.rb +7 -0
  172. data/lib/generators/dummy/templates/migrations/create_chapters.rb +13 -0
  173. data/lib/generators/dummy/templates/migrations/create_home_pages.rb +9 -0
  174. data/lib/generators/dummy/templates/migrations/create_node_extra_fields.rb +5 -0
  175. data/lib/generators/dummy/templates/migrations/create_publishers.rb +8 -0
  176. data/lib/generators/dummy/templates/migrations/create_text_pages.rb +9 -0
  177. data/lib/generators/dummy/templates/models/author.rb +10 -0
  178. data/lib/generators/dummy/templates/models/banner.rb +5 -0
  179. data/lib/generators/dummy/templates/models/book.rb +19 -0
  180. data/lib/generators/dummy/templates/models/book_sequel.rb +4 -0
  181. data/lib/generators/dummy/templates/models/bundle.rb +17 -0
  182. data/lib/generators/dummy/templates/models/chapter.rb +7 -0
  183. data/lib/generators/dummy/templates/models/home_page.rb +5 -0
  184. data/lib/generators/dummy/templates/models/node.rb +10 -0
  185. data/lib/generators/dummy/templates/models/publisher.rb +9 -0
  186. data/lib/generators/dummy/templates/models/text_page.rb +5 -0
  187. data/lib/generators/dummy/templates/views/contacts/show.html.haml +1 -0
  188. data/lib/generators/dummy/templates/views/home_pages/show.haml +1 -0
  189. data/lib/generators/dummy/templates/views/layouts/application.html.haml +22 -0
  190. data/lib/generators/dummy/templates/views/text_pages/show.haml +1 -0
  191. data/lib/generators/releaf/install_generator.rb +93 -0
  192. data/lib/generators/releaf/templates/initializers/haml.rb +1 -0
  193. data/lib/generators/releaf/templates/initializers/releaf.rb +30 -0
  194. data/lib/generators/releaf/templates/migrations/create_releaf_nodes.rb +28 -0
  195. data/lib/generators/releaf/templates/migrations/create_releaf_permissions.rb +12 -0
  196. data/lib/generators/releaf/templates/migrations/create_releaf_richtext_attachments.rb +12 -0
  197. data/lib/generators/releaf/templates/migrations/create_releaf_roles.rb +9 -0
  198. data/lib/generators/releaf/templates/migrations/create_releaf_settings.rb +17 -0
  199. data/lib/generators/releaf/templates/migrations/create_releaf_translations.rb +21 -0
  200. data/lib/generators/releaf/templates/migrations/create_releaf_users.rb +52 -0
  201. data/lib/generators/releaf/templates/models/node.rb +3 -0
  202. data/lib/generators/releaf/templates/seeds/seeds.rb +54 -0
  203. data/lib/releaf/core/application.rb +17 -0
  204. data/lib/releaf/core/builders_autoload.rb +27 -0
  205. data/lib/releaf/core/component.rb +9 -0
  206. data/lib/releaf/core/configuration.rb +101 -0
  207. data/lib/releaf/core/engine.rb +35 -0
  208. data/lib/releaf/core/exceptions.rb +38 -0
  209. data/lib/releaf/core/route_mapper.rb +59 -0
  210. data/lib/releaf/core/settings_ui_component.rb +7 -0
  211. data/lib/releaf/core/validation_error_codes.rb +36 -0
  212. data/lib/releaf/version.rb +3 -0
  213. data/lib/releaf-core.rb +14 -0
  214. data/lib/tasks/releaf_tasks.rake +4 -0
  215. data/releaf-core.gemspec +35 -0
  216. data/spec/builders/builders/association_reflector_spec.rb +138 -0
  217. data/spec/builders/builders/base_spec.rb +276 -0
  218. data/spec/builders/builders/collection_spec.rb +18 -0
  219. data/spec/builders/builders/confirm_destroy_dialog_builder_spec.rb +71 -0
  220. data/spec/builders/builders/confirm_dialog_builder_spec.rb +105 -0
  221. data/spec/builders/builders/edit_builder_spec.rb +215 -0
  222. data/spec/builders/builders/form_builder_spec.rb +562 -0
  223. data/spec/builders/builders/index_builder_spec.rb +345 -0
  224. data/spec/builders/builders/orderer_spec.rb +22 -0
  225. data/spec/builders/builders/page/header_builder_spec.rb +143 -0
  226. data/spec/builders/builders/page/layout_builder_spec.rb +73 -0
  227. data/spec/builders/builders/page/menu_builder_spec.rb +160 -0
  228. data/spec/builders/builders/pagination_builder_spec.rb +330 -0
  229. data/spec/builders/builders/resource_dialog_spec.rb +21 -0
  230. data/spec/builders/builders/resource_view_spec.rb +158 -0
  231. data/spec/builders/builders/show_builder_spec.rb +7 -0
  232. data/spec/builders/builders/table_builder_spec.rb +638 -0
  233. data/spec/builders/builders/template_spec.rb +12 -0
  234. data/spec/builders/builders/toolbox_builder_spec.rb +67 -0
  235. data/spec/builders/builders/toolbox_spec.rb +48 -0
  236. data/spec/builders/builders/view_spec.rb +281 -0
  237. data/spec/builders/builders_spec.rb +134 -0
  238. data/spec/builders/core/settings/form_builder_spec.rb +69 -0
  239. data/spec/builders/core/settings/table_builder_spec.rb +21 -0
  240. data/spec/controllers/concerns/releaf/richtext_attachments_spec.rb +51 -0
  241. data/spec/controllers/releaf/base_controller_spec.rb +447 -0
  242. data/spec/controllers/releaf/core/settings_controller_spec.rb +31 -0
  243. data/spec/features/ajaxbox_spec.rb +111 -0
  244. data/spec/features/authorization_spec.rb +50 -0
  245. data/spec/features/dragonfly_integration_spec.rb +24 -0
  246. data/spec/features/edit_actions_spec.rb +142 -0
  247. data/spec/features/errors_spec.rb +29 -0
  248. data/spec/features/index_actions_spec.rb +85 -0
  249. data/spec/features/index_table_spec.rb +32 -0
  250. data/spec/features/menu_spec.rb +71 -0
  251. data/spec/features/richtext_attachments_spec.rb +64 -0
  252. data/spec/features/richtext_embed_spec.rb +29 -0
  253. data/spec/features/richtext_spec.rb +19 -0
  254. data/spec/features/search_spec.rb +825 -0
  255. data/spec/features/settings_spec.rb +38 -0
  256. data/spec/features/title_spec.rb +13 -0
  257. data/spec/fixtures/common_fields.yml +17 -0
  258. data/spec/fixtures/cs.png +0 -0
  259. data/spec/fixtures/time.formats.xlsx +0 -0
  260. data/spec/fixtures/unicorn.jpg +0 -0
  261. data/spec/helpers/application_helper_spec.rb +75 -0
  262. data/spec/helpers/button_helper_spec.rb +146 -0
  263. data/spec/lib/releaf/core/application_spec.rb +42 -0
  264. data/spec/lib/releaf/core/assets_resolver_spec.rb +113 -0
  265. data/spec/lib/releaf/core/configuration_spec.rb +230 -0
  266. data/spec/lib/releaf/core/default_searchable_fields_spec.rb +161 -0
  267. data/spec/lib/releaf/core/error_formatter_spec.rb +242 -0
  268. data/spec/lib/releaf/core/item_orderer_spec.rb +142 -0
  269. data/spec/lib/releaf/core/resource_base_spec.rb +174 -0
  270. data/spec/lib/releaf/core/resource_fields_spec.rb +12 -0
  271. data/spec/lib/releaf/core/resource_params_spec.rb +117 -0
  272. data/spec/lib/releaf/core/resource_table_fields_spec.rb +18 -0
  273. data/spec/lib/releaf/core/resource_utilities_spec.rb +87 -0
  274. data/spec/lib/releaf/core/responders/access_denied_responder_spec.rb +12 -0
  275. data/spec/lib/releaf/core/responders/after_save_responder_spec.rb +102 -0
  276. data/spec/lib/releaf/core/responders/confirm_destroy_responder_spec.rb +26 -0
  277. data/spec/lib/releaf/core/responders/destroy_responder_spec.rb +30 -0
  278. data/spec/lib/releaf/core/responders/error_responder_spec.rb +26 -0
  279. data/spec/lib/releaf/core/responders/feature_disabled_responder_spec.rb +12 -0
  280. data/spec/lib/releaf/core/responders/page_not_found_responder_spec.rb +12 -0
  281. data/spec/lib/releaf/core/responders_spec.rb +60 -0
  282. data/spec/lib/releaf/core/template_field_type_mapper_spec.rb +311 -0
  283. data/spec/lib/validation_error_codes_spec.rb +56 -0
  284. data/spec/misc/factories_spec.rb +43 -0
  285. data/spec/models/settings_spec.rb +58 -0
  286. data/spec/routing/route_mapper_spec.rb +185 -0
  287. data/spec/rspec_helpers/test_helpers_spec.rb +20 -0
  288. metadata +657 -0
@@ -0,0 +1,59 @@
1
+ module Releaf::Core::RouteMapper
2
+ # Pass given resource to "resources" mount method and
3
+ # add extra routes for members and collections needed by releaf
4
+ def releaf_resources(*args, &block)
5
+ resources *args do
6
+ yield if block_given?
7
+ member do
8
+ get :confirm_destroy if route_enabled?(:destroy, args.last)
9
+ get :toolbox if route_enabled?(:toolbox, args.last)
10
+ end
11
+ collection do
12
+ post :create_releaf_richtext_attachment if route_enabled?(:releaf_richtext_attachments, args.last)
13
+ end
14
+ end
15
+ end
16
+
17
+ def initialize_releaf_components
18
+ Releaf.application.config.components.each do|component_class|
19
+ if component_class.respond_to? :draw_component_routes
20
+ component_class.draw_component_routes(self)
21
+ end
22
+ end
23
+ end
24
+
25
+ def mount_releaf_at(mount_location, options={}, &block)
26
+ mount_location_namespace = mount_location.gsub("/", "").to_sym
27
+ Releaf.application.config.mount_location = mount_location_namespace.to_s
28
+ scope mount_location do
29
+ initialize_releaf_components
30
+
31
+ if mount_location_namespace.empty?
32
+ yield if block_given?
33
+ else
34
+ namespace mount_location_namespace, path: nil do
35
+ yield if block_given?
36
+ end
37
+ end
38
+
39
+ namespace :releaf, path: nil do
40
+ get '/*path' => 'core/errors#page_not_found'
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def route_enabled?(route, options)
48
+ include_route = true
49
+ if options.is_a? Hash
50
+ if options[:only] && !options[:only].include?(route.to_sym)
51
+ include_route = false
52
+ elsif options[:except].try(:include?, route.to_sym)
53
+ include_route = false
54
+ end
55
+ end
56
+
57
+ include_route
58
+ end
59
+ end
@@ -0,0 +1,7 @@
1
+ module Releaf::Core::SettingsUIComponent
2
+ extend Releaf::Core::Component
3
+
4
+ def self.draw_component_routes router
5
+ resource_route(router, :core, :settings)
6
+ end
7
+ end
@@ -0,0 +1,36 @@
1
+ module ActiveModel
2
+ class ErrorMessage < String
3
+ attr_accessor :error_code, :data
4
+
5
+ def initialize(message, error_code = nil, data = nil)
6
+ super message
7
+ @error_code = error_code
8
+ @data = data
9
+ end
10
+ end
11
+
12
+ class Errors
13
+ def add(attribute, message = nil, options = {})
14
+ # build error code from message symbol
15
+ error_code = normalize_error_code(attribute, message, options)
16
+ message = normalize_message(attribute, message, options)
17
+ if exception = options[:strict]
18
+ exception = ActiveModel::StrictValidationFailed if exception == true
19
+ raise exception, full_message(attribute, message)
20
+ end
21
+
22
+ # use customized String subclass with "error_code" attribute
23
+ self[attribute] << ErrorMessage.new(message, error_code, options[:data])
24
+ end
25
+
26
+ def normalize_error_code(attribute, message, options)
27
+ if !options[:error_code].blank?
28
+ options[:error_code]
29
+ elsif message.class == Symbol
30
+ message
31
+ else
32
+ :invalid
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Releaf
2
+ VERSION = "0.2.1"
3
+ end
@@ -0,0 +1,14 @@
1
+ module Releaf
2
+ require 'releaf/core/engine'
3
+ require 'releaf/core/configuration'
4
+ require 'releaf/core/application'
5
+ require 'releaf/core/route_mapper'
6
+ require 'releaf/core/exceptions'
7
+ require 'releaf/core/validation_error_codes'
8
+
9
+ class << self
10
+ def application
11
+ @@application ||= Releaf::Core::Application.new
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :releaf do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,35 @@
1
+ require File.expand_path('../lib/releaf/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "releaf-core"
5
+ s.version = Releaf::VERSION
6
+
7
+ s.summary = "core gem for releaf"
8
+ s.description = "Admin interface for RubyOnRails projects inspired by Leaf CMS"
9
+ s.authors = ["CubeSystems"]
10
+ s.email = 'info@cubesystems.lv'
11
+ s.homepage = 'https://github.com/cubesystems/releaf'
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = Dir["spec/**/*"]
15
+
16
+ s.add_dependency 'rails', '~> 4.2', '>= 4.2.0'
17
+ s.add_dependency 'i18n', '~> 0.7', '>= 0.7.0'
18
+ s.add_dependency 'sprockets-rails', '~> 3.0', '>= 3.0.0'
19
+ s.add_dependency 'sass-rails'
20
+ s.add_dependency 'jquery-rails'
21
+ s.add_dependency 'jquery-ui-rails'
22
+ s.add_dependency 'railties'
23
+ s.add_dependency 'haml-rails'
24
+ s.add_dependency 'dragonfly'
25
+ s.add_dependency 'rails-settings-cached', '>= 0.4.5'
26
+ s.add_dependency 'ckeditor_rails'
27
+ s.add_dependency 'acts_as_list'
28
+ s.add_dependency 'will_paginate'
29
+ s.add_dependency 'font-awesome-rails'
30
+ s.add_dependency 'jquery-cookie-rails'
31
+ s.add_dependency 'globalize-accessors'
32
+ s.add_dependency 'rack-cache'
33
+
34
+ s.required_ruby_version = '>= 2.2.0'
35
+ end
@@ -0,0 +1,138 @@
1
+ require 'rails_helper'
2
+
3
+ describe Releaf::Builders::AssociationReflector, type: :class do
4
+ let(:reflection){ Book.reflect_on_association("chapters") }
5
+ subject{ described_class.new(reflection, :b, "xx") }
6
+
7
+ describe "#initialize" do
8
+ it "assigns given reflection" do
9
+ expect(subject.reflection).to eq(reflection)
10
+ end
11
+
12
+ it "assigns given fields" do
13
+ expect(subject.fields).to eq(:b)
14
+ end
15
+
16
+ it "normalizes to symbol and assigns given sortable name" do
17
+ expect(subject.sortable_column_name).to eq(:xx)
18
+ end
19
+ end
20
+
21
+ describe "#destroyable?" do
22
+ context "when reflection allow to destroy through nested attributes" do
23
+ it "returns true" do
24
+ subject.reflection = Book.reflect_on_association("book_sequels")
25
+ expect(subject.destroyable?).to be true
26
+ end
27
+ end
28
+
29
+ context "when reflection does not allow to destroy through nested attributes" do
30
+ it "returns false" do
31
+ expect(subject.destroyable?).to be false
32
+ end
33
+ end
34
+
35
+ it "caches result" do
36
+ expect(subject.reflection.active_record).to receive(:nested_attributes_options).and_call_original.once
37
+ subject.destroyable?
38
+ subject.destroyable?
39
+ subject.destroyable?
40
+ end
41
+ end
42
+
43
+ describe "#sortable?" do
44
+ context "when expected and actual order clauses are same" do
45
+ it "returns true" do
46
+ allow(subject).to receive(:expected_order_clause).and_return(:a)
47
+ allow(subject).to receive(:actual_order_clause).and_return(:a)
48
+ expect(subject.sortable?).to be true
49
+ end
50
+ end
51
+
52
+ context "when expected and actual order clauses differs" do
53
+ it "returns false" do
54
+ allow(subject).to receive(:expected_order_clause).and_return(:a)
55
+ allow(subject).to receive(:actual_order_clause).and_return(:b)
56
+ expect(subject.sortable?).to be false
57
+ end
58
+ end
59
+
60
+ it "caches result" do
61
+ expect(subject).to receive(:expected_order_clause).and_return(:x).once
62
+ expect(subject).to receive(:actual_order_clause).and_return(:y).once
63
+ subject.sortable?
64
+ subject.sortable?
65
+ subject.sortable?
66
+ end
67
+ end
68
+
69
+ describe "#actual_order_clause" do
70
+ context "when scope exists within reflection" do
71
+ it "returns actual reflection klass order clause with evaluated scope" do
72
+ relation = reflection.klass.all.order(:item_position)
73
+ allow(subject).to receive(:extract_order_clause).with(relation).and_return(:y)
74
+ expect(subject.actual_order_clause).to eq(:y)
75
+ end
76
+ end
77
+
78
+ context "when no scope exists within reflection" do
79
+ it "returns actual reflection klass order clause" do
80
+ subject.reflection = Book.reflect_on_association("sequels")
81
+ relation = subject.reflection.klass.all
82
+ allow(subject).to receive(:extract_order_clause).with(relation).and_return(:y)
83
+ expect(subject.actual_order_clause).to eq(:y)
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "#expected_order_clause" do
89
+ it "returns expected reflection klass order clause for sortable column name" do
90
+ subject.sortable_column_name = :title
91
+ relation = reflection.klass.all.order(:title)
92
+ allow(subject).to receive(:extract_order_clause).with(relation).and_return(:y)
93
+ expect(subject.expected_order_clause).to eq(:y)
94
+ end
95
+ end
96
+
97
+ describe "#extract_order_clause" do
98
+ it "returns order clauses normalized to string for given relation" do
99
+ relation = Book.order(genre: :desc)
100
+ expected_result = if mysql?
101
+ "`books`.`genre` DESC"
102
+ elsif postgresql?
103
+ '"books"."genre" DESC'
104
+ else
105
+ fail
106
+ end
107
+ expect(subject.extract_order_clause(relation)).to eq(expected_result)
108
+ end
109
+
110
+ context "when relation has no order clauses" do
111
+ it "returns empty string" do
112
+ relation = Book.all
113
+ expect(subject.extract_order_clause(relation)).to eq("")
114
+ end
115
+ end
116
+ end
117
+
118
+ describe "#value_as_sql" do
119
+ context "when given value respond to sql" do
120
+ it "return resulting sql" do
121
+ expected_result = if mysql?
122
+ "SELECT `books`.* FROM `books`"
123
+ elsif postgresql?
124
+ 'SELECT "books".* FROM "books"'
125
+ else
126
+ fail
127
+ end
128
+ expect(subject.value_as_sql(Book.all)).to eq(expected_result)
129
+ end
130
+ end
131
+
132
+ context "when given value does not respond to sql" do
133
+ it "return given value" do
134
+ expect(subject.value_as_sql(12)).to eq(12)
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,276 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::Base, type: :module do
4
+ class FormBuilderTestHelper < ActionView::Base
5
+ include Releaf::ButtonHelper
6
+ include Releaf::ApplicationHelper
7
+ include FontAwesome::Rails::IconHelper
8
+ end
9
+ class BuilderIncluder
10
+ include Releaf::Builders::Base
11
+ attr_accessor :template
12
+ end
13
+
14
+ let(:subject){ BuilderIncluder.new }
15
+ let(:template){ FormBuilderTestHelper.new }
16
+
17
+ before do
18
+ subject.template = template
19
+ end
20
+
21
+ describe "delegations" do
22
+ [:controller, :controller_name, :url_for, :form_for,
23
+ :releaf_button, :params, :form_tag, :file_field_tag,
24
+ :request, :check_box_tag, :label_tag, :content_tag, :hidden_field_tag,
25
+ :render, :link_to, :flash, :truncate, :radio_button_tag,
26
+ :options_for_select, :action_name, :options_from_collection_for_select,
27
+ :select_tag, :text_field_tag,
28
+ :image_tag, :jquery_date_format, :cookies, :button_tag, :merge_attributes
29
+ ].each do|method_name|
30
+ it "deletages #{method_name} to template" do
31
+ expect(subject).to delegate_method(method_name).to(:template)
32
+ end
33
+ end
34
+
35
+ [:layout_settings, :access_control, :controller_scope_name, :feature_available?,
36
+ :index_url].each do|method_name|
37
+ it "delegates #{method_name} to controller" do
38
+ expect(subject).to delegate_method(method_name).to(:controller)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#html_escape" do
44
+ it "escapes given value with " do
45
+ allow(ERB::Util).to receive(:html_escape).with("a").and_return("b")
46
+ expect(subject.html_escape("a")).to eq("b")
47
+ end
48
+ end
49
+
50
+
51
+ it "aliases #button to #releaf_button" do
52
+ allow(subject.template).to receive(:releaf_button).with("x", a: "y", b: "z").and_return("xx")
53
+ expect(subject.button("x", a: "y", b: "z")).to eq("xx")
54
+ end
55
+
56
+ describe "#icon" do
57
+ it "returns template fa_icon output" do
58
+ expect(subject.icon("check")).to eq('<i class="fa fa-check"></i>')
59
+ end
60
+ end
61
+
62
+ describe "#tag" do
63
+ context "when block is not given" do
64
+ context "when passing string as content" do
65
+ let(:output) do
66
+ subject.tag(:span, "<p>x</p>", class: "red")
67
+ end
68
+
69
+ it "returns an instance of ActiveSupport::SafeBuffer" do
70
+ expect( output ).to be_a ActiveSupport::SafeBuffer
71
+
72
+ end
73
+
74
+ it "passes all arguments to template #content_tag method and returns properly escaped result" do
75
+ expect( output ).to eq('<span class="red">&lt;p&gt;x&lt;/p&gt;</span>')
76
+ end
77
+ end
78
+
79
+ context "when passing safe buffer as content" do
80
+ let(:output) do
81
+ subject.tag(:span, ActiveSupport::SafeBuffer.new("<p>x</p>"), class: "red")
82
+ end
83
+
84
+ it "returns an instance of ActiveSupport::SafeBuffer" do
85
+ expect( output ).to be_a ActiveSupport::SafeBuffer
86
+
87
+ end
88
+
89
+ it "passes all arguments to template #content_tag method and returns properly escaped result" do
90
+ expect( output ).to eq('<span class="red"><p>x</p></span>')
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ context "when block is given" do
97
+ context "when block evaluates to array" do
98
+ let(:content) do
99
+ [
100
+ '<p>foo</p>',
101
+ 'bar',
102
+ ActiveSupport::SafeBuffer.new('<p>baz</p>')
103
+ ]
104
+ end
105
+
106
+ let(:output) do
107
+ subject.tag(:div, class: 'important') { content }
108
+ end
109
+
110
+ it "returns an instance of ActiveSupport::SafeBuffer" do
111
+ expect( output ).to be_a ActiveSupport::SafeBuffer
112
+ end
113
+
114
+ it "safely joins array" do
115
+ expect( template ).to receive(:safe_join).with(content).and_call_original
116
+ output
117
+ end
118
+
119
+ it "passes joined result to #template#content_tag as content" do
120
+ allow( template ).to receive(:safe_join).with(content).and_return('super duper')
121
+ expect( output ).to eq('<div class="important">super duper</div>')
122
+ end
123
+
124
+ it "returns properly escaped result" do
125
+ expect( output ).to eq('<div class="important">&lt;p&gt;foo&lt;/p&gt;bar<p>baz</p></div>')
126
+ end
127
+
128
+ end
129
+
130
+ context "when block evaluates to other than array" do
131
+ let(:output) do
132
+ subject.tag(:div, class: 'important') { '<p>content</p>' }
133
+ end
134
+
135
+ it "returns an instance of ActiveSupport::SafeBuffer" do
136
+ expect( output ).to be_a ActiveSupport::SafeBuffer
137
+ end
138
+
139
+ it "doesn't call #template#safe_join" do
140
+ expect( template ).to_not receive(:safe_join)
141
+ output
142
+ end
143
+
144
+ it "keeps safe buffer unmodified and pass to #template#content_tag as content which won't be escaped" do
145
+ expect( subject.tag(:div, class: 'important') { ActiveSupport::SafeBuffer.new('<p>content</p>') } ).to eq '<div class="important"><p>content</p></div>'
146
+ end
147
+
148
+ it "passes block result to #template#content_tag as content which will be escaped" do
149
+ expect( output ).to eq '<div class="important">&lt;p&gt;content&lt;/p&gt;</div>'
150
+ end
151
+
152
+ it "casts block result to string" do
153
+ expect( subject.tag(:div, class: 'important') { 1 } ).to eq '<div class="important">1</div>'
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ describe "#wrapper" do
160
+ context "when block is given" do
161
+ let(:output) do
162
+ subject.wrapper(class: 'c') do
163
+ '<span class="a">b</span>'.html_safe
164
+ end
165
+ end
166
+
167
+ it "wrapps given content within div element with given attributes" do
168
+ expect(output).to eq('<div class="c"><span class="a">b</span></div>')
169
+ end
170
+ end
171
+
172
+ context "when block is not given" do
173
+ it "wrapps given content within div element with given attributes" do
174
+ expect(subject.wrapper('<span class="a">b</span>'.html_safe, class: "c")).to eq('<div class="c"><span class="a">b</span></div>')
175
+ end
176
+ end
177
+ end
178
+
179
+ describe "#template_variable" do
180
+ it "returns template instance variable value for given key" do
181
+ template.instance_variable_set("@test", "xx")
182
+ expect(subject.template_variable("test")).to eq("xx")
183
+ end
184
+ end
185
+
186
+ describe "#safe_join" do
187
+ let(:content) do
188
+ ['foo', '<p>bar</p>', ActiveSupport::SafeBuffer.new('<p>baz</p>')]
189
+ end
190
+
191
+ let(:output) do
192
+ subject.safe_join { content }
193
+ end
194
+
195
+ it "returns an instance of ActiveSupport::SafeBuffer" do
196
+ expect( output ).to be_a ActiveSupport::SafeBuffer
197
+ end
198
+
199
+ it "passes block result to #template#safe_join" do
200
+ expect( template ).to receive(:safe_join).with(content).and_call_original
201
+ output
202
+ end
203
+
204
+ it "returns correctly escaped result" do
205
+ expect( output ).to eq 'foo&lt;p&gt;bar&lt;/p&gt;<p>baz</p>'
206
+ end
207
+ end
208
+
209
+ describe "#t" do
210
+ before do
211
+ allow(subject).to receive(:default_translation_scope).and_return("_default_scope_")
212
+ end
213
+
214
+ it "passes all arguments to I18n.t and returns translation" do
215
+ allow(I18n).to receive(:t).with("x", default: "y", scope: "z").and_return("translated value")
216
+ expect(subject.t("x", default: "y", scope: "z")).to eq("translated value")
217
+ end
218
+
219
+ context "when :scope option passed" do
220
+ it "uses default translation scope controller translation scope" do
221
+ expect(I18n).to receive(:t).with("x", scope: "zzz").and_return("asd")
222
+ subject.t("x", scope: "zzz")
223
+ end
224
+ end
225
+
226
+ context "when no :scope option passed" do
227
+ it "adds controller translation scope" do
228
+ expect(I18n).to receive(:t).with("x", scope: "_default_scope_").and_return("asd")
229
+ subject.t("x")
230
+ end
231
+ end
232
+ end
233
+
234
+ describe "#translate_locale" do
235
+ it "returns translated locale within `locales` scope" do
236
+ allow(subject).to receive(:t).with("de", scope: "locales").and_return("dzerman")
237
+ expect(subject.translate_locale("de")).to eq("dzerman")
238
+ end
239
+ end
240
+
241
+ describe "#locale_options" do
242
+ it "returns array with translated locales usable for rails options helper" do
243
+ allow(subject).to receive(:t).with("de", scope: "locales").and_return("dzerman")
244
+ allow(subject).to receive(:t).with("lv", scope: "locales").and_return("latvian")
245
+ expect(subject.locale_options(["de", "lv"])).to eq([["dzerman", "de"], ["latvian", "lv"]])
246
+ end
247
+ end
248
+
249
+ describe "#resource_to_text" do
250
+ let(:resource){ Releaf::Permissions::User.new(name: "a", surname: "b") }
251
+
252
+ context "when given resource respond to #to_text method" do
253
+ it "returns resource #to_text output" do
254
+ expect(subject.resource_to_text(resource)).to eq("a b")
255
+ end
256
+ end
257
+
258
+ context "when given resource does not respond to #to_text method" do
259
+ it "returns resource #to_s output" do
260
+ allow(resource).to receive(:respond_to?).and_call_original
261
+ allow(resource).to receive(:respond_to?).with(:to_text).and_return(false)
262
+ allow(resource).to receive(:to_s).and_return("x")
263
+ expect(subject.resource_to_text(resource)).to eq("x")
264
+ end
265
+ end
266
+ end
267
+
268
+ describe "#default_translation_scope" do
269
+ it "returns controller scope" do
270
+ controller = Releaf::BaseController.new
271
+ allow(subject).to receive(:controller).and_return(controller)
272
+ allow(controller).to receive(:controller_scope_name).and_return("x")
273
+ expect(subject.default_translation_scope).to eq("x")
274
+ end
275
+ end
276
+ end