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.
- checksums.yaml +7 -0
- data/LICENSE +24 -0
- data/app/assets/fonts/releaf/RobotoRegular_normal_400.ttf +0 -0
- data/app/assets/fonts/releaf/RobotoRegular_normal_400.woff +0 -0
- data/app/assets/fonts/releaf/RobotoRegular_normal_400.woff2 +0 -0
- data/app/assets/images/releaf/icons/apple-touch-icon-114x114-precomposed.png +0 -0
- data/app/assets/images/releaf/icons/apple-touch-icon-152x152-precomposed.png +0 -0
- data/app/assets/images/releaf/icons/apple-touch-icon-72x72-precomposed.png +0 -0
- data/app/assets/images/releaf/icons/favicon.ico +0 -0
- data/app/assets/images/releaf/icons/favicon.png +0 -0
- data/app/assets/images/releaf/icons/msapplication-tile-144x144.png +0 -0
- data/app/assets/images/releaf/logo-login.png +0 -0
- data/app/assets/images/releaf/logo.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/mediaembed/icons/hidpi/mediaembed.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/mediaembed/icons/mediaembed.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/mediaembed/lang/en.js +12 -0
- data/app/assets/javascripts/ckeditor/plugins/mediaembed/lang/es.js +12 -0
- data/app/assets/javascripts/ckeditor/plugins/mediaembed/plugin.js +63 -0
- data/app/assets/javascripts/releaf/3rd_party/jquery-ui-timepicker-addon.js +1882 -0
- data/app/assets/javascripts/releaf/3rd_party/jquery.magnific-popup.min.js +4 -0
- data/app/assets/javascripts/releaf/application.js +13 -0
- data/app/assets/javascripts/releaf/include/ajax.js +66 -0
- data/app/assets/javascripts/releaf/include/ajaxbox.js +179 -0
- data/app/assets/javascripts/releaf/include/dialogs.js +13 -0
- data/app/assets/javascripts/releaf/include/field.type_associated_set.js +32 -0
- data/app/assets/javascripts/releaf/include/field.type_date_or_datetime_or_time.js +73 -0
- data/app/assets/javascripts/releaf/include/field.type_richtext.js +188 -0
- data/app/assets/javascripts/releaf/include/loader.js +45 -0
- data/app/assets/javascripts/releaf/include/localization.js +213 -0
- data/app/assets/javascripts/releaf/include/nested_fields.js +295 -0
- data/app/assets/javascripts/releaf/include/notifications.js +267 -0
- data/app/assets/javascripts/releaf/include/pagination.js +19 -0
- data/app/assets/javascripts/releaf/include/profile_settings.js +28 -0
- data/app/assets/javascripts/releaf/include/remote_validator.js +437 -0
- data/app/assets/javascripts/releaf/include/search.js +140 -0
- data/app/assets/javascripts/releaf/include/sidebar.js +149 -0
- data/app/assets/javascripts/releaf/include/sortable.js +69 -0
- data/app/assets/javascripts/releaf/include/toolbox.js +221 -0
- data/app/assets/javascripts/releaf/include/url_builder.js +193 -0
- data/app/assets/stylesheets/releaf/application.scss +9 -0
- data/app/assets/stylesheets/releaf/environment/extras.scss +11 -0
- data/app/assets/stylesheets/releaf/environment/functions/units.scss +12 -0
- data/app/assets/stylesheets/releaf/environment/functions.scss +1 -0
- data/app/assets/stylesheets/releaf/environment/mixins/blocks.scss +133 -0
- data/app/assets/stylesheets/releaf/environment/mixins/elements.scss +64 -0
- data/app/assets/stylesheets/releaf/environment/mixins/text.scss +61 -0
- data/app/assets/stylesheets/releaf/environment/mixins.scss +3 -0
- data/app/assets/stylesheets/releaf/environment/variables/colors.scss +93 -0
- data/app/assets/stylesheets/releaf/environment/variables/dimensions.scss +0 -0
- data/app/assets/stylesheets/releaf/environment/variables/magnific-popup.scss +6 -0
- data/app/assets/stylesheets/releaf/environment/variables.scss +5 -0
- data/app/assets/stylesheets/releaf/environment.scss +4 -0
- data/app/assets/stylesheets/releaf/layout/base.scss +32 -0
- data/app/assets/stylesheets/releaf/layout/breadcrumbs.scss +47 -0
- data/app/assets/stylesheets/releaf/layout/buttons.scss +107 -0
- data/app/assets/stylesheets/releaf/layout/deprecated.scss +29 -0
- data/app/assets/stylesheets/releaf/layout/dialogs.scss +138 -0
- data/app/assets/stylesheets/releaf/layout/errors.scss +28 -0
- data/app/assets/stylesheets/releaf/layout/extras.scss +10 -0
- data/app/assets/stylesheets/releaf/layout/fields.scss +305 -0
- data/app/assets/stylesheets/releaf/layout/fonts.scss +16 -0
- data/app/assets/stylesheets/releaf/layout/footer.scss +80 -0
- data/app/assets/stylesheets/releaf/layout/forms.scss +23 -0
- data/app/assets/stylesheets/releaf/layout/header.scss +55 -0
- data/app/assets/stylesheets/releaf/layout/icons.scss +4 -0
- data/app/assets/stylesheets/releaf/layout/images.scss +4 -0
- data/app/assets/stylesheets/releaf/layout/links.scss +7 -0
- data/app/assets/stylesheets/releaf/layout/localization.scss +79 -0
- data/app/assets/stylesheets/releaf/layout/main.scss +43 -0
- data/app/assets/stylesheets/releaf/layout/notifications.scss +67 -0
- data/app/assets/stylesheets/releaf/layout/pagination.scss +18 -0
- data/app/assets/stylesheets/releaf/layout/search.scss +70 -0
- data/app/assets/stylesheets/releaf/layout/sections.scss +138 -0
- data/app/assets/stylesheets/releaf/layout/sidebar.scss +306 -0
- data/app/assets/stylesheets/releaf/layout/tables.scss +99 -0
- data/app/assets/stylesheets/releaf/layout/text.scss +31 -0
- data/app/assets/stylesheets/releaf/layout/toolboxes.scss +69 -0
- data/app/assets/stylesheets/releaf/layout.scss +35 -0
- data/app/assets/stylesheets/releaf/vendor/magnific-popup/main.scss +596 -0
- data/app/assets/stylesheets/releaf/vendor/magnific-popup/settings.scss +45 -0
- data/app/builders/releaf/builders/association_reflector.rb +58 -0
- data/app/builders/releaf/builders/base.rb +80 -0
- data/app/builders/releaf/builders/collection.rb +8 -0
- data/app/builders/releaf/builders/confirm_destroy_dialog_builder.rb +25 -0
- data/app/builders/releaf/builders/confirm_dialog_builder.rb +54 -0
- data/app/builders/releaf/builders/edit_builder.rb +66 -0
- data/app/builders/releaf/builders/form_builder.rb +594 -0
- data/app/builders/releaf/builders/index_builder.rb +118 -0
- data/app/builders/releaf/builders/orderer.rb +5 -0
- data/app/builders/releaf/builders/page/header_builder.rb +70 -0
- data/app/builders/releaf/builders/page/layout_builder.rb +155 -0
- data/app/builders/releaf/builders/page/menu_builder.rb +140 -0
- data/app/builders/releaf/builders/pagination_builder.rb +107 -0
- data/app/builders/releaf/builders/refused_destroy_dialog_builder.rb +68 -0
- data/app/builders/releaf/builders/resource.rb +9 -0
- data/app/builders/releaf/builders/resource_dialog.rb +8 -0
- data/app/builders/releaf/builders/resource_view.rb +54 -0
- data/app/builders/releaf/builders/show_builder.rb +3 -0
- data/app/builders/releaf/builders/table_builder.rb +280 -0
- data/app/builders/releaf/builders/tags/releaf_associated_set_field.rb +40 -0
- data/app/builders/releaf/builders/template.rb +8 -0
- data/app/builders/releaf/builders/toolbox.rb +23 -0
- data/app/builders/releaf/builders/toolbox_builder.rb +27 -0
- data/app/builders/releaf/builders/view.rb +132 -0
- data/app/builders/releaf/builders.rb +38 -0
- data/app/builders/releaf/core/settings/form_builder.rb +21 -0
- data/app/builders/releaf/core/settings/table_builder.rb +11 -0
- data/app/controllers/concerns/releaf/breadcrumbs.rb +42 -0
- data/app/controllers/concerns/releaf/richtext_attachments.rb +20 -0
- data/app/controllers/releaf/base_controller.rb +458 -0
- data/app/controllers/releaf/core/errors_controller.rb +5 -0
- data/app/controllers/releaf/core/settings_controller.rb +50 -0
- data/app/helpers/releaf/application_helper.rb +53 -0
- data/app/helpers/releaf/button_helper.rb +50 -0
- data/app/helpers/releaf/javascript_helper.rb +75 -0
- data/app/lib/releaf/core/assets_resolver.rb +58 -0
- data/app/lib/releaf/core/default_searchable_fields.rb +43 -0
- data/app/lib/releaf/core/error_formatter.rb +103 -0
- data/app/lib/releaf/core/item_orderer.rb +102 -0
- data/app/lib/releaf/core/resource_base.rb +66 -0
- data/app/lib/releaf/core/resource_fields.rb +6 -0
- data/app/lib/releaf/core/resource_params.rb +47 -0
- data/app/lib/releaf/core/resource_table_fields.rb +10 -0
- data/app/lib/releaf/core/resource_utilities.rb +36 -0
- data/app/lib/releaf/core/responders/access_denied_responder.rb +9 -0
- data/app/lib/releaf/core/responders/after_save_responder.rb +28 -0
- data/app/lib/releaf/core/responders/confirm_destroy_responder.rb +13 -0
- data/app/lib/releaf/core/responders/destroy_responder.rb +10 -0
- data/app/lib/releaf/core/responders/error_responder.rb +9 -0
- data/app/lib/releaf/core/responders/feature_disabled_responder.rb +9 -0
- data/app/lib/releaf/core/responders/page_not_found_responder.rb +9 -0
- data/app/lib/releaf/core/responders.rb +31 -0
- data/app/lib/releaf/core/search.rb +147 -0
- data/app/lib/releaf/core/template_field_type_mapper.rb +127 -0
- data/app/models/releaf/richtext_attachment.rb +6 -0
- data/app/models/releaf/settings.rb +27 -0
- data/app/views/layouts/releaf/admin.html.erb +1 -0
- data/app/views/releaf/base/confirm_destroy.ruby +1 -0
- data/app/views/releaf/base/create_releaf_richtext_attachment.haml +1 -0
- data/app/views/releaf/base/edit.ruby +1 -0
- data/app/views/releaf/base/index.ruby +1 -0
- data/app/views/releaf/base/new.ruby +1 -0
- data/app/views/releaf/base/refused_destroy.ruby +1 -0
- data/app/views/releaf/base/show.ruby +1 -0
- data/app/views/releaf/base/toolbox.ruby +1 -0
- data/app/views/releaf/error_pages/_error.html.haml +10 -0
- data/app/views/releaf/error_pages/access_denied.html.haml +1 -0
- data/app/views/releaf/error_pages/feature_disabled.html.haml +1 -0
- data/app/views/releaf/error_pages/page_not_found.html.haml +2 -0
- data/lib/generators/dummy/install_generator.rb +18 -0
- data/lib/generators/dummy/templates/builders/admin/books/form_builder.rb +13 -0
- data/lib/generators/dummy/templates/builders/admin/books/index_builder.rb +30 -0
- data/lib/generators/dummy/templates/builders/admin/books/table_builder.rb +7 -0
- data/lib/generators/dummy/templates/builders/admin/nodes/form_builder.rb +7 -0
- data/lib/generators/dummy/templates/config/routes.rb +19 -0
- data/lib/generators/dummy/templates/controllers/admin/authors_controller.rb +12 -0
- data/lib/generators/dummy/templates/controllers/admin/books_controller.rb +17 -0
- data/lib/generators/dummy/templates/controllers/admin/chapters_controller.rb +3 -0
- data/lib/generators/dummy/templates/controllers/admin/publishers_controller.rb +3 -0
- data/lib/generators/dummy/templates/controllers/application_controller.rb +39 -0
- data/lib/generators/dummy/templates/controllers/concerns/.keep +0 -0
- data/lib/generators/dummy/templates/controllers/concerns/node_controller.rb +37 -0
- data/lib/generators/dummy/templates/controllers/contacts_controller.rb +3 -0
- data/lib/generators/dummy/templates/controllers/home_pages_controller.rb +3 -0
- data/lib/generators/dummy/templates/controllers/text_pages_controller.rb +3 -0
- data/lib/generators/dummy/templates/initializers/releaf.rb +35 -0
- data/lib/generators/dummy/templates/migrations/create_authors.rb +14 -0
- data/lib/generators/dummy/templates/migrations/create_banners.rb +11 -0
- data/lib/generators/dummy/templates/migrations/create_book_sequels.rb +14 -0
- data/lib/generators/dummy/templates/migrations/create_books.rb +27 -0
- data/lib/generators/dummy/templates/migrations/create_bundles.rb +7 -0
- data/lib/generators/dummy/templates/migrations/create_chapters.rb +13 -0
- data/lib/generators/dummy/templates/migrations/create_home_pages.rb +9 -0
- data/lib/generators/dummy/templates/migrations/create_node_extra_fields.rb +5 -0
- data/lib/generators/dummy/templates/migrations/create_publishers.rb +8 -0
- data/lib/generators/dummy/templates/migrations/create_text_pages.rb +9 -0
- data/lib/generators/dummy/templates/models/author.rb +10 -0
- data/lib/generators/dummy/templates/models/banner.rb +5 -0
- data/lib/generators/dummy/templates/models/book.rb +19 -0
- data/lib/generators/dummy/templates/models/book_sequel.rb +4 -0
- data/lib/generators/dummy/templates/models/bundle.rb +17 -0
- data/lib/generators/dummy/templates/models/chapter.rb +7 -0
- data/lib/generators/dummy/templates/models/home_page.rb +5 -0
- data/lib/generators/dummy/templates/models/node.rb +10 -0
- data/lib/generators/dummy/templates/models/publisher.rb +9 -0
- data/lib/generators/dummy/templates/models/text_page.rb +5 -0
- data/lib/generators/dummy/templates/views/contacts/show.html.haml +1 -0
- data/lib/generators/dummy/templates/views/home_pages/show.haml +1 -0
- data/lib/generators/dummy/templates/views/layouts/application.html.haml +22 -0
- data/lib/generators/dummy/templates/views/text_pages/show.haml +1 -0
- data/lib/generators/releaf/install_generator.rb +93 -0
- data/lib/generators/releaf/templates/initializers/haml.rb +1 -0
- data/lib/generators/releaf/templates/initializers/releaf.rb +30 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_nodes.rb +28 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_permissions.rb +12 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_richtext_attachments.rb +12 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_roles.rb +9 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_settings.rb +17 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_translations.rb +21 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_users.rb +52 -0
- data/lib/generators/releaf/templates/models/node.rb +3 -0
- data/lib/generators/releaf/templates/seeds/seeds.rb +54 -0
- data/lib/releaf/core/application.rb +17 -0
- data/lib/releaf/core/builders_autoload.rb +27 -0
- data/lib/releaf/core/component.rb +9 -0
- data/lib/releaf/core/configuration.rb +101 -0
- data/lib/releaf/core/engine.rb +35 -0
- data/lib/releaf/core/exceptions.rb +38 -0
- data/lib/releaf/core/route_mapper.rb +59 -0
- data/lib/releaf/core/settings_ui_component.rb +7 -0
- data/lib/releaf/core/validation_error_codes.rb +36 -0
- data/lib/releaf/version.rb +3 -0
- data/lib/releaf-core.rb +14 -0
- data/lib/tasks/releaf_tasks.rake +4 -0
- data/releaf-core.gemspec +35 -0
- data/spec/builders/builders/association_reflector_spec.rb +138 -0
- data/spec/builders/builders/base_spec.rb +276 -0
- data/spec/builders/builders/collection_spec.rb +18 -0
- data/spec/builders/builders/confirm_destroy_dialog_builder_spec.rb +71 -0
- data/spec/builders/builders/confirm_dialog_builder_spec.rb +105 -0
- data/spec/builders/builders/edit_builder_spec.rb +215 -0
- data/spec/builders/builders/form_builder_spec.rb +562 -0
- data/spec/builders/builders/index_builder_spec.rb +345 -0
- data/spec/builders/builders/orderer_spec.rb +22 -0
- data/spec/builders/builders/page/header_builder_spec.rb +143 -0
- data/spec/builders/builders/page/layout_builder_spec.rb +73 -0
- data/spec/builders/builders/page/menu_builder_spec.rb +160 -0
- data/spec/builders/builders/pagination_builder_spec.rb +330 -0
- data/spec/builders/builders/resource_dialog_spec.rb +21 -0
- data/spec/builders/builders/resource_view_spec.rb +158 -0
- data/spec/builders/builders/show_builder_spec.rb +7 -0
- data/spec/builders/builders/table_builder_spec.rb +638 -0
- data/spec/builders/builders/template_spec.rb +12 -0
- data/spec/builders/builders/toolbox_builder_spec.rb +67 -0
- data/spec/builders/builders/toolbox_spec.rb +48 -0
- data/spec/builders/builders/view_spec.rb +281 -0
- data/spec/builders/builders_spec.rb +134 -0
- data/spec/builders/core/settings/form_builder_spec.rb +69 -0
- data/spec/builders/core/settings/table_builder_spec.rb +21 -0
- data/spec/controllers/concerns/releaf/richtext_attachments_spec.rb +51 -0
- data/spec/controllers/releaf/base_controller_spec.rb +447 -0
- data/spec/controllers/releaf/core/settings_controller_spec.rb +31 -0
- data/spec/features/ajaxbox_spec.rb +111 -0
- data/spec/features/authorization_spec.rb +50 -0
- data/spec/features/dragonfly_integration_spec.rb +24 -0
- data/spec/features/edit_actions_spec.rb +142 -0
- data/spec/features/errors_spec.rb +29 -0
- data/spec/features/index_actions_spec.rb +85 -0
- data/spec/features/index_table_spec.rb +32 -0
- data/spec/features/menu_spec.rb +71 -0
- data/spec/features/richtext_attachments_spec.rb +64 -0
- data/spec/features/richtext_embed_spec.rb +29 -0
- data/spec/features/richtext_spec.rb +19 -0
- data/spec/features/search_spec.rb +825 -0
- data/spec/features/settings_spec.rb +38 -0
- data/spec/features/title_spec.rb +13 -0
- data/spec/fixtures/common_fields.yml +17 -0
- data/spec/fixtures/cs.png +0 -0
- data/spec/fixtures/time.formats.xlsx +0 -0
- data/spec/fixtures/unicorn.jpg +0 -0
- data/spec/helpers/application_helper_spec.rb +75 -0
- data/spec/helpers/button_helper_spec.rb +146 -0
- data/spec/lib/releaf/core/application_spec.rb +42 -0
- data/spec/lib/releaf/core/assets_resolver_spec.rb +113 -0
- data/spec/lib/releaf/core/configuration_spec.rb +230 -0
- data/spec/lib/releaf/core/default_searchable_fields_spec.rb +161 -0
- data/spec/lib/releaf/core/error_formatter_spec.rb +242 -0
- data/spec/lib/releaf/core/item_orderer_spec.rb +142 -0
- data/spec/lib/releaf/core/resource_base_spec.rb +174 -0
- data/spec/lib/releaf/core/resource_fields_spec.rb +12 -0
- data/spec/lib/releaf/core/resource_params_spec.rb +117 -0
- data/spec/lib/releaf/core/resource_table_fields_spec.rb +18 -0
- data/spec/lib/releaf/core/resource_utilities_spec.rb +87 -0
- data/spec/lib/releaf/core/responders/access_denied_responder_spec.rb +12 -0
- data/spec/lib/releaf/core/responders/after_save_responder_spec.rb +102 -0
- data/spec/lib/releaf/core/responders/confirm_destroy_responder_spec.rb +26 -0
- data/spec/lib/releaf/core/responders/destroy_responder_spec.rb +30 -0
- data/spec/lib/releaf/core/responders/error_responder_spec.rb +26 -0
- data/spec/lib/releaf/core/responders/feature_disabled_responder_spec.rb +12 -0
- data/spec/lib/releaf/core/responders/page_not_found_responder_spec.rb +12 -0
- data/spec/lib/releaf/core/responders_spec.rb +60 -0
- data/spec/lib/releaf/core/template_field_type_mapper_spec.rb +311 -0
- data/spec/lib/validation_error_codes_spec.rb +56 -0
- data/spec/misc/factories_spec.rb +43 -0
- data/spec/models/settings_spec.rb +58 -0
- data/spec/routing/route_mapper_spec.rb +185 -0
- data/spec/rspec_helpers/test_helpers_spec.rb +20 -0
- metadata +657 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
describe Releaf::Builders::Collection, type: :module do
|
|
4
|
+
class CollectionIncluder
|
|
5
|
+
include Releaf::Builders::Base
|
|
6
|
+
include Releaf::Builders::Template
|
|
7
|
+
include Releaf::Builders::Collection
|
|
8
|
+
end
|
|
9
|
+
class CollectionTestHelper < ActionView::Base
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "it assigns template collection instance variable to instance 'collection' accessor on initialization" do
|
|
13
|
+
template = CollectionTestHelper.new
|
|
14
|
+
template.instance_variable_set("@collection", "x")
|
|
15
|
+
subject = CollectionIncluder.new(template)
|
|
16
|
+
expect(subject.collection).to eq("x")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
describe Releaf::Builders::ConfirmDestroyDialogBuilder, type: :class do
|
|
4
|
+
class ConfirmDestroyDialogTestHelper < ActionView::Base
|
|
5
|
+
include FontAwesome::Rails::IconHelper
|
|
6
|
+
include Releaf::ButtonHelper
|
|
7
|
+
include Releaf::ApplicationHelper
|
|
8
|
+
|
|
9
|
+
def protect_against_forgery?
|
|
10
|
+
true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def form_authenticity_token
|
|
14
|
+
"xxx"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def request_forgery_protection_token
|
|
18
|
+
"yyy"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
let(:template){ ConfirmDestroyDialogTestHelper.new }
|
|
23
|
+
let(:object){ Book.new(id: 99, title: "book title") }
|
|
24
|
+
let(:subject){ described_class.new(template) }
|
|
25
|
+
|
|
26
|
+
before do
|
|
27
|
+
subject.resource = object
|
|
28
|
+
allow(subject.template).to receive(:controller).and_return(Releaf::BaseController.new)
|
|
29
|
+
allow(subject.controller).to receive(:index_url).and_return("y")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#question_content" do
|
|
33
|
+
it "localized destroy question" do
|
|
34
|
+
allow(subject).to receive(:t).with("Do you want to delete the following object?").and_return("xx")
|
|
35
|
+
expect(subject.question_content).to eq("xx")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe "#description_content" do
|
|
40
|
+
it "returns `resource_to_text` value" do
|
|
41
|
+
allow(subject).to receive(:resource_to_text).with(object).and_return("xx")
|
|
42
|
+
expect(subject.description_content).to eq("xx")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe "#section_body" do
|
|
47
|
+
it "returns destroy description content" do
|
|
48
|
+
content = '<div class="body"><i class="fa fa-trash-o"></i><div class="question">Do you want to delete the following object?</div><div class="description">book title</div></div>'
|
|
49
|
+
expect(subject.section_body).to eq(content)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "#confirm_method" do
|
|
54
|
+
it "returns :delete" do
|
|
55
|
+
expect(subject.confirm_method).to eq(:delete)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "#icon_name" do
|
|
60
|
+
it "returns trash icon" do
|
|
61
|
+
expect(subject.icon_name).to eq("trash-o")
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "#confirm_url" do
|
|
66
|
+
it "returns resource destroy url" do
|
|
67
|
+
allow(subject.template).to receive(:url_for).with(action: 'destroy', id: 99, index_url: "y").and_return("x")
|
|
68
|
+
expect(subject.confirm_url).to eq("x")
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
describe Releaf::Builders::ConfirmDialogBuilder, type: :class do
|
|
4
|
+
class ConfirmDestroyDialogTestHelper < ActionView::Base
|
|
5
|
+
include FontAwesome::Rails::IconHelper
|
|
6
|
+
include Releaf::ButtonHelper
|
|
7
|
+
include Releaf::ApplicationHelper
|
|
8
|
+
|
|
9
|
+
def protect_against_forgery?
|
|
10
|
+
true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def form_authenticity_token
|
|
14
|
+
"xxx"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def request_forgery_protection_token
|
|
18
|
+
"yyy"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class ConfirmDialogBuilderInheriter < Releaf::Builders::ConfirmDialogBuilder
|
|
23
|
+
def confirm_url; end
|
|
24
|
+
def icon_name; end
|
|
25
|
+
def question_content; end
|
|
26
|
+
def description_content; end
|
|
27
|
+
def confirm_method; end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
let(:template){ ConfirmDestroyDialogTestHelper.new }
|
|
31
|
+
let(:object){ Book.new(id: 99, title: "book title") }
|
|
32
|
+
let(:subject){ ConfirmDialogBuilderInheriter.new(template) }
|
|
33
|
+
|
|
34
|
+
before do
|
|
35
|
+
subject.resource = object
|
|
36
|
+
allow(subject.template).to receive(:controller).and_return(Releaf::BaseController.new)
|
|
37
|
+
allow(subject.controller).to receive(:index_url).and_return("y")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "#section_body" do
|
|
41
|
+
it "returns destroy description content" do
|
|
42
|
+
allow(subject).to receive(:section_body_blocks).and_return(["a", "b"])
|
|
43
|
+
content = '<div class="body">ab</div>'
|
|
44
|
+
expect(subject.section_body).to eq(content)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#section_body_blocks" do
|
|
49
|
+
it "returns section body blocks" do
|
|
50
|
+
allow(subject).to receive(:icon_name).and_return("circle")
|
|
51
|
+
allow(subject).to receive(:question_content).and_return("question")
|
|
52
|
+
allow(subject).to receive(:description_content).and_return("description")
|
|
53
|
+
|
|
54
|
+
allow(subject).to receive(:icon).with("circle").and_return("ikon")
|
|
55
|
+
allow(subject).to receive(:tag).with(:div, "question", class: "question").and_return("question")
|
|
56
|
+
allow(subject).to receive(:tag).with(:div, "description", class: "description").and_return("description")
|
|
57
|
+
expect(subject.section_body_blocks).to eq(["ikon", "question", "description"])
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe "#section_attributes" do
|
|
62
|
+
it "adds `confirm` class" do
|
|
63
|
+
expect(subject.section_attributes[:class]).to include("confirm")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "#footer_primary_tools" do
|
|
68
|
+
it "returns array with cancel and confirm forms" do
|
|
69
|
+
allow(subject).to receive(:cancel_button).and_return("a")
|
|
70
|
+
allow(subject).to receive(:confirm_button).and_return("b")
|
|
71
|
+
expect(subject.footer_primary_tools).to eq(["a", "b"])
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe "#confirm_form_options" do
|
|
76
|
+
it "returns confirm form options" do
|
|
77
|
+
allow(subject).to receive(:confirm_url).and_return("x")
|
|
78
|
+
allow(subject).to receive(:confirm_method).and_return("tt")
|
|
79
|
+
expect(subject.confirm_form_options).to eq(builder: Releaf::Builders::FormBuilder, url: "x", as: :resource, method: "tt")
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe "#confirm_button" do
|
|
84
|
+
it "returns confirm button" do
|
|
85
|
+
allow(subject).to receive(:t).with("Yes").and_return("Yess")
|
|
86
|
+
allow(subject).to receive(:button).with("Yess", "check", class: "danger", type: "submit").and_return("x")
|
|
87
|
+
expect(subject.confirm_button).to eq("x")
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
describe "#cancel_url" do
|
|
92
|
+
it "returns index url" do
|
|
93
|
+
allow(subject).to receive(:index_url).and_return("x")
|
|
94
|
+
expect(subject.cancel_url).to eq("x")
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe "#cancel_button" do
|
|
99
|
+
it "returns cancel button" do
|
|
100
|
+
allow(subject).to receive(:t).with("No").and_return("Noo")
|
|
101
|
+
allow(subject).to receive(:button).with("Noo", "ban", class: "secondary", data: {type: "cancel"}, href: "y").and_return("x")
|
|
102
|
+
expect(subject.cancel_button).to eq("x")
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
describe Releaf::Builders::EditBuilder, type: :class do
|
|
4
|
+
class TranslationsEditBuilderTestHelper < ActionView::Base
|
|
5
|
+
include Releaf::ApplicationHelper
|
|
6
|
+
include Releaf::ButtonHelper
|
|
7
|
+
include FontAwesome::Rails::IconHelper
|
|
8
|
+
|
|
9
|
+
def protect_against_forgery?
|
|
10
|
+
true
|
|
11
|
+
end
|
|
12
|
+
def form_authenticity_token
|
|
13
|
+
"xxx"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def request_forgery_protection_token
|
|
17
|
+
"yyy"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
let(:template){ TranslationsEditBuilderTestHelper.new }
|
|
22
|
+
let(:subject){ described_class.new(template) }
|
|
23
|
+
let(:controller){ Releaf::BaseController.new }
|
|
24
|
+
let(:resource){ Book.new }
|
|
25
|
+
|
|
26
|
+
before do
|
|
27
|
+
allow(template).to receive(:controller).and_return(controller)
|
|
28
|
+
allow(controller).to receive(:action_name).and_return(:edit)
|
|
29
|
+
allow(subject).to receive(:resource).and_return(resource)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#section_content" do
|
|
33
|
+
before do
|
|
34
|
+
allow(subject).to receive(:section_attributes).and_return(a: "b")
|
|
35
|
+
allow(subject).to receive(:form_options).and_return(url: "xxx", builder: Releaf::Builders::FormBuilder)
|
|
36
|
+
allow(subject).to receive(:index_url_preserver).and_return("_index_url_")
|
|
37
|
+
allow(subject).to receive(:section_blocks).and_return(["_section_","_blocks_"])
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "returns section with index url preserver and section blocks" do
|
|
41
|
+
expect(subject.section_content).to eq('<form class="new_book" id="new_book" action="xxx" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="yyy" value="xxx" />_index_url__section__blocks_</form>')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "assigns form instance to builder" do
|
|
45
|
+
expect{ subject.section_content }.to change{ subject.form }.from(nil)
|
|
46
|
+
expect(subject.form).to be_instance_of Releaf::Builders::FormBuilder
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "#index_url_preserver" do
|
|
51
|
+
it "returns hidden index url input" do
|
|
52
|
+
allow(subject).to receive(:params).and_return(index_url: "?asd=23&lf=dd")
|
|
53
|
+
result = '<input type="hidden" name="index_url" id="index_url" value="?asd=23&lf=dd" />'
|
|
54
|
+
expect(subject.index_url_preserver).to eq(result)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe "#section_body_blocks" do
|
|
59
|
+
it "returns array with error notices and form fields" do
|
|
60
|
+
allow(subject).to receive(:error_notices).and_return("err")
|
|
61
|
+
allow(subject).to receive(:form_fields).and_return("fields")
|
|
62
|
+
expect(subject.section_body_blocks).to eq(["err", "fields"])
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe "#error_notices" do
|
|
67
|
+
|
|
68
|
+
before do
|
|
69
|
+
allow(subject).to receive(:error_notices_header).and_return("<error_notice_header />".html_safe)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "when errors exists" do
|
|
73
|
+
|
|
74
|
+
it "returns errors block" do
|
|
75
|
+
resource.valid?
|
|
76
|
+
|
|
77
|
+
expect(subject.error_notices).to match_html(%Q[
|
|
78
|
+
<div class="form-error-box">
|
|
79
|
+
<error_notice_header />
|
|
80
|
+
<ul>
|
|
81
|
+
<li class="error">Title Blank</li>
|
|
82
|
+
</ul>
|
|
83
|
+
</div>
|
|
84
|
+
])
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context "when no errors present" do
|
|
89
|
+
it "returns nil" do
|
|
90
|
+
expect(subject.error_notices).to be nil
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "#error_notices_header" do
|
|
96
|
+
it "returns validation errors notices header" do
|
|
97
|
+
resource.valid?
|
|
98
|
+
expect(subject.error_notices_header).to eq('<strong>1 validation error occured:</strong>')
|
|
99
|
+
|
|
100
|
+
resource.title = "xx"
|
|
101
|
+
resource.valid?
|
|
102
|
+
expect(subject.error_notices_header).to eq('<strong>0 validation errors occured:</strong>')
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe "#footer_primary_tools" do
|
|
107
|
+
before do
|
|
108
|
+
allow(subject).to receive(:save_button).and_return("_svbtn_")
|
|
109
|
+
allow(subject).to receive(:save_and_create_another_button).and_return("_svacrbtn_")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context "when create_another is availble" do
|
|
113
|
+
it "returns an array with save_and_create_another and save buttons" do
|
|
114
|
+
allow(subject).to receive(:create_another_available?).and_return true
|
|
115
|
+
expect(subject.footer_primary_tools).to eq(["_svacrbtn_", "_svbtn_"])
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context "when create_another is not available" do
|
|
120
|
+
it "returns an array with save button" do
|
|
121
|
+
allow(subject).to receive(:create_another_available?).and_return false
|
|
122
|
+
expect(subject.footer_primary_tools).to eq(["_svbtn_"])
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe "#create_another_available?" do
|
|
129
|
+
|
|
130
|
+
before do
|
|
131
|
+
controller.setup
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context "when editing an existing record" do
|
|
135
|
+
let(:resource){ FactoryGirl.create(:book) }
|
|
136
|
+
|
|
137
|
+
context "when controller has create_another feature enabled" do
|
|
138
|
+
it "returns false" do
|
|
139
|
+
expect(subject.create_another_available?).to be false
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context "when controller has create_another feature disabled" do
|
|
144
|
+
it "returns false" do
|
|
145
|
+
expect(subject.create_another_available?).to be false
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
context "when creating a new record" do
|
|
151
|
+
context "when controller has create_another feature enabled" do
|
|
152
|
+
it "returns true" do
|
|
153
|
+
expect(subject.create_another_available?).to be true
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
context "when controller has create_another feature disabled" do
|
|
158
|
+
it "returns false" do
|
|
159
|
+
allow(controller).to receive(:feature_available?).with(:create_another).and_return false
|
|
160
|
+
expect(subject.create_another_available?).to be false
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
context "when resource is not present" do
|
|
166
|
+
let(:resource){ nil }
|
|
167
|
+
it "returns false" do
|
|
168
|
+
expect(subject.create_another_available?).to be false
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
describe "#save_and_create_another_button" do
|
|
175
|
+
it "returns save and create button" do
|
|
176
|
+
allow(template).to receive(:fa_icon).with("plus").and_return('<plus_icon />'.html_safe)
|
|
177
|
+
allow(subject).to receive(:t).with("Save and create another").and_return("Save and ccrr")
|
|
178
|
+
expect(subject.save_and_create_another_button).to match_html(%Q[
|
|
179
|
+
<button class="button with-icon secondary" title="Save and ccrr" type="submit" autocomplete="off" name="after_save" value="create_another" data-type="ok" data-disable="true">
|
|
180
|
+
<plus_icon />
|
|
181
|
+
Save and ccrr
|
|
182
|
+
</button>
|
|
183
|
+
])
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
describe "#save_button" do
|
|
189
|
+
it "returns save button" do
|
|
190
|
+
allow(subject).to receive(:button)
|
|
191
|
+
.with("to_list", "check", {class: "primary", data: {type: "ok", disable: true}, type: "submit"})
|
|
192
|
+
.and_return("_btn_")
|
|
193
|
+
allow(subject).to receive(:t).with("Save").and_return("to_list")
|
|
194
|
+
expect(subject.save_button).to eq("_btn_")
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
describe "#form_options" do
|
|
199
|
+
it "returns controller form options for current action and resource" do
|
|
200
|
+
allow(controller).to receive(:form_options).with(:edit, resource, :resource).and_return(:y)
|
|
201
|
+
expect(subject.form_options).to eq(:y)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
describe "#form_fields" do
|
|
206
|
+
it "returns form `releaf_fields` output for form `field_names` casted to array" do
|
|
207
|
+
form = Releaf::Builders::FormBuilder.new(:book, Book.new, template, {})
|
|
208
|
+
subject.form = form
|
|
209
|
+
allow(form).to receive(:field_names).and_return({a: 1, b: 2})
|
|
210
|
+
allow(form).to receive(:releaf_fields).with([[:a, 1], [:b, 2]]).and_return(:x)
|
|
211
|
+
|
|
212
|
+
expect(subject.form_fields).to eq(:x)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
describe Releaf::Builders::FormBuilder, type: :class do
|
|
4
|
+
class FormBuilderTestHelper < ActionView::Base
|
|
5
|
+
include Releaf::ApplicationHelper
|
|
6
|
+
include Releaf::ButtonHelper
|
|
7
|
+
include FontAwesome::Rails::IconHelper
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
let(:template){ FormBuilderTestHelper.new }
|
|
11
|
+
let(:object){ Book.new }
|
|
12
|
+
let(:subject){ described_class.new(:book, object, template, {}) }
|
|
13
|
+
let(:normalized_fields){
|
|
14
|
+
[
|
|
15
|
+
{
|
|
16
|
+
render_method: "render_title",
|
|
17
|
+
field: "title",
|
|
18
|
+
subfields: nil
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
render_method: "render_author_id",
|
|
22
|
+
field: "author_id",
|
|
23
|
+
subfields: nil
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
render_method: "render_chapters",
|
|
27
|
+
field: :chapters,
|
|
28
|
+
subfields: ["title", "text", "sample_html"]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
render_method: "render_book_sequels",
|
|
32
|
+
field: :book_sequels,
|
|
33
|
+
subfields: ["sequel_id"]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
it "includes Releaf::Builders::Base" do
|
|
39
|
+
expect(described_class.ancestors).to include(Releaf::Builders::Base)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "includes Releaf::Builders::Orderer" do
|
|
43
|
+
expect(described_class.ancestors).to include(Releaf::Builders::Orderer)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe "#field_names" do
|
|
47
|
+
it "returns field names for object class" do
|
|
48
|
+
allow(Releaf::Core::ResourceFields).to receive(:new).with(object.class).and_call_original
|
|
49
|
+
allow_any_instance_of(Releaf::Core::ResourceFields).to receive(:values).and_return(["a", "b"])
|
|
50
|
+
expect(subject.field_names).to eq(["a", "b"])
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe "#field_render_method_name" do
|
|
55
|
+
it "returns method name for given field" do
|
|
56
|
+
expect(subject.field_render_method_name(:title)).to eq("render_title")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context "when builder has parent builder(-s)" do
|
|
60
|
+
it "traverses through all builders and add relation name option to field name" do
|
|
61
|
+
root_builder = described_class.new(:author, Author.new, template, {})
|
|
62
|
+
middle_builder = described_class.new(:author, Author.new, template, {relation_name: :pages, parent_builder: root_builder})
|
|
63
|
+
subject.options[:parent_builder] = middle_builder
|
|
64
|
+
subject.options[:relation_name] = :chapters
|
|
65
|
+
|
|
66
|
+
expect(subject.field_render_method_name(:title)).to eq("render_pages_chapters_title")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe "#normalize_fields" do
|
|
72
|
+
it "returns normalized fields for use with #releaf_fields method" do
|
|
73
|
+
fields = [
|
|
74
|
+
"title",
|
|
75
|
+
"author_id",
|
|
76
|
+
{chapters: ["title", "text", "sample_html"]},
|
|
77
|
+
{book_sequels: ["sequel_id"]}
|
|
78
|
+
]
|
|
79
|
+
expect(subject.normalize_fields(fields)).to eq(normalized_fields)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "handles multi-key hashes" do
|
|
83
|
+
fields = [
|
|
84
|
+
"title",
|
|
85
|
+
"author_id",
|
|
86
|
+
{
|
|
87
|
+
chapters: ["title", "text", "sample_html"],
|
|
88
|
+
book_sequels: ["sequel_id"]
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
expect(subject.normalize_fields(fields)).to eq(normalized_fields)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "#releaf_fields" do
|
|
96
|
+
it "normalizes given fields with #normalize_fields" do
|
|
97
|
+
allow(subject).to receive(:render_field_by_options)
|
|
98
|
+
expect(subject).to receive(:normalize_fields).with([:a, :b]).and_return([:x, :y])
|
|
99
|
+
subject.releaf_fields(:a, :b)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "passes all normalized field options to #render_field" do
|
|
103
|
+
allow(subject).to receive(:normalize_fields).and_return([:x, :y])
|
|
104
|
+
expect(subject).to receive(:render_field_by_options).with(:x)
|
|
105
|
+
expect(subject).to receive(:render_field_by_options).with(:y)
|
|
106
|
+
subject.releaf_fields(:a, :b)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "concatenates and return all #render_field_by_options outputs with #safe_join" do
|
|
110
|
+
allow(subject).to receive(:render_field_by_options).and_return('_a_', '_b_')
|
|
111
|
+
allow(subject).to receive(:normalize_fields).and_return([:x, :y])
|
|
112
|
+
expect(subject).to receive(:safe_join).with(no_args){|&block|
|
|
113
|
+
expect(block.call).to eq(['_a_', '_b_'])
|
|
114
|
+
}.and_return("xxx")
|
|
115
|
+
expect(subject.releaf_fields(:a, :b)).to eq("xxx")
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "#render_field_by_options" do
|
|
120
|
+
let(:options){ {
|
|
121
|
+
render_method: "sortable_column_name", # just random method here
|
|
122
|
+
field: "title",
|
|
123
|
+
subfields: [:a, :b],
|
|
124
|
+
} }
|
|
125
|
+
|
|
126
|
+
before do
|
|
127
|
+
allow(subject).to receive(:reflect_on_association).with("title").and_return(:x)
|
|
128
|
+
allow(subject).to receive(:sortable_column_name)
|
|
129
|
+
.with(no_args).and_return("_render_method_content_")
|
|
130
|
+
allow(subject).to receive(:releaf_association_fields)
|
|
131
|
+
.with(:x, [:a, :b]).and_return("_association_method_content_")
|
|
132
|
+
allow(subject).to receive(:releaf_field)
|
|
133
|
+
.with("title").and_return("_releaf_field_content_")
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context "when method defined in options[:render_method] exists" do
|
|
137
|
+
it "returns this method output" do
|
|
138
|
+
expect(subject.render_field_by_options(options)).to eq("_render_method_content_")
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
context "when custom method does not exist" do
|
|
143
|
+
before do
|
|
144
|
+
options[:render_method] = "something_unexisting"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
context "when reflection exists for given field" do
|
|
148
|
+
it "returns #releaf_association_fields by passing options[:field] and options[:subfields]" do
|
|
149
|
+
expect(subject.render_field_by_options(options)).to eq("_association_method_content_")
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context "when reflection does not exist for given field" do
|
|
154
|
+
it "returns #releaf_field with options[:field] as argument" do
|
|
155
|
+
allow(subject).to receive(:reflect_on_association).with("title").and_return(nil)
|
|
156
|
+
expect(subject.render_field_by_options(options)).to eq("_releaf_field_content_")
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
describe "#reflect_on_association" do
|
|
163
|
+
it "returns reflection for given reflection name" do
|
|
164
|
+
expect(subject.reflect_on_association(:author)).to eq(object.class.reflections["author"])
|
|
165
|
+
expect(subject.reflect_on_association("author")).to eq(object.class.reflections["author"])
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe "#association_reflector" do
|
|
170
|
+
before do
|
|
171
|
+
resource_fields = subject.resource_fields
|
|
172
|
+
allow(resource_fields).to receive(:association_attributes).with(:x).and_return([:c, :d])
|
|
173
|
+
|
|
174
|
+
allow(subject).to receive(:resource_fields).and_return(resource_fields)
|
|
175
|
+
allow(subject).to receive(:sortable_column_name).and_return("sortable column name")
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "returns association reflector for given reflection" do
|
|
179
|
+
expect(subject.association_reflector(:x, [:a, :b])).to be_instance_of Releaf::Builders::AssociationReflector
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "pass reflection, fields and sortable column name to association reflector constructor" do
|
|
183
|
+
expect(Releaf::Builders::AssociationReflector).to receive(:new)
|
|
184
|
+
.with(:x, [:a, :b], "sortable column name")
|
|
185
|
+
subject.association_reflector(:x, [:a, :b])
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
context "when given fields is nil" do
|
|
189
|
+
it "uses resource fields returned association fields instead" do
|
|
190
|
+
expect(Releaf::Builders::AssociationReflector).to receive(:new)
|
|
191
|
+
.with(:x, [:c, :d], "sortable column name")
|
|
192
|
+
subject.association_reflector(:x, nil)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
describe "#releaf_association_fields" do
|
|
198
|
+
let(:reflector){ Releaf::Builders::AssociationReflector.new(:a, :b, :c) }
|
|
199
|
+
let(:fields){ ["a"] }
|
|
200
|
+
|
|
201
|
+
before do
|
|
202
|
+
allow(subject).to receive(:association_reflector).with(:author, fields).and_return(reflector)
|
|
203
|
+
allow(subject).to receive(:releaf_has_many_association).with(reflector).and_return("_has_many_content_")
|
|
204
|
+
allow(subject).to receive(:releaf_belongs_to_association).with(reflector).and_return("_belongs_to_content_")
|
|
205
|
+
allow(subject).to receive(:releaf_has_one_association).with(reflector).and_return("_has_one_content_")
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
context "when reflector macro is :has_many" do
|
|
209
|
+
it "renders association with #releaf_has_many_association" do
|
|
210
|
+
allow(reflector).to receive(:macro).and_return(:has_many)
|
|
211
|
+
expect(subject.releaf_association_fields(:author, fields)).to eq("_has_many_content_")
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
context "when :belongs_to association given" do
|
|
216
|
+
it "renders association with #releaf_belongs_to_association" do
|
|
217
|
+
allow(reflector).to receive(:macro).and_return(:belongs_to)
|
|
218
|
+
expect(subject.releaf_association_fields(:author, fields)).to eq("_belongs_to_content_")
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
context "when :has_one association given" do
|
|
223
|
+
it "renders association with #releaf_has_one_association" do
|
|
224
|
+
allow(reflector).to receive(:macro).and_return(:has_one)
|
|
225
|
+
expect(subject.releaf_association_fields(:author, fields)).to eq("_has_one_content_")
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
context "when non implemented assocation type given" do
|
|
230
|
+
it "raises error" do
|
|
231
|
+
allow(reflector).to receive(:macro).and_return(:new_macro_type)
|
|
232
|
+
expect{ subject.releaf_association_fields(:author, fields) }.to raise_error("not implemented")
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
describe "#input_wrapper_with_label" do
|
|
238
|
+
before do
|
|
239
|
+
allow(subject).to receive(:wrapper).with("input_content", class: "value").and_return("input_content")
|
|
240
|
+
allow(subject).to receive(:releaf_label).with(:color, "label_attributes", "options").and_return("label_content")
|
|
241
|
+
allow(subject).to receive(:field).with(:color, "field_attributes", "options"){ |name, field, options, &block|
|
|
242
|
+
expect(block.call).to eq("label_contentinput_content")
|
|
243
|
+
}.and_return("content")
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it "returns wrapped label and input content" do
|
|
247
|
+
expect(subject.input_wrapper_with_label(:color, "input_content", label: "label_attributes", field: "field_attributes", options: "options"))
|
|
248
|
+
.to eq("content")
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
context "when block given" do
|
|
252
|
+
it "safely concatinate block output to content" do
|
|
253
|
+
content = 'input_content<input type="hidden" name="book[id]" id="book_id" />'
|
|
254
|
+
allow(subject).to receive(:wrapper).with(content, class: "value").and_return("input_content")
|
|
255
|
+
expect(subject.input_wrapper_with_label(:color, "input_content", label: "label_attributes", field: "field_attributes", options: "options"){ subject.hidden_field(:id) })
|
|
256
|
+
.to eq("content")
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
it "correctly handles block nil output" do
|
|
260
|
+
expect(subject.input_wrapper_with_label(:color, "input_content", label: "label_attributes", field: "field_attributes", options: "options"){ })
|
|
261
|
+
.to eq("content")
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
describe "#releaf_label" do
|
|
267
|
+
it "passes options :label value to #label_text and use returned value for label text content" do
|
|
268
|
+
allow(subject).to receive(:label_text).with(:color, a: "b").and_return("xx")
|
|
269
|
+
result = '<div class="label-wrap"><label for="book_color">xx</label></div>'
|
|
270
|
+
|
|
271
|
+
expect(subject.releaf_label(:color, {}, label: {a: "b"})).to eq(result)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it "uses #label_attributes for label attributes" do
|
|
275
|
+
allow(subject).to receive(:label_attributes).with(:color, {class: "red"}, {a: "b"}).and_return(class: "red blue")
|
|
276
|
+
result = '<div class="label-wrap"><label class="red blue" for="book_color">Color</label></div>'
|
|
277
|
+
|
|
278
|
+
expect(subject.releaf_label(:color, {class: "red"}, {a: "b"})).to eq(result)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
context "when options[:label][:description] is not blank" do
|
|
282
|
+
context "when label has full version" do
|
|
283
|
+
it "includes description" do
|
|
284
|
+
result = '<div class="label-wrap"><label for="book_color">Color</label><div class="description">xxx</div></div>'
|
|
285
|
+
expect(subject.releaf_label(:color, {}, label: {description: "xxx"})).to eq(result)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
context "when label has minimal version" do
|
|
290
|
+
it "does not include description" do
|
|
291
|
+
result = '<label for="book_color">Color</label>'
|
|
292
|
+
expect(subject.releaf_label(:color, {}, label: {minimal: true})).to eq(result)
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
context "when options[:label][:minimal] is true" do
|
|
298
|
+
it "returns label tag without wrap element" do
|
|
299
|
+
result = '<label for="book_color">Color</label>'
|
|
300
|
+
expect(subject).to_not receive(:wrapper)
|
|
301
|
+
expect(subject.releaf_label(:color, {}, label: {minimal: true})).to eq(result)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
context "when options[:label][:minimal] is not true" do
|
|
306
|
+
it "returns label tag with wrap element" do
|
|
307
|
+
allow(subject).to receive(:wrapper).with('<label for="book_color">Color</label>', class: "label-wrap").and_return("x")
|
|
308
|
+
expect(subject.releaf_label(:color, {}, label: {minimal: false})).to eq("x")
|
|
309
|
+
expect(subject.releaf_label(:color, {}, label: {minimal: nil})).to eq("x")
|
|
310
|
+
expect(subject.releaf_label(:color, {}, label: {adasd: "xx"})).to eq("x")
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
describe "#releaf_number_field" do
|
|
317
|
+
it "returns input with type 'number'" do
|
|
318
|
+
expect(subject).to receive(:number_field).with("title", { value: nil, step: "any", class: "text" }).and_return("x")
|
|
319
|
+
expect(subject).to receive(:input_wrapper_with_label).with("title", "x", { label: {}, field: {}, options: { field: { type: "number" }}}).and_return("y")
|
|
320
|
+
expect(subject.releaf_number_field("title")).to eq("y")
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
context "aliases" do
|
|
324
|
+
let(:releaf_number_field_method) { subject.method(:releaf_number_field) }
|
|
325
|
+
|
|
326
|
+
it "is aliased by #releaf_integer_field" do
|
|
327
|
+
expect(subject.method(:releaf_integer_field)).to eq(releaf_number_field_method)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "is aliased by #releaf_float_field" do
|
|
331
|
+
expect(subject.method(:releaf_float_field)).to eq(releaf_number_field_method)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it "is aliased by #releaf_decimal_field" do
|
|
335
|
+
expect(subject.method(:releaf_decimal_field)).to eq(releaf_number_field_method)
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
describe "#field_attributes" do
|
|
341
|
+
it "adds field data and class attributes" do
|
|
342
|
+
expect(subject.field_attributes(:color, {}, {field: {type: "text"}})).to eq(data: {name: :color}, class: ["field", "type-text"])
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
it "merges attributes over build-in data hash" do
|
|
346
|
+
expect(subject.field_attributes(:color, {data: {other: "x"}}, {})[:data]).to eq(name: :color, other: "x")
|
|
347
|
+
expect(subject.field_attributes(:color, {data: {other: "x", name: :lll}}, {})[:data]).to eq(name: :lll, other: "x")
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it "supports class attributes merging" do
|
|
351
|
+
expect(subject.field_attributes(:color, {class: ["a", "b"]}, {})[:class]).to eq(["field", "type-", "a", "b"])
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
describe "#label_attributes" do
|
|
356
|
+
it "returns unmodified attributes (allow further override by other builders)" do
|
|
357
|
+
expect(subject.label_attributes(:color, {data: "x"}, {})).to eq(data: "x")
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
describe "#input_attributes" do
|
|
362
|
+
it "returns unmodified attributes (allow further override by other builders)" do
|
|
363
|
+
expect(subject.input_attributes(:color, {data: "x"}, {})).to eq(data: "x")
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
describe "#label_text" do
|
|
368
|
+
it "returns model attributes scoped translated value" do
|
|
369
|
+
allow(subject).to receive(:translate_attribute).with("color").and_return("x")
|
|
370
|
+
expect(subject.label_text(:color)).to eq("x")
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
context "when :label_text option exists" do
|
|
374
|
+
context "when :label_text is not blank" do
|
|
375
|
+
it "returns :label_text option" do
|
|
376
|
+
expect(subject.label_text(:color, label_text: "krāsa")).to eq("krāsa")
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
context "when :label_text is blank" do
|
|
381
|
+
it "returns translated value" do
|
|
382
|
+
expect(subject.label_text(:color, label_text: nil)).to eq("Color")
|
|
383
|
+
expect(subject.label_text(:color, label_text: "")).to eq("Color")
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
context "when :translation_key option exists" do
|
|
389
|
+
context "when :translation_key is not blank" do
|
|
390
|
+
it "passes :translation_key option to translation and return translated value" do
|
|
391
|
+
allow(subject).to receive(:translate_attribute).with("true_color").and_return("x")
|
|
392
|
+
expect(subject.label_text(:color, translation_key: "true_color")).to eq("x")
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
context "when :translation_key is blank" do
|
|
397
|
+
it "returns translated value" do
|
|
398
|
+
expect(subject.label_text(:color, translation_key: nil)).to eq("Color")
|
|
399
|
+
expect(subject.label_text(:color, translation_key: "")).to eq("Color")
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
describe "#sortable_column_name" do
|
|
406
|
+
it "returns 'item_position'" do
|
|
407
|
+
expect( subject.sortable_column_name ).to eq 'item_position'
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
describe "#releaf_item_field_collection" do
|
|
412
|
+
context "when collection exists within options" do
|
|
413
|
+
it "returns collection" do
|
|
414
|
+
expect(subject.releaf_item_field_collection(:author_id, collection: "x")).to eq("x")
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
context "when collection does not exist within options" do
|
|
419
|
+
it "returns all relation objects" do
|
|
420
|
+
allow(Author).to receive(:all).and_return("y")
|
|
421
|
+
expect(subject.releaf_item_field_collection(:author_id)).to eq("y")
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
describe "#releaf_item_field_choices" do
|
|
427
|
+
before do
|
|
428
|
+
subject.object.author_id = 3
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
context "when no select_options passed within options" do
|
|
432
|
+
it "prefills select_options with corresponding collection array" do
|
|
433
|
+
collection = [Author.new(name: "a", surname: "b", id: 1), Author.new(name: "c", surname: "d", id: 2)]
|
|
434
|
+
allow(subject).to receive(:releaf_item_field_collection)
|
|
435
|
+
.with(:author_id, x: "a").and_return(collection)
|
|
436
|
+
allow(subject).to receive(:options_for_select).with([["a b", 1], ["c d", 2]], 3).and_return("xx")
|
|
437
|
+
expect(subject.releaf_item_field_choices(:author_id, x: "a")).to eq("xx")
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
context "when options have select_options passed" do
|
|
442
|
+
context "when select_options is array" do
|
|
443
|
+
it "process and return select options with `options_for_select` rails helper" do
|
|
444
|
+
collection = [["a b", 1], ["c d", 2]]
|
|
445
|
+
allow(subject).to receive(:options_for_select).with(collection, 3).and_return("xx")
|
|
446
|
+
expect(subject.releaf_item_field_choices(:author_id, select_options: collection)).to eq("xx")
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
context "when select_options is not array" do
|
|
451
|
+
it "returns select_options value" do
|
|
452
|
+
expect(subject.releaf_item_field_choices(:author_id, select_options: "xx")).to eq("xx")
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
describe "#relation_name" do
|
|
459
|
+
it "strips _id from given string and returns it as symbol" do
|
|
460
|
+
expect(subject.relation_name("admin_id")).to eq(:admin)
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
describe "#format_date_or_time_value" do
|
|
465
|
+
context "when given value type is :time" do
|
|
466
|
+
it "format normalized value to default format with `strftime`" do
|
|
467
|
+
value = Date.parse("15 Jan 2015")
|
|
468
|
+
time = Time.parse("15 Jan 2015 12:10:04")
|
|
469
|
+
allow(subject).to receive(:date_or_time_default_format).with(:time).and_return("%H:%M")
|
|
470
|
+
allow(subject).to receive(:normalize_date_or_time_value).with(value, :time).and_return(time)
|
|
471
|
+
|
|
472
|
+
expect(subject.format_date_or_time_value(value, :time)).to eq("12:10")
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
context "when given value type is other than :time" do
|
|
477
|
+
it "format normalized value to default format with `I18n.l`" do
|
|
478
|
+
value = Date.parse("15 Jan 2015")
|
|
479
|
+
time = Time.parse("15 Jan 2015 12:10:04")
|
|
480
|
+
|
|
481
|
+
allow(subject).to receive(:date_or_time_default_format).with(:date).and_return("_format_")
|
|
482
|
+
allow(subject).to receive(:normalize_date_or_time_value).with(value, :date).and_return(time)
|
|
483
|
+
allow(I18n).to receive(:l).with(time, default: "_format_").and_return("x")
|
|
484
|
+
expect(subject.format_date_or_time_value(value, :date)).to eq("x")
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
allow(subject).to receive(:date_or_time_default_format).with(:datetime).and_return("_format_")
|
|
488
|
+
allow(subject).to receive(:normalize_date_or_time_value).with(value, :datetime).and_return(time)
|
|
489
|
+
allow(I18n).to receive(:l).with(time, default: "_format_").and_return("y")
|
|
490
|
+
expect(subject.format_date_or_time_value(value, :datetime)).to eq("y")
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
describe "#locales" do
|
|
496
|
+
it "returns object globalize locales" do
|
|
497
|
+
allow(subject.object.class).to receive(:globalize_locales).and_return([:de, :ru])
|
|
498
|
+
expect(subject.locales).to eq([:de, :ru])
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
describe "#default_locale" do
|
|
503
|
+
before do
|
|
504
|
+
allow(subject).to receive(:cookies).and_return({})
|
|
505
|
+
allow(I18n).to receive(:locale).and_return(:ru)
|
|
506
|
+
allow(subject).to receive(:locales).and_return([:de, :ru])
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
context "when cookies has stored locale" do
|
|
510
|
+
it "returns stored locale normalized to symbol" do
|
|
511
|
+
allow(subject).to receive(:cookies).and_return("releaf.i18n.locale".to_sym => "de")
|
|
512
|
+
expect(subject.default_locale).to eq(:de)
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
context "when cookies hasn't stored locale" do
|
|
517
|
+
it "returns current I18n locale" do
|
|
518
|
+
expect(subject.default_locale).to eq(:ru)
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
context "when stored locale or I18n locale is not within form locales" do
|
|
523
|
+
it "returns first form locale" do
|
|
524
|
+
allow(subject).to receive(:locales).and_return([:lv, :en])
|
|
525
|
+
expect(subject.default_locale).to eq(:lv)
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
describe "#normalize_date_or_time_value" do
|
|
531
|
+
context "when :time type given" do
|
|
532
|
+
it "casts value to time" do
|
|
533
|
+
value = Date.parse("15 Jan 2015")
|
|
534
|
+
expect(subject.normalize_date_or_time_value(value, :time)).to be_instance_of Time
|
|
535
|
+
expect(subject.normalize_date_or_time_value(value, :time)).to eq(value.to_time)
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
context "when :datetime type given" do
|
|
540
|
+
it "casts value to datetime" do
|
|
541
|
+
value = Time.parse("15 Jan 2015 12:10:04")
|
|
542
|
+
expect(subject.normalize_date_or_time_value(value, :datetime)).to be_instance_of DateTime
|
|
543
|
+
expect(subject.normalize_date_or_time_value(value, :datetime)).to eq(value.to_datetime)
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
context "when :time type given" do
|
|
548
|
+
it "casts value to date" do
|
|
549
|
+
value = DateTime.parse("15 Jan 2015 12:10:04")
|
|
550
|
+
expect(subject.normalize_date_or_time_value(value, :date)).to be_instance_of Date
|
|
551
|
+
expect(subject.normalize_date_or_time_value(value, :date)).to eq(value.to_date)
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
describe "#translate_attribute" do
|
|
557
|
+
it "translates given attribute within object translation scope" do
|
|
558
|
+
allow(object.class).to receive(:human_attribute_name).with("x", create_default: false).and_return("z")
|
|
559
|
+
expect(subject.translate_attribute("x")).to eq("z")
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
end
|