releaf-core 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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,18 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::ResourceTableFields do
4
+ subject{ described_class.new(Book) }
5
+
6
+ describe "#excluded_attributes" do
7
+ it "returns attributes to exclude from table alongside parent method list" do
8
+ allow(subject).to receive(:table_excluded_attributes).and_return(%w(xxx yyy))
9
+ expect(subject.excluded_attributes).to include("id", "created_at", "xxx", "yyy")
10
+ end
11
+ end
12
+
13
+ describe "#table_excluded_attributes" do
14
+ it "returns array with attributes matching *_html pattern" do
15
+ expect(subject.table_excluded_attributes).to eq(%w(summary_html))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,87 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::ResourceUtilities do
4
+ let(:resource){ Releaf::Permissions::Role.new }
5
+ let(:users_association){ resource.class.reflect_on_association(:users) }
6
+ let(:permissions_association){ resource.class.reflect_on_association(:permissions) }
7
+
8
+ describe ".restricted_associations" do
9
+ it "returns hash with restricted association objects and controller" do
10
+ allow(described_class).to receive(:restricted_associations).with(resource).and_return([permissions_association, users_association])
11
+ allow(described_class).to receive(:association_controller).with(users_association).and_return("aa")
12
+ allow(described_class).to receive(:association_controller).with(permissions_association).and_return("bb")
13
+ resource.users.build
14
+ resource.permissions.build
15
+
16
+ expect(described_class.restricted_relations(resource)).to eq(
17
+ users: {objects: resource.users, controller: "aa"},
18
+ permissions: {objects: resource.permissions, controller: "bb"},
19
+ )
20
+ end
21
+ end
22
+
23
+ describe ".association_controller" do
24
+ it "returns guessed controller from given association name" do
25
+ expect(described_class.association_controller(users_association)).to eq("users")
26
+ end
27
+
28
+ context "when no controller guessed" do
29
+ it "returns nil" do
30
+ expect(described_class.association_controller(permissions_association)).to be nil
31
+ end
32
+ end
33
+ end
34
+
35
+ describe ".restricted_associations" do
36
+ it "returns array with restricted associations" do
37
+ allow(described_class).to receive(:restricted_association?).with(resource, users_association).and_return(false)
38
+ allow(described_class).to receive(:restricted_association?).with(resource, permissions_association).and_return(true)
39
+ expect(described_class.restricted_associations(resource)).to eq([permissions_association])
40
+ end
41
+ end
42
+
43
+ describe ".restricted_association?" do
44
+ context "when associations with dependent option `restrict_with_exception` given" do
45
+ let(:association){ resource.class.reflect_on_association(:users) }
46
+
47
+ context "when association object(-s) exists" do
48
+ it "returns true" do
49
+ resource.users.build
50
+ users = resource.users
51
+ allow(resource).to receive(:users).and_return(users)
52
+ allow(users).to receive(:exists?).and_return(true)
53
+ expect(described_class.restricted_association?(resource, association)).to be true
54
+ end
55
+ end
56
+
57
+ context "when association object(-s) does not exist" do
58
+ it "returns false" do
59
+ expect(described_class.restricted_association?(resource, association)).to be false
60
+ end
61
+ end
62
+ end
63
+
64
+ context "when associations with dependent option other than `restrict_with_exception` given" do
65
+ it "returns false" do
66
+ association = resource.class.reflect_on_association(:permissions)
67
+ expect(described_class.restricted_association?(resource, association)).to be false
68
+ end
69
+ end
70
+ end
71
+
72
+ describe ".destroyable?" do
73
+ context "when no restricted association" do
74
+ it "returns true" do
75
+ allow(described_class).to receive(:restricted_associations).with(resource).and_return([])
76
+ expect(described_class.destroyable?(resource)).to be true
77
+ end
78
+ end
79
+
80
+ context "when restricted association exist" do
81
+ it "returns false" do
82
+ allow(described_class).to receive(:restricted_associations).with(resource).and_return([:a])
83
+ expect(described_class.destroyable?(resource)).to be false
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,12 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Responders::AccessDeniedResponder, type: :controller do
4
+ controller{}
5
+ subject{ described_class.new(controller, []) }
6
+
7
+ describe "#status_code" do
8
+ it "returns 404" do
9
+ expect(subject.status_code).to eq(403)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,102 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Responders::AfterSaveResponder, type: :controller do
4
+ let(:controller){ Releaf::BaseController.new }
5
+ let(:resource){ Book.new}
6
+ subject{ described_class.new(controller, [resource]) }
7
+
8
+ describe "#json_resource_errors" do
9
+ it "returns resource errors formatted with `Releaf::Releaf::ErrorFormatter`" do
10
+ allow(Releaf::Core::ErrorFormatter).to receive(:format_errors).with(resource).and_return(a: "b")
11
+ expect(subject.json_resource_errors).to eq(errors: {a: "b"})
12
+ end
13
+ end
14
+
15
+ describe "#render_notification?" do
16
+ before do
17
+ allow(subject).to receive(:has_errors?).and_return(true)
18
+ allow(subject).to receive(:format).and_return(:json)
19
+ end
20
+
21
+ context "when request format is other json" do
22
+ it "returns true" do
23
+ allow(subject).to receive(:format).and_return(:html)
24
+ expect(subject.render_notification?).to be true
25
+ end
26
+ end
27
+
28
+ context "when object has no errors" do
29
+ it "returns true" do
30
+ allow(subject).to receive(:has_errors?).and_return(false)
31
+ expect(subject.render_notification?).to be true
32
+ end
33
+ end
34
+
35
+ context "when request format is json and object has errors" do
36
+ it "returns false" do
37
+ expect(subject.render_notification?).to be false
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#respond" do
43
+ before do
44
+ allow(subject).to receive(:to_html)
45
+ end
46
+
47
+ context "when render notifications return `true`" do
48
+ it "renders notification with success value true/false whether resource has errors" do
49
+ allow(subject).to receive(:render_notification?).and_return(true)
50
+ allow(subject).to receive(:has_errors?).and_return(true)
51
+ expect(subject.controller).to receive(:render_notification).with(false)
52
+ subject.respond
53
+
54
+ allow(subject).to receive(:has_errors?).and_return(false)
55
+ expect(subject.controller).to receive(:render_notification).with(true)
56
+ subject.respond
57
+ end
58
+ end
59
+
60
+ context "when render notifications return `false`" do
61
+ it "does not render notification" do
62
+ allow(subject).to receive(:render_notification?).and_return(false)
63
+ expect(subject.controller).to_not receive(:render_notification)
64
+ subject.respond
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#to_json" do
70
+ context "when resource has errors" do
71
+ it "calls `display_errors`" do
72
+ allow(subject).to receive(:has_errors?).and_return(true)
73
+ expect(subject).to receive(:display_errors)
74
+ subject.to_json
75
+ end
76
+ end
77
+
78
+ context "when resource has no errors" do
79
+ before do
80
+ allow(subject).to receive(:resource_location).and_return("some_url")
81
+ allow(subject).to receive(:has_errors?).and_return(false)
82
+ end
83
+
84
+ context "when options has :redirect key" do
85
+ it "calls `display_errors`" do
86
+ allow(subject).to receive(:options).and_return(redirect: true)
87
+ expect(subject).to receive(:render).with(json: {url: "some_url"}, status: 303)
88
+ subject.to_json
89
+ end
90
+ end
91
+
92
+ context "when options has key :destroyable with `false` value" do
93
+ it "renders `refused_destroy` template" do
94
+ allow(subject).to receive(:options).and_return({})
95
+ expect(subject).to receive(:redirect_to).with("some_url", status: 303)
96
+ subject.to_json
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+
@@ -0,0 +1,26 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Responders::ConfirmDestroyResponder, type: :controller do
4
+ let(:controller){ Releaf::BaseController.new }
5
+ let(:resource){ Book.new}
6
+ subject{ described_class.new(controller, [resource]) }
7
+
8
+ describe "#to_html" do
9
+ context "when options has key :destroyable with `true` value" do
10
+ it "renders default view" do
11
+ allow(subject).to receive(:options).and_return(destroyable: true)
12
+ expect(subject).to receive(:default_render)
13
+ subject.to_html
14
+ end
15
+ end
16
+
17
+ context "when options has key :destroyable with `false` value" do
18
+ it "renders `refused_destroy` template" do
19
+ allow(subject).to receive(:options).and_return(destroyable: false)
20
+ expect(subject).to receive(:render).with("refused_destroy")
21
+ subject.to_html
22
+ end
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,30 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Responders::DestroyResponder, type: :controller do
4
+ let(:controller){ Releaf::BaseController.new }
5
+ let(:resource){ Book.new}
6
+ subject{ described_class.new(controller, [resource]) }
7
+
8
+ describe "#to_html" do
9
+ before do
10
+ allow(controller).to receive(:request).and_return(request)
11
+ allow(controller).to receive(:formats).and_return([:html])
12
+ allow(subject).to receive(:default_render)
13
+ end
14
+
15
+ context "when resource has been successfully destroyed" do
16
+ it "renders success notification" do
17
+ resource.destroy
18
+ expect(subject.controller).to receive(:render_notification).with(true, failure_message_key: "cant destroy, because relations exists")
19
+ subject.to_html
20
+ end
21
+ end
22
+
23
+ context "when resource has not been destroyed" do
24
+ it "renders failure notification" do
25
+ expect(subject.controller).to receive(:render_notification).with(false, failure_message_key: "cant destroy, because relations exists")
26
+ subject.to_html
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Responders::ErrorResponder, type: :controller do
4
+ class Releaf::Core::Responders::DummyErrorResponder < ActionController::Responder
5
+ include Releaf::Core::Responders::ErrorResponder
6
+ def status_code
7
+ 401
8
+ end
9
+ end
10
+
11
+ controller{}
12
+ subject{ Releaf::Core::Responders::DummyErrorResponder.new(controller, []) }
13
+
14
+ describe "#template" do
15
+ it "returns template based on class name" do
16
+ expect(subject.template).to eq("dummy_error")
17
+ end
18
+ end
19
+
20
+ describe "#to_html" do
21
+ it "renders error template with class status code" do
22
+ expect(subject).to receive(:render).with("releaf/error_pages/dummy_error", status: 401)
23
+ subject.to_html
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Responders::FeatureDisabledResponder, type: :controller do
4
+ controller{}
5
+ subject{ described_class.new(controller, []) }
6
+
7
+ describe "#status_code" do
8
+ it "returns 404" do
9
+ expect(subject.status_code).to eq(403)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Responders::PageNotFoundResponder, type: :controller do
4
+ controller{}
5
+ subject{ described_class.new(controller, []) }
6
+
7
+ describe "#status_code" do
8
+ it "returns 404" do
9
+ expect(subject.status_code).to eq(404)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,60 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Responders, type: :controller do
4
+ subject{ Releaf::BaseController.new }
5
+
6
+ describe "#respond_with" do
7
+ before do
8
+ allow(subject).to receive(:active_responder).and_return(Releaf::Core::Responders::AfterSaveResponder)
9
+ allow(subject).to receive(:request).and_return(request)
10
+ allow(subject).to receive(:content_type).and_return(:html)
11
+ end
12
+
13
+ context "when no responder defined within options" do
14
+ it "adds active responder to `responder` options" do
15
+ expect(Releaf::Core::Responders::AfterSaveResponder).to receive(:call)
16
+ subject.respond_with(nil)
17
+ end
18
+ end
19
+
20
+ context "when responder is defined within options" do
21
+ it "adds active responder to `responder` options" do
22
+ expect(Releaf::Core::Responders::AfterSaveResponder).to_not receive(:call)
23
+ expect(Releaf::Core::Responders::PageNotFoundResponder).to receive(:call)
24
+ subject.respond_with(nil, responder: Releaf::Core::Responders::PageNotFoundResponder)
25
+ end
26
+ end
27
+ end
28
+
29
+ describe "#action_responders" do
30
+ it "returns hash with action to responders matching" do
31
+ hash = {
32
+ create: Releaf::Core::Responders::AfterSaveResponder,
33
+ update: Releaf::Core::Responders::AfterSaveResponder,
34
+ confirm_destroy: Releaf::Core::Responders::ConfirmDestroyResponder,
35
+ destroy: Releaf::Core::Responders::DestroyResponder,
36
+ access_denied: Releaf::Core::Responders::AccessDeniedResponder,
37
+ feature_disabled: Releaf::Core::Responders::FeatureDisabledResponder,
38
+ page_not_found: Releaf::Core::Responders::PageNotFoundResponder,
39
+ }
40
+ expect(subject.action_responders).to eq(hash)
41
+ end
42
+ end
43
+
44
+ describe "#action_responder" do
45
+ it "returns matching responder for given action" do
46
+ allow(subject).to receive(:action_responders).and_return(a: "x")
47
+ expect(subject.action_responder(:a)).to eq("x")
48
+ allow(subject).to receive(:action_responders).and_return(b: "x")
49
+ expect(subject.action_responder(:a)).to be nil
50
+ end
51
+ end
52
+
53
+ describe "#active_responder" do
54
+ it "returns currect action matching responder" do
55
+ allow(subject).to receive(:action_name).and_return(:save)
56
+ allow(subject).to receive(:action_responder).with(:save).and_return("x")
57
+ expect(subject.active_responder).to eq("x")
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,311 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::TemplateFieldTypeMapper do
4
+ let(:object){ double("generic object") }
5
+
6
+ def file_field_error_message field_name, obj
7
+ "object doesn't respond to `%s` method. Did you forgot to add `file_accessor :%s` to `%s` model?" % [field_name, field_name, obj.class.name]
8
+ end
9
+
10
+ def image_field_error_message field_name, obj
11
+ "object doesn't respond to `%s` method. Did you forgot to add `image_accessor :%s` to `%s` model?" % [field_name, field_name, obj.class.name]
12
+ end
13
+
14
+ describe ".field_type_name", pending: true do
15
+ it "needs tests"
16
+ end
17
+
18
+ describe ".use_i18n?" do
19
+ context "when object translates" do
20
+ context "when given attribute translatable" do
21
+ it "returns true" do
22
+ expect(described_class.use_i18n?(Book.new, :description)).to be true
23
+ end
24
+ end
25
+
26
+ context "when attribute does not translatable" do
27
+ it "returns false" do
28
+ expect(described_class.use_i18n?(Book.new, :title)).to be false
29
+ end
30
+ end
31
+ end
32
+
33
+ context "when object does not translates" do
34
+ it "returns false" do
35
+ expect(described_class.use_i18n?(Releaf::Permissions::User.new, :password)).to be false
36
+ end
37
+ end
38
+ end
39
+
40
+ describe ".image_or_error" do
41
+ context "given field_name that doesn't end with _uid" do
42
+ it "raises ArgumentError" do
43
+ allow(object).to receive(:image)
44
+ expect { subject.send(:image_or_error, 'image', object) }.to raise_error ArgumentError
45
+ end
46
+ end
47
+
48
+ context 'given field_name is `image_uid`' do
49
+ context 'when object responds to `image` method' do
50
+ it "returns 'image'" do
51
+ allow(object).to receive(:image)
52
+ expect( subject.send(:image_or_error, 'image_uid', object) ).to eq 'image'
53
+ end
54
+ end
55
+
56
+ context 'when object does not respond to `image` method' do
57
+ it 'raises RuntimeError' do
58
+ expect { subject.send(:image_or_error, 'image_uid', object) }.to raise_error(RuntimeError, image_field_error_message('image', object))
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ describe ".file_or_error" do
65
+ context "given field_name that doesn't end with _uid" do
66
+ it "raises ArgumentError" do
67
+ allow(object).to receive(:file)
68
+ expect { subject.send(:file_or_error, 'file', object) }.to raise_error ArgumentError
69
+ end
70
+ end
71
+
72
+ context 'given field_name is `file_uid`' do
73
+ context 'when object responds to `file` method' do
74
+ it "returns 'file'" do
75
+ allow(object).to receive(:file)
76
+ expect( subject.send(:file_or_error, 'file_uid', object) ).to eq 'file'
77
+ end
78
+ end
79
+
80
+ context 'when object does not respond to `file` method' do
81
+ it 'raises RuntimeError' do
82
+ expect { subject.send(:file_or_error, 'file_uid', object) }.to raise_error(RuntimeError, file_field_error_message('file', object))
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ describe ".field_type_name_for_string" do
89
+ %w[thumbnail_uid image_uid photo_uid photography_uid picture_uid avatar_uid logo_uid banner_uid icon_uid].each do |field_name|
90
+ context "when attribute name is '#{field_name}'" do
91
+ context "when object responds to '#{field_name.sub(/_uid$/, '')}'" do
92
+ it "returns 'image'" do
93
+ allow(object).to receive(field_name.sub(/_uid$/, '').to_sym)
94
+ expect( subject.send(:field_type_name_for_string, field_name, object) ).to eq 'image'
95
+ end
96
+ end
97
+
98
+ context "when object doesn't respond to '#{field_name.sub(/_uid$/, '')}'" do
99
+ it "raises RuntimeError" do
100
+ test_field_name = field_name.sub(/_uid$/, '')
101
+ expect { subject.send(:field_type_name_for_string, field_name, object) }.to raise_error(RuntimeError, image_field_error_message(test_field_name, object))
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ %w[image_uid2 uid].each do |field_name|
108
+ context "when attribute_name is '#{field_name}'" do
109
+ it "doesn't return 'image'" do
110
+ expect( subject.send(:field_type_name_for_string, field_name, nil) ).to_not eq 'image'
111
+ end
112
+
113
+ it "doesn't return 'file'" do
114
+ expect( subject.send(:field_type_name_for_string, field_name, nil) ).to_not eq 'file'
115
+ end
116
+ end
117
+ end
118
+
119
+ %w[some_uid other_uid cook_file_uid file_uid].each do |field_name|
120
+ context "when attribute name is '#{field_name}'" do
121
+ context "when object responds to '#{field_name.sub(/_uid$/, '')}'" do
122
+ it "returns 'file'" do
123
+ allow(object).to receive(field_name.sub(/_uid$/, '').to_sym)
124
+ expect( subject.send(:field_type_name_for_string, field_name, object) ).to eq 'file'
125
+ end
126
+ end
127
+
128
+ context "when object doesn't respond to '#{field_name.sub(/_uid$/, '')}'" do
129
+ it "raises RuntimeError" do
130
+ test_field_name = field_name.sub(/_uid$/, '')
131
+ expect { subject.send(:field_type_name_for_string, field_name, object) }.to raise_error(RuntimeError, file_field_error_message(test_field_name, object))
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ %w[pin password password_confirmation encrypted_password some_password some_password_for_secretary].each do |field_name|
138
+ context "when attribute name is '#{field_name}'" do
139
+ it "returns 'password'" do
140
+ expect( subject.send(:field_type_name_for_string, field_name, nil) ).to eq 'password'
141
+ end
142
+ end
143
+ end
144
+
145
+ %w[this_pin pin_that some_pin_for_admin].each do |field_name|
146
+ context "when attribute name is '#{field_name}'" do
147
+ it "doesn't return 'password'" do
148
+ expect( subject.send(:field_type_name_for_string, field_name, nil) ).to_not eq 'password'
149
+ end
150
+ end
151
+ end
152
+
153
+ %w[email admin_email].each do |field_name|
154
+ context "when attribute name is '#{field_name}'" do
155
+ it "returns 'email'" do
156
+ expect( subject.send(:field_type_name_for_string, field_name, nil) ).to eq 'email'
157
+ end
158
+ end
159
+ end
160
+
161
+ context "when attribute name is 'email_for_admin'" do
162
+ it "doesn't return 'email'" do
163
+ expect( subject.send(:field_type_name_for_string, 'email_for_admin', nil) ).to_not eq 'email'
164
+ end
165
+ end
166
+
167
+ %w[link awesome_link].each do |field_name|
168
+ context "when attribute name is '#{field_name}'" do
169
+ it "returns 'link'" do
170
+ expect( subject.send(:field_type_name_for_string, field_name, nil) ).to eq 'link'
171
+ end
172
+ end
173
+ end
174
+
175
+ context "when attribute name is 'link_to_awesome_site'" do
176
+ it "doesn't return 'link'" do
177
+ expect( subject.send(:field_type_name_for_string, 'link_to_awesome_site', nil) ).to_not eq 'link'
178
+ end
179
+ end
180
+
181
+ %w[www homepage admin_homepage www_page homepage_www url homepage_url site_url url_for_this_site].each do |field_name|
182
+ context "when attribute name is '#{field_name}'" do
183
+ it "doesn't return 'link'" do
184
+ expect( subject.send(:field_type_name_for_string, field_name, nil) ).to_not eq 'link'
185
+ end
186
+ end
187
+ end
188
+
189
+ %w[www homepage url some_pin uid everything_else html].each do |field_name|
190
+ context "when attribute name is '#{field_name}'" do
191
+ it "returns 'text'" do
192
+ expect( subject.send(:field_type_name_for_string, field_name, nil) ).to eq 'text'
193
+ end
194
+ end
195
+ end
196
+ end # describe ".field_type_name_for_string"
197
+
198
+
199
+ describe '.field_type_name_for_text' do
200
+ %w[url homepage random_url random_homepage random_link cool_link].each do |field_name|
201
+ context "when attribute name is '#{field_name}'" do
202
+ it "returns 'link'" do
203
+ expect( subject.send(:field_type_name_for_text, field_name, nil) ).to eq 'link'
204
+ end
205
+ end
206
+ end
207
+
208
+ %w[url_for_site link_to_site link home_page homepage_for_site].each do |field_name|
209
+ context "when attribute name is '#{field_name}'" do
210
+ it "doesn't return 'link'" do
211
+ expect( subject.send(:field_type_name_for_text, field_name, nil) ).to_not eq 'link'
212
+ end
213
+ end
214
+ end
215
+
216
+ %w[html random_html].each do |field_name|
217
+ context "when attribute name is '#{field_name}'" do
218
+ it "returns 'richtext'" do
219
+ expect( subject.send(:field_type_name_for_text, field_name, nil) ).to eq 'richtext'
220
+ end
221
+ end
222
+ end
223
+
224
+ context "when attribute name is 'html_for_description'" do
225
+ it "doesn't return 'richtext'" do
226
+ expect( subject.send(:field_type_name_for_text, 'html_for_description', nil) ).to_not eq 'richtext'
227
+ end
228
+ end
229
+
230
+ %w[text description random html_text].each do |field_name|
231
+ context "when attribute name is '#{field_name}'" do
232
+ it "returns 'textarea'" do
233
+ expect( subject.send(:field_type_name_for_text, field_name, nil) ).to eq 'textarea'
234
+ end
235
+ end
236
+ end
237
+ end # describe '.field_type_name_for_text'
238
+
239
+ describe ".field_type_name_for_datetime" do
240
+ %w[no matter what].each do |field_name|
241
+ context "when attribute name is '#{field_name}'" do
242
+ it "returns 'datetime'" do
243
+ expect( subject.send(:field_type_name_for_datetime, field_name, nil) ).to eq 'datetime'
244
+ end
245
+ end
246
+ end
247
+ end # describe ".field_type_name_for_datetime" do
248
+ describe ".field_type_name_for_date" do
249
+ %w[no matter what].each do |field_name|
250
+ context "when attribute name is '#{field_name}'" do
251
+ it "returns 'date'" do
252
+ expect( subject.send(:field_type_name_for_date, field_name, nil) ).to eq 'date'
253
+ end
254
+ end
255
+ end
256
+ end # describe ".field_type_name_for_date" do
257
+ describe ".field_type_name_for_time" do
258
+ %w[no matter what].each do |field_name|
259
+ context "when attribute name is '#{field_name}'" do
260
+ it "returns 'time'" do
261
+ expect( subject.send(:field_type_name_for_time, field_name, nil) ).to eq 'time'
262
+ end
263
+ end
264
+ end
265
+ end # describe ".field_type_name_for_time" do
266
+ describe ".field_type_name_for_boolean" do
267
+ %w[no matter what].each do |field_name|
268
+ context "when attribute name is '#{field_name}'" do
269
+ it "returns 'boolean'" do
270
+ expect( subject.send(:field_type_name_for_boolean, field_name, nil) ).to eq 'boolean'
271
+ end
272
+ end
273
+ end
274
+ end # describe ".field_type_name_for_boolean" do
275
+ describe ".field_type_name_for_float" do
276
+ %w[no matter what].each do |field_name|
277
+ context "when attribute name is '#{field_name}'" do
278
+ it "returns 'float'" do
279
+ expect( subject.send(:field_type_name_for_float, field_name, nil) ).to eq 'float'
280
+ end
281
+ end
282
+ end
283
+ end # describe ".field_type_name_for_float" do
284
+
285
+ describe ".field_type_name_for_integer" do
286
+ before do
287
+ author = FactoryGirl.create(:author)
288
+ @book = FactoryGirl.create(:book, :author => author)
289
+ end
290
+
291
+ context "when attributes ends with '_id'" do
292
+ context "when there's an ActiveRecord association" do
293
+ it "returns 'item'" do
294
+ expect( subject.send(:field_type_name_for_integer, 'author_id', @book) ).to eq 'item'
295
+ end
296
+ end
297
+
298
+ context "when there's no ActiveRecord association" do
299
+ it "returns 'text'" do
300
+ expect( subject.send(:field_type_name_for_integer, 'random_field_id', @book) ).to eq 'integer'
301
+ end
302
+ end
303
+ end
304
+
305
+ context "when attribute doesn't end with '_id'" do
306
+ it "returns 'text'" do
307
+ expect( subject.send(:field_type_name_for_integer, 'random_field', nil) ).to eq 'integer'
308
+ end
309
+ end
310
+ end # describe ".field_type_name_for_integer"
311
+ end