releaf-core 0.2.1 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +19 -21
  3. data/app/assets/javascripts/releaf/application.js +1 -2
  4. data/app/assets/javascripts/releaf/include/field.type_date_or_datetime_or_time.js +19 -21
  5. data/app/assets/javascripts/releaf/include/field.type_richtext.js +31 -9
  6. data/app/assets/javascripts/releaf/include/localization.js +3 -8
  7. data/app/assets/javascripts/releaf/include/nested_fields.js +1 -1
  8. data/app/assets/javascripts/releaf/include/remote_validator.js +7 -4
  9. data/app/assets/javascripts/releaf/include/sortable.js +1 -1
  10. data/app/assets/javascripts/releaf/include/{profile_settings.js → store_settings.js} +4 -10
  11. data/app/assets/javascripts/releaf/include/toolbox.js +7 -11
  12. data/app/assets/stylesheets/releaf/layout/fields.scss +1 -0
  13. data/app/assets/stylesheets/releaf/layout/header.scss +1 -0
  14. data/app/assets/stylesheets/releaf/layout/search.scss +15 -0
  15. data/app/builders/releaf/builders/base.rb +11 -9
  16. data/app/builders/releaf/builders/confirm_destroy_dialog_builder.rb +2 -2
  17. data/app/builders/releaf/builders/confirm_dialog_builder.rb +3 -3
  18. data/app/builders/releaf/builders/edit_builder.rb +51 -6
  19. data/app/builders/releaf/builders/form_builder/associated_set_field.rb +37 -0
  20. data/app/builders/releaf/builders/form_builder/associations.rb +153 -0
  21. data/app/builders/releaf/builders/form_builder/boolean_fields.rb +12 -0
  22. data/app/builders/releaf/builders/form_builder/date_fields.rb +30 -0
  23. data/app/builders/releaf/builders/form_builder/fields.rb +10 -0
  24. data/app/builders/releaf/builders/form_builder/file_fields.rb +47 -0
  25. data/app/builders/releaf/builders/form_builder/i18n_fields.rb +75 -0
  26. data/app/builders/releaf/builders/form_builder/label.rb +34 -0
  27. data/app/builders/releaf/builders/form_builder/number_fields.rb +13 -0
  28. data/app/builders/releaf/builders/form_builder/richtext_fields.rb +28 -0
  29. data/app/builders/releaf/builders/form_builder/text_fields.rb +43 -0
  30. data/app/builders/releaf/builders/form_builder.rb +8 -489
  31. data/app/builders/releaf/builders/index_builder.rb +10 -3
  32. data/app/builders/releaf/builders/page/header_builder.rb +23 -59
  33. data/app/builders/releaf/builders/page/layout_builder.rb +125 -115
  34. data/app/builders/releaf/builders/page/menu_builder.rb +96 -106
  35. data/app/builders/releaf/builders/refused_destroy_dialog_builder.rb +7 -12
  36. data/app/builders/releaf/builders/resource_view.rb +4 -4
  37. data/app/builders/releaf/builders/table_builder.rb +20 -30
  38. data/app/builders/releaf/builders/toolbox_builder.rb +1 -1
  39. data/app/builders/releaf/builders/utilities/date_fields.rb +100 -0
  40. data/app/builders/releaf/builders/utilities/resolve_attribute_field_method_name.rb +80 -0
  41. data/app/builders/releaf/builders/view.rb +5 -2
  42. data/app/builders/releaf/settings/form_builder.rb +18 -0
  43. data/app/builders/releaf/settings/table_builder.rb +9 -0
  44. data/app/controllers/releaf/action_controller.rb +174 -0
  45. data/app/controllers/releaf/{core/errors_controller.rb → errors_controller.rb} +1 -1
  46. data/app/controllers/releaf/root_controller.rb +23 -0
  47. data/app/controllers/releaf/settings_controller.rb +22 -0
  48. data/app/helpers/releaf/application_helper.rb +1 -1
  49. data/app/lib/releaf/action_controller/ajax.rb +24 -0
  50. data/app/lib/releaf/action_controller/breadcrumbs.rb +26 -0
  51. data/app/lib/releaf/action_controller/builders.rb +34 -0
  52. data/app/lib/releaf/action_controller/features.rb +47 -0
  53. data/app/lib/releaf/action_controller/notifications.rb +28 -0
  54. data/app/lib/releaf/action_controller/resources.rb +59 -0
  55. data/app/{controllers/concerns/releaf → lib/releaf/action_controller}/richtext_attachments.rb +1 -1
  56. data/app/lib/releaf/action_controller/search.rb +22 -0
  57. data/app/lib/releaf/action_controller/urls.rb +49 -0
  58. data/app/lib/releaf/action_controller/views.rb +29 -0
  59. data/app/lib/releaf/assets_resolver.rb +51 -0
  60. data/app/lib/releaf/build_errors_hash.rb +81 -0
  61. data/app/lib/releaf/controller_definition.rb +22 -0
  62. data/app/lib/releaf/controller_group_definition.rb +12 -0
  63. data/app/lib/releaf/{core/default_searchable_fields.rb → default_searchable_fields.rb} +1 -1
  64. data/app/lib/releaf/{core/resource_base.rb → resource_base.rb} +14 -6
  65. data/app/lib/releaf/{core/resource_fields.rb → resource_fields.rb} +1 -1
  66. data/app/lib/releaf/{core/resource_params.rb → resource_params.rb} +3 -3
  67. data/app/lib/releaf/resource_table_fields.rb +10 -0
  68. data/app/lib/releaf/{core/resource_utilities.rb → resource_utilities.rb} +2 -2
  69. data/app/lib/releaf/{core/responders → responders}/access_denied_responder.rb +2 -2
  70. data/app/lib/releaf/{core/responders → responders}/after_save_responder.rb +3 -3
  71. data/app/lib/releaf/{core/responders → responders}/confirm_destroy_responder.rb +1 -1
  72. data/app/lib/releaf/{core/responders → responders}/destroy_responder.rb +1 -1
  73. data/app/lib/releaf/{core/responders → responders}/error_responder.rb +1 -1
  74. data/app/lib/releaf/{core/responders → responders}/feature_disabled_responder.rb +2 -2
  75. data/app/lib/releaf/{core/responders → responders}/page_not_found_responder.rb +2 -2
  76. data/app/lib/releaf/responders.rb +31 -0
  77. data/app/lib/releaf/{core/search.rb → search.rb} +1 -1
  78. data/app/lib/releaf/settings/normalize_value.rb +45 -0
  79. data/app/lib/releaf/settings/register.rb +45 -0
  80. data/app/models/releaf/settings.rb +25 -13
  81. data/app/services/array/reorder.rb +82 -0
  82. data/app/views/releaf/{base → action}/confirm_destroy.ruby +0 -0
  83. data/app/views/releaf/{base → action}/create_releaf_richtext_attachment.haml +0 -0
  84. data/app/views/releaf/{base → action}/edit.ruby +0 -0
  85. data/app/views/releaf/{base → action}/index.ruby +0 -0
  86. data/app/views/releaf/{base → action}/new.ruby +0 -0
  87. data/app/views/releaf/{base → action}/refused_destroy.ruby +0 -0
  88. data/app/views/releaf/{base → action}/show.ruby +0 -0
  89. data/app/views/releaf/{base → action}/toolbox.ruby +0 -0
  90. data/lib/generators/dummy/install_generator.rb +5 -0
  91. data/lib/generators/dummy/templates/assets/javascripts/controllers/admin/books.js +23 -0
  92. data/lib/generators/dummy/templates/assets/javascripts/controllers/admin/nodes.js +1 -0
  93. data/lib/generators/dummy/templates/assets/javascripts/controllers/admin/other_site/other_nodes.js +1 -0
  94. data/lib/generators/dummy/templates/assets/stylesheets/controllers/admin/nodes.scss +1 -0
  95. data/lib/generators/dummy/templates/assets/stylesheets/controllers/admin/other_site/other_nodes.scss +1 -0
  96. data/lib/generators/dummy/templates/builders/admin/books/form_builder.rb +11 -1
  97. data/lib/generators/dummy/templates/config/routes.rb +31 -7
  98. data/lib/generators/dummy/templates/controllers/admin/authors_controller.rb +3 -6
  99. data/lib/generators/dummy/templates/controllers/admin/books_controller.rb +1 -1
  100. data/lib/generators/dummy/templates/controllers/admin/chapters_controller.rb +1 -1
  101. data/lib/generators/dummy/templates/controllers/admin/nodes_controller.rb +3 -0
  102. data/lib/generators/dummy/templates/controllers/admin/other_site/other_nodes_controller.rb +3 -0
  103. data/lib/generators/dummy/templates/controllers/admin/publishers_controller.rb +1 -1
  104. data/lib/generators/dummy/templates/controllers/application_controller.rb +27 -5
  105. data/lib/generators/dummy/templates/controllers/concerns/node_controller.rb +13 -3
  106. data/lib/generators/dummy/templates/controllers/contacts_controller.rb +3 -1
  107. data/lib/generators/dummy/templates/initializers/releaf.rb +31 -25
  108. data/lib/generators/dummy/templates/migrations/create_home_pages.rb +1 -0
  109. data/lib/generators/dummy/templates/migrations/create_other_nodes.rb +29 -0
  110. data/lib/generators/dummy/templates/models/author.rb +2 -2
  111. data/lib/generators/dummy/templates/models/book.rb +0 -2
  112. data/lib/generators/dummy/templates/models/chapter.rb +0 -2
  113. data/lib/generators/dummy/templates/models/home_page.rb +1 -0
  114. data/lib/generators/dummy/templates/models/other_site/other_node.rb +7 -0
  115. data/lib/generators/dummy/templates/models/publisher.rb +0 -5
  116. data/lib/generators/dummy/templates/models/text_page.rb +0 -1
  117. data/lib/generators/dummy/templates/views/contacts/show.html.haml +1 -1
  118. data/lib/generators/dummy/templates/views/layouts/application.html.haml +9 -1
  119. data/lib/generators/dummy/templates/views/text_pages/show.haml +1 -1
  120. data/lib/generators/releaf/templates/initializers/releaf.rb +6 -17
  121. data/lib/generators/releaf/templates/migrations/create_releaf_translations.rb +13 -14
  122. data/lib/generators/releaf/templates/seeds/seeds.rb +28 -32
  123. data/lib/releaf/{core/application.rb → application.rb} +5 -4
  124. data/lib/releaf/{core/component.rb → component.rb} +6 -2
  125. data/lib/releaf/configuration.rb +95 -0
  126. data/lib/releaf/core_ext/array/reorder.rb +5 -0
  127. data/lib/releaf/engine.rb +12 -0
  128. data/lib/releaf/exceptions.rb +5 -0
  129. data/lib/releaf/instance_cache.rb +72 -0
  130. data/lib/releaf/{core → rails_ext}/validation_error_codes.rb +1 -1
  131. data/lib/releaf/root/configuration.rb +6 -0
  132. data/lib/releaf/root/default_controller_resolver.rb +37 -0
  133. data/lib/releaf/root/settings_manager.rb +12 -0
  134. data/lib/releaf/root.rb +17 -0
  135. data/lib/releaf/{core/route_mapper.rb → route_mapper.rb} +6 -6
  136. data/lib/releaf/service.rb +11 -0
  137. data/lib/releaf/settings_ui.rb +7 -0
  138. data/lib/releaf/version.rb +1 -1
  139. data/lib/releaf-core.rb +38 -9
  140. data/spec/builders/{builders → releaf/builders}/association_reflector_spec.rb +0 -0
  141. data/spec/builders/{builders → releaf/builders}/base_spec.rb +17 -21
  142. data/spec/builders/{builders → releaf/builders}/collection_spec.rb +0 -0
  143. data/spec/builders/{builders → releaf/builders}/confirm_destroy_dialog_builder_spec.rb +5 -5
  144. data/spec/builders/{builders → releaf/builders}/confirm_dialog_builder_spec.rb +9 -7
  145. data/spec/builders/{builders → releaf/builders}/edit_builder_spec.rb +127 -20
  146. data/spec/builders/releaf/builders/form_builder/associations_spec.rb +129 -0
  147. data/spec/builders/releaf/builders/form_builder/date_fields_spec.rb +86 -0
  148. data/spec/builders/releaf/builders/form_builder/i18n_fields_spec.rb +48 -0
  149. data/spec/builders/releaf/builders/form_builder/label_spec.rb +106 -0
  150. data/spec/builders/releaf/builders/form_builder/number_fields_spec.rb +37 -0
  151. data/spec/builders/releaf/builders/form_builder_spec.rb +228 -0
  152. data/spec/builders/{builders → releaf/builders}/index_builder_spec.rb +29 -10
  153. data/spec/builders/releaf/builders/page/header_builder_spec.rb +65 -0
  154. data/spec/builders/releaf/builders/page/layout_builder_spec.rb +170 -0
  155. data/spec/builders/releaf/builders/page/menu_builder_spec.rb +345 -0
  156. data/spec/builders/{builders → releaf/builders}/pagination_builder_spec.rb +0 -0
  157. data/spec/builders/{builders → releaf/builders}/resource_dialog_spec.rb +0 -0
  158. data/spec/builders/{builders → releaf/builders}/resource_view_spec.rb +8 -8
  159. data/spec/builders/{builders → releaf/builders}/show_builder_spec.rb +0 -0
  160. data/spec/builders/{builders → releaf/builders}/table_builder_spec.rb +31 -75
  161. data/spec/builders/{builders → releaf/builders}/template_spec.rb +0 -0
  162. data/spec/builders/{builders → releaf/builders}/toolbox_builder_spec.rb +4 -4
  163. data/spec/builders/{builders → releaf/builders}/toolbox_spec.rb +0 -0
  164. data/spec/builders/releaf/builders/utilities/date_fields_spec.rb +125 -0
  165. data/spec/builders/releaf/builders/utilities/resolve_attribute_field_method_name_spec.rb +318 -0
  166. data/spec/builders/{builders → releaf/builders}/view_spec.rb +1 -1
  167. data/spec/builders/{builders_spec.rb → releaf/builders_spec.rb} +0 -0
  168. data/spec/builders/releaf/settings/form_builder_spec.rb +48 -0
  169. data/spec/builders/{core → releaf}/settings/table_builder_spec.rb +6 -4
  170. data/spec/controllers/concerns/releaf/richtext_attachments_spec.rb +1 -1
  171. data/spec/controllers/releaf/{base_controller_spec.rb → action_controller_spec.rb} +132 -161
  172. data/spec/controllers/releaf/root_controller_spec.rb +40 -0
  173. data/spec/controllers/releaf/settings_controller_spec.rb +52 -0
  174. data/spec/error_hash_builder_spec.rb +83 -0
  175. data/spec/ext/array_reorder_spec.rb +12 -0
  176. data/spec/features/ajaxbox_spec.rb +6 -6
  177. data/spec/features/errors_spec.rb +2 -1
  178. data/spec/features/index_table_spec.rb +6 -3
  179. data/spec/features/richtext_attachments_spec.rb +2 -2
  180. data/spec/features/richtext_custom_config_spec.rb +28 -0
  181. data/spec/features/richtext_embed_spec.rb +1 -1
  182. data/spec/features/richtext_spec.rb +10 -1
  183. data/spec/features/search_spec.rb +1 -1
  184. data/spec/features/settings_spec.rb +10 -5
  185. data/spec/helpers/application_helper_spec.rb +4 -6
  186. data/spec/lib/releaf/action_controller/features_spec.rb +171 -0
  187. data/spec/lib/releaf/action_controller/search_spec.rb +84 -0
  188. data/spec/lib/releaf/{core/application_spec.rb → application_spec.rb} +7 -6
  189. data/spec/lib/releaf/assets_resolver_spec.rb +130 -0
  190. data/spec/lib/releaf/build_errors_hash_spec.rb +141 -0
  191. data/spec/lib/releaf/configuration_spec.rb +205 -0
  192. data/spec/lib/releaf/controller_definition_spec.rb +49 -0
  193. data/spec/lib/releaf/controller_group_definition_spec.rb +27 -0
  194. data/spec/lib/releaf/{core/default_searchable_fields_spec.rb → default_searchable_fields_spec.rb} +1 -1
  195. data/spec/lib/releaf/instance_cache_spec.rb +98 -0
  196. data/spec/lib/releaf/{core/resource_base_spec.rb → resource_base_spec.rb} +59 -21
  197. data/spec/lib/releaf/{core/resource_fields_spec.rb → resource_fields_spec.rb} +1 -1
  198. data/spec/lib/releaf/{core/resource_params_spec.rb → resource_params_spec.rb} +3 -5
  199. data/spec/lib/releaf/resource_table_fields_spec.rb +20 -0
  200. data/spec/lib/releaf/{core/resource_utilities_spec.rb → resource_utilities_spec.rb} +1 -1
  201. data/spec/lib/releaf/{core/responders → responders}/access_denied_responder_spec.rb +1 -1
  202. data/spec/lib/releaf/{core/responders → responders}/after_save_responder_spec.rb +9 -8
  203. data/spec/lib/releaf/{core/responders → responders}/confirm_destroy_responder_spec.rb +2 -2
  204. data/spec/lib/releaf/{core/responders → responders}/destroy_responder_spec.rb +2 -2
  205. data/spec/lib/releaf/{core/responders → responders}/error_responder_spec.rb +4 -4
  206. data/spec/lib/releaf/{core/responders → responders}/feature_disabled_responder_spec.rb +1 -1
  207. data/spec/lib/releaf/{core/responders → responders}/page_not_found_responder_spec.rb +1 -1
  208. data/spec/lib/releaf/{core/responders_spec.rb → responders_spec.rb} +14 -14
  209. data/spec/lib/releaf/root/configuration_spec.rb +9 -0
  210. data/spec/lib/releaf/root/default_controller_resolver_spec.rb +108 -0
  211. data/spec/lib/releaf/root_spec.rb +13 -0
  212. data/spec/lib/releaf/service_spec.rb +20 -0
  213. data/spec/lib/releaf/settings/normalize_value_spec.rb +103 -0
  214. data/spec/lib/releaf/settings/register_spec.rb +135 -0
  215. data/spec/lib/releaf/settings_manager_spec.rb +22 -0
  216. data/spec/lib/validation_error_codes_spec.rb +1 -1
  217. data/spec/misc/factories_spec.rb +0 -12
  218. data/spec/models/settings_spec.rb +74 -32
  219. data/spec/routing/route_mapper_spec.rb +5 -5
  220. data/spec/rspec_helpers/test_helpers_spec.rb +1 -1
  221. data/spec/rspec_helpers/test_spec.rb +14 -0
  222. data/spec/{lib/releaf/core/item_orderer_spec.rb → services/array/reorder_spec.rb} +32 -53
  223. metadata +299 -224
  224. data/app/builders/releaf/builders/orderer.rb +0 -5
  225. data/app/builders/releaf/builders/tags/releaf_associated_set_field.rb +0 -40
  226. data/app/builders/releaf/core/settings/form_builder.rb +0 -21
  227. data/app/builders/releaf/core/settings/table_builder.rb +0 -11
  228. data/app/controllers/concerns/releaf/breadcrumbs.rb +0 -42
  229. data/app/controllers/releaf/base_controller.rb +0 -458
  230. data/app/controllers/releaf/core/settings_controller.rb +0 -50
  231. data/app/helpers/releaf/javascript_helper.rb +0 -75
  232. data/app/lib/releaf/core/assets_resolver.rb +0 -58
  233. data/app/lib/releaf/core/error_formatter.rb +0 -103
  234. data/app/lib/releaf/core/item_orderer.rb +0 -102
  235. data/app/lib/releaf/core/resource_table_fields.rb +0 -10
  236. data/app/lib/releaf/core/responders.rb +0 -31
  237. data/app/lib/releaf/core/template_field_type_mapper.rb +0 -127
  238. data/lib/generators/dummy/templates/controllers/concerns/.keep +0 -0
  239. data/lib/releaf/core/builders_autoload.rb +0 -27
  240. data/lib/releaf/core/configuration.rb +0 -101
  241. data/lib/releaf/core/engine.rb +0 -35
  242. data/lib/releaf/core/exceptions.rb +0 -38
  243. data/lib/releaf/core/settings_ui_component.rb +0 -7
  244. data/releaf-core.gemspec +0 -35
  245. data/spec/builders/builders/form_builder_spec.rb +0 -562
  246. data/spec/builders/builders/orderer_spec.rb +0 -22
  247. data/spec/builders/builders/page/header_builder_spec.rb +0 -143
  248. data/spec/builders/builders/page/layout_builder_spec.rb +0 -73
  249. data/spec/builders/builders/page/menu_builder_spec.rb +0 -160
  250. data/spec/builders/core/settings/form_builder_spec.rb +0 -69
  251. data/spec/controllers/releaf/core/settings_controller_spec.rb +0 -31
  252. data/spec/lib/releaf/core/assets_resolver_spec.rb +0 -113
  253. data/spec/lib/releaf/core/configuration_spec.rb +0 -230
  254. data/spec/lib/releaf/core/error_formatter_spec.rb +0 -242
  255. data/spec/lib/releaf/core/resource_table_fields_spec.rb +0 -18
  256. data/spec/lib/releaf/core/template_field_type_mapper_spec.rb +0 -311
@@ -1,14 +1,22 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe Releaf::BaseController do
3
+ describe Releaf::ActionController do
4
4
  let(:new_resource){ Author.new }
5
5
  let(:resource){ create(:author) }
6
6
  let(:subject){ DummyController.new }
7
- class DummyController < Releaf::BaseController
7
+
8
+ module DummyControllerModule; end;
9
+
10
+ class DummyController < Releaf::ActionController
11
+ include DummyControllerModule
8
12
  def resource_class
9
13
  Author
10
14
  end
11
15
  end
16
+
17
+ class Dummy::ChildDummyController < DummyController; end;
18
+ class Dummy::GrandChildDummyController < Dummy::ChildDummyController; end;
19
+
12
20
  class FooFormBuilder; end
13
21
 
14
22
  describe "#action_views" do
@@ -22,33 +30,6 @@ describe Releaf::BaseController do
22
30
  end
23
31
  end
24
32
 
25
- describe "#action_features" do
26
- before do
27
- subject.setup
28
- end
29
-
30
- it "returns action > feature mapped hash" do
31
- expect(subject.action_features).to eq({
32
- index: :index,
33
- new: :create,
34
- create: :create,
35
- show: :edit,
36
- edit: :edit,
37
- update: :edit,
38
- confirm_destroy: :destroy,
39
- destroy: :destroy
40
- }.with_indifferent_access)
41
- end
42
-
43
- context "when `show` feature is available" do
44
- it "returns show > show feature mapping" do
45
- allow(subject).to receive(:feature_available?).and_call_original
46
- allow(subject).to receive(:feature_available?).with(:show).and_return(true)
47
- expect(subject.action_features[:show]).to eq(:show)
48
- end
49
- end
50
- end
51
-
52
33
  describe "#action_view" do
53
34
  context "when given view does not exists within action views hash" do
54
35
  it "returns given action" do
@@ -75,79 +56,88 @@ describe Releaf::BaseController do
75
56
  end
76
57
  end
77
58
 
78
- describe "#form_url" do
79
- context "when given resource is new record" do
80
- it "returns url for create method" do
81
- allow(subject).to receive(:url_for).with(action: 'create', id: nil).and_return("/res/new")
82
- expect(subject.form_url(:edit, new_resource)).to eq("/res/new")
59
+ describe "#page_title" do
60
+ before do
61
+ allow(Rails.application.class).to receive(:parent_name).and_return("DummyApp")
62
+ end
63
+
64
+ context "when controller definition exists" do
65
+ it "returns localized controller name from definitioned followed by application name" do
66
+ definition = Releaf::ControllerDefinition.new("xx")
67
+ allow(definition).to receive(:localized_name).and_return("Books")
68
+ allow(subject).to receive(:definition).and_return(definition)
69
+ expect(subject.page_title).to eq("Books - DummyApp")
83
70
  end
84
71
  end
85
72
 
86
- context "when given resource is existing record" do
87
- it "returns url for update method" do
88
- allow(subject).to receive(:url_for).with(action: 'update', id: resource.id).and_return("/res/edit/")
89
- expect(subject.form_url(:edit, resource)).to eq("/res/edit/")
73
+ context "when controller definition does not exist" do
74
+ it "returns only application name" do
75
+ allow(subject).to receive(:definition).and_return(nil)
76
+ expect(subject.page_title).to eq("DummyApp")
90
77
  end
91
78
  end
92
79
  end
93
80
 
94
- describe "#form_attributes" do
95
- it "returns basic releaf form attributes" do
96
- attributes = {
97
- multipart: true,
98
- novalidate: "",
99
- class: ["new-user"],
100
- id: "new-user",
101
- data: {
102
- "remote"=>true,
103
- "remote-validation"=>true,
104
- "type"=>:json
105
- }
106
- }
107
- expect(subject.form_attributes(:edit, new_resource, :user)).to eq(attributes)
81
+ describe "#builder_class" do
82
+ it "returns controller class scoped builder for given builder type" do
83
+ allow(subject).to receive(:builder_scopes).and_return(["a", "b"])
84
+ allow(Releaf::Builders).to receive(:builder_class).with(["a", "b"], :form).and_return("x")
85
+ expect(subject.builder_class(:form)).to eq("x")
108
86
  end
87
+ end
109
88
 
110
- it "changes class/id depending whether given object is persisted" do
111
- expect(subject.form_attributes(:edit, new_resource, :user)[:id]).to eq("new-user")
112
- expect(subject.form_attributes(:edit, new_resource, :user)[:class]).to eq(["new-user"])
89
+ describe "#short_name" do
90
+ it "returns undercored class name with Controller suffix removed" do
91
+ allow(subject).to receive(:class).and_return(Admin::BooksController)
92
+ expect(subject.short_name).to eq("admin/books")
93
+ end
94
+ end
113
95
 
114
- expect(subject.form_attributes(:edit, resource, :user)[:id]).to eq("edit-user")
115
- expect(subject.form_attributes(:edit, resource, :user)[:class]).to eq(["edit-user"])
96
+ describe "#definition" do
97
+ it "returns controller definition for controller short name" do
98
+ allow(Releaf::ControllerDefinition).to receive(:for).with("xxx").and_return("yyy")
99
+ allow(subject).to receive(:short_name).and_return("xxx")
100
+ expect(subject.definition).to eq("yyy")
116
101
  end
102
+ end
117
103
 
118
- it "adds has-error class if object has any errors" do
119
- resource.name = nil
120
- expect(resource.valid?).to be false
121
- expect(subject.form_attributes(:edit, resource, :user)[:class]).to eq(["edit-user", "has-error"])
104
+ describe "#builder_scopes" do
105
+ context "when controller is a direct child of Releaf::ActionController" do
106
+ it "returns an array with own and application builder scopes" do
107
+ allow(subject).to receive(:application_scope).and_return("xxx")
108
+ expect(subject.builder_scopes).to eq(["Dummy", "xxx"])
109
+ end
122
110
  end
123
111
 
112
+ context "when controller is a deeper descendant of Releaf::ActionController" do
113
+ let(:subject) { Dummy::GrandChildDummyController.new }
114
+ it "includes ancestor scopes up to but not including Releaf::ActionController" do
115
+ allow(subject).to receive(:application_scope).and_return("xxx")
116
+ expect(subject.class).to receive(:ancestor_controllers).and_call_original
117
+ expect(subject.builder_scopes).to eq(["Dummy::GrandChildDummy", "Dummy::ChildDummy", "Dummy", "xxx"])
118
+ end
119
+ end
124
120
  end
125
121
 
126
- describe "#builder_class" do
127
- it "returns controller class scoped builder for given builder type" do
128
- allow(subject).to receive(:builder_scopes).and_return(["a", "b"])
129
- allow(Releaf::Builders).to receive(:builder_class).with(["a", "b"], :form).and_return("x")
130
- expect(subject.builder_class(:form)).to eq("x")
122
+ describe ".own_builder_scope" do
123
+ it "returns controller class name without 'Controller'" do
124
+ expect(DummyController.own_builder_scope).to eq "Dummy"
131
125
  end
132
126
  end
133
127
 
134
- describe "#builder_scopes" do
135
- it "returns array with normalized controller class name scope and project builder scope" do
136
- allow(subject).to receive(:application_builder_scope).and_return("xxx")
137
- expect(subject.builder_scopes).to eq(["Dummy", "xxx"])
128
+ describe ".ancestor_controllers" do
129
+ it "return all ancestor controllers up to but not including Releaf::ActionController" do
130
+ expect(DummyController.ancestor_controllers).to eq []
131
+ expect(Dummy::GrandChildDummyController.ancestor_controllers).to eq([Dummy::ChildDummyController, DummyController])
138
132
  end
139
133
  end
140
134
 
141
- describe "#application_builder_scope" do
142
- it "returns node builder scope within releaf mount location scope" do
143
- allow(subject).to receive(:application_scope).and_return("Admin")
144
- expect(subject.application_builder_scope).to eq("Admin::Builders")
145
-
146
- allow(subject).to receive(:application_scope).and_return("")
147
- expect(subject.application_builder_scope).to eq("Builders")
135
+ describe ".ancestor_builder_scopes" do
136
+ it "return builder scopes for all ancestor controllers" do
137
+ allow(Dummy::ChildDummyController).to receive(:own_builder_scope).and_call_original
138
+ allow(DummyController).to receive(:own_builder_scope).and_call_original
148
139
 
149
- allow(subject).to receive(:application_scope).and_return(nil)
150
- expect(subject.application_builder_scope).to eq("Builders")
140
+ expect(Dummy::GrandChildDummyController.ancestor_builder_scopes).to eq(['Dummy::ChildDummy', 'Dummy'])
151
141
  end
152
142
  end
153
143
 
@@ -168,91 +158,89 @@ describe Releaf::BaseController do
168
158
  expect(subject.application_scope).to eq(nil)
169
159
  end
170
160
  end
171
-
172
- describe "#table_options" do
173
- it "returns table options" do
174
- allow(subject).to receive(:builder_class).with(:table).and_return("CustomTableBuilderClassHere")
175
- allow(subject).to receive(:feature_available?).with(:toolbox).and_return("boolean_value_here")
176
-
177
- options = {
178
- builder: "CustomTableBuilderClassHere",
179
- toolbox: "boolean_value_here"
180
- }
181
- expect(subject.table_options).to eq(options)
182
- end
183
- end
184
-
185
- describe "#form_options" do
186
- it "returns form options" do
187
- allow(subject).to receive(:builder_class).with(:form).and_return("CustomFormBuilderClassHere")
188
- allow(subject).to receive(:form_url).with(:delete, resource).and_return("/some-url-here")
189
- allow(subject).to receive(:form_attributes).with(:delete, resource, :author).and_return(some: "options_here")
190
-
191
- options = {
192
- builder: "CustomFormBuilderClassHere",
193
- as: :author,
194
- url: "/some-url-here",
195
- html: {some: "options_here"}
196
- }
197
- expect(subject.form_options(:delete, resource, :author)).to eq(options)
198
- end
199
- end
200
161
  end
201
162
 
202
- # use Admin::BooksController / Admin::AuthorsController as it inherit Releaf::BaseController and
163
+ # use Admin::BooksController / Admin::AuthorsController as it inherit Releaf::ActionController and
203
164
  # have no extra methods or overrides
204
165
  describe Admin::AuthorsController do
205
166
  before do
206
167
  sign_in FactoryGirl.create(:user)
207
168
  end
208
169
 
209
- describe "#index_url" do
170
+ describe "#index_path" do
210
171
  context "when action is other than :index" do
211
- context "when params have 'index_url' defined" do
212
- it "returns params 'index_url'" do
213
- url = "/admin/something?a=1&b=2"
214
- get :new, index_url: url
215
- expect(subject.index_url).to eq(url)
172
+ context "when params have valid `index_path` value" do
173
+ it "returns params 'index_path'" do
174
+ get :new, index_path: "xxxxxxxx"
175
+ allow(subject).to receive(:valid_index_path?).with("xxxxxxxx").and_return(true)
176
+ expect(subject.index_path).to eq("xxxxxxxx")
216
177
  end
217
178
  end
218
179
 
219
- context "when does not have 'index_url' defined" do
220
- it "returns index action url" do
221
- get :new
222
- expect(subject.index_url).to eq("http://test.host/admin/authors")
180
+ context "when params have invalid `index_path` value" do
181
+ it "returns index action path" do
182
+ get :new, index_path: "xxxxxxxx"
183
+ allow(subject).to receive(:valid_index_path?).with("xxxxxxxx").and_return(false)
184
+ expect(subject.index_path).to eq("/admin/authors")
223
185
  end
224
186
  end
225
187
  end
226
188
 
227
189
  context "when action is :index" do
228
- it "returns #current_url value" do
190
+ it "returns #current_path value" do
229
191
  get :index
230
- allow(subject).to receive(:current_url).and_return("random_string")
231
- expect(subject.index_url).to eq("random_string")
192
+ allow(subject).to receive(:current_path).and_return("random_string")
193
+ expect(subject.index_path).to eq("random_string")
194
+ end
195
+ end
196
+ end
197
+
198
+ describe "#valid_index_path?" do
199
+ context "when given value is string that starts with `/`" do
200
+ it "returns true" do
201
+ expect(subject.valid_index_path?("/admin/something?a=1&b=2")).to be true
202
+ end
203
+ end
204
+
205
+ context "when given value is string that starts with other char than `/`" do
206
+ it "returns false" do
207
+ expect(subject.valid_index_path?("http:///admin/something?a=1&b=2")).to be false
208
+ end
209
+ end
210
+
211
+ context "when given value is not string" do
212
+ it "returns false" do
213
+ expect(subject.valid_index_path?(123)).to be false
214
+ end
215
+ end
216
+
217
+ context "when given value is blank" do
218
+ it "returns false" do
219
+ expect(subject.valid_index_path?(nil)).to be false
232
220
  end
233
221
  end
234
222
  end
235
223
 
236
- describe "#current_url" do
224
+ describe "#current_path" do
237
225
  it "returns current url without `ajax` param" do
238
226
  get :index, ajax: 1, search: "something", page: 1
239
- expect(subject.current_url).to eq("/admin/authors?page=1&search=something")
227
+ expect(subject.current_path).to eq("/admin/authors?page=1&search=something")
240
228
  end
241
229
 
242
230
  context "when no query parameters exists" do
243
231
  it "returns only request path" do
244
232
  get :index
245
- expect(subject.current_url).to eq("/admin/authors")
233
+ expect(subject.current_path).to eq("/admin/authors")
246
234
  end
247
235
  end
248
236
 
249
237
  it "caches current url value" do
250
238
  get :index
251
239
  expect(subject).to receive(:request).twice.and_call_original
252
- subject.current_url
253
- subject.current_url
254
- subject.current_url
255
- subject.current_url
240
+ subject.current_path
241
+ subject.current_path
242
+ subject.current_path
243
+ subject.current_path
256
244
  end
257
245
  end
258
246
 
@@ -319,7 +307,7 @@ describe Admin::AuthorsController do
319
307
  end
320
308
  end
321
309
 
322
- context "when @resources_per_page is nil" do
310
+ context "when resources_per_page is nil" do
323
311
  it "assigns all resources to @collection" do
324
312
  get :index, show_all: 1
325
313
  expect(assigns(:collection).is_a?(ActiveRecord::Relation)).to be true
@@ -327,7 +315,7 @@ describe Admin::AuthorsController do
327
315
  end
328
316
  end
329
317
 
330
- context "when @resources_per_page is not nil" do
318
+ context "when resources_per_page is not nil" do
331
319
  it "assigns maximum 20 resources to @collection" do
332
320
  get :index
333
321
  expect(assigns(:collection).is_a?(ActiveRecord::Relation)).to be true
@@ -338,9 +326,9 @@ describe Admin::AuthorsController do
338
326
 
339
327
  describe "DELETE #destroy" do
340
328
  before do
341
- @author = FactoryGirl.create(:author)
342
- FactoryGirl.create(:book, title: "The book", author: @author)
343
- FactoryGirl.create(:book, title: "Almost the book", author: @author)
329
+ @author = FactoryGirl.create(:author)
330
+ FactoryGirl.create(:book, title: "The book", author: @author)
331
+ FactoryGirl.create(:book, title: "Almost the book", author: @author)
344
332
  end
345
333
 
346
334
  it "creates flash error with message" do
@@ -350,13 +338,11 @@ describe Admin::AuthorsController do
350
338
  end
351
339
  end
352
340
 
353
-
354
341
  describe Admin::BooksController do
355
342
  before do
356
343
  sign_in FactoryGirl.create(:user)
357
344
  @breadcrumbs_base = [
358
- {name: I18n.t('home', scope: 'admin.breadcrumbs'), url: releaf_root_path},
359
- {name: I18n.t('admin/books', scope: "admin.controllers"), url: admin_books_path},
345
+ {name: I18n.t('admin/books'), url: admin_books_path}
360
346
  ]
361
347
  end
362
348
 
@@ -399,17 +385,14 @@ describe Admin::BooksController do
399
385
  describe "GET #new" do
400
386
  it "assigns the requested record to @resource" do
401
387
  get :new
402
-
403
388
  expect(assigns(:resource).new_record?).to be true
404
389
  end
405
390
 
406
- context "when the requested record responds to #to_text" do
407
- it "uses the result of #to_text for resource's breadcrumb name" do
408
- get :new
409
- breadcrumbs = @breadcrumbs_base + [{name: "New record", url: new_admin_book_path}]
391
+ it "assigns special breadcrumb part for new record" do
392
+ get :new
393
+ breadcrumbs = @breadcrumbs_base + [{name: "New record", url: new_admin_book_path}]
410
394
 
411
- expect(assigns(:breadcrumbs)).to eq(breadcrumbs)
412
- end
395
+ expect(assigns(:breadcrumbs)).to eq(breadcrumbs)
413
396
  end
414
397
  end
415
398
 
@@ -424,24 +407,12 @@ describe Admin::BooksController do
424
407
  expect(assigns(:resource)).to eq(@resource)
425
408
  end
426
409
 
427
- context "when the requested record responds to #to_text" do
428
- it "uses the result of #to_text for resource's breadcrumb name" do
429
- get :edit, id: @resource
430
- breadcrumbs = @breadcrumbs_base + [{name: @resource.to_text, url: edit_admin_book_path(@resource.id)}]
431
-
432
- expect(assigns(:breadcrumbs)).to eq(breadcrumbs)
433
- end
434
- end
435
-
436
- context "when the requested record does not respond to #to_text" do
437
- it "uses default translation for resource's breadcrumb name" do
438
- skip "Find out way how to stub loaded resource #respond_to?(:to_text)"
439
- allow_any_instance_of(Book).to receive(:respond_to?).with(:to_text).and_return(false)
440
- get :edit, id: @resource
441
- breadcrumbs = @breadcrumbs_base + [{name: "Edit resource", url: edit_admin_book_path(@resource.id)}]
410
+ it "assigns breadcrumb for resource" do
411
+ allow(Releaf::ResourceBase).to receive(:title).with(@resource).and_return("xxx")
412
+ get :edit, id: @resource
413
+ breadcrumbs = @breadcrumbs_base + [{name: "xxx", url: edit_admin_book_path(@resource.id)}]
442
414
 
443
- expect(assigns(:breadcrumbs)).to eq(breadcrumbs)
444
- end
415
+ expect(assigns(:breadcrumbs)).to eq(breadcrumbs)
445
416
  end
446
417
  end
447
418
  end
@@ -0,0 +1,40 @@
1
+ require 'rails_helper'
2
+
3
+ describe Releaf::RootController do
4
+ login_as_user :user
5
+
6
+ describe "GET home" do
7
+ it "redirects to default controller resolver returned path authorized as user" do
8
+ allow(Releaf.application.config.root.default_controller_resolver).to receive(:call)
9
+ .with(current_controller: subject).and_return("_randompath_")
10
+ get :home
11
+ expect(response).to redirect_to("_randompath_")
12
+ end
13
+ end
14
+
15
+
16
+ describe "PUT settings" do
17
+ context 'when params[:settings] is not Hash' do
18
+ it "has a 422 status code" do
19
+ post :store_settings
20
+ expect(Releaf.application.config.settings_manager).to_not receive(:write)
21
+ expect(response.status).to eq(422)
22
+ end
23
+ end
24
+
25
+ context 'when params[:settings] is Hash' do
26
+ it "has a 200 status code" do
27
+ allow(Releaf.application.config.settings_manager).to receive(:write)
28
+ post :store_settings, settings: {dummy: 'maybe'}
29
+ expect(response.status).to eq(200)
30
+ end
31
+
32
+ it "saves given data within current user settings, casting true/false strings to boolean" do
33
+ expect(Releaf.application.config.settings_manager).to receive(:write).with(controller: subject, key: "dummy", value: "maybe")
34
+ expect(Releaf.application.config.settings_manager).to receive(:write).with(controller: subject, key: "be_true", value: true)
35
+ expect(Releaf.application.config.settings_manager).to receive(:write).with(controller: subject, key: "be_false", value: false)
36
+ post :store_settings, settings: {dummy: "maybe", be_true: 'true', be_false: 'false'}
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,52 @@
1
+ require 'rails_helper'
2
+
3
+ describe Releaf::SettingsController do
4
+ login_as_user :user
5
+
6
+ describe "GET index" do
7
+ login_as_user :user
8
+ it "lists only settings that not scoped to any object and exists within `Releaf::Settings.registry`" do
9
+ Releaf::Settings.destroy_all
10
+ Releaf::Settings.registry = {}
11
+
12
+ Releaf::Settings.create(var: "a", value: "1")
13
+ Releaf::Settings.create(var: "b", value: "2")
14
+ Releaf::Settings.create(var: "c", value: "2")
15
+ Releaf::Settings.create(var: "a", value: "3", thing_type: "User", thing_id: "1")
16
+
17
+ Releaf::Settings.register(key: "a", default: "x", description: "some setting")
18
+ Releaf::Settings.register(key: "b", default: "xxxx", description: "some other setting")
19
+
20
+ get :index
21
+ expect(assigns(:collection).size).to eq(2)
22
+ end
23
+ end
24
+
25
+ describe "PATCH update" do
26
+ login_as_user :user
27
+ it "updates settings object with normalized value" do
28
+ Releaf::Settings.destroy_all
29
+ Releaf::Settings.registry = {}
30
+ Releaf::Settings.register(key: "a", default: false, type: "boolean")
31
+
32
+ allow(Releaf::Settings::NormalizeValue).to receive(:call).
33
+ with(value: "1", input_type: :boolean).and_return(88)
34
+
35
+ patch :update, {id: Releaf::Settings.first.id, resource: {value: "1"}}
36
+ expect(Releaf::Settings.first.value).to eq(88)
37
+ end
38
+ end
39
+
40
+ describe "#features" do
41
+ it "has `index`, `search` and `edit` features" do
42
+ expect(subject.features).to eq([:index, :edit, :search])
43
+ end
44
+ end
45
+
46
+ describe "#resources" do
47
+ it "returns only registered settings ordered by `var`" do
48
+ allow(Releaf::Settings).to receive(:registered).and_return(:x)
49
+ expect(subject.resources).to eq(:x)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,83 @@
1
+ require 'rails_helper'
2
+ describe "Errors hash builder" do
3
+ class DummyResourceValidatorAuthor < Author
4
+ self.table_name = 'authors'
5
+ has_many :books, inverse_of: :author, class_name: :DummyResourceValidatorBook, foreign_key: :author_id
6
+ end
7
+
8
+ class DummyResourceValidatorBook < Book
9
+ self.table_name = 'books'
10
+ belongs_to :author, inverse_of: :books, class_name: :DummyResourceValidatorAuthor
11
+
12
+ validates_presence_of :author
13
+ accepts_nested_attributes_for :author
14
+ end
15
+
16
+ let(:resource) { DummyResourceValidatorBook.new }
17
+ let(:error){ ActiveModel::ErrorMessage.new("blank value", :blank) }
18
+
19
+ subject do
20
+ Releaf::BuildErrorsHash.new(resource: resource, field_name_prefix: :resource)
21
+ end
22
+
23
+ describe "#format_errors" do
24
+ it "adds error to errors" do
25
+ expected_result = {
26
+ "resource[title]" => [
27
+ {error_code: :blank, message: "can't be blank"},
28
+ {error_code: :invalid, message: "test error"},
29
+ ],
30
+ "resource[author_id]" => [
31
+ {error_code: :blank, message: "can't be blank"},
32
+ {error_code: :invalid, message: "Invalid author"}
33
+ ],
34
+ "resource" => [
35
+ {error_code: :invalid, message: "error on base"}
36
+ ]
37
+ }
38
+ resource.valid?
39
+ resource.chapters.new(id: 12)
40
+ resource.chapters.new(title: 'test')
41
+ resource.errors.add(:base, 'error on base')
42
+ resource.errors.add(:title, "test error")
43
+ resource.errors.add(:author_id, "Invalid author")
44
+ expect(subject.call).to eq(expected_result)
45
+
46
+ resource.title = "xxx"
47
+ resource.build_author
48
+ resource.valid?
49
+
50
+ expected_result = {
51
+ "resource[chapters_attributes][0][title]" => [
52
+ {error_code: :blank, message: "can't be blank"},
53
+ {error_code: :blank, message: "can't be blank"},
54
+ {error_code: :blank, message: "can't be blank"}
55
+ ],
56
+ "resource[chapters_attributes][0][text]" => [
57
+ {error_code: :blank, message: "can't be blank"},
58
+ {error_code: :blank, message: "can't be blank"},
59
+ {error_code: :blank, message: "can't be blank"}
60
+ ],
61
+ "resource[chapters_attributes][0][sample_html]" => [
62
+ {error_code: :blank, message: "can't be blank"},
63
+ {error_code: :blank, message: "can't be blank"},
64
+ {error_code: :blank, message: "can't be blank"}
65
+ ],
66
+ "resource[chapters_attributes][1][text]" => [
67
+ {error_code: :blank, message: "can't be blank"},
68
+ {error_code: :blank, message: "can't be blank"},
69
+ {error_code: :blank, message: "can't be blank"}
70
+ ],
71
+ "resource[chapters_attributes][1][sample_html]" => [
72
+ {error_code: :blank, message: "can't be blank"},
73
+ {error_code: :blank, message: "can't be blank"},
74
+ {error_code: :blank, message: "can't be blank"}
75
+ ],
76
+ "resource[author_attributes][name]" => [
77
+ {error_code: :blank, message: "can't be blank"}
78
+ ]
79
+ }
80
+ expect(subject.call).to eq(expected_result)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,12 @@
1
+ require "rails_helper"
2
+
3
+ describe Array do
4
+ let(:subject){ [:a, :b, :c] }
5
+
6
+ describe "#reorder" do
7
+ it "return reordered result for given options from `Array::Reorder` service" do
8
+ expect(Array::Reorder).to receive(:call).with(array: subject, values: :b, options: :last).and_call_original
9
+ expect(subject.reorder(:b, :last)).to eq([:a, :c, :b])
10
+ end
11
+ end
12
+ end