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,12 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::Template, type: :module do
4
+ class TemplateClassIncluder
5
+ include Releaf::Builders::Template
6
+ end
7
+
8
+ it "it assigns template argument to instance 'template' accessor on initialization" do
9
+ subject = TemplateClassIncluder.new("x")
10
+ expect(subject.template).to eq("x")
11
+ end
12
+ end
@@ -0,0 +1,67 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::ToolboxBuilder, type: :class do
4
+ class ToolboxBuilderTestHelper < ActionView::Base
5
+ include Releaf::ButtonHelper
6
+ include Releaf::ApplicationHelper
7
+ end
8
+
9
+ subject { described_class.new(template) }
10
+ let(:template){ ToolboxBuilderTestHelper.new }
11
+
12
+ it "includes Releaf::Builders::Base" do
13
+ expect(described_class.ancestors).to include(Releaf::Builders::Base)
14
+ end
15
+
16
+ it "includes Releaf::Builders::Template" do
17
+ expect(described_class.ancestors).to include(Releaf::Builders::Template)
18
+ end
19
+
20
+ it "includes Releaf::Builders::Resource" do
21
+ expect(described_class.ancestors).to include(Releaf::Builders::Resource)
22
+ end
23
+
24
+ describe "#output" do
25
+ it "returns safely joined items" do
26
+ allow(subject).to receive(:items).and_return([ '<', ActiveSupport::SafeBuffer.new(">")])
27
+ expect(subject.output).to eq("<li>&lt;</li><li>></li>")
28
+ end
29
+ end
30
+
31
+ describe "#items" do
32
+ before{ allow(subject).to receive(:destroy_confirmation_link).and_return("x") }
33
+
34
+ context "when no destroy feature is available" do
35
+ it "returns array with destroy button html" do
36
+ allow(subject).to receive(:feature_available?).with(:destroy).and_return(true)
37
+ expect(subject.items).to eq(["x"])
38
+ end
39
+ end
40
+
41
+ context "when destroy feature is not available" do
42
+ it "returns empty array" do
43
+ allow(subject).to receive(:feature_available?).with(:destroy).and_return(false)
44
+ expect(subject.items).to eq([])
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#destroy_confirmation_link" do
50
+ it "returns destroy confirmation link" do
51
+ allow(subject).to receive(:t).with("Delete").and_return("dlt")
52
+ allow(subject).to receive(:destroy_confirmation_url).and_return("www.xxx")
53
+ content = '<a class="button ajaxbox danger" title="dlt" href="www.xxx" data-modal="true">dlt</a>'
54
+ expect(subject.destroy_confirmation_link).to eq(content)
55
+ end
56
+ end
57
+
58
+ describe "#destroy_confirmation_url" do
59
+ it "returns resource destroy confirmation url with index_url param" do
60
+ subject.resource = Book.new(id: 99)
61
+ allow(subject.template).to receive(:url_for).with(action: :confirm_destroy, id: 99, index_url: "y").and_return("x")
62
+ allow(subject.template).to receive(:controller).and_return(Releaf::BaseController.new)
63
+ allow(subject.controller).to receive(:index_url).and_return("y")
64
+ expect(subject.destroy_confirmation_url).to eq("x")
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,48 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::Toolbox, type: :class do
4
+ class ToolboxTestTemplate < ActionView::Base
5
+ end
6
+
7
+ class UnitTestToolboxBuilder
8
+ include Releaf::Builders::Base
9
+ include Releaf::Builders::Template
10
+ include Releaf::Builders::Toolbox
11
+ end
12
+
13
+ subject { UnitTestToolboxBuilder.new(template) }
14
+ let(:template){ ToolboxTestTemplate.new }
15
+ let(:resource){ Releaf::Permissions::User.new }
16
+
17
+ describe "#toolbox" do
18
+ context "when the passed object is a new record" do
19
+ it "returns empty string" do
20
+ expect(subject.toolbox(resource)).to eq("")
21
+ end
22
+ end
23
+
24
+ context "when the passed object is an existing record" do
25
+ it "returns toolbox HTML with trigger and without items" do
26
+ resource.id = 212
27
+ allow(resource).to receive(:new_record?).and_return(false)
28
+ allow(subject).to receive(:t).with("Tools").and_return("tls")
29
+ allow(subject).to receive(:icon).with("ellipsis-v").and_return("<kebab_icon />".html_safe)
30
+ allow(subject).to receive(:icon).with("caret-up").and_return("<caret_icon />".html_safe)
31
+ allow(subject).to receive(:action_name).and_return("edit")
32
+ allow(subject).to receive(:url_for).with({action: :toolbox, id: 212, context: "edit", some_param: 89}).and_return("/toolbox_action")
33
+
34
+ expect(subject.toolbox(resource, some_param: 89)).to match_html(%Q[
35
+ <div class="toolbox" data-url="/toolbox_action">
36
+ <button class="button trigger only-icon" type="button" title="tls">
37
+ <kebab_icon />
38
+ </button>
39
+ <menu class="toolbox-items" type="toolbar">
40
+ <caret_icon />
41
+ <ul></ul>
42
+ </menu>
43
+ </div>
44
+ ])
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,281 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::View, type: :class do
4
+ class ViewTestHelper < ActionView::Base
5
+ include FontAwesome::Rails::IconHelper
6
+ end
7
+
8
+ class ViewTestIncluder
9
+ include Releaf::Builders::Base
10
+ include Releaf::Builders::Template
11
+ include Releaf::Builders::View
12
+ end
13
+
14
+ subject { ViewTestIncluder.new(template) }
15
+ let(:template){ ViewTestHelper.new }
16
+
17
+ it "includes Releaf::Builders::Base" do
18
+ expect(described_class.ancestors).to include(Releaf::Builders::Base)
19
+ end
20
+
21
+ it "includes Releaf::Builders::Template" do
22
+ expect(described_class.ancestors).to include(Releaf::Builders::Template)
23
+ end
24
+
25
+ describe "#output" do
26
+ before do
27
+ allow(subject).to receive(:header).and_return(ActiveSupport::SafeBuffer.new("<"))
28
+ allow(subject).to receive(:section).and_return(ActiveSupport::SafeBuffer.new(">"))
29
+ end
30
+
31
+ it "returns safely joined header and section outputs" do
32
+ allow(subject).to receive(:dialog?).and_return(false)
33
+ expect(subject.output).to eq("<>")
34
+ end
35
+
36
+ context "within dialog" do
37
+ it "does not return header content" do
38
+ allow(subject).to receive(:dialog?).and_return(true)
39
+ expect(subject.output).to eq(">")
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#dialog?" do
45
+ let(:controller){ Releaf::BaseController.new }
46
+
47
+ before do
48
+ allow(template).to receive(:controller).and_return(controller)
49
+ end
50
+
51
+ context "when controller has ajax mode enabled" do
52
+ it "returns true" do
53
+ allow(controller).to receive(:ajax?).and_return(true)
54
+ expect(subject.dialog?).to be true
55
+ end
56
+ end
57
+
58
+ context "when controller has ajax mode disabled" do
59
+ it "returns false" do
60
+ allow(controller).to receive(:ajax?).and_return(false)
61
+ expect(subject.dialog?).to be false
62
+ end
63
+ end
64
+ end
65
+
66
+ describe "#dialog_name" do
67
+ class UnitTestDialogBuilder
68
+ include Releaf::Builders::Base
69
+ include Releaf::Builders::Template
70
+ include Releaf::Builders::View
71
+ end
72
+
73
+ it "returns normalized, dashed dialog name taken from dialog class name" do
74
+ subject = UnitTestDialogBuilder.new(template)
75
+ expect(subject.dialog_name).to eq("unit-test")
76
+
77
+ subject = Releaf::Builders::EditBuilder.new(template)
78
+ expect(subject.dialog_name).to eq("edit")
79
+ end
80
+ end
81
+
82
+ describe "#header" do
83
+ it "returns safely joined breadcrumbs, flash notices and header extras within header tag" do
84
+ allow(subject).to receive(:breadcrumbs).and_return(ActiveSupport::SafeBuffer.new("breadcrumbs>"))
85
+ allow(subject).to receive(:flash_notices).and_return(ActiveSupport::SafeBuffer.new(">_and_notices_"))
86
+ allow(subject).to receive(:header_extras).and_return(ActiveSupport::SafeBuffer.new(">extras"))
87
+ expect(subject.header).to eq("<header>breadcrumbs>>_and_notices_>extras</header>")
88
+ end
89
+ end
90
+
91
+ describe "#section" do
92
+ it "returns safely joined section blocks within section tag" do
93
+ allow(subject).to receive(:section_attributes).and_return(class: "xx")
94
+ allow(subject).to receive(:section_blocks).and_return([ '<', ActiveSupport::SafeBuffer.new(">")])
95
+ expect(subject.section).to eq('<section class="xx">&lt;></section>')
96
+ end
97
+ end
98
+
99
+ describe "#section_attributes" do
100
+ context "within dialog" do
101
+ it "returns hash with dialog classes" do
102
+ allow(subject).to receive(:dialog?).and_return(true)
103
+ allow(subject).to receive(:dialog_name).and_return("xxx")
104
+ expect(subject.section_attributes).to eq(class: ["dialog", "xxx"])
105
+ end
106
+ end
107
+
108
+ context "when not within dialog" do
109
+ it "returns empty hash" do
110
+ allow(subject).to receive(:dialog?).and_return(false)
111
+ expect(subject.section_attributes).to eq({})
112
+ end
113
+ end
114
+ end
115
+
116
+ describe "#breadcrumbs" do
117
+ context "when breadcrumbs template variable exists" do
118
+ it "returns safely joined breadcrumbs items list within nav element" do
119
+ allow(subject).to receive(:template_variable).with("breadcrumbs").and_return([:a, :b, :c])
120
+ allow(subject).to receive(:breadcrumb_item).with(:a, false).and_return(">a")
121
+ allow(subject).to receive(:breadcrumb_item).with(:b, false).and_return(ActiveSupport::SafeBuffer.new(">b"))
122
+ allow(subject).to receive(:breadcrumb_item).with(:c, true).and_return(">c")
123
+ content = '<nav><ul class="breadcrumbs">&gt;a>b&gt;c</ul></nav>'
124
+ expect(subject.breadcrumbs).to eq(content)
125
+ end
126
+ end
127
+
128
+ context "when breadcrumbs template variable does not exists" do
129
+ it "returns nil" do
130
+ allow(subject).to receive(:template_variable).with("breadcrumbs").and_return(nil)
131
+ expect(subject.breadcrumbs).to be nil
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "#breadcrumb_item" do
137
+ context "when given breadcrumb item has url" do
138
+ it "returns name wrapped within link" do
139
+ expect(subject.breadcrumb_item({url: "asa", name: "x"}, true)).to eq('<li><a href="asa">x</a></li>')
140
+ end
141
+ end
142
+
143
+ context "when given breadcrumb item has no url" do
144
+ it "returns only name" do
145
+ expect(subject.breadcrumb_item({name: "x"}, true)).to eq('<li>x</li>')
146
+ end
147
+ end
148
+
149
+ it "adds breadcrumb icon after except when last element given" do
150
+ expect(subject.breadcrumb_item({name: "x"}, true)).to eq('<li>x</li>')
151
+ expect(subject.breadcrumb_item({name: "x"}, false)).to eq('<li>x<i class="fa fa-chevron-right"></i></li>')
152
+ end
153
+ end
154
+
155
+ describe "#flash_notices" do
156
+ it "returns safely joined flash items" do
157
+ allow(subject).to receive(:flash).and_return(a: "xx", b: "yy")
158
+ allow(subject).to receive(:flash_item).with(:a, "xx").and_return(ActiveSupport::SafeBuffer.new("<a"))
159
+ allow(subject).to receive(:flash_item).with(:b, "yy").and_return("b>")
160
+ expect(subject.flash_notices).to eq("<ab&gt;")
161
+ end
162
+ end
163
+
164
+ describe "#flash_item" do
165
+ it "returns flash item" do
166
+ expect(subject.flash_item(:error, "some error")).to eq('<div class="flash" data-type="error">some error</div>')
167
+ end
168
+
169
+ it "supports flash item data as hash" do
170
+ expect(subject.flash_item(:error, "id" => "unique", "message" => "errrrrror")).to eq('<div class="flash" data-type="error" data-id="unique">errrrrror</div>')
171
+ end
172
+ end
173
+
174
+ describe "#header_extras" do
175
+ it "returns nil (method to override in later classes)" do
176
+ expect(subject.header_extras).to be nil
177
+ end
178
+ end
179
+
180
+ describe "#section_blocks" do
181
+ it "returns array of section header, body and footer blocks" do
182
+ allow(subject).to receive(:section_header).and_return("a")
183
+ allow(subject).to receive(:section_body).and_return("b")
184
+ allow(subject).to receive(:section_footer).and_return("c")
185
+
186
+ expect(subject.section_blocks).to eq(["a", "b", "c"])
187
+ end
188
+ end
189
+
190
+ describe "#section_header" do
191
+ it "returns header content with header extras" do
192
+ allow(subject).to receive(:section_header_text).and_return("sektion h")
193
+ allow(subject).to receive(:section_header_extras).and_return("extras")
194
+ expect(subject.section_header).to eq("<header><h1>sektion h</h1>extras</header>")
195
+ end
196
+ end
197
+
198
+ describe "#section_header_text" do
199
+ it "returns nil (method to override in later classes)" do
200
+ expect(subject.section_header_text).to be nil
201
+ end
202
+ end
203
+
204
+ describe "#section_header_extras" do
205
+ it "returns nil (method to override in later classes)" do
206
+ expect(subject.section_header_extras).to be nil
207
+ end
208
+ end
209
+
210
+ describe "#section_body" do
211
+ it "returns nil (method to override in later classes)" do
212
+ expect(subject.section_body).to be nil
213
+ end
214
+ end
215
+
216
+ describe "#section_footer" do
217
+ it "returns footer with footer attributes and content" do
218
+ allow(subject).to receive(:section_footer_class).and_return(["axx", "b"])
219
+ allow(subject).to receive(:footer_tools).and_return("footer content")
220
+ expect(subject.section_footer).to eq('<footer class="axx b">footer content</footer>')
221
+ end
222
+ end
223
+
224
+ describe "#section_footer_class" do
225
+ context "within dialog" do
226
+ it "returns nil" do
227
+ allow(subject).to receive(:dialog?).and_return(true)
228
+ expect(subject.section_footer_class).to be nil
229
+ end
230
+ end
231
+
232
+ context "when not within dialog" do
233
+ it "returns :main" do
234
+ allow(subject).to receive(:dialog?).and_return(false)
235
+ expect(subject.section_footer_class).to eq(:main)
236
+ end
237
+ end
238
+ end
239
+
240
+ describe "#footer_tools" do
241
+ it "returns footer tools" do
242
+ allow(subject).to receive(:footer_blocks).and_return([ActiveSupport::SafeBuffer.new("<a"), "b>"])
243
+ expect(subject.footer_tools).to eq('<div class="tools"><ab&gt;</div>')
244
+ end
245
+ end
246
+
247
+ describe "#footer_blocks" do
248
+ it "returns array of footer primary and secondary blocks" do
249
+ allow(subject).to receive(:footer_primary_block).and_return("a")
250
+ allow(subject).to receive(:footer_secondary_block).and_return("b")
251
+
252
+ expect(subject.footer_blocks).to eq(["a", "b"])
253
+ end
254
+ end
255
+
256
+ describe "#footer_primary_block" do
257
+ it "returns footer tools" do
258
+ allow(subject).to receive(:footer_primary_tools).and_return([ActiveSupport::SafeBuffer.new("<a"), "b>"])
259
+ expect(subject.footer_primary_block).to eq('<div class="primary"><ab&gt;</div>')
260
+ end
261
+ end
262
+
263
+ describe "#footer_secondary_block" do
264
+ it "returns footer tools" do
265
+ allow(subject).to receive(:footer_secondary_tools).and_return([ActiveSupport::SafeBuffer.new("<a"), "b>"])
266
+ expect(subject.footer_secondary_block).to eq('<div class="secondary"><ab&gt;</div>')
267
+ end
268
+ end
269
+
270
+ describe "#footer_primary_tools" do
271
+ it "returns nil (method to override in later classes)" do
272
+ expect(subject.footer_primary_tools).to be nil
273
+ end
274
+ end
275
+
276
+ describe "#footer_secondary_tools" do
277
+ it "returns nil (method to override in later classes)" do
278
+ expect(subject.footer_secondary_tools).to be nil
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,134 @@
1
+ require 'rails_helper'
2
+
3
+ describe Releaf::Builders, type: :class do
4
+ module Admin::Advanced
5
+ class FormBuilder
6
+ end
7
+ class AuthorsController
8
+ end
9
+ end
10
+
11
+ class Admin::Advanced::Builders < Releaf::Builders; end
12
+
13
+ describe ".builder_class" do
14
+ before do
15
+ allow(described_class).to receive(:inherited_builder_scopes).and_return(["Releaf::Permissions::Users"])
16
+ end
17
+
18
+ it "returns first existing builder class from given and inherited scopes" do
19
+ expect(described_class).to receive(:builder_class_at_scope).with("Admin::Advanced", :form)
20
+ .and_return(nil).ordered
21
+ expect(described_class).to receive(:builder_class_at_scope).with("Releaf::Permissions::Users", :form)
22
+ .and_return(Releaf::Permissions::Users::FormBuilder).ordered
23
+
24
+ expect(described_class.builder_class(["Admin::Advanced"], :form)).to eq(Releaf::Permissions::Users::FormBuilder)
25
+ end
26
+
27
+ context "when no builders exists for given scope and type" do
28
+ it "raises error" do
29
+ allow(described_class).to receive(:builder_class_at_scope).and_return(nil)
30
+ error_message = 'unexisting builder (type: form; scopes: Admin::Advanced)'
31
+ expect{ described_class.builder_class(["Admin::Advanced"], :form) }.to raise_error(ArgumentError, error_message)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe ".builder_class_at_scope" do
37
+ before do
38
+ allow(described_class).to receive(:constant_defined_at_scope?)
39
+ .with("Releaf::Builders", Object).and_return(true)
40
+ allow(described_class).to receive(:constant_defined_at_scope?)
41
+ .with("Releaf::Builders::EditBuilder", Releaf::Builders).and_return(true)
42
+ end
43
+
44
+ context "when scope and builder exists" do
45
+ it "returns builder class" do
46
+ expect(described_class.builder_class_at_scope("Releaf::Builders", :edit)).to eq(Releaf::Builders::EditBuilder)
47
+ end
48
+ end
49
+
50
+ context "when scope exists but builder does not" do
51
+ it "returns nil" do
52
+ allow(described_class).to receive(:constant_defined_at_scope?)
53
+ .with("Releaf::Builders", Object).and_return(false)
54
+ expect(described_class.builder_class_at_scope("Releaf::Builders", :edit)).to be nil
55
+ end
56
+ end
57
+
58
+ context "when scope does not exist" do
59
+ it "returns nil" do
60
+ allow(described_class).to receive(:constant_defined_at_scope?)
61
+ .with("Releaf::Builders::EditBuilder", Releaf::Builders).and_return(false)
62
+ expect(described_class.builder_class_at_scope("Releaf::Builders", :edit)).to be nil
63
+ end
64
+ end
65
+ end
66
+
67
+ describe ".constant_defined_at_scope?" do
68
+ before do
69
+ allow(Releaf).to receive(:const_get).and_call_original
70
+ end
71
+
72
+ it "checks constant existence within given scope" do
73
+ expect(Releaf).to receive(:const_get).with("Releaf::Builders::FormBuilder").and_call_original
74
+ described_class.constant_defined_at_scope?("Releaf::Builders::FormBuilder", Releaf)
75
+
76
+ expect(Releaf).to receive(:const_get).with("Releaf::Builders::AnotherFormBuilder").and_call_original
77
+ described_class.constant_defined_at_scope?("Releaf::Builders::AnotherFormBuilder", Releaf)
78
+
79
+ expect(Admin).to receive(:const_get).with("Admin:xx").and_call_original
80
+ described_class.constant_defined_at_scope?("Admin:xx", Admin)
81
+ end
82
+
83
+ context "when constant exists at given namespace" do
84
+ it "returns true" do
85
+ expect(described_class.constant_defined_at_scope?("Releaf::Builders::FormBuilder", Releaf)).to be true
86
+ end
87
+
88
+ it "compare constant with constant at given namespace and check whether it exists" do
89
+ allow(Admin).to receive(:const_get).with("Admin:xx").and_return(true)
90
+ expect(described_class.constant_defined_at_scope?("Admin:xx", Admin)).to be false
91
+ end
92
+ end
93
+
94
+ context "when NameError raised" do
95
+ context "when error message matches against constant name pattern" do
96
+ it "returns false" do
97
+ allow(described_class).to receive(:constant_name_error?)
98
+ .with("uninitialized constant Releaf::Builders::AnotherFormBuilder", "Releaf::Builders::AnotherFormBuilder")
99
+ .and_return(true)
100
+ expect(described_class.constant_defined_at_scope?("Releaf::Builders::AnotherFormBuilder", Releaf)).to be false
101
+ end
102
+ end
103
+
104
+ context "when error message does not match against constant name pattern" do
105
+ it "reraises it" do
106
+ allow(described_class).to receive(:constant_name_error?)
107
+ .with("uninitialized constant Releaf::Builders::AnotherFormBuilder", "Releaf::Builders::AnotherFormBuilder")
108
+ .and_return(false)
109
+
110
+ expect{ described_class.constant_defined_at_scope?("Releaf::Builders::AnotherFormBuilder", Releaf) }
111
+ .to raise_error(NameError, "uninitialized constant Releaf::Builders::AnotherFormBuilder")
112
+ end
113
+ end
114
+ end
115
+
116
+ context "when any other error raised" do
117
+ it "does not rescue it" do
118
+ allow(Releaf).to receive(:const_get).with("Releaf::Builders::FormBuilder")
119
+ .and_raise(ArgumentError, "xxx")
120
+ expect(described_class).to_not receive(:constant_name_error?)
121
+
122
+ expect{ described_class.constant_defined_at_scope?("Releaf::Builders::FormBuilder", Releaf) }
123
+ .to raise_error(ArgumentError, "xxx")
124
+ end
125
+ end
126
+ end
127
+
128
+ describe ".inherited_builder_scopes" do
129
+ it "returns inherited classes except Object and BasicObject" do
130
+ expect(described_class.inherited_builder_scopes).to eq(["Releaf::Builders"])
131
+ expect(Admin::Advanced::Builders.inherited_builder_scopes).to eq(["Admin::Advanced::Builders", "Releaf::Builders"])
132
+ end
133
+ end
134
+ end