releaf-core 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,21 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
describe Releaf::Builders::ResourceDialog, type: :class do
|
4
|
+
class DialogTestHelper < ActionView::Base
|
5
|
+
end
|
6
|
+
|
7
|
+
class UnitTestDialogBuilder
|
8
|
+
include Releaf::Builders::Base
|
9
|
+
include Releaf::Builders::Template
|
10
|
+
include Releaf::Builders::ResourceDialog
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { UnitTestDialogBuilder.new(template) }
|
14
|
+
let(:template){ DialogTestHelper.new }
|
15
|
+
|
16
|
+
describe "#dialog?" do
|
17
|
+
it "always returns true" do
|
18
|
+
expect(subject.dialog?).to be true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
describe Releaf::Builders::ResourceView, type: :class do
|
4
|
+
class ResourceViewIncluder
|
5
|
+
include Releaf::Builders::ResourceView
|
6
|
+
end
|
7
|
+
|
8
|
+
class ResourceViewTestHelper < ActionView::Base
|
9
|
+
include Releaf::ApplicationHelper
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:described_class){ ResourceViewIncluder }
|
13
|
+
let(:template){ ResourceViewTestHelper.new }
|
14
|
+
let(:subject){ described_class.new(template) }
|
15
|
+
let(:controller){ Releaf::BaseController.new }
|
16
|
+
let(:resource){ Book.new }
|
17
|
+
|
18
|
+
before do
|
19
|
+
allow(template).to receive(:controller).and_return(controller)
|
20
|
+
allow(subject).to receive(:resource).and_return(resource)
|
21
|
+
allow(subject).to receive(:index_url).and_return("_index_url_")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "includes Releaf::Builders::View" do
|
25
|
+
expect(described_class.ancestors).to include(Releaf::Builders::View)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "includes Releaf::Builders::Resource" do
|
29
|
+
expect(described_class.ancestors).to include(Releaf::Builders::Resource)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "includes Releaf::Builders::Toolbox" do
|
33
|
+
expect(described_class.ancestors).to include(Releaf::Builders::Toolbox)
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#section" do
|
37
|
+
before do
|
38
|
+
allow(subject).to receive(:section_attributes).and_return(a: "b")
|
39
|
+
allow(subject).to receive(:section_blocks).and_return(["_section_","_blocks_"])
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns section with index url preserver and section blocks" do
|
43
|
+
expect(subject.section).to eq('<section a="b">_section__blocks_</section>')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#section_header_text" do
|
48
|
+
before do
|
49
|
+
allow(subject).to receive(:t).with("Create new resource").and_return("newww")
|
50
|
+
allow(subject).to receive(:resource_to_text).with(resource).and_return("existng")
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when resource is new object" do
|
54
|
+
it "returns resource to text cast result" do
|
55
|
+
expect(subject.section_header_text).to eq("newww")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when resource is persisted object" do
|
60
|
+
it "returns resource to text cast result" do
|
61
|
+
allow(resource).to receive(:new_record?).and_return(false)
|
62
|
+
expect(subject.section_header_text).to eq("existng")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#section_header_extras" do
|
68
|
+
before do
|
69
|
+
allow(subject).to receive(:toolbox).with(resource, index_url: "_index_url_").and_return("_tlbx_")
|
70
|
+
allow(subject).to receive(:feature_available?).with(:toolbox).and_return(true)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "returns header extras with toolbox button" do
|
74
|
+
expect(subject.section_header_extras).to eq('<div class="extras toolbox-wrap">_tlbx_</div>')
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when toolbox feature is not available" do
|
78
|
+
it "returns nil" do
|
79
|
+
allow(subject).to receive(:feature_available?).with(:toolbox).and_return(false)
|
80
|
+
expect(subject.section_header_extras).to be nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#section_body" do
|
86
|
+
it "returns section body block with applied section body attributes" do
|
87
|
+
allow(subject).to receive(:section_body_blocks).and_return(["a", "b"])
|
88
|
+
allow(subject).to receive(:section_body_attributes).and_return(class: "x")
|
89
|
+
expect(subject.section_body).to eq('<div class="x">ab</div>')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#section_body_attributes" do
|
94
|
+
it "returns section hash with body class" do
|
95
|
+
expect(subject.section_body_attributes).to eq(class: ["body"])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#section_body_blocks" do
|
100
|
+
it "returns empty array" do
|
101
|
+
expect(subject.section_body_blocks).to eq([])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#footer_secondary_tools" do
|
106
|
+
before do
|
107
|
+
allow(subject).to receive(:back_to_list_button).and_return("_btn_")
|
108
|
+
allow(subject).to receive(:back_to_list?).and_return(true)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "returns array with back to list button" do
|
112
|
+
expect(subject.footer_secondary_tools).to eq(["_btn_"])
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when toolbox feature is not available" do
|
116
|
+
it "returns empty array" do
|
117
|
+
allow(subject).to receive(:back_to_list?).and_return(false)
|
118
|
+
expect(subject.footer_secondary_tools).to eq([])
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#back_to_list?" do
|
124
|
+
before do
|
125
|
+
allow(subject).to receive(:params).and_return(index_url: "xxx")
|
126
|
+
allow(subject).to receive(:feature_available?).with(:index).and_return(true)
|
127
|
+
end
|
128
|
+
|
129
|
+
context "when index feature is available and index_url is present within params" do
|
130
|
+
it "returns true" do
|
131
|
+
expect(subject.back_to_list?).to be true
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when index_url is not present within params" do
|
136
|
+
it "returns false" do
|
137
|
+
allow(subject).to receive(:params).and_return(search: "xxx")
|
138
|
+
expect(subject.back_to_list?).to be false
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "when index feature is not available" do
|
143
|
+
it "returns false" do
|
144
|
+
allow(subject).to receive(:feature_available?).with(:index).and_return(false)
|
145
|
+
expect(subject.back_to_list?).to be false
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#back_to_list_button" do
|
151
|
+
it "returns `back to list` button" do
|
152
|
+
allow(subject).to receive(:button)
|
153
|
+
.with("to_list", "caret-left", {class: "secondary", href: "_index_url_"}).and_return("_btn_")
|
154
|
+
allow(subject).to receive(:t).with("Back to list").and_return("to_list")
|
155
|
+
expect(subject.back_to_list_button).to eq("_btn_")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,638 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
describe Releaf::Builders::TableBuilder, type: :class do
|
4
|
+
class TableBuilderTestHelper < ActionView::Base
|
5
|
+
include Releaf::ApplicationHelper
|
6
|
+
end
|
7
|
+
|
8
|
+
class DummyTableBuilderInheriter < Releaf::Builders::TableBuilder
|
9
|
+
def some_cell_method(resource, column); end
|
10
|
+
def custom_format(resource, column); end
|
11
|
+
def format_big_boolean_content(resource, column); end
|
12
|
+
def title_cell; end
|
13
|
+
def custom_title(resource); end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:template){ TableBuilderTestHelper.new }
|
17
|
+
let(:resource_class){ Book }
|
18
|
+
let(:resource){ resource_class.new(id: 77, title: "Life of Brian") }
|
19
|
+
let(:collection){ Book.all }
|
20
|
+
let(:options){ {toolbox: false} }
|
21
|
+
let(:subject){ described_class.new(collection, resource_class, template, options) }
|
22
|
+
let(:inheriter_subject){ DummyTableBuilderInheriter.new(collection, resource_class, template, options) }
|
23
|
+
|
24
|
+
it "includes Releaf::Builders::Base" do
|
25
|
+
expect(described_class.ancestors).to include(Releaf::Builders::Base)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "includes Releaf::Builders::Toolbox" do
|
29
|
+
expect(described_class.ancestors).to include(Releaf::Builders::Toolbox)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "includes Releaf::Builders::Orderer" do
|
33
|
+
expect(described_class.ancestors).to include(Releaf::Builders::Orderer)
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#initialize" do
|
37
|
+
it "assigns collection" do
|
38
|
+
expect(subject.collection.to_sql).to eq(collection.to_sql)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "assigns resource_class" do
|
42
|
+
expect(subject.resource_class).to eq(resource_class)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "assigns template" do
|
46
|
+
expect(subject.template).to eq(template)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "assigns options" do
|
50
|
+
expect(subject.options).to eq(options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#columns" do
|
55
|
+
it "returns columns schema" do
|
56
|
+
allow(subject).to receive(:columns_schema).and_return("schema")
|
57
|
+
expect(subject.columns).to eq("schema")
|
58
|
+
end
|
59
|
+
|
60
|
+
it "caches columns schema data" do
|
61
|
+
expect(subject).to receive(:columns_schema).and_return("schema").once
|
62
|
+
subject.columns
|
63
|
+
subject.columns
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#column_names" do
|
68
|
+
it "returns column names for resource_class" do
|
69
|
+
allow(Releaf::Core::ResourceTableFields).to receive(:new).with(subject.resource_class).and_call_original
|
70
|
+
allow_any_instance_of(Releaf::Core::ResourceTableFields).to receive(:values)
|
71
|
+
.with(include_associations: false).and_return(["a", "b"])
|
72
|
+
expect(subject.column_names).to eq(["a", "b"])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#columns_schema" do
|
77
|
+
before do
|
78
|
+
allow(subject).to receive(:column_names).and_return([:price, :title, :author_id])
|
79
|
+
allow(subject).to receive(:cell_content_method).with(:price).and_return(:title_content)
|
80
|
+
allow(subject).to receive(:cell_content_method).with(:title).and_return(:title_content)
|
81
|
+
allow(subject).to receive(:cell_content_method).with(:author_id).and_return(nil)
|
82
|
+
allow(subject).to receive(:cell_format_method).with(:author_id).and_return(:some_text_format)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns hash with columns and corresponding method" do
|
86
|
+
allow(subject).to receive(:cell_method).with(:price).and_return("price_cell")
|
87
|
+
allow(subject).to receive(:cell_method).with(:title).and_return(nil)
|
88
|
+
allow(subject).to receive(:cell_method).with(:author_id).and_return(nil)
|
89
|
+
columns = {
|
90
|
+
price: {cell_method: "price_cell"},
|
91
|
+
title: {content_method: :title_content},
|
92
|
+
author_id: {format_method: :some_text_format}
|
93
|
+
}
|
94
|
+
expect(subject.columns_schema).to eq(columns)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "preserves order as in #column_names" do
|
98
|
+
expect(subject.columns_schema.keys).to eq([:price, :title, :author_id])
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when options[:toolbox] value is 'true'" do
|
102
|
+
let(:options){ {toolbox: true} }
|
103
|
+
it "adds toolbox as last column" do
|
104
|
+
expect(subject.columns_schema.keys.last).to eq(:toolbox)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "uses #toolbox_cell for toolbox cell rendering" do
|
108
|
+
expect(subject.columns_schema[:toolbox]).to eq(cell_method: "toolbox_cell")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#column_klass" do
|
114
|
+
context "when association column given" do
|
115
|
+
it "returns corresponding association class" do
|
116
|
+
resource.author = Author.new(name: "Brian")
|
117
|
+
expect(subject.column_klass(resource_class, "author.name")).to eq(Author)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when base resource column given" do
|
122
|
+
it "returns give resource class" do
|
123
|
+
expect(subject.column_klass(resource_class, "year")).to eq(resource_class)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "#column_value" do
|
129
|
+
it "returns value for column of given resource" do
|
130
|
+
expect(subject.column_value(resource, "title")).to eq("Life of Brian")
|
131
|
+
end
|
132
|
+
|
133
|
+
it "supports association columns" do
|
134
|
+
resource.author = Author.new(name: "Brian")
|
135
|
+
expect(subject.column_value(resource, "author.name")).to eq("Brian")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "supports empty association columns" do
|
139
|
+
resource.author = nil
|
140
|
+
expect(subject.column_value(resource, "author.name")).to be nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "#output" do
|
145
|
+
before do
|
146
|
+
allow(subject).to receive(:empty_body).and_return("empty")
|
147
|
+
end
|
148
|
+
|
149
|
+
it "returns table with #empty_body content" do
|
150
|
+
allow(subject).to receive(:table_attributes).and_return(class: "a", data: {some: "b"})
|
151
|
+
content = '<table class="a" data-some="b">empty</table>'
|
152
|
+
expect(subject.output).to eq(content)
|
153
|
+
end
|
154
|
+
|
155
|
+
context "when collection is not empty" do
|
156
|
+
it "returns table with #header and #body" do
|
157
|
+
create(:book)
|
158
|
+
content = '<table class="table books">header_contentbody_content</table>'
|
159
|
+
allow(subject).to receive(:head).and_return("header_content")
|
160
|
+
allow(subject).to receive(:body).and_return("body_content")
|
161
|
+
|
162
|
+
expect(subject.output).to eq(content)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "when collection is empty" do
|
167
|
+
it "returns table with #empty_body content" do
|
168
|
+
content = '<table class="table books">empty</table>'
|
169
|
+
expect(subject.output).to eq(content)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "#table_attributes" do
|
175
|
+
it "returns hash with table and pluralized, dasherized resource classes" do
|
176
|
+
expect(subject.table_attributes).to eq(class: ["table", "books"])
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "#head" do
|
181
|
+
it "returns header row with #head_cell generated cells for each columns" do
|
182
|
+
allow(subject).to receive(:column_names).and_return([:price, :title, :author_id])
|
183
|
+
allow(subject).to receive(:head_cell).with(:price).and_return("_price_cell_")
|
184
|
+
allow(subject).to receive(:head_cell).with(:title).and_return("_title_cell_")
|
185
|
+
allow(subject).to receive(:head_cell).with(:author_id).and_return("_author_id_cell_")
|
186
|
+
|
187
|
+
content = '<thead><tr>_price_cell__title_cell__author_id_cell_</tr></thead>'
|
188
|
+
expect(subject.head).to eq(content)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe "#head_cell" do
|
193
|
+
it "returns 'th' element with content from #head_cell_column" do
|
194
|
+
allow(subject).to receive(:head_cell_content).with(:title).and_return("_title_content_")
|
195
|
+
content = '<th>_title_content_</th>'
|
196
|
+
expect(subject.head_cell(:title)).to eq(content)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
describe "#head_cell_content" do
|
202
|
+
it "returns translated column scoped to resource class attributes" do
|
203
|
+
allow(resource_class).to receive(:human_attribute_name).with("some_long_name", create_default: false).and_return("Taittls")
|
204
|
+
expect(subject.head_cell_content("some_long_name")).to eq('Taittls')
|
205
|
+
end
|
206
|
+
|
207
|
+
it "casts given column to string" do
|
208
|
+
allow(resource_class).to receive(:human_attribute_name).with("title", create_default: false).and_return("Taittls")
|
209
|
+
expect(subject.head_cell_content(:title)).to eq('Taittls')
|
210
|
+
end
|
211
|
+
|
212
|
+
context "when column value is 'toolbox'" do
|
213
|
+
it "returns nil" do
|
214
|
+
expect(subject.head_cell_content(:toolbox)).to eq(nil)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe "#empty_body" do
|
220
|
+
it "returns empty table body content" do
|
221
|
+
allow(subject).to receive(:t).with("Nothing found").and_return("ntnn")
|
222
|
+
content = '<tr><th><div class="nothing-found">ntnn</div></th></tr>'
|
223
|
+
expect(subject.empty_body).to eq(content)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe "#body" do
|
228
|
+
it "returns table body with rows for each collection items generated with #row method" do
|
229
|
+
subject.collection = ["a", "b"]
|
230
|
+
allow(subject).to receive(:row).with("a").and_return("_a_row_")
|
231
|
+
allow(subject).to receive(:row).with("b").and_return("_b_row_")
|
232
|
+
|
233
|
+
content = '<tbody class="tbody">_a_row__b_row_</tbody>'
|
234
|
+
expect(subject.body).to eq(content)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe "#row_url" do
|
239
|
+
let(:controller){ Releaf::BaseController.new }
|
240
|
+
|
241
|
+
before do
|
242
|
+
allow(subject).to receive(:controller).and_return(controller)
|
243
|
+
allow(controller).to receive(:index_url).and_return("_index_url_")
|
244
|
+
end
|
245
|
+
|
246
|
+
it "returns edit url for given resource" do
|
247
|
+
allow(subject).to receive(:row_url_action).with(resource).and_return(:show)
|
248
|
+
allow(template).to receive(:url_for).with(action: :show, id: 77, index_url: "_index_url_").and_return('_url_')
|
249
|
+
expect(subject.row_url(resource)).to eq('_url_')
|
250
|
+
end
|
251
|
+
|
252
|
+
context "when resource do not have row url action" do
|
253
|
+
it "returns nil" do
|
254
|
+
allow(subject).to receive(:row_url_action).with(resource).and_return(nil)
|
255
|
+
expect(subject.row_url(resource)).to be nil
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "#row_url_action" do
|
261
|
+
let(:controller){ Releaf::BaseController.new }
|
262
|
+
|
263
|
+
before do
|
264
|
+
allow(subject).to receive(:controller).and_return(controller)
|
265
|
+
allow(controller).to receive(:feature_available?).with(:show).and_return(true)
|
266
|
+
allow(controller).to receive(:feature_available?).with(:edit).and_return(true)
|
267
|
+
end
|
268
|
+
|
269
|
+
context "when show and edit features is available" do
|
270
|
+
it "returns :show" do
|
271
|
+
expect(subject.row_url_action(resource)).to eq(:show)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
context "when show feature is not available and edit feature is available" do
|
276
|
+
it "returns :edit" do
|
277
|
+
allow(controller).to receive(:feature_available?).with(:show).and_return(false)
|
278
|
+
expect(subject.row_url_action(resource)).to eq(:edit)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
context "when show and edit features is not available" do
|
283
|
+
it "returns nil" do
|
284
|
+
allow(controller).to receive(:feature_available?).with(:show).and_return(false)
|
285
|
+
allow(controller).to receive(:feature_available?).with(:edit).and_return(false)
|
286
|
+
expect(subject.row_url_action(resource)).to be nil
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
describe "#row_attributes" do
|
292
|
+
it "returns row attributes with html class and resource id as data value" do
|
293
|
+
resource = resource_class.new(id: 77)
|
294
|
+
expect(subject.row_attributes(resource)).to eq(class: "row", data: {id: 77})
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
describe "#row" do
|
299
|
+
it "adds attributes returned from #row_attributes to row" do
|
300
|
+
resource = resource_class.new
|
301
|
+
allow(subject).to receive(:column_names).and_return([])
|
302
|
+
allow(subject).to receive(:row_attributes).with(resource).and_return(class: "color", data: {color: "red"})
|
303
|
+
allow(subject).to receive(:row_url)
|
304
|
+
|
305
|
+
content = '<tr class="color" data-color="red"></tr>'
|
306
|
+
expect(subject.row(resource)).to eq(content)
|
307
|
+
end
|
308
|
+
|
309
|
+
it "calls #row_url only once" do
|
310
|
+
resource = resource_class.new
|
311
|
+
allow(subject).to receive(:column_names).and_return([:title, :author_id])
|
312
|
+
expect(subject).to receive(:row_url).with(resource).once
|
313
|
+
subject.row(resource)
|
314
|
+
end
|
315
|
+
|
316
|
+
it "output each cell contents by using either custom or default cell method" do
|
317
|
+
columns = {
|
318
|
+
title: {cell_method: "some_cell_method"},
|
319
|
+
color: {},
|
320
|
+
}
|
321
|
+
resource = resource_class.new(id: 89)
|
322
|
+
|
323
|
+
allow(inheriter_subject).to receive(:columns).and_return(columns)
|
324
|
+
allow(inheriter_subject).to receive(:row_url).with(resource).and_return("url_value")
|
325
|
+
|
326
|
+
allow(inheriter_subject).to receive(:some_cell_method)
|
327
|
+
.with(resource, cell_method: "some_cell_method", url: "url_value").and_return("_title_cell_value")
|
328
|
+
allow(inheriter_subject).to receive(:cell)
|
329
|
+
.with(resource, :color, url: "url_value").and_return("_color_cell_value")
|
330
|
+
|
331
|
+
content = '<tr class="row" data-id="89">_title_cell_value_color_cell_value</tr>'
|
332
|
+
expect(inheriter_subject.row(resource)).to eq(content)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
describe "#cell_content" do
|
337
|
+
it "returns format method output with resource and column as arguments" do
|
338
|
+
options = {format_method: "custom_format"}
|
339
|
+
allow(inheriter_subject).to receive(:custom_format).with("a", :title).and_return('_custom " format_')
|
340
|
+
|
341
|
+
content = '_custom " format_'
|
342
|
+
expect(inheriter_subject.cell_content("a", :title, options)).to eq(content)
|
343
|
+
end
|
344
|
+
|
345
|
+
context "when given options has :content_method" do
|
346
|
+
it "returns content method output with resource as argument" do
|
347
|
+
options = {content_method: "custom_title", format_method: "custom_format"}
|
348
|
+
allow(inheriter_subject).to receive(:custom_title).with("a").and_return('_custom " _value_')
|
349
|
+
|
350
|
+
content = '_custom " _value_'
|
351
|
+
expect(inheriter_subject.cell_content("a", :title, options)).to eq(content)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe "#format_text_content" do
|
357
|
+
it "returns truncated and escape column value" do
|
358
|
+
allow(subject).to receive(:column_value).with(resource, :title)
|
359
|
+
.and_return('"Pra<tag>nt commodo cursus magn')
|
360
|
+
expect(subject.format_text_content(resource, :title))
|
361
|
+
.to eq('"Pra<tag>nt commodo cursus magn')
|
362
|
+
end
|
363
|
+
|
364
|
+
it "casts value to string before truncation" do
|
365
|
+
allow(subject).to receive(:column_value).with(resource, :title)
|
366
|
+
.and_return(nil)
|
367
|
+
expect(subject.format_text_content(resource, :title)).to eq("")
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
describe "#format_string_content" do
|
372
|
+
context "when resource column value respond to #to_text method" do
|
373
|
+
it "returns value #to_text" do
|
374
|
+
fake_obj = double
|
375
|
+
allow(fake_obj).to receive(:to_text).and_return("nineninine")
|
376
|
+
|
377
|
+
allow(subject).to receive(:column_value).with(resource, :id)
|
378
|
+
.and_return(fake_obj)
|
379
|
+
|
380
|
+
expect(subject.format_string_content(resource, :id)).to eq("nineninine")
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
context "when resource column value do not respond to #to_text method" do
|
385
|
+
it "returns value casted to string" do
|
386
|
+
allow(subject).to receive(:column_value).with(resource, :id)
|
387
|
+
.and_return(99)
|
388
|
+
|
389
|
+
expect(subject.format_string_content(resource, :id)).to eq("99")
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
describe "#format_boolean_content" do
|
395
|
+
context "when resource column value is 'true'" do
|
396
|
+
it "returns localized 'yes' value" do
|
397
|
+
allow(subject).to receive(:t).with("Yes").and_return("Jā")
|
398
|
+
allow(subject).to receive(:column_value).with(resource, :active)
|
399
|
+
.and_return(true)
|
400
|
+
|
401
|
+
expect(subject.format_boolean_content(resource, :active)).to eq("Jā")
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
context "when resource column value is other than 'true'" do
|
406
|
+
it "returns localized 'no' value" do
|
407
|
+
allow(subject).to receive(:t).with("No").and_return("Nē")
|
408
|
+
allow(subject).to receive(:column_value).with(resource, :active)
|
409
|
+
.and_return(false)
|
410
|
+
expect(subject.format_boolean_content(resource, :active)).to eq("Nē")
|
411
|
+
|
412
|
+
allow(subject).to receive(:column_value).with(resource, :active)
|
413
|
+
.and_return(nil)
|
414
|
+
expect(subject.format_boolean_content(resource, :active)).to eq("Nē")
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
describe "#format_date_content" do
|
420
|
+
it "returns localized date value" do
|
421
|
+
value = Date.parse("2012.12.29")
|
422
|
+
allow(subject).to receive(:column_value).with(resource, :birth_date)
|
423
|
+
.and_return(value)
|
424
|
+
|
425
|
+
expect(I18n).to receive(:l).with(value, format: :default, default: "%Y-%m-%d")
|
426
|
+
.and_call_original
|
427
|
+
|
428
|
+
expect(subject.format_date_content(resource, :birth_date)).to eq("2012-12-29")
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
describe "#format_datetime_content" do
|
433
|
+
it "returns localized datetime value" do
|
434
|
+
value = DateTime.parse("2012.12.29 17:12:07")
|
435
|
+
allow(subject).to receive(:column_value).with(resource, :created_at)
|
436
|
+
.and_return(value)
|
437
|
+
|
438
|
+
expect(I18n).to receive(:l).with(value, format: :default, default: "%Y-%m-%d %H:%M:%S")
|
439
|
+
.and_call_original
|
440
|
+
|
441
|
+
expect(subject.format_datetime_content(resource, :created_at)).to eq("2012-12-29 17:12:07")
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
describe "#association_name" do
|
446
|
+
it "normalizes given column name by removing '_id' postfix and returning new value as symbol" do
|
447
|
+
expect(subject.association_name(:author_id)).to eq(:author)
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
describe "#format_association_content" do
|
452
|
+
it "pass resource and association name to #format_string_content" do
|
453
|
+
resource = resource_class.new
|
454
|
+
allow(subject).to receive(:association_name).with(:author_id).and_return(:another_author)
|
455
|
+
allow(subject).to receive(:format_string_content).with(resource, :another_author).and_return("x")
|
456
|
+
|
457
|
+
expect(subject.format_association_content(resource, :author_id)).to eq("x")
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
describe "#cell_content_method" do
|
462
|
+
context "when custom cell content method exists" do
|
463
|
+
it "returns custom cell content method name" do
|
464
|
+
expect(subject.cell_content_method(:format_string)).to eq("format_string_content")
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
context "when custom cell content does not method exist" do
|
469
|
+
it "returns nil" do
|
470
|
+
expect(subject.cell_content_method(:title)).to be nil
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
describe "#cell_method" do
|
476
|
+
context "when custom cell method exists" do
|
477
|
+
it "returns custom cell method name" do
|
478
|
+
expect(inheriter_subject.cell_method(:title)).to eq("title_cell")
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
context "when custom cell does not method exist" do
|
483
|
+
it "returns nil" do
|
484
|
+
expect(subject.cell_method(:title)).to be nil
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
describe "#toolbox_cell" do
|
490
|
+
let(:controller){ double(ActionController::Base) }
|
491
|
+
before do
|
492
|
+
allow(subject).to receive(:controller).and_return(controller)
|
493
|
+
allow(controller).to receive(:index_url).and_return("_index_url_")
|
494
|
+
end
|
495
|
+
|
496
|
+
it "returns cell with toolbox" do
|
497
|
+
allow(subject).to receive(:toolbox)
|
498
|
+
.with(resource, index_url: "_index_url_").and_return("_toolbox_")
|
499
|
+
|
500
|
+
content = '<td class="only-icon toolbox-cell">_toolbox_</td>'
|
501
|
+
expect(subject.toolbox_cell(resource, {})).to eq(content)
|
502
|
+
end
|
503
|
+
|
504
|
+
it "merges given toolbox options and passes it to toolbox heplper" do
|
505
|
+
allow(subject.controller).to receive(:index_url).and_return("_index_url_")
|
506
|
+
expect(subject).to receive(:toolbox)
|
507
|
+
.with(resource, index_url: "_index_url_", some_url: "xx").and_return("_toolbox_")
|
508
|
+
subject.toolbox_cell(resource, {toolbox: {some_url: "xx"}})
|
509
|
+
|
510
|
+
expect(subject).to receive(:toolbox)
|
511
|
+
.with(resource, index_url: "xx").and_return("_toolbox_")
|
512
|
+
subject.toolbox_cell(resource, {toolbox: {index_url: "xx"}})
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
describe "#format_image_content" do
|
517
|
+
context "when resource value is not blank" do
|
518
|
+
let(:resource){ create(:book, cover_image: File.expand_path('../fixtures/cs.png', __dir__)) }
|
519
|
+
|
520
|
+
it "returns thumnail image" do
|
521
|
+
pattern = /\<img alt=\"\" src=\"\/media\/.*\" \/\>/
|
522
|
+
expect(subject.format_image_content(resource, :cover_image_uid)).to match(pattern)
|
523
|
+
end
|
524
|
+
|
525
|
+
it "uses 16px height for thumbnail" do
|
526
|
+
expect(resource.cover_image).to receive(:thumb).with('x16').and_call_original
|
527
|
+
subject.format_image_content(resource, :cover_image_uid)
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
context "when resource value is blank" do
|
532
|
+
it "returns nil" do
|
533
|
+
expect(subject.format_image_content(resource, :cover_image_uid)).to be nil
|
534
|
+
end
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
describe "#column_type" do
|
539
|
+
it "returns database column type for given column" do
|
540
|
+
expect(subject.column_type(resource_class, :active)).to eq(:boolean)
|
541
|
+
expect(subject.column_type(resource_class, :created_at)).to eq(:datetime)
|
542
|
+
end
|
543
|
+
|
544
|
+
context "when given column does not exists within database column definitions" do
|
545
|
+
it "returns :string as default value" do
|
546
|
+
expect(subject.column_type(resource_class, :random_title)).to eq(:string)
|
547
|
+
end
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
551
|
+
describe "#column_type_format_method" do
|
552
|
+
it "uses column klass and column name for type calculation" do
|
553
|
+
allow(subject).to receive(:column_klass).with(resource_class, "some.column").and_return(Chapter)
|
554
|
+
expect(subject).to receive(:column_type).with(Chapter, "some.column")
|
555
|
+
subject.column_type_format_method("some.column")
|
556
|
+
end
|
557
|
+
|
558
|
+
context "when format method for returned column type exists" do
|
559
|
+
it "returns column type format method" do
|
560
|
+
allow(subject).to receive(:column_type).and_return(:date)
|
561
|
+
expect(subject.column_type_format_method(:title)).to eq(:format_date_content)
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
context "when format method for returned column type does not exist" do
|
566
|
+
it "returns :format_string_content" do
|
567
|
+
allow(subject).to receive(:column_type).and_return(:big_boolean)
|
568
|
+
expect(subject.column_type_format_method(:title)).to eq(:format_string_content)
|
569
|
+
end
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
describe "#cell_format_method" do
|
574
|
+
before do
|
575
|
+
allow(subject).to receive(:association_column?).with(:title).and_return(false)
|
576
|
+
allow(subject).to receive(:image_column?).with(:title).and_return(false)
|
577
|
+
allow(subject).to receive(:column_type_format_method).with(:title).and_return(:format_crazy_shit)
|
578
|
+
end
|
579
|
+
|
580
|
+
it "returns #column_type_format_method for given column" do
|
581
|
+
expect(subject.cell_format_method(:title)).to eq(:format_crazy_shit)
|
582
|
+
end
|
583
|
+
|
584
|
+
context "when #association_column? returns true for given column" do
|
585
|
+
it "returns :format_association_content" do
|
586
|
+
allow(subject).to receive(:association_column?).with(:title).and_return(true)
|
587
|
+
expect(subject.cell_format_method(:title)).to eq(:format_association_content)
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
context "when #association_column? returns true for given column" do
|
592
|
+
it "returns :format_association_content" do
|
593
|
+
allow(subject).to receive(:image_column?).with(:title).and_return(true)
|
594
|
+
expect(subject.cell_format_method(:title)).to eq(:format_image_content)
|
595
|
+
end
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
describe "#association_column?" do
|
600
|
+
context "when given column is association" do
|
601
|
+
it "returns true" do
|
602
|
+
expect(subject.association_column?(:author_id)).to be true
|
603
|
+
end
|
604
|
+
end
|
605
|
+
|
606
|
+
context "when given column is not association" do
|
607
|
+
it "returns false" do
|
608
|
+
expect(subject.association_column?(:title)).to be false
|
609
|
+
end
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
describe "#cell" do
|
614
|
+
context "when cell options :url value is blank" do
|
615
|
+
it "returns cell with #cell_content output" do
|
616
|
+
options = {a: "x"}
|
617
|
+
allow(subject).to receive(:cell_content)
|
618
|
+
.with(resource, :title, options).and_return("_cell_content_")
|
619
|
+
content = '<td>_cell_content_</td>'
|
620
|
+
|
621
|
+
expect(subject.cell(resource, :title, options)).to eq(content)
|
622
|
+
|
623
|
+
options[:url] = nil
|
624
|
+
expect(subject.cell(resource, :title, options)).to eq(content)
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
context "when cell options :url value is not blank" do
|
629
|
+
it "returns cell with #cell_content output wrapped in 'a' element" do
|
630
|
+
allow(subject).to receive(:cell_content)
|
631
|
+
.with(resource, :title, {a: "x", url: "y"}).and_return("_cell_content_")
|
632
|
+
|
633
|
+
content = '<td><a href="y">_cell_content_</a></td>'
|
634
|
+
expect(subject.cell(resource, :title, {a: "x", url: "y"})).to eq(content)
|
635
|
+
end
|
636
|
+
end
|
637
|
+
end
|
638
|
+
end
|