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,32 @@
1
+ require 'rails_helper'
2
+ feature "Index tables" do
3
+ background do
4
+ auth_as_user
5
+ publisher = create(:publisher, title: "ABC books")
6
+ author = create(:author, publisher: publisher)
7
+ another_author = create(:author, name: "Steve", publisher: nil)
8
+ @book_1 = create(:book, title: "good book", author: author)
9
+ @book_2 = create(:book, title: "steevs book", author: another_author)
10
+ end
11
+
12
+ scenario "shows books author publisher title" do
13
+ visit admin_books_path
14
+
15
+ within ".table.books thead tr" do
16
+ cells = ["Title", "Year", "Author", "Genre", "Active", "Published at", "Price", "Stars", "Cover image uid", "Description", "Author publisher title"]
17
+ expect(page).to have_cells_text(cells, type: "th")
18
+ end
19
+
20
+ within ".table.books tbody" do
21
+ within "tr[data-id='#{@book_1.id}']" do
22
+ cells = ["good book", "", "Aleksandrs Lielais", "", "", "No", "", "", "", "", "ABC books"]
23
+ expect(page).to have_cells_text(cells)
24
+ end
25
+
26
+ within "tr[data-id='#{@book_2.id}']" do
27
+ cells = ["steevs book", "", "Steve Lielais", "", "", "No", "", "", "", "", ""]
28
+ expect(page).to have_cells_text(cells)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,71 @@
1
+ require 'rails_helper'
2
+ describe "Side menu visual appearance", js: true do
3
+ before do
4
+ Rails.cache.clear
5
+ @user = auth_as_user
6
+ visit releaf_permissions_user_profile_path
7
+ end
8
+
9
+ describe "collapsing functionality" do
10
+ context "when logged first time" do
11
+ it "has side menu opened" do
12
+ expect(page).to_not have_css('body.side-compact')
13
+ end
14
+ end
15
+
16
+ context "when click to collapse button" do
17
+ it "collapses side menu" do
18
+ find('aside .compacter button').click
19
+
20
+ expect(page).to have_css('body.side-compact')
21
+ end
22
+
23
+ it "has permanent collapsing status" do
24
+ find('aside .compacter button').click
25
+ wait_for_settings_update('releaf.side.compact')
26
+ visit releaf_permissions_user_profile_path
27
+
28
+ expect(page).to have_css('body.side-compact')
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "menu groups collapsing" do
34
+ context "when logged first time" do
35
+ it "menu item groups is not collapsed" do
36
+ expect(page).to have_css('aside li[data-name="permissions"]:not(.collapsed)')
37
+ end
38
+ end
39
+
40
+ context "when collapsing submenu group with active item" do
41
+ it "collapses menu group" do
42
+ find('aside li[data-name="permissions"] > .trigger').click
43
+ expect(page).to have_css('aside li[data-name="permissions"].collapsed')
44
+ end
45
+
46
+ it "does not keep menu group collapsing permanent" do
47
+ find('aside li[data-name="permissions"] > .trigger').click
48
+ wait_for_settings_update('releaf.menu.collapsed.permissions')
49
+
50
+ visit releaf_permissions_users_path
51
+ expect(page).to have_css('aside li[data-name="permissions"]:not(.collapsed)')
52
+ end
53
+ end
54
+
55
+ context "when collapsing submenu group without active item" do
56
+ it "collapses menu group" do
57
+ find('aside li[data-name="inventory"] > .trigger').click
58
+
59
+ expect(page).to have_css('aside li[data-name="inventory"].collapsed')
60
+ end
61
+
62
+ it "keeps menu group collapsing permanent" do
63
+ find('aside li[data-name="inventory"] > .trigger').click
64
+ wait_for_settings_update('releaf.menu.collapsed.inventory')
65
+ visit releaf_permissions_user_profile_path
66
+
67
+ expect(page).to have_css('aside li[data-name="inventory"].collapsed')
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,64 @@
1
+ require 'rails_helper'
2
+ feature "Richtext attachments", js: true do
3
+ background do
4
+ # preload ActsAsNode classes
5
+ Rails.application.eager_load!
6
+ auth_as_user
7
+ end
8
+
9
+ scenario "Upload image and insert it within text" do
10
+ visit new_releaf_content_node_path(content_type: 'HomePage')
11
+ fill_in("Name", with: "Image test")
12
+ select('en', from: 'Locale')
13
+
14
+ status_script = 'CKEDITOR.instances["resource_content_attributes_intro_text_html"].status=="ready"'
15
+ expect { page.evaluate_script(status_script) }.to become_true
16
+
17
+ find(".cke_toolbox a[title='Image']").click
18
+ expect(page).to have_css(".cke_dialog_title", text: "Image Properties")
19
+ click_link "Upload"
20
+
21
+ within_frame(find("iframe.cke_dialog_ui_input_file")) do
22
+ fixture_path = File.expand_path('../fixtures/cs.png', __dir__)
23
+ attach_file(:upload, fixture_path)
24
+ end
25
+
26
+ click_link "Send it to the Server"
27
+ expect(page).to have_content("Preview")
28
+ click_link "OK"
29
+
30
+ expect(page).to have_css(".cke_editor_resource_content_attributes_intro_text_html") # wait focus switch finished
31
+ save_and_check_response "Create succeeded"
32
+
33
+ visit "/image-test"
34
+ expect(page).to have_css("img[src='#{Releaf::RichtextAttachment.last.file.url}']")
35
+ end
36
+
37
+ scenario "Upload file and insert url to it" do
38
+ visit new_releaf_content_node_path(content_type: 'HomePage')
39
+ fill_in("Name", with: "Link test")
40
+ select('en', from: 'Locale')
41
+
42
+ status_script = 'CKEDITOR.instances["resource_content_attributes_intro_text_html"].status=="ready"'
43
+ expect { page.evaluate_script(status_script) }.to become_true
44
+
45
+ find(".cke_toolbox a[title='Link']").click
46
+ expect(page).to have_css(".cke_dialog_title", text: "Link")
47
+ click_link "Upload"
48
+
49
+ within_frame(find("iframe.cke_dialog_ui_input_file")) do
50
+ fixture_path = File.expand_path('../fixtures/cs.png', __dir__)
51
+ attach_file(:upload, fixture_path)
52
+ end
53
+
54
+ click_link "Send it to the Server"
55
+ expect(page).to have_content("Link Type")
56
+ click_link "OK"
57
+
58
+ expect(page).to have_css(".cke_editor_resource_content_attributes_intro_text_html") # wait focus switch finished
59
+ save_and_check_response "Create succeeded"
60
+
61
+ visit "/link-test"
62
+ expect(page).to have_css("a[href='#{Releaf::RichtextAttachment.last.file.url}']")
63
+ end
64
+ end
@@ -0,0 +1,29 @@
1
+ require 'rails_helper'
2
+ feature "Richtext embed", js: true do
3
+ background do
4
+ # preload ActsAsNode classes
5
+ Rails.application.eager_load!
6
+ auth_as_user
7
+ end
8
+
9
+ scenario "Add embed to richtext" do
10
+ visit new_releaf_content_node_path(content_type: 'HomePage')
11
+ fill_in("Name", with: "Embed test")
12
+ select('en', from: 'Locale')
13
+
14
+ status_script = 'CKEDITOR.instances["resource_content_attributes_intro_text_html"].status=="ready"'
15
+ expect { page.evaluate_script(status_script) }.to become_true
16
+
17
+ find(".cke_toolbox a[title='Embed Media']").click
18
+ expect(page).to have_css(".cke_dialog_title", text: "Embed Media")
19
+
20
+ fill_in "Paste Embed Code Here", with: '<iframe src="500.html" />'
21
+ click_link "OK"
22
+
23
+ expect(page).to have_css(".cke_editor_resource_content_attributes_intro_text_html") # wait focus switch finished
24
+ save_and_check_response "Create succeeded"
25
+
26
+ visit "/embed-test"
27
+ expect(page).to have_css("iframe[src='500.html']")
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ require 'rails_helper'
2
+ feature "Richtext editing", js: true do
3
+ background do
4
+ auth_as_user
5
+ end
6
+
7
+ scenario "Image toolbar available when controller support attachments" do
8
+ visit new_releaf_content_node_path(content_type: 'TextPage')
9
+ fill_in_richtext 'Text', with: "some text"
10
+ expect(page).to have_css("a.cke_button__image")
11
+ end
12
+
13
+ scenario "Image toolbar unavailable when controller doesn't support attachments" do
14
+ allow_any_instance_of(Admin::BooksController).to receive(:releaf_richtext_attachment_upload_url).and_return("")
15
+ visit new_admin_book_path
16
+ fill_in_richtext "Summary", with: "some text"
17
+ expect(page).to_not have_css("a.cke_button__image")
18
+ end
19
+ end
@@ -0,0 +1,825 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Core::Search do
4
+
5
+ describe "searching in models attributes" do
6
+ with_model :Tester, scope: :all do
7
+ table do |t|
8
+ t.string :name
9
+ t.string :surname
10
+ end
11
+ end
12
+
13
+ before(:all) do
14
+ @tester1 = Tester.create!(name: 'Jānis')
15
+ @tester2 = Tester.create!(name: 'Pēteris', surname: 'Grābeklis')
16
+ @tester3 = Tester.create!(name: 'Pēteris', surname: 'Lazdiņš')
17
+ @tester4 = Tester.create!(surname: 'Lazdiņš')
18
+ end
19
+
20
+ it "can search in single column" do
21
+ params = {
22
+ relation: Tester,
23
+ fields: [:name],
24
+ text: 'Pēteris'
25
+ }
26
+ expect( described_class.prepare(params) ).to match_array [@tester2, @tester3]
27
+ end
28
+
29
+ it "can search in multiple columns" do
30
+ params = {
31
+ relation: Tester,
32
+ fields: [:name, :surname],
33
+ text: 'Lazdiņš Pēteris'
34
+ }
35
+ expect( described_class.prepare(params) ).to match_array [@tester3]
36
+ end
37
+
38
+ it "is case insensitive" do
39
+ params = {
40
+ relation: Tester,
41
+ fields: [:name],
42
+ text: 'jānis'
43
+ }
44
+ expect( described_class.prepare(params) ).to match_array [@tester1]
45
+ end
46
+
47
+ it "doesn't suffer from injections" do
48
+ expected_results = if mysql?
49
+ /LIKE '%SQL\\\'injection%'/
50
+ elsif postgresql?
51
+ /ILIKE '%SQL''injection%'/
52
+ else
53
+ fail
54
+ end
55
+ params = {
56
+ relation: Tester,
57
+ fields: [:name],
58
+ text: "SQL'injection"
59
+ }
60
+ expect( described_class.prepare(params).to_sql ).to match(expected_results)
61
+ end
62
+ end
63
+
64
+ describe "searching in has_many association attributes" do
65
+ with_model :Programmer, scope: :all do
66
+ model do
67
+ has_many :projects
68
+ end
69
+ end
70
+
71
+ with_model :Project, scope: :all do
72
+ table do |t|
73
+ t.string :title
74
+ t.string :description
75
+ t.integer :programmer_id
76
+ end
77
+
78
+ model do
79
+ belongs_to :programmer
80
+ end
81
+ end
82
+
83
+ before(:all) do
84
+ @programmer1 = Programmer.create!
85
+ @programmer2 = Programmer.create!
86
+ @programmer3 = Programmer.create!
87
+
88
+ Project.create(programmer: @programmer1, title: 'Good')
89
+ Project.create(programmer: @programmer1, title: 'Bad', description: 'legacy code')
90
+ Project.create(programmer: @programmer2, title: 'Ugy', description: 'php')
91
+ Project.create(programmer: @programmer3, title: 'Very good')
92
+ Project.create(programmer: @programmer3, title: 'good', description: 'ruby')
93
+ end
94
+
95
+ it "finds records" do
96
+ params = {
97
+ relation: Programmer,
98
+ fields: [projects: [:title]],
99
+ text: 'bad'
100
+ }
101
+ expect( described_class.prepare(params) ).to match_array [@programmer1]
102
+ end
103
+
104
+ it "returns distinct records" do
105
+ params = {
106
+ relation: Programmer,
107
+ fields: [projects: [:title]],
108
+ text: 'good'
109
+ }
110
+ expect( described_class.prepare(params) ).to match_array [@programmer1, @programmer3]
111
+ end
112
+
113
+ it "searches different columns" do
114
+ params = {
115
+ relation: Programmer,
116
+ fields: [projects: [:title, :description]],
117
+ text: 'good ruby'
118
+ }
119
+ expect( described_class.prepare(params) ).to match_array [@programmer3]
120
+ end
121
+ end
122
+
123
+ describe "searching in belongs_to association attributes" do
124
+ with_model :Programmer, scope: :all do
125
+ table do |t|
126
+ t.integer :project_manager_id
127
+ end
128
+
129
+ model do
130
+ belongs_to :project_manager
131
+ end
132
+ end
133
+
134
+ with_model :ProjectManager, scope: :all do
135
+ table do |t|
136
+ t.string :name
137
+ t.string :surname
138
+ end
139
+ end
140
+
141
+ before(:all) do
142
+ project_manager1 = ProjectManager.create!(name: 'Jānis')
143
+ project_manager2 = ProjectManager.create!(name: 'Pēteris', surname: 'Ozols')
144
+ project_manager3 = ProjectManager.create!(name: 'Jānis', surname: 'Ozols')
145
+
146
+ @programmer1 = Programmer.create!(project_manager: project_manager1)
147
+ @programmer2 = Programmer.create!(project_manager: project_manager2)
148
+ @programmer3 = Programmer.create!(project_manager: project_manager3)
149
+ end
150
+
151
+ it "finds records" do
152
+ params = {
153
+ relation: Programmer,
154
+ fields: [project_manager: [:name]],
155
+ text: 'pēteris'
156
+ }
157
+ expect( described_class.prepare(params) ).to match_array [@programmer2]
158
+ end
159
+
160
+ it "searches different columns" do
161
+ params = {
162
+ relation: Programmer,
163
+ fields: [project_manager: [:name, :surname]],
164
+ text: 'jānis ozols'
165
+ }
166
+ expect( described_class.prepare(params) ).to match_array [@programmer3]
167
+ end
168
+ end
169
+
170
+ describe "searching in has_one association attributes" do
171
+ with_model :Programmer, scope: :all do
172
+ model do
173
+ has_one :account
174
+ end
175
+ end
176
+
177
+ with_model :Account, scope: :all do
178
+ table do |t|
179
+ t.string :login
180
+ t.string :email
181
+ t.integer :programmer_id
182
+ end
183
+
184
+ model do
185
+ belongs_to :programmer
186
+ end
187
+ end
188
+
189
+ before(:all) do
190
+ @programmer1 = Programmer.create!
191
+ @programmer2 = Programmer.create!
192
+ @programmer3 = Programmer.create!
193
+
194
+ Account.create!(programmer: @programmer1, login: 'god', email: 'god@example.com')
195
+ Account.create!(programmer: @programmer2, login: 'devil', email: 'devil@example.com')
196
+ Account.create!(programmer: @programmer3, login: 'unknown', email: 'who@example.com')
197
+ end
198
+
199
+ it "finds records" do
200
+ params = {
201
+ relation: Programmer,
202
+ fields: [account: [:login]],
203
+ text: 'god'
204
+ }
205
+ expect( described_class.prepare(params) ).to match_array [@programmer1]
206
+ end
207
+
208
+ it "searches different columns" do
209
+ params = {
210
+ relation: Programmer,
211
+ fields: [account: [:login, :email]],
212
+ text: 'unknown who'
213
+ }
214
+ expect( described_class.prepare(params) ).to match_array [@programmer3]
215
+ end
216
+
217
+ end
218
+
219
+ describe "searching in has_many through assocation attributes" do
220
+ with_model :Programmer, scope: :all do
221
+ model do
222
+ has_many :commits
223
+ has_many :projects, through: :commits
224
+ end
225
+ end
226
+
227
+ with_model :Commit, scope: :all do
228
+ table do |t|
229
+ t.integer :programmer_id
230
+ t.integer :project_id
231
+ end
232
+
233
+ model do
234
+ belongs_to :programmer
235
+ belongs_to :project
236
+ end
237
+ end
238
+
239
+ with_model :Project, scope: :all do
240
+ table do |t|
241
+ t.string :name
242
+ t.string :description
243
+ end
244
+ end
245
+
246
+ before(:all) do
247
+ @programmer1 = Programmer.create!
248
+ @programmer2 = Programmer.create!
249
+ @programmer3 = Programmer.create!
250
+
251
+ project1 = Project.create!(name: 'Good')
252
+ project2 = Project.create!(name: 'Bad', description: 'legacy code')
253
+ project3 = Project.create!(name: 'Ugy', description: 'php')
254
+ project4 = Project.create!(name: 'Very good')
255
+ project5 = Project.create!(name: 'good', description: 'ruby')
256
+
257
+ Commit.create!(programmer: @programmer1, project: project1)
258
+ Commit.create!(programmer: @programmer1, project: project2)
259
+ Commit.create!(programmer: @programmer2, project: project2)
260
+ Commit.create!(programmer: @programmer2, project: project3)
261
+ Commit.create!(programmer: @programmer1, project: project4)
262
+ Commit.create!(programmer: @programmer3, project: project5)
263
+ end
264
+
265
+ it "finds records" do
266
+ params = {
267
+ relation: Programmer,
268
+ fields: [projects: [:name, :description]],
269
+ text: 'good'
270
+ }
271
+ expect( described_class.prepare(params) ).to match_array [@programmer1, @programmer3]
272
+ end
273
+ end
274
+
275
+ describe "searching in has_one through assocation attributes" do
276
+ with_model :Supplier, scope: :all do
277
+ model do |t|
278
+ has_one :account
279
+ has_one :account_history, through: :account
280
+ end
281
+ end
282
+
283
+ with_model :Account, scope: :all do
284
+ table do |t|
285
+ t.integer :supplier_id
286
+ end
287
+
288
+ model do
289
+ belongs_to :supplier
290
+ has_one :account_history
291
+ end
292
+ end
293
+
294
+ with_model :AccountHistory, scope: :all do
295
+ table do |t|
296
+ t.integer :account_id
297
+ t.string :old_login
298
+ end
299
+
300
+ model do
301
+ belongs_to :account
302
+ end
303
+ end
304
+
305
+ before(:all) do
306
+ @supplier1 = Supplier.create!
307
+ @supplier2 = Supplier.create!
308
+ @supplier3 = Supplier.create!
309
+
310
+ account1 = Account.create!(supplier: @supplier1)
311
+ account2 = Account.create!(supplier: @supplier2)
312
+ account3 = Account.create!(supplier: @supplier3)
313
+
314
+ AccountHistory.create!(account: account1, old_login: 'marusja')
315
+ AccountHistory.create!(account: account2, old_login: 'ķirmis')
316
+ AccountHistory.create!(account: account3, old_login: 'grauzējs')
317
+ end
318
+
319
+ it "finds correct records" do
320
+ params = {
321
+ relation: Supplier,
322
+ fields: [account_history: [:old_login]],
323
+ text: 'ķirmis'
324
+ }
325
+ expect( described_class.prepare(params) ).to match_array [@supplier2]
326
+ end
327
+
328
+ end
329
+
330
+ describe "searching in polymorphic has_many association" do
331
+ with_model :Note, scope: :all do
332
+ table do |t|
333
+ t.integer :owner_id
334
+ t.string :owner_type
335
+ t.string :text
336
+ end
337
+
338
+ model do
339
+ belongs_to :owner, polymorphic: true
340
+ end
341
+ end
342
+
343
+ with_model :Account, scope: :all do
344
+ model do
345
+ has_many :notes, as: :owner
346
+ end
347
+ end
348
+
349
+ with_model :Supplier, scope: :all do
350
+ model do
351
+ has_many :notes, as: :owner
352
+ end
353
+ end
354
+
355
+ before(:all) do
356
+ @account1 = Account.create!
357
+ @account2 = Account.create!
358
+ @supplier1 = Supplier.create!
359
+ @supplier2 = Supplier.create!
360
+
361
+ Note.create!(owner: @account1, text: 'one')
362
+ Note.create!(owner: @supplier1, text: 'two')
363
+ Note.create!(owner: @account2, text: 'three')
364
+ Note.create!(owner: @supplier2, text: 'four')
365
+ end
366
+
367
+ it "finds correct record" do
368
+ params = {
369
+ relation: Account,
370
+ fields: [notes: [:text]],
371
+ text: 'one'
372
+ }
373
+ expect( described_class.prepare(params) ).to match_array [@account1]
374
+ end
375
+
376
+ it "uses owner_type when joining" do
377
+ params = {
378
+ relation: Account,
379
+ fields: [notes: [:text]],
380
+ text: 'two'
381
+ }
382
+ expect( described_class.prepare(params) ).to match_array []
383
+ end
384
+ end
385
+
386
+ describe "searching in polymorphic has_one association" do
387
+ with_model :Note, scope: :all do
388
+ table do |t|
389
+ t.integer :owner_id
390
+ t.string :owner_type
391
+ t.string :text
392
+ end
393
+
394
+ model do
395
+ belongs_to :owner, polymorphic: true
396
+ end
397
+ end
398
+
399
+ with_model :Account, scope: :all do
400
+ model do
401
+ has_one :note, as: :owner
402
+ end
403
+ end
404
+
405
+ with_model :Supplier, scope: :all do
406
+ model do
407
+ has_one :note, as: :owner
408
+ end
409
+ end
410
+
411
+ before(:all) do
412
+ @account1 = Account.create!
413
+ @account2 = Account.create!
414
+ @supplier1 = Supplier.create!
415
+ @supplier2 = Supplier.create!
416
+
417
+ Note.create!(owner: @account1, text: 'one')
418
+ Note.create!(owner: @supplier1, text: 'two')
419
+ Note.create!(owner: @account2, text: 'three')
420
+ Note.create!(owner: @supplier2, text: 'four')
421
+ end
422
+
423
+ it "finds correct record" do
424
+ params = {
425
+ relation: Account,
426
+ fields: [note: [:text]],
427
+ text: 'one'
428
+ }
429
+ expect( described_class.prepare(params) ).to match_array [@account1]
430
+ end
431
+
432
+ it "uses owner_type when joining" do
433
+ params = {
434
+ relation: Account,
435
+ fields: [note: [:text]],
436
+ text: 'two'
437
+ }
438
+ expect( described_class.prepare(params) ).to match_array []
439
+ end
440
+
441
+ end
442
+
443
+ describe "searching in scoped association" do
444
+ with_model :Post, scope: :all do
445
+ model do
446
+ has_many :comments, -> { where(deleted: false) }
447
+ has_many :deleted_comments, -> { where(deleted: true) }, class_name: :Comment
448
+ end
449
+ end
450
+
451
+ with_model :Comment, scope: :all do
452
+ table do |t|
453
+ t.integer :post_id
454
+ t.boolean :deleted, default: false
455
+ t.string :text
456
+ end
457
+
458
+ model do
459
+ belongs_to :post
460
+ end
461
+ end
462
+
463
+ before(:all) do
464
+ @post1 = Post.create!
465
+ @post2 = Post.create!
466
+ @post3 = Post.create!
467
+
468
+ Comment.create!(post: @post1, text: 'one')
469
+ Comment.create!(post: @post2, text: 'one', deleted: true)
470
+ Comment.create!(post: @post3, text: 'two')
471
+ Comment.create!(post: @post3, text: 'one', deleted: true)
472
+ end
473
+
474
+ it "finds correct records" do
475
+ params = {
476
+ relation: Post,
477
+ fields: [comments: [:text]],
478
+ text: 'one'
479
+ }
480
+ expect( described_class.prepare(params) ).to match_array [@post1]
481
+ end
482
+
483
+ it "finds correct records" do
484
+ params = {
485
+ relation: Post,
486
+ fields: [deleted_comments: [:text]],
487
+ text: 'one'
488
+ }
489
+ expect( described_class.prepare(params) ).to match_array [@post2, @post3]
490
+ end
491
+ end
492
+
493
+ describe "searching in same table through different associations" do
494
+
495
+ with_model :Writer, scope: :all do
496
+ table do |t|
497
+ t.string :name
498
+ end
499
+ end
500
+
501
+ with_model :Post, scope: :all do
502
+ table do |t|
503
+ t.integer :writer_id
504
+ t.integer :editor_id
505
+ end
506
+
507
+ model do
508
+ belongs_to :writer, class_name: :Writer
509
+ belongs_to :editor, class_name: :Writer
510
+ end
511
+ end
512
+
513
+ before(:all) do
514
+ writer1 = Writer.create!(name: 'Jānis')
515
+ writer2 = Writer.create!(name: 'Pēteris')
516
+ writer3 = Writer.create!(name: 'Juris')
517
+ writer4 = Writer.create!(name: 'Jurģis')
518
+
519
+ @post1 = Post.create!(writer: writer1, editor: writer2)
520
+ @post2 = Post.create!(writer: writer1, editor: writer3)
521
+ @post3 = Post.create!(writer: writer2, editor: writer1)
522
+ @post4 = Post.create!(writer: writer2)
523
+ @post5 = Post.create!(writer: writer3, editor: writer4)
524
+ @post6 = Post.create!( editor: writer3)
525
+ end
526
+
527
+ it "returns correct records" do
528
+ params = {
529
+ relation: Post,
530
+ fields: [writer: [:name], editor: [:name]],
531
+ text: 'Pēteris'
532
+ }
533
+ expect( described_class.prepare(params) ).to match_array [@post1, @post3, @post4]
534
+ end
535
+
536
+ it "returns correct records" do
537
+ params = {
538
+ relation: Post,
539
+ fields: [writer: [:name], editor: [:name]],
540
+ text: 'Juris'
541
+ }
542
+ expect( described_class.prepare(params) ).to match_array [@post2, @post5, @post6]
543
+ end
544
+ end
545
+
546
+ describe "searching in association table that is already joined" do
547
+ with_model :Writer, scope: :all do
548
+ table do |t|
549
+ t.string :name
550
+ end
551
+ end
552
+
553
+ with_model :Post, scope: :all do
554
+ table do |t|
555
+ t.integer :writer_id
556
+ end
557
+
558
+ model do
559
+ belongs_to :writer
560
+ end
561
+ end
562
+
563
+ before(:all) do
564
+ writer1 = Writer.create!(name: 'Jānis')
565
+ writer2 = Writer.create!(name: 'Pēteris')
566
+ writer3 = Writer.create!(name: 'Juris')
567
+ writer4 = Writer.create!(name: 'Jurģis')
568
+
569
+ @post1 = Post.create!(writer: writer1)
570
+ @post2 = Post.create!(writer: writer1)
571
+ @post3 = Post.create!(writer: writer2)
572
+ @post4 = Post.create!(writer: writer2)
573
+ @post5 = Post.create!(writer: writer3)
574
+ @post6 = Post.create!
575
+ end
576
+
577
+ it "returns correct records" do
578
+ params = {
579
+ relation: Post.joins(:writer),
580
+ fields: [writer: [:name]],
581
+ text: 'Pēteris'
582
+ }
583
+ expect( described_class.prepare(params) ).to match_array [@post3, @post4]
584
+ end
585
+ end
586
+
587
+ describe "searching deeply nested attributes" do
588
+ with_model :Programmer, scope: :all do
589
+ table do |t|
590
+ t.integer :manager_id
591
+ end
592
+
593
+ model do
594
+ belongs_to :manager, class_name: :ProjectManager
595
+ end
596
+ end
597
+
598
+ with_model :ProjectManager, scope: :all do
599
+ table do |t|
600
+ t.string :name
601
+ t.string :surname
602
+ end
603
+
604
+ model do
605
+ has_many :programmers, foreign_key: :manager_id
606
+ has_many :projects, foreign_key: :manager_id
607
+ end
608
+ end
609
+
610
+ with_model :Project, scope: :all do
611
+ table do |t|
612
+ t.string :name
613
+ t.integer :manager_id
614
+ end
615
+
616
+ model do
617
+ belongs_to :manager, class_name: :ProjectManager
618
+ end
619
+ end
620
+
621
+ before(:all) do
622
+ manager1 = ProjectManager.create!
623
+ manager2 = ProjectManager.create!
624
+ manager3 = ProjectManager.create!
625
+
626
+ @programmer1 = Programmer.create!(manager: manager1)
627
+ @programmer2 = Programmer.create!(manager: manager2)
628
+ @programmer3 = Programmer.create!(manager: manager2)
629
+
630
+ Project.create!(name: 'one', manager: manager1)
631
+ Project.create!(name: 'two', manager: manager1)
632
+ Project.create!(name: 'three', manager: manager2)
633
+ Project.create!(name: 'four', manager: manager3)
634
+ end
635
+
636
+ it "returns correct records" do
637
+ params = {
638
+ relation: Programmer,
639
+ fields: [manager: [projects: [:name]]],
640
+ text: 'three'
641
+ }
642
+ expect( described_class.prepare(params) ).to match_array [@programmer2, @programmer3]
643
+ end
644
+ end
645
+
646
+ describe "searching with joins and includes" do
647
+ with_model :Writer, scope: :all do
648
+ table do |t|
649
+ t.string :name
650
+ end
651
+ end
652
+
653
+ with_model :Post, scope: :all do
654
+ table do |t|
655
+ t.integer :writer_id
656
+ end
657
+
658
+ model do
659
+ belongs_to :writer
660
+ end
661
+ end
662
+
663
+ before(:all) do
664
+ writer1 = Writer.create!(name: 'Jānis')
665
+ writer2 = Writer.create!(name: 'Pēteris')
666
+ writer3 = Writer.create!(name: 'Juris')
667
+ writer4 = Writer.create!(name: 'Jurģis')
668
+
669
+ @post1 = Post.create!(writer: writer1)
670
+ @post2 = Post.create!(writer: writer1)
671
+ @post3 = Post.create!(writer: writer2)
672
+ @post4 = Post.create!(writer: writer2)
673
+ @post5 = Post.create!(writer: writer3)
674
+ @post6 = Post.create!
675
+ end
676
+
677
+ it "returns correct records" do
678
+ params = {
679
+ relation: Post.includes(:writer).references(:writer),
680
+ fields: [writer: [:name]],
681
+ text: 'Pēteris'
682
+ }
683
+ expect( described_class.prepare(params) ).to match_array [@post3, @post4]
684
+ end
685
+ end
686
+
687
+ describe "searching in polymorphic association form STI class" do
688
+ with_model :Note, scope: :all do
689
+ table do |t|
690
+ t.integer :owner_id
691
+ t.string :owner_type
692
+ t.string :text
693
+ end
694
+
695
+ model do
696
+ belongs_to :owner, polymorphic: true
697
+ end
698
+ end
699
+
700
+ with_model :Account, scope: :all do
701
+ table do |t|
702
+ t.string :type
703
+ end
704
+
705
+ model do
706
+ has_many :notes, as: :owner
707
+ end
708
+ end
709
+
710
+ before(:all) do
711
+ class SecretAccount < Account; end
712
+
713
+ @account1 = Account.create!
714
+ @account2 = SecretAccount.create!
715
+ @account3 = Account.create!
716
+ @account4 = SecretAccount.create!
717
+
718
+ Note.create!(owner: @account1, text: 'one')
719
+ Note.create!(owner: @account2, text: 'two')
720
+ Note.create!(owner: @account3, text: 'three')
721
+ Note.create!(owner: @account4, text: 'four')
722
+ end
723
+
724
+ after(:all) do
725
+ # clenaup temp constant
726
+ Object.send(:remove_const, :SecretAccount) if Object.constants.include?(:SecretAccount)
727
+ end
728
+
729
+ it "finds correct record" do
730
+ params = {
731
+ relation: SecretAccount,
732
+ fields: [notes: [:text]],
733
+ text: 'one'
734
+ }
735
+ expect( described_class.prepare(params) ).to match_array []
736
+ end
737
+
738
+ it "finds correct record" do
739
+ params = {
740
+ relation: SecretAccount,
741
+ fields: [notes: [:text]],
742
+ text: 'two'
743
+ }
744
+ expect( described_class.prepare(params) ).to match_array [@account2]
745
+ end
746
+
747
+ it "finds correct record" do
748
+ params = {
749
+ relation: Account,
750
+ fields: [notes: [:text]],
751
+ text: 'two'
752
+ }
753
+ expect( described_class.prepare(params) ).to match_array [@account2]
754
+ end
755
+
756
+ it "finds correct record" do
757
+ params = {
758
+ relation: Account,
759
+ fields: [notes: [:text]],
760
+ text: 'one'
761
+ }
762
+ expect( described_class.prepare(params) ).to match_array [@account1]
763
+ end
764
+
765
+ end
766
+
767
+ describe "searching in localized attributes" do
768
+
769
+ with_model :Post, scope: :all do
770
+ model do
771
+ translates :title
772
+ globalize_accessors
773
+ end
774
+ end
775
+
776
+ with_model :PostTranslation, scope: :all do
777
+ table do |t|
778
+ t.integer Post.reflect_on_association(:translations).foreign_key
779
+ t.string :locale
780
+ t.string :title
781
+ end
782
+ end
783
+
784
+ before(:all) do
785
+ Post::Translation.send(:table_name=, PostTranslation.table_name)
786
+
787
+ @post1 = Post.create!(title_lv: 'bar', title_en: 'foo')
788
+ @post2 = Post.create!(title_lv: 'foo', title_en: 'bar')
789
+ @post3 = Post.create!(title_lv: 'foo', title_en: 'foo')
790
+ @post4 = Post.create!(title_lv: 'bar', title_en: 'bar')
791
+ end
792
+
793
+ context "when current locale is lv" do
794
+ before(:each) do
795
+ I18n.locale = 'lv'
796
+ end
797
+
798
+ after(:each) do
799
+ I18n.locale = 'en'
800
+ end
801
+
802
+ it "it searches in current locale only", focus: true do
803
+ params = {
804
+ relation: Post,
805
+ fields: [translations: [:title]],
806
+ text: 'foo'
807
+ }
808
+ expect( described_class.prepare(params) ).to match_array [@post2, @post3]
809
+ end
810
+ end
811
+
812
+ context "when current locale is en" do
813
+ it "it searches in current locale only", focus: true do
814
+ params = {
815
+ relation: Post,
816
+ fields: [translations: [:title]],
817
+ text: 'foo'
818
+ }
819
+ expect( described_class.prepare(params) ).to match_array [@post1, @post3]
820
+ end
821
+ end
822
+
823
+ end
824
+
825
+ end