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,21 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::ResourceDialog, type: :class do
4
+ class DialogTestHelper < ActionView::Base
5
+ end
6
+
7
+ class UnitTestDialogBuilder
8
+ include Releaf::Builders::Base
9
+ include Releaf::Builders::Template
10
+ include Releaf::Builders::ResourceDialog
11
+ end
12
+
13
+ subject { UnitTestDialogBuilder.new(template) }
14
+ let(:template){ DialogTestHelper.new }
15
+
16
+ describe "#dialog?" do
17
+ it "always returns true" do
18
+ expect(subject.dialog?).to be true
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,158 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::ResourceView, type: :class do
4
+ class ResourceViewIncluder
5
+ include Releaf::Builders::ResourceView
6
+ end
7
+
8
+ class ResourceViewTestHelper < ActionView::Base
9
+ include Releaf::ApplicationHelper
10
+ end
11
+
12
+ let(:described_class){ ResourceViewIncluder }
13
+ let(:template){ ResourceViewTestHelper.new }
14
+ let(:subject){ described_class.new(template) }
15
+ let(:controller){ Releaf::BaseController.new }
16
+ let(:resource){ Book.new }
17
+
18
+ before do
19
+ allow(template).to receive(:controller).and_return(controller)
20
+ allow(subject).to receive(:resource).and_return(resource)
21
+ allow(subject).to receive(:index_url).and_return("_index_url_")
22
+ end
23
+
24
+ it "includes Releaf::Builders::View" do
25
+ expect(described_class.ancestors).to include(Releaf::Builders::View)
26
+ end
27
+
28
+ it "includes Releaf::Builders::Resource" do
29
+ expect(described_class.ancestors).to include(Releaf::Builders::Resource)
30
+ end
31
+
32
+ it "includes Releaf::Builders::Toolbox" do
33
+ expect(described_class.ancestors).to include(Releaf::Builders::Toolbox)
34
+ end
35
+
36
+ describe "#section" do
37
+ before do
38
+ allow(subject).to receive(:section_attributes).and_return(a: "b")
39
+ allow(subject).to receive(:section_blocks).and_return(["_section_","_blocks_"])
40
+ end
41
+
42
+ it "returns section with index url preserver and section blocks" do
43
+ expect(subject.section).to eq('<section a="b">_section__blocks_</section>')
44
+ end
45
+ end
46
+
47
+ describe "#section_header_text" do
48
+ before do
49
+ allow(subject).to receive(:t).with("Create new resource").and_return("newww")
50
+ allow(subject).to receive(:resource_to_text).with(resource).and_return("existng")
51
+ end
52
+
53
+ context "when resource is new object" do
54
+ it "returns resource to text cast result" do
55
+ expect(subject.section_header_text).to eq("newww")
56
+ end
57
+ end
58
+
59
+ context "when resource is persisted object" do
60
+ it "returns resource to text cast result" do
61
+ allow(resource).to receive(:new_record?).and_return(false)
62
+ expect(subject.section_header_text).to eq("existng")
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "#section_header_extras" do
68
+ before do
69
+ allow(subject).to receive(:toolbox).with(resource, index_url: "_index_url_").and_return("_tlbx_")
70
+ allow(subject).to receive(:feature_available?).with(:toolbox).and_return(true)
71
+ end
72
+
73
+ it "returns header extras with toolbox button" do
74
+ expect(subject.section_header_extras).to eq('<div class="extras toolbox-wrap">_tlbx_</div>')
75
+ end
76
+
77
+ context "when toolbox feature is not available" do
78
+ it "returns nil" do
79
+ allow(subject).to receive(:feature_available?).with(:toolbox).and_return(false)
80
+ expect(subject.section_header_extras).to be nil
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#section_body" do
86
+ it "returns section body block with applied section body attributes" do
87
+ allow(subject).to receive(:section_body_blocks).and_return(["a", "b"])
88
+ allow(subject).to receive(:section_body_attributes).and_return(class: "x")
89
+ expect(subject.section_body).to eq('<div class="x">ab</div>')
90
+ end
91
+ end
92
+
93
+ describe "#section_body_attributes" do
94
+ it "returns section hash with body class" do
95
+ expect(subject.section_body_attributes).to eq(class: ["body"])
96
+ end
97
+ end
98
+
99
+ describe "#section_body_blocks" do
100
+ it "returns empty array" do
101
+ expect(subject.section_body_blocks).to eq([])
102
+ end
103
+ end
104
+
105
+ describe "#footer_secondary_tools" do
106
+ before do
107
+ allow(subject).to receive(:back_to_list_button).and_return("_btn_")
108
+ allow(subject).to receive(:back_to_list?).and_return(true)
109
+ end
110
+
111
+ it "returns array with back to list button" do
112
+ expect(subject.footer_secondary_tools).to eq(["_btn_"])
113
+ end
114
+
115
+ context "when toolbox feature is not available" do
116
+ it "returns empty array" do
117
+ allow(subject).to receive(:back_to_list?).and_return(false)
118
+ expect(subject.footer_secondary_tools).to eq([])
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "#back_to_list?" do
124
+ before do
125
+ allow(subject).to receive(:params).and_return(index_url: "xxx")
126
+ allow(subject).to receive(:feature_available?).with(:index).and_return(true)
127
+ end
128
+
129
+ context "when index feature is available and index_url is present within params" do
130
+ it "returns true" do
131
+ expect(subject.back_to_list?).to be true
132
+ end
133
+ end
134
+
135
+ context "when index_url is not present within params" do
136
+ it "returns false" do
137
+ allow(subject).to receive(:params).and_return(search: "xxx")
138
+ expect(subject.back_to_list?).to be false
139
+ end
140
+ end
141
+
142
+ context "when index feature is not available" do
143
+ it "returns false" do
144
+ allow(subject).to receive(:feature_available?).with(:index).and_return(false)
145
+ expect(subject.back_to_list?).to be false
146
+ end
147
+ end
148
+ end
149
+
150
+ describe "#back_to_list_button" do
151
+ it "returns `back to list` button" do
152
+ allow(subject).to receive(:button)
153
+ .with("to_list", "caret-left", {class: "secondary", href: "_index_url_"}).and_return("_btn_")
154
+ allow(subject).to receive(:t).with("Back to list").and_return("to_list")
155
+ expect(subject.back_to_list_button).to eq("_btn_")
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,7 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::ShowBuilder, type: :class do
4
+ it "includes `Releaf::Builders::ResourceView`" do
5
+ expect(described_class.ancestors).to include(Releaf::Builders::ResourceView)
6
+ end
7
+ end
@@ -0,0 +1,638 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Builders::TableBuilder, type: :class do
4
+ class TableBuilderTestHelper < ActionView::Base
5
+ include Releaf::ApplicationHelper
6
+ end
7
+
8
+ class DummyTableBuilderInheriter < Releaf::Builders::TableBuilder
9
+ def some_cell_method(resource, column); end
10
+ def custom_format(resource, column); end
11
+ def format_big_boolean_content(resource, column); end
12
+ def title_cell; end
13
+ def custom_title(resource); end
14
+ end
15
+
16
+ let(:template){ TableBuilderTestHelper.new }
17
+ let(:resource_class){ Book }
18
+ let(:resource){ resource_class.new(id: 77, title: "Life of Brian") }
19
+ let(:collection){ Book.all }
20
+ let(:options){ {toolbox: false} }
21
+ let(:subject){ described_class.new(collection, resource_class, template, options) }
22
+ let(:inheriter_subject){ DummyTableBuilderInheriter.new(collection, resource_class, template, options) }
23
+
24
+ it "includes Releaf::Builders::Base" do
25
+ expect(described_class.ancestors).to include(Releaf::Builders::Base)
26
+ end
27
+
28
+ it "includes Releaf::Builders::Toolbox" do
29
+ expect(described_class.ancestors).to include(Releaf::Builders::Toolbox)
30
+ end
31
+
32
+ it "includes Releaf::Builders::Orderer" do
33
+ expect(described_class.ancestors).to include(Releaf::Builders::Orderer)
34
+ end
35
+
36
+ describe "#initialize" do
37
+ it "assigns collection" do
38
+ expect(subject.collection.to_sql).to eq(collection.to_sql)
39
+ end
40
+
41
+ it "assigns resource_class" do
42
+ expect(subject.resource_class).to eq(resource_class)
43
+ end
44
+
45
+ it "assigns template" do
46
+ expect(subject.template).to eq(template)
47
+ end
48
+
49
+ it "assigns options" do
50
+ expect(subject.options).to eq(options)
51
+ end
52
+ end
53
+
54
+ describe "#columns" do
55
+ it "returns columns schema" do
56
+ allow(subject).to receive(:columns_schema).and_return("schema")
57
+ expect(subject.columns).to eq("schema")
58
+ end
59
+
60
+ it "caches columns schema data" do
61
+ expect(subject).to receive(:columns_schema).and_return("schema").once
62
+ subject.columns
63
+ subject.columns
64
+ end
65
+ end
66
+
67
+ describe "#column_names" do
68
+ it "returns column names for resource_class" do
69
+ allow(Releaf::Core::ResourceTableFields).to receive(:new).with(subject.resource_class).and_call_original
70
+ allow_any_instance_of(Releaf::Core::ResourceTableFields).to receive(:values)
71
+ .with(include_associations: false).and_return(["a", "b"])
72
+ expect(subject.column_names).to eq(["a", "b"])
73
+ end
74
+ end
75
+
76
+ describe "#columns_schema" do
77
+ before do
78
+ allow(subject).to receive(:column_names).and_return([:price, :title, :author_id])
79
+ allow(subject).to receive(:cell_content_method).with(:price).and_return(:title_content)
80
+ allow(subject).to receive(:cell_content_method).with(:title).and_return(:title_content)
81
+ allow(subject).to receive(:cell_content_method).with(:author_id).and_return(nil)
82
+ allow(subject).to receive(:cell_format_method).with(:author_id).and_return(:some_text_format)
83
+ end
84
+
85
+ it "returns hash with columns and corresponding method" do
86
+ allow(subject).to receive(:cell_method).with(:price).and_return("price_cell")
87
+ allow(subject).to receive(:cell_method).with(:title).and_return(nil)
88
+ allow(subject).to receive(:cell_method).with(:author_id).and_return(nil)
89
+ columns = {
90
+ price: {cell_method: "price_cell"},
91
+ title: {content_method: :title_content},
92
+ author_id: {format_method: :some_text_format}
93
+ }
94
+ expect(subject.columns_schema).to eq(columns)
95
+ end
96
+
97
+ it "preserves order as in #column_names" do
98
+ expect(subject.columns_schema.keys).to eq([:price, :title, :author_id])
99
+ end
100
+
101
+ context "when options[:toolbox] value is 'true'" do
102
+ let(:options){ {toolbox: true} }
103
+ it "adds toolbox as last column" do
104
+ expect(subject.columns_schema.keys.last).to eq(:toolbox)
105
+ end
106
+
107
+ it "uses #toolbox_cell for toolbox cell rendering" do
108
+ expect(subject.columns_schema[:toolbox]).to eq(cell_method: "toolbox_cell")
109
+ end
110
+ end
111
+ end
112
+
113
+ describe "#column_klass" do
114
+ context "when association column given" do
115
+ it "returns corresponding association class" do
116
+ resource.author = Author.new(name: "Brian")
117
+ expect(subject.column_klass(resource_class, "author.name")).to eq(Author)
118
+ end
119
+ end
120
+
121
+ context "when base resource column given" do
122
+ it "returns give resource class" do
123
+ expect(subject.column_klass(resource_class, "year")).to eq(resource_class)
124
+ end
125
+ end
126
+ end
127
+
128
+ describe "#column_value" do
129
+ it "returns value for column of given resource" do
130
+ expect(subject.column_value(resource, "title")).to eq("Life of Brian")
131
+ end
132
+
133
+ it "supports association columns" do
134
+ resource.author = Author.new(name: "Brian")
135
+ expect(subject.column_value(resource, "author.name")).to eq("Brian")
136
+ end
137
+
138
+ it "supports empty association columns" do
139
+ resource.author = nil
140
+ expect(subject.column_value(resource, "author.name")).to be nil
141
+ end
142
+ end
143
+
144
+ describe "#output" do
145
+ before do
146
+ allow(subject).to receive(:empty_body).and_return("empty")
147
+ end
148
+
149
+ it "returns table with #empty_body content" do
150
+ allow(subject).to receive(:table_attributes).and_return(class: "a", data: {some: "b"})
151
+ content = '<table class="a" data-some="b">empty</table>'
152
+ expect(subject.output).to eq(content)
153
+ end
154
+
155
+ context "when collection is not empty" do
156
+ it "returns table with #header and #body" do
157
+ create(:book)
158
+ content = '<table class="table books">header_contentbody_content</table>'
159
+ allow(subject).to receive(:head).and_return("header_content")
160
+ allow(subject).to receive(:body).and_return("body_content")
161
+
162
+ expect(subject.output).to eq(content)
163
+ end
164
+ end
165
+
166
+ context "when collection is empty" do
167
+ it "returns table with #empty_body content" do
168
+ content = '<table class="table books">empty</table>'
169
+ expect(subject.output).to eq(content)
170
+ end
171
+ end
172
+ end
173
+
174
+ describe "#table_attributes" do
175
+ it "returns hash with table and pluralized, dasherized resource classes" do
176
+ expect(subject.table_attributes).to eq(class: ["table", "books"])
177
+ end
178
+ end
179
+
180
+ describe "#head" do
181
+ it "returns header row with #head_cell generated cells for each columns" do
182
+ allow(subject).to receive(:column_names).and_return([:price, :title, :author_id])
183
+ allow(subject).to receive(:head_cell).with(:price).and_return("_price_cell_")
184
+ allow(subject).to receive(:head_cell).with(:title).and_return("_title_cell_")
185
+ allow(subject).to receive(:head_cell).with(:author_id).and_return("_author_id_cell_")
186
+
187
+ content = '<thead><tr>_price_cell__title_cell__author_id_cell_</tr></thead>'
188
+ expect(subject.head).to eq(content)
189
+ end
190
+ end
191
+
192
+ describe "#head_cell" do
193
+ it "returns 'th' element with content from #head_cell_column" do
194
+ allow(subject).to receive(:head_cell_content).with(:title).and_return("_title_content_")
195
+ content = '<th>_title_content_</th>'
196
+ expect(subject.head_cell(:title)).to eq(content)
197
+ end
198
+ end
199
+
200
+
201
+ describe "#head_cell_content" do
202
+ it "returns translated column scoped to resource class attributes" do
203
+ allow(resource_class).to receive(:human_attribute_name).with("some_long_name", create_default: false).and_return("Taittls")
204
+ expect(subject.head_cell_content("some_long_name")).to eq('Taittls')
205
+ end
206
+
207
+ it "casts given column to string" do
208
+ allow(resource_class).to receive(:human_attribute_name).with("title", create_default: false).and_return("Taittls")
209
+ expect(subject.head_cell_content(:title)).to eq('Taittls')
210
+ end
211
+
212
+ context "when column value is 'toolbox'" do
213
+ it "returns nil" do
214
+ expect(subject.head_cell_content(:toolbox)).to eq(nil)
215
+ end
216
+ end
217
+ end
218
+
219
+ describe "#empty_body" do
220
+ it "returns empty table body content" do
221
+ allow(subject).to receive(:t).with("Nothing found").and_return("ntnn")
222
+ content = '<tr><th><div class="nothing-found">ntnn</div></th></tr>'
223
+ expect(subject.empty_body).to eq(content)
224
+ end
225
+ end
226
+
227
+ describe "#body" do
228
+ it "returns table body with rows for each collection items generated with #row method" do
229
+ subject.collection = ["a", "b"]
230
+ allow(subject).to receive(:row).with("a").and_return("_a_row_")
231
+ allow(subject).to receive(:row).with("b").and_return("_b_row_")
232
+
233
+ content = '<tbody class="tbody">_a_row__b_row_</tbody>'
234
+ expect(subject.body).to eq(content)
235
+ end
236
+ end
237
+
238
+ describe "#row_url" do
239
+ let(:controller){ Releaf::BaseController.new }
240
+
241
+ before do
242
+ allow(subject).to receive(:controller).and_return(controller)
243
+ allow(controller).to receive(:index_url).and_return("_index_url_")
244
+ end
245
+
246
+ it "returns edit url for given resource" do
247
+ allow(subject).to receive(:row_url_action).with(resource).and_return(:show)
248
+ allow(template).to receive(:url_for).with(action: :show, id: 77, index_url: "_index_url_").and_return('_url_')
249
+ expect(subject.row_url(resource)).to eq('_url_')
250
+ end
251
+
252
+ context "when resource do not have row url action" do
253
+ it "returns nil" do
254
+ allow(subject).to receive(:row_url_action).with(resource).and_return(nil)
255
+ expect(subject.row_url(resource)).to be nil
256
+ end
257
+ end
258
+ end
259
+
260
+ describe "#row_url_action" do
261
+ let(:controller){ Releaf::BaseController.new }
262
+
263
+ before do
264
+ allow(subject).to receive(:controller).and_return(controller)
265
+ allow(controller).to receive(:feature_available?).with(:show).and_return(true)
266
+ allow(controller).to receive(:feature_available?).with(:edit).and_return(true)
267
+ end
268
+
269
+ context "when show and edit features is available" do
270
+ it "returns :show" do
271
+ expect(subject.row_url_action(resource)).to eq(:show)
272
+ end
273
+ end
274
+
275
+ context "when show feature is not available and edit feature is available" do
276
+ it "returns :edit" do
277
+ allow(controller).to receive(:feature_available?).with(:show).and_return(false)
278
+ expect(subject.row_url_action(resource)).to eq(:edit)
279
+ end
280
+ end
281
+
282
+ context "when show and edit features is not available" do
283
+ it "returns nil" do
284
+ allow(controller).to receive(:feature_available?).with(:show).and_return(false)
285
+ allow(controller).to receive(:feature_available?).with(:edit).and_return(false)
286
+ expect(subject.row_url_action(resource)).to be nil
287
+ end
288
+ end
289
+ end
290
+
291
+ describe "#row_attributes" do
292
+ it "returns row attributes with html class and resource id as data value" do
293
+ resource = resource_class.new(id: 77)
294
+ expect(subject.row_attributes(resource)).to eq(class: "row", data: {id: 77})
295
+ end
296
+ end
297
+
298
+ describe "#row" do
299
+ it "adds attributes returned from #row_attributes to row" do
300
+ resource = resource_class.new
301
+ allow(subject).to receive(:column_names).and_return([])
302
+ allow(subject).to receive(:row_attributes).with(resource).and_return(class: "color", data: {color: "red"})
303
+ allow(subject).to receive(:row_url)
304
+
305
+ content = '<tr class="color" data-color="red"></tr>'
306
+ expect(subject.row(resource)).to eq(content)
307
+ end
308
+
309
+ it "calls #row_url only once" do
310
+ resource = resource_class.new
311
+ allow(subject).to receive(:column_names).and_return([:title, :author_id])
312
+ expect(subject).to receive(:row_url).with(resource).once
313
+ subject.row(resource)
314
+ end
315
+
316
+ it "output each cell contents by using either custom or default cell method" do
317
+ columns = {
318
+ title: {cell_method: "some_cell_method"},
319
+ color: {},
320
+ }
321
+ resource = resource_class.new(id: 89)
322
+
323
+ allow(inheriter_subject).to receive(:columns).and_return(columns)
324
+ allow(inheriter_subject).to receive(:row_url).with(resource).and_return("url_value")
325
+
326
+ allow(inheriter_subject).to receive(:some_cell_method)
327
+ .with(resource, cell_method: "some_cell_method", url: "url_value").and_return("_title_cell_value")
328
+ allow(inheriter_subject).to receive(:cell)
329
+ .with(resource, :color, url: "url_value").and_return("_color_cell_value")
330
+
331
+ content = '<tr class="row" data-id="89">_title_cell_value_color_cell_value</tr>'
332
+ expect(inheriter_subject.row(resource)).to eq(content)
333
+ end
334
+ end
335
+
336
+ describe "#cell_content" do
337
+ it "returns format method output with resource and column as arguments" do
338
+ options = {format_method: "custom_format"}
339
+ allow(inheriter_subject).to receive(:custom_format).with("a", :title).and_return('_custom " format_')
340
+
341
+ content = '_custom " format_'
342
+ expect(inheriter_subject.cell_content("a", :title, options)).to eq(content)
343
+ end
344
+
345
+ context "when given options has :content_method" do
346
+ it "returns content method output with resource as argument" do
347
+ options = {content_method: "custom_title", format_method: "custom_format"}
348
+ allow(inheriter_subject).to receive(:custom_title).with("a").and_return('_custom " _value_')
349
+
350
+ content = '_custom " _value_'
351
+ expect(inheriter_subject.cell_content("a", :title, options)).to eq(content)
352
+ end
353
+ end
354
+ end
355
+
356
+ describe "#format_text_content" do
357
+ it "returns truncated and escape column value" do
358
+ allow(subject).to receive(:column_value).with(resource, :title)
359
+ .and_return('"Pra<tag>nt commodo cursus magn')
360
+ expect(subject.format_text_content(resource, :title))
361
+ .to eq('&quot;Pra&lt;tag&gt;nt commodo cursus magn')
362
+ end
363
+
364
+ it "casts value to string before truncation" do
365
+ allow(subject).to receive(:column_value).with(resource, :title)
366
+ .and_return(nil)
367
+ expect(subject.format_text_content(resource, :title)).to eq("")
368
+ end
369
+ end
370
+
371
+ describe "#format_string_content" do
372
+ context "when resource column value respond to #to_text method" do
373
+ it "returns value #to_text" do
374
+ fake_obj = double
375
+ allow(fake_obj).to receive(:to_text).and_return("nineninine")
376
+
377
+ allow(subject).to receive(:column_value).with(resource, :id)
378
+ .and_return(fake_obj)
379
+
380
+ expect(subject.format_string_content(resource, :id)).to eq("nineninine")
381
+ end
382
+ end
383
+
384
+ context "when resource column value do not respond to #to_text method" do
385
+ it "returns value casted to string" do
386
+ allow(subject).to receive(:column_value).with(resource, :id)
387
+ .and_return(99)
388
+
389
+ expect(subject.format_string_content(resource, :id)).to eq("99")
390
+ end
391
+ end
392
+ end
393
+
394
+ describe "#format_boolean_content" do
395
+ context "when resource column value is 'true'" do
396
+ it "returns localized 'yes' value" do
397
+ allow(subject).to receive(:t).with("Yes").and_return("Jā")
398
+ allow(subject).to receive(:column_value).with(resource, :active)
399
+ .and_return(true)
400
+
401
+ expect(subject.format_boolean_content(resource, :active)).to eq("Jā")
402
+ end
403
+ end
404
+
405
+ context "when resource column value is other than 'true'" do
406
+ it "returns localized 'no' value" do
407
+ allow(subject).to receive(:t).with("No").and_return("Nē")
408
+ allow(subject).to receive(:column_value).with(resource, :active)
409
+ .and_return(false)
410
+ expect(subject.format_boolean_content(resource, :active)).to eq("Nē")
411
+
412
+ allow(subject).to receive(:column_value).with(resource, :active)
413
+ .and_return(nil)
414
+ expect(subject.format_boolean_content(resource, :active)).to eq("Nē")
415
+ end
416
+ end
417
+ end
418
+
419
+ describe "#format_date_content" do
420
+ it "returns localized date value" do
421
+ value = Date.parse("2012.12.29")
422
+ allow(subject).to receive(:column_value).with(resource, :birth_date)
423
+ .and_return(value)
424
+
425
+ expect(I18n).to receive(:l).with(value, format: :default, default: "%Y-%m-%d")
426
+ .and_call_original
427
+
428
+ expect(subject.format_date_content(resource, :birth_date)).to eq("2012-12-29")
429
+ end
430
+ end
431
+
432
+ describe "#format_datetime_content" do
433
+ it "returns localized datetime value" do
434
+ value = DateTime.parse("2012.12.29 17:12:07")
435
+ allow(subject).to receive(:column_value).with(resource, :created_at)
436
+ .and_return(value)
437
+
438
+ expect(I18n).to receive(:l).with(value, format: :default, default: "%Y-%m-%d %H:%M:%S")
439
+ .and_call_original
440
+
441
+ expect(subject.format_datetime_content(resource, :created_at)).to eq("2012-12-29 17:12:07")
442
+ end
443
+ end
444
+
445
+ describe "#association_name" do
446
+ it "normalizes given column name by removing '_id' postfix and returning new value as symbol" do
447
+ expect(subject.association_name(:author_id)).to eq(:author)
448
+ end
449
+ end
450
+
451
+ describe "#format_association_content" do
452
+ it "pass resource and association name to #format_string_content" do
453
+ resource = resource_class.new
454
+ allow(subject).to receive(:association_name).with(:author_id).and_return(:another_author)
455
+ allow(subject).to receive(:format_string_content).with(resource, :another_author).and_return("x")
456
+
457
+ expect(subject.format_association_content(resource, :author_id)).to eq("x")
458
+ end
459
+ end
460
+
461
+ describe "#cell_content_method" do
462
+ context "when custom cell content method exists" do
463
+ it "returns custom cell content method name" do
464
+ expect(subject.cell_content_method(:format_string)).to eq("format_string_content")
465
+ end
466
+ end
467
+
468
+ context "when custom cell content does not method exist" do
469
+ it "returns nil" do
470
+ expect(subject.cell_content_method(:title)).to be nil
471
+ end
472
+ end
473
+ end
474
+
475
+ describe "#cell_method" do
476
+ context "when custom cell method exists" do
477
+ it "returns custom cell method name" do
478
+ expect(inheriter_subject.cell_method(:title)).to eq("title_cell")
479
+ end
480
+ end
481
+
482
+ context "when custom cell does not method exist" do
483
+ it "returns nil" do
484
+ expect(subject.cell_method(:title)).to be nil
485
+ end
486
+ end
487
+ end
488
+
489
+ describe "#toolbox_cell" do
490
+ let(:controller){ double(ActionController::Base) }
491
+ before do
492
+ allow(subject).to receive(:controller).and_return(controller)
493
+ allow(controller).to receive(:index_url).and_return("_index_url_")
494
+ end
495
+
496
+ it "returns cell with toolbox" do
497
+ allow(subject).to receive(:toolbox)
498
+ .with(resource, index_url: "_index_url_").and_return("_toolbox_")
499
+
500
+ content = '<td class="only-icon toolbox-cell">_toolbox_</td>'
501
+ expect(subject.toolbox_cell(resource, {})).to eq(content)
502
+ end
503
+
504
+ it "merges given toolbox options and passes it to toolbox heplper" do
505
+ allow(subject.controller).to receive(:index_url).and_return("_index_url_")
506
+ expect(subject).to receive(:toolbox)
507
+ .with(resource, index_url: "_index_url_", some_url: "xx").and_return("_toolbox_")
508
+ subject.toolbox_cell(resource, {toolbox: {some_url: "xx"}})
509
+
510
+ expect(subject).to receive(:toolbox)
511
+ .with(resource, index_url: "xx").and_return("_toolbox_")
512
+ subject.toolbox_cell(resource, {toolbox: {index_url: "xx"}})
513
+ end
514
+ end
515
+
516
+ describe "#format_image_content" do
517
+ context "when resource value is not blank" do
518
+ let(:resource){ create(:book, cover_image: File.expand_path('../fixtures/cs.png', __dir__)) }
519
+
520
+ it "returns thumnail image" do
521
+ pattern = /\<img alt=\"\" src=\"\/media\/.*\" \/\>/
522
+ expect(subject.format_image_content(resource, :cover_image_uid)).to match(pattern)
523
+ end
524
+
525
+ it "uses 16px height for thumbnail" do
526
+ expect(resource.cover_image).to receive(:thumb).with('x16').and_call_original
527
+ subject.format_image_content(resource, :cover_image_uid)
528
+ end
529
+ end
530
+
531
+ context "when resource value is blank" do
532
+ it "returns nil" do
533
+ expect(subject.format_image_content(resource, :cover_image_uid)).to be nil
534
+ end
535
+ end
536
+ end
537
+
538
+ describe "#column_type" do
539
+ it "returns database column type for given column" do
540
+ expect(subject.column_type(resource_class, :active)).to eq(:boolean)
541
+ expect(subject.column_type(resource_class, :created_at)).to eq(:datetime)
542
+ end
543
+
544
+ context "when given column does not exists within database column definitions" do
545
+ it "returns :string as default value" do
546
+ expect(subject.column_type(resource_class, :random_title)).to eq(:string)
547
+ end
548
+ end
549
+ end
550
+
551
+ describe "#column_type_format_method" do
552
+ it "uses column klass and column name for type calculation" do
553
+ allow(subject).to receive(:column_klass).with(resource_class, "some.column").and_return(Chapter)
554
+ expect(subject).to receive(:column_type).with(Chapter, "some.column")
555
+ subject.column_type_format_method("some.column")
556
+ end
557
+
558
+ context "when format method for returned column type exists" do
559
+ it "returns column type format method" do
560
+ allow(subject).to receive(:column_type).and_return(:date)
561
+ expect(subject.column_type_format_method(:title)).to eq(:format_date_content)
562
+ end
563
+ end
564
+
565
+ context "when format method for returned column type does not exist" do
566
+ it "returns :format_string_content" do
567
+ allow(subject).to receive(:column_type).and_return(:big_boolean)
568
+ expect(subject.column_type_format_method(:title)).to eq(:format_string_content)
569
+ end
570
+ end
571
+ end
572
+
573
+ describe "#cell_format_method" do
574
+ before do
575
+ allow(subject).to receive(:association_column?).with(:title).and_return(false)
576
+ allow(subject).to receive(:image_column?).with(:title).and_return(false)
577
+ allow(subject).to receive(:column_type_format_method).with(:title).and_return(:format_crazy_shit)
578
+ end
579
+
580
+ it "returns #column_type_format_method for given column" do
581
+ expect(subject.cell_format_method(:title)).to eq(:format_crazy_shit)
582
+ end
583
+
584
+ context "when #association_column? returns true for given column" do
585
+ it "returns :format_association_content" do
586
+ allow(subject).to receive(:association_column?).with(:title).and_return(true)
587
+ expect(subject.cell_format_method(:title)).to eq(:format_association_content)
588
+ end
589
+ end
590
+
591
+ context "when #association_column? returns true for given column" do
592
+ it "returns :format_association_content" do
593
+ allow(subject).to receive(:image_column?).with(:title).and_return(true)
594
+ expect(subject.cell_format_method(:title)).to eq(:format_image_content)
595
+ end
596
+ end
597
+ end
598
+
599
+ describe "#association_column?" do
600
+ context "when given column is association" do
601
+ it "returns true" do
602
+ expect(subject.association_column?(:author_id)).to be true
603
+ end
604
+ end
605
+
606
+ context "when given column is not association" do
607
+ it "returns false" do
608
+ expect(subject.association_column?(:title)).to be false
609
+ end
610
+ end
611
+ end
612
+
613
+ describe "#cell" do
614
+ context "when cell options :url value is blank" do
615
+ it "returns cell with #cell_content output" do
616
+ options = {a: "x"}
617
+ allow(subject).to receive(:cell_content)
618
+ .with(resource, :title, options).and_return("_cell_content_")
619
+ content = '<td>_cell_content_</td>'
620
+
621
+ expect(subject.cell(resource, :title, options)).to eq(content)
622
+
623
+ options[:url] = nil
624
+ expect(subject.cell(resource, :title, options)).to eq(content)
625
+ end
626
+ end
627
+
628
+ context "when cell options :url value is not blank" do
629
+ it "returns cell with #cell_content output wrapped in 'a' element" do
630
+ allow(subject).to receive(:cell_content)
631
+ .with(resource, :title, {a: "x", url: "y"}).and_return("_cell_content_")
632
+
633
+ content = '<td><a href="y">_cell_content_</a></td>'
634
+ expect(subject.cell(resource, :title, {a: "x", url: "y"})).to eq(content)
635
+ end
636
+ end
637
+ end
638
+ end