releaf-core 0.2.1 → 1.0.3

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 (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
@@ -0,0 +1,141 @@
1
+ require 'rails_helper'
2
+
3
+ describe Releaf::BuildErrorsHash do
4
+ let(:resource) { Book.new }
5
+ let(:error){ ActiveModel::ErrorMessage.new("blank value", :blank) }
6
+
7
+ subject do
8
+ described_class.new(resource: resource, field_name_prefix: :resource)
9
+ end
10
+
11
+ describe "#call" do
12
+ it "returns hash with merged errors" do
13
+ allow(subject).to receive(:errors).and_return([
14
+ {
15
+ field_name: "name",
16
+ message: "error blank",
17
+ error_code: :blank,
18
+ },
19
+ {
20
+ field_name: "name",
21
+ message: "invalid format",
22
+ error_code: :invalid_format,
23
+ },
24
+ {
25
+ field_name: "surname",
26
+ message: "error blank",
27
+ error_code: :blank,
28
+ },
29
+ ])
30
+ expect(subject.call).to eq(
31
+ "name" => [{message: "error blank", error_code: :blank}, {message: "invalid format", error_code: :invalid_format}],
32
+ "surname" => [{message: "error blank", error_code: :blank}]
33
+ )
34
+ end
35
+ end
36
+
37
+ describe "#errors" do
38
+ it "returns flattened errors array" do
39
+ allow(resource).to receive(:errors).and_return(name: "er1", surname: "er2", role: "er3")
40
+ allow(subject).to receive(:format_error).with(:name, "er1").and_return("error1")
41
+ allow(subject).to receive(:format_error).with(:surname, "er2").and_return("error2")
42
+ allow(subject).to receive(:format_error).with(:role, "er3").and_return(["error3", "error4"])
43
+ expect(subject.errors).to eq(["error1", "error2", "error3", "error4"])
44
+ end
45
+ end
46
+
47
+ describe "#format_error" do
48
+ before do
49
+ allow(subject).to receive(:attribute_error).with(:name, "er1").and_return("error1")
50
+ allow(subject).to receive(:nested_attribute_errors).with(:name).and_return(["error1", "error2"])
51
+ end
52
+
53
+ context "when resource attribute given" do
54
+ it "returns attribute error" do
55
+ allow(subject).to receive(:resource_attribute?).and_return(true)
56
+ expect(subject.format_error(:name, "er1")).to eq("error1")
57
+ end
58
+ end
59
+
60
+ context "when nested attribute given" do
61
+ it "returns nested attribute errors" do
62
+ allow(subject).to receive(:resource_attribute?).and_return(false)
63
+ expect(subject.format_error(:name, "er1")).to eq(["error1", "error2"])
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "#attribute_error" do
69
+ it "returns attribute error hash" do
70
+ allow(subject).to receive(:field_name).with(:name).and_return("xxx_name")
71
+ expect(subject.format_error(:name, error)).to eq(field_name: "xxx_name", error_code: :blank, message: "blank value")
72
+ end
73
+ end
74
+
75
+ describe "#single_association?" do
76
+ context "for :belongs_to association" do
77
+ it "returns true" do
78
+ expect( subject.single_association?('author') ).to be true
79
+ end
80
+ end
81
+
82
+ context "for :has_many association" do
83
+ it "returns false" do
84
+ expect( subject.single_association?('chapters') ).to be false
85
+ end
86
+ end
87
+
88
+ context "for :has_one association" do
89
+ it "returns true" do
90
+ allow(subject).to receive(:association_type).with('author').and_return(:has_one)
91
+ expect( subject.single_association?('author') ).to be true
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "#association" do
97
+ it "returns active record reflection of association" do
98
+ expect( subject.send(:association, 'author') ).to eq Book.reflect_on_association(:author)
99
+ end
100
+ end
101
+
102
+ describe "#association_type" do
103
+ it "returns active record reflection macro" do
104
+ expect( subject.association_type('author') ).to eq :belongs_to
105
+ end
106
+ end
107
+
108
+ describe "#resource_attribute?" do
109
+ context "when attribute name contains dot" do
110
+ it "returns false" do
111
+ expect( subject.resource_attribute?('test.attribute') ).to be false
112
+ end
113
+ end
114
+
115
+ context "when attribute name doesn't contain dot" do
116
+ it "returns true" do
117
+ expect( subject.resource_attribute?('test') ).to be true
118
+ end
119
+ end
120
+ end
121
+
122
+ describe "#field_name" do
123
+ context "when error is on base" do
124
+ it "returns resource field_id" do
125
+ expect( subject.field_name('base')).to eq 'resource'
126
+ end
127
+ end
128
+
129
+ context "when attribute is association" do
130
+ it "returns field_id for associations foreign key" do
131
+ expect( subject.field_name('author')).to eq 'resource[author_id]'
132
+ end
133
+ end
134
+
135
+ context "when attribute is not association" do
136
+ it "returns field_id for field" do
137
+ expect( subject.field_name('title')).to eq 'resource[title]'
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,205 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::Configuration do
4
+ class DummyComponentA
5
+ def self.configure_component; end
6
+ end
7
+ class DummyComponentB
8
+ def self.initialize_component; end
9
+ end
10
+ class DummyComponentC
11
+ def self.initialize_component; end
12
+ def self.configure_component; end
13
+ end
14
+
15
+ describe "#components=" do
16
+ before do
17
+ allow(subject).to receive(:flatten_components).with(["x", "s"])
18
+ .and_return([DummyComponentA, DummyComponentB, DummyComponentC])
19
+ end
20
+
21
+ it "assigns normalized components" do
22
+ expect{ subject.components = ["x", "s"] }.to change{ subject.components }.to([DummyComponentA, DummyComponentB, DummyComponentC])
23
+ end
24
+
25
+ it "calls component configuration if available" do
26
+ expect(DummyComponentA).to receive(:configure_component).ordered
27
+ expect(DummyComponentC).to receive(:configure_component).ordered
28
+ subject.components = ["x", "s"]
29
+ end
30
+ end
31
+
32
+ describe "#initialize_components" do
33
+ it "adds component configuration and calls component initializing method if available" do
34
+ allow(subject).to receive(:components).and_return([DummyComponentA, DummyComponentB, DummyComponentC])
35
+ expect(DummyComponentB).to receive(:initialize_component).ordered
36
+ expect(DummyComponentC).to receive(:initialize_component).ordered
37
+ subject.initialize_components
38
+ end
39
+ end
40
+
41
+ describe "#add_configuration" do
42
+ it "creates configuration class accessor for given configuration instance, and assigns given instance to it" do
43
+ class Releaf::Configuration::DummySampleConfiguration; end
44
+ configuration = Releaf::Configuration::DummySampleConfiguration.new
45
+
46
+ expect(subject.respond_to?(:dummy_sample)).to be false
47
+ subject.add_configuration(configuration)
48
+
49
+ expect(subject.respond_to?(:dummy_sample)).to be true
50
+ expect(subject.dummy_sample).to eq(configuration)
51
+ end
52
+ end
53
+
54
+ describe "#initialize_locales" do
55
+ before do
56
+ subject.available_locales = [:a, :b]
57
+ subject.available_admin_locales = [:b, :c]
58
+ allow(::I18n).to receive(:available_locales=)
59
+ end
60
+
61
+ it "assigns available locales to `I18n.available_locales`" do
62
+ expect(::I18n).to receive(:available_locales=).with([:a, :b])
63
+ subject.initialize_locales
64
+ end
65
+
66
+ context "when no `available_admin_locales` defined" do
67
+ it "overwrites it with available locales" do
68
+ expect{ subject.initialize_locales }.to_not change{ subject.available_admin_locales }
69
+
70
+ subject.available_admin_locales = nil
71
+ expect{ subject.initialize_locales }.to change{ subject.available_admin_locales }.to eq([:a, :b])
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "#all_locales" do
77
+ before do
78
+ subject.available_locales = [:a, :b]
79
+ subject.available_admin_locales = [:b, :c]
80
+ end
81
+
82
+ it "merges unique locales form admin and available locales, casts it to strings and assign to `all_locales`" do
83
+ expect( subject.all_locales ).to eq(["a", "b", "c"])
84
+ end
85
+
86
+ it "caches resolved locales" do
87
+ expect(subject).to receive(:available_locales).and_call_original.once
88
+ expect(subject).to receive(:available_admin_locales).and_call_original.once
89
+ subject.all_locales
90
+ subject.all_locales
91
+ end
92
+ end
93
+
94
+ describe "#flatten_components" do
95
+ it "returns recursively flattened component list" do
96
+ class DummyComponentA; end
97
+ class DummyComponentB
98
+ def self.components
99
+ ["o", "p"]
100
+ end
101
+ end
102
+
103
+ allow(subject).to receive(:flatten_components).and_call_original
104
+ allow(subject).to receive(:flatten_components).with(["o", "p"]).and_return(["x", "y"])
105
+ expect(subject.flatten_components([DummyComponentA, DummyComponentB])).to eq([DummyComponentA, "x", "y", DummyComponentB])
106
+ end
107
+ end
108
+
109
+ describe "#menu=" do
110
+ it "normalizes menu before assigning" do
111
+ allow(described_class).to receive(:normalize_controllers).with(["a"]).and_return(["aa"])
112
+ expect{ subject.menu = ["a"] }.to change{ subject.menu }.to(["aa"])
113
+ end
114
+ end
115
+
116
+ describe "#additional_controllers=" do
117
+ it "normalizes additional controllers before assigning" do
118
+ allow(described_class).to receive(:normalize_controllers).with(["b"]).and_return(["bb"])
119
+ expect{ subject.additional_controllers = ["b"] }.to change{ subject.additional_controllers }.to(["bb"])
120
+ end
121
+ end
122
+
123
+ describe "#controllers" do
124
+ it "returns extracted controllers from menu and additional controllers attributes" do
125
+ allow(subject).to receive(:menu).and_return(["a", "b"])
126
+ allow(subject).to receive(:additional_controllers).and_return(["c", "d"])
127
+ allow(subject).to receive(:extract_controllers).with(["a", "b", "c", "d"]).and_return("xxx")
128
+ expect( subject.controllers ).to eq("xxx")
129
+ end
130
+
131
+ it "caches resolved controllers" do
132
+ expect(subject).to receive(:extract_controllers).and_call_original.once
133
+ subject.controllers
134
+ subject.controllers
135
+ end
136
+ end
137
+
138
+ describe "#available_controllers" do
139
+ before do
140
+ allow(subject).to receive(:controllers).and_return("c" => "d", "l" => "k")
141
+ end
142
+
143
+ it "returns controller names" do
144
+ expect( subject.available_controllers ).to eq(["c", "l"])
145
+ end
146
+
147
+ it "caches resolved controller names" do
148
+ expect(subject).to receive(:controllers).and_call_original.once
149
+ subject.available_controllers
150
+ subject.available_controllers
151
+ end
152
+ end
153
+
154
+ describe "#extract_controllers" do
155
+ it "returns recursively built hash with controllers from given array" do
156
+ item_1 = Releaf::ControllerDefinition.new(name: "aa", controller: :a)
157
+ item_2 = Releaf::ControllerDefinition.new(name: "bb", controller: :b)
158
+ item_3 = Releaf::ControllerDefinition.new(name: "cc", controller: :c)
159
+ item_4 = Releaf::ControllerDefinition.new(name: "dd", controller: :d)
160
+ item_5 = Releaf::ControllerDefinition.new(name: "ff", controller: :f)
161
+
162
+ group_item_1 = Releaf::ControllerGroupDefinition.new(name: "x", items: [])
163
+ group_item_2 = Releaf::ControllerGroupDefinition.new(name: "y", items: [])
164
+ allow(group_item_1).to receive(:controllers).and_return([item_3, item_4])
165
+ allow(group_item_2).to receive(:controllers).and_return([item_5])
166
+
167
+ list = [item_1, group_item_1, group_item_2, item_2]
168
+ result = {a: item_1, b: item_2, c: item_3, d: item_4, f: item_5}
169
+ expect(subject.extract_controllers(list)).to eq(result)
170
+ end
171
+ end
172
+
173
+ describe ".normalize_controllers" do
174
+ it "returns list of normalized controllers" do
175
+ item_1 = Releaf::ControllerDefinition.new(name: "aa", controller: :a)
176
+ item_2 = Releaf::ControllerDefinition.new(name: "bb", controller: :b)
177
+ item_3 = Releaf::ControllerDefinition.new(name: "cc", controller: :c)
178
+
179
+ group_item_1 = Releaf::ControllerGroupDefinition.new(name: "x", items: [])
180
+ group_item_2 = Releaf::ControllerGroupDefinition.new(name: "y", items: [])
181
+
182
+ allow(Releaf::ControllerGroupDefinition).to receive(:new).with(items: "x").and_return(group_item_2)
183
+ allow(Releaf::ControllerDefinition).to receive(:new).with(name: "y").and_return(item_2)
184
+ allow(Releaf::ControllerDefinition).to receive(:new).with("z").and_return(item_3)
185
+
186
+ list = [
187
+ item_1,
188
+ group_item_1,
189
+ {items: "x"},
190
+ {name: "y"},
191
+ "z"
192
+ ]
193
+
194
+ result = [
195
+ item_1,
196
+ group_item_1,
197
+ group_item_2,
198
+ item_2,
199
+ item_3
200
+ ]
201
+
202
+ expect(described_class.normalize_controllers(list)).to eq(result)
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,49 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::ControllerDefinition do
4
+ subject{ described_class.new(name: "op", controller: "admin/books") }
5
+
6
+ describe ".for" do
7
+ it "returns definition from applicaiton controller config for given controller name" do
8
+ allow(Releaf.application.config).to receive(:controllers).and_return("xxx" => "yyy")
9
+ expect(described_class.for("xxx")).to eq("yyy")
10
+ end
11
+ end
12
+
13
+ describe "#initialize" do
14
+ it "assigns `name` option value" do
15
+ expect(subject.name).to eq("op")
16
+ end
17
+
18
+ it "assigns `controller` option value to `controller_name`" do
19
+ expect(subject.controller_name).to eq("admin/books")
20
+ end
21
+
22
+ context "when no `name` option value given" do
23
+ it "takes `controller` option value as `name` value" do
24
+ subject = described_class.new(controller: "admin/books")
25
+ expect(subject.name).to eq("admin/books")
26
+ end
27
+ end
28
+
29
+ context "when string passed instead of Hash" do
30
+ it "takes string as controller option value" do
31
+ subject = described_class.new("admin/authors")
32
+ expect(subject.controller_name).to eq("admin/authors")
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#localized_name" do
38
+ it "returns localized name" do
39
+ allow(I18n).to receive(:t).with("op", scope: "admin.controllers").and_return("poiugasd")
40
+ expect(subject.localized_name).to eq("poiugasd")
41
+ end
42
+ end
43
+
44
+ describe "#path" do
45
+ it "returns controller index path" do
46
+ expect(subject.path).to eq("/admin/books")
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,27 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::ControllerGroupDefinition do
4
+ subject{ described_class.new(name: "xxx", items: [:a, :b]) }
5
+
6
+ before do
7
+ allow(Releaf::ControllerDefinition).to receive(:new).with(:a).and_return("c_a")
8
+ allow(Releaf::ControllerDefinition).to receive(:new).with(:b).and_return("c_b")
9
+ end
10
+
11
+ describe "#initialize" do
12
+ it "assigns `name` option value" do
13
+ expect(subject.name).to eq("xxx")
14
+ end
15
+
16
+ it "assigns array with initialized `Releaf::ControllerDefinition` items built from `items` option value" do
17
+ expect(subject.controllers).to eq(["c_a", "c_b"])
18
+ end
19
+ end
20
+
21
+ describe "#localized_name" do
22
+ it "returns localized name" do
23
+ allow(I18n).to receive(:t).with("xxx", scope: "admin.controllers").and_return("poiugasd")
24
+ expect(subject.localized_name).to eq("poiugasd")
25
+ end
26
+ end
27
+ end
@@ -1,6 +1,6 @@
1
1
  require "rails_helper"
2
2
 
3
- describe Releaf::Core::DefaultSearchableFields do
3
+ describe Releaf::DefaultSearchableFields do
4
4
  # emulate klass::Translations
5
5
  with_model :SearchableObjectTranslations, scope: :all do
6
6
  table do |t|
@@ -0,0 +1,98 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::InstanceCache, type: :class do
4
+ class InstanceCacheIncluder
5
+ include Releaf::InstanceCache
6
+ cache_instance_methods :some_value, :another_value
7
+ cache_instance_method :one_more_another_value
8
+
9
+ def calculated_value
10
+ instance_cache(:calculated_value) do
11
+ some_value
12
+ end
13
+ end
14
+
15
+ def some_value
16
+ 1 + 2
17
+ end
18
+
19
+ def another_value
20
+ "xx"
21
+ end
22
+
23
+ def one_more_another_value
24
+ "yy"
25
+ end
26
+ end
27
+
28
+ subject{ InstanceCacheIncluder.new }
29
+
30
+ it "keeps previously defined `method_added` method" do
31
+ class InstanceCacheIncluder2
32
+ cattr_accessor :test_value
33
+
34
+ def self.method_added(method_name)
35
+ self.test_value = method_name if method_name == :some_value
36
+ end
37
+ include Releaf::InstanceCache
38
+ cache_instance_method :some_value
39
+
40
+ def some_value
41
+ :xx
42
+ end
43
+ end
44
+
45
+ subject = InstanceCacheIncluder2.new
46
+ expect(InstanceCacheIncluder2.test_value).to eq(:some_value)
47
+ allow(subject).to receive(:instance_cache_original_some_value).and_return(:yyy).once
48
+ expect(subject.some_value).to eq(:yyy)
49
+ subject.some_value
50
+ end
51
+
52
+ describe ".instance_cache_original_method_name" do
53
+ it "returns name of uncached original method name" do
54
+ expect(subject.class.instance_cache_original_method_name(:some_method)).to eq("instance_cache_original_some_method")
55
+ end
56
+ end
57
+
58
+ describe "#instance_cache" do
59
+ it "stores block value to instance cache store" do
60
+ expect{ subject.calculated_value }.to change{ subject.instance_cache_store[:calculated_value] }.to(3)
61
+ end
62
+
63
+ it "returns returns value when caching happen" do
64
+ expect(subject.calculated_value).to eq(3)
65
+ end
66
+
67
+ it "returns cached value when called second time" do
68
+ subject.calculated_value
69
+ expect(subject.calculated_value).to eq(3)
70
+ end
71
+
72
+ it "does not evaluate block twice when called second time" do
73
+ expect(subject).to receive(:some_value).and_call_original.once
74
+ subject.calculated_value
75
+ subject.calculated_value
76
+ end
77
+ end
78
+
79
+ describe "#reset_instance_cache" do
80
+ it "assigns empty hash to instance hash store" do
81
+ subject.instance_cache_store[:x] = 1
82
+ expect{ subject.reset_instance_cache }.to change{ subject.instance_cache_store }.from(x: 1).to({})
83
+ end
84
+ end
85
+
86
+ describe ".cache_instance_methods" do
87
+ it "adds cache wrapper for all given methods" do
88
+ expect(subject.class.cached_instance_methods).to eq([:some_value, :another_value, :one_more_another_value])
89
+
90
+ allow(subject).to receive(:instance_cache_original_another_value).and_return("xxx").once
91
+ expect(subject).to receive(:instance_cache) do|x, &block|
92
+ expect(block.call).to eq("xxx")
93
+ end.and_return("yyy")
94
+
95
+ expect(subject.another_value).to eq("yyy")
96
+ end
97
+ end
98
+ end
@@ -1,6 +1,6 @@
1
1
  require "rails_helper"
2
2
 
3
- describe Releaf::Core::ResourceBase do
3
+ describe Releaf::ResourceBase do
4
4
  subject{ described_class.new(Book) }
5
5
 
6
6
  describe "#initialize" do
@@ -31,9 +31,28 @@ describe Releaf::Core::ResourceBase do
31
31
  end
32
32
 
33
33
  describe "#localized_attributes" do
34
- it "returns array of all localized attributes params" do
34
+ before do
35
35
  allow(subject.resource_class).to receive(:translated_attribute_names).and_return([:title, :summary])
36
- expect(subject.localized_attributes).to eq(["title", "summary"])
36
+ end
37
+
38
+ it "caches returned result" do
39
+ expect(subject).to receive(:localized_attributes?).and_return(true).once
40
+ subject.localized_attributes
41
+ subject.localized_attributes
42
+ end
43
+
44
+ context "when resource has localized attributes" do
45
+ it "returns array of all localized attributes params" do
46
+ allow(subject).to receive(:localized_attributes?).and_return(true)
47
+ expect(subject.localized_attributes).to eq(["title", "summary"])
48
+ end
49
+ end
50
+
51
+ context "when resource has no localized attributes" do
52
+ it "returns empty array" do
53
+ allow(subject).to receive(:localized_attributes?).and_return(false)
54
+ expect(subject.localized_attributes).to eq([])
55
+ end
37
56
  end
38
57
  end
39
58
 
@@ -75,36 +94,29 @@ describe Releaf::Core::ResourceBase do
75
94
  before do
76
95
  allow(subject).to receive(:associations_attributes).and_return(["x", "y"])
77
96
  allow(subject).to receive(:base_attributes).and_return(["a", "b"])
78
- allow(subject).to receive(:localized_attributes?).and_return(false)
97
+ allow(subject).to receive(:localized_attributes).and_return(["c", "d"])
79
98
  end
80
99
 
81
- it "returns resource params array alongside associations params" do
82
- expect(subject.values).to eq(["a", "b", "x", "y"])
100
+ it "returns resource base and localized attributes array alongside associations params" do
101
+ expect(subject.values).to eq(["a", "b", "c", "d", "x", "y"])
83
102
  end
84
103
 
85
- context "when `include_associations` is false" do
86
- it "does not include association params" do
87
- expect(subject.values(include_associations: false)).to eq(["a", "b"])
88
- end
104
+ it "excludes all excludable base and localized attributes from returned array" do
105
+ allow(subject).to receive(:excluded_attributes).and_return(["a", "d", "x"])
106
+ expect(subject.values).to eq(["b", "c", "x", "y"])
89
107
  end
90
108
 
91
- context "when resource has localized attributes" do
92
- it "returns resource base attributes array alongside localized attributes" do
93
- allow(subject).to receive(:localized_attributes?).and_return(true)
94
- allow(subject).to receive(:localized_attributes).and_return(["c", "d"])
95
- expect(subject.values).to eq(["a", "b", "c", "d", "x", "y"])
109
+ context "when `include_associations` is false" do
110
+ it "does not include association params" do
111
+ expect(subject.values(include_associations: false)).to eq(["a", "b", "c", "d"])
96
112
  end
97
113
  end
98
114
  end
99
115
 
100
116
  describe "#base_attributes" do
101
- it "returns array with non-excluded attributes" do
117
+ it "returns array of resource columns" do
102
118
  allow(subject.resource_class).to receive(:column_names).and_return(["a", "b", "c"])
103
- allow(subject).to receive(:excluded_attributes).and_return(["a"])
104
- expect(subject.base_attributes).to eq(["b", "c"])
105
-
106
- allow(subject).to receive(:excluded_attributes).and_return(["c"])
107
- expect(subject.base_attributes).to eq(["a", "b"])
119
+ expect(subject.base_attributes).to eq(["a", "b", "c"])
108
120
  end
109
121
  end
110
122
 
@@ -171,4 +183,30 @@ describe Releaf::Core::ResourceBase do
171
183
  expect(subject.excluded_associations).to eq([:translations])
172
184
  end
173
185
  end
186
+
187
+ describe ".title" do
188
+ let(:resource){ Releaf::Permissions::User.new(name: "a", surname: "b") }
189
+ it "tries all `title_methods` methods and returns first existing method result" do
190
+ allow(described_class).to receive(:title_methods).and_return([:to_s, :id, :releaf_title])
191
+ allow(resource).to receive(:to_s).and_return("x")
192
+ allow(resource).to receive(:id).and_return("zz")
193
+ allow(resource).to receive(:releaf_title).and_return("yy")
194
+
195
+ allow(resource).to receive(:respond_to?).with(:to_s).and_return(false)
196
+ allow(resource).to receive(:respond_to?).with(:id).and_return(false)
197
+ allow(resource).to receive(:respond_to?).with(:releaf_title).and_return(true)
198
+ expect(described_class.title(resource)).to eq("yy")
199
+
200
+ allow(resource).to receive(:respond_to?).with(:to_s).and_return(false)
201
+ allow(resource).to receive(:respond_to?).with(:id).and_return(true)
202
+ expect(resource).to_not receive(:respond_to?).with(:releaf_title)
203
+ expect(described_class.title(resource)).to eq("zz")
204
+ end
205
+ end
206
+
207
+ describe ".title_methods" do
208
+ it "returns array of methods for trying cast resource to text" do
209
+ expect(described_class.title_methods).to eq([:releaf_title, :name, :title, :to_s])
210
+ end
211
+ end
174
212
  end
@@ -1,6 +1,6 @@
1
1
  require "rails_helper"
2
2
 
3
- describe Releaf::Core::ResourceFields do
3
+ describe Releaf::ResourceFields do
4
4
  subject{ described_class.new(Book) }
5
5
 
6
6
  describe "#excluded_attributes" do