From 6606aa29cd869356c181e97b2d4fd7e92566c595 Mon Sep 17 00:00:00 2001 From: Mantas Masalskis Date: Wed, 18 Sep 2019 19:25:04 +0200 Subject: [PATCH] Don't use stubs for UserInfo.current_user_id because it blocks the use case where UserInfo.current_user_id is changed at runtime. --- .gitlab-ci.yml | 1 + .rubocop_todo.yml | 7 - .../knowledge_base_breadcrumb_helper.rb | 58 ++++++ app/helpers/knowledge_base_helper.rb | 174 +----------------- ...knowledge_base_public_page_title_helper.rb | 21 +++ .../knowledge_base_rich_text_helper.rb | 25 +++ app/helpers/knowledge_base_top_bar_helper.rb | 38 ++++ .../knowledge_base_visibility_note_helper.rb | 41 +++++ app/models/knowledge_base/answer.rb | 3 + .../public/_breadcrumb.html.erb | 4 +- .../public/answers/show.html.erb | 4 +- .../public/categories/_answer.html.erb | 2 +- .../public/categories/_category.html.erb | 2 +- .../public/categories/index.html.erb | 4 +- .../knowledge_base/public/not_found.html.erb | 2 +- .../public/show_alternatives.html.erb | 2 +- app/views/layouts/knowledge_base.html.erb | 10 +- spec/factories/knowledge_base.rb | 2 +- spec/factories/knowledge_base/answer.rb | 6 + .../knowledge_base/answer/translation.rb | 27 ++- .../answer/translation/content.rb | 2 +- spec/factories/knowledge_base/category.rb | 6 + .../knowledge_base/category/translation.rb | 30 ++- spec/factories/knowledge_base/translation.rb | 1 + .../answer/translation/content_spec.rb | 4 +- .../knowledge_base/answer/translation_spec.rb | 4 +- spec/models/knowledge_base/answer_spec.rb | 2 +- spec/models/knowledge_base/category_spec.rb | 2 +- spec/support/capybara/selectors.rb | 19 ++ spec/support/knowledge_base_contexts.rb | 35 ++++ spec/support/user_info.rb | 34 +--- .../knowledge_base_public/editor_spec.rb | 42 +++++ .../knowledge_base_public/guest_spec.rb | 110 +++++++++++ 33 files changed, 482 insertions(+), 242 deletions(-) create mode 100644 app/helpers/knowledge_base_breadcrumb_helper.rb create mode 100644 app/helpers/knowledge_base_public_page_title_helper.rb create mode 100644 app/helpers/knowledge_base_rich_text_helper.rb create mode 100644 app/helpers/knowledge_base_top_bar_helper.rb create mode 100644 app/helpers/knowledge_base_visibility_note_helper.rb create mode 100644 spec/support/knowledge_base_contexts.rb create mode 100644 spec/system/knowledge_base_public/editor_spec.rb create mode 100644 spec/system/knowledge_base_public/guest_spec.rb diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e2977302d..db58de1ec 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -336,6 +336,7 @@ browser:build: paths: - public/assets/.sprockets-manifest* - public/assets/application-* + - public/assets/knowledge_base* - public/assets/print-* .services_browser_template: &services_browser_definition diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 633278d00..d55e39f3e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -86,13 +86,6 @@ Rails/HasManyOrHasOneDependent: - 'app/models/ticket/state_type.rb' - 'app/models/user.rb' -# Offense count: 15 -# Configuration parameters: Include. -# Include: app/helpers/**/*.rb -Rails/HelperInstanceVariable: - Exclude: - - 'app/helpers/knowledge_base_helper.rb' - # Offense count: 808 Style/Documentation: Enabled: false diff --git a/app/helpers/knowledge_base_breadcrumb_helper.rb b/app/helpers/knowledge_base_breadcrumb_helper.rb new file mode 100644 index 000000000..57880285b --- /dev/null +++ b/app/helpers/knowledge_base_breadcrumb_helper.rb @@ -0,0 +1,58 @@ +module KnowledgeBaseBreadcrumbHelper + def render_breadcrumb_if_needed(knowledge_base, object, alternative) + objects = calculate_breadcrumb_path(object, alternative) + + return if objects.empty? + + render 'knowledge_base/public/breadcrumb', + { + objects: objects, + knowledge_base: knowledge_base + } + end + + def calculate_breadcrumb_path(object, alternative) + objects = calculate_breadcrumb_to_category(object&.parent) + + last = if alternative.present? && alternative.translations.any? + Translation.translate(system_locale_via_uri&.locale, 'Alternative translations') + else + object + end + + objects + [last].compact + end + + def calculate_breadcrumb_to_category(category) + return [] if category.blank? + + output = [category] + + parent = category + while (parent = find_category(parent&.parent_id)) + output << parent + end + + output.compact.reverse + end + + def breadcrumb_path_for(object, locale = params.fetch(:locale)) + case object + when KnowledgeBase + help_root_path(locale: locale) + when KnowledgeBase::Category + help_category_path(object.translation, locale: locale) + when KnowledgeBase::Answer + help_answer_path(object.category.translation, object.translation, locale: locale) + end + end + + def breadcrumb_text_for(object) + case object + when HasTranslations + object.translation.title + else + object + end + end +end diff --git a/app/helpers/knowledge_base_helper.rb b/app/helpers/knowledge_base_helper.rb index 0e9bf8a1c..78dc13193 100644 --- a/app/helpers/knowledge_base_helper.rb +++ b/app/helpers/knowledge_base_helper.rb @@ -1,97 +1,11 @@ module KnowledgeBaseHelper - def render_breadcrumb_if_needed - objects = [] + def effective_layout_name(knowledge_base, object) + layout_prefix = object.present? ? :category : :homepage - if @object - objects += calculate_breadcrumb_to_category(@category || @object&.parent) - end - - last = if @alternative.present? && @alternative.translations.any? - Translation.translate(system_locale_via_uri&.locale, 'Alternative translations') - else - @object - end - - objects << last if last.present? - - return if objects.empty? - - render 'knowledge_base/public/breadcrumb', - { - objects: objects, - knowledge_base: @knowledge_base - } + knowledge_base.send("#{layout_prefix}_layout") end - def calculate_breadcrumb_to_category(category) - output = [category] - - parent = category - while (parent = find_category(parent&.parent_id)) - output << parent - end - - output.compact.reverse - end - - def visibility_note(object) - return if !current_user&.permissions?('knowledge_base.editor') - - text = visibility_text(object) - - return if text.nil? - - render 'knowledge_base/public/visibility_note', text: text - end - - def visibility_text(object) - case object - when CanBePublished - visiblity_text_can_be_published(object) - when KnowledgeBase::Category - visiblity_text_category(object) - end - end - - def visiblity_text_can_be_published(object) - case object.can_be_published_aasm.current_state - when :internal - 'internal' - when :archived - 'archived' - when :draft - 'not published' - end - end - - def visiblity_text_category(object) - return if object.public_content? - - if object.self_with_children_answers.only_internal.any? - 'hidden, visible only internally' - else - 'hidden, no published answers' - end - end - - def breadcrumb_path_for(object, locale = params.fetch(:locale)) - case object - when KnowledgeBase - help_root_path(locale: locale) - when KnowledgeBase::Category - help_category_path(object.translation, locale: locale) - when KnowledgeBase::Answer - help_answer_path(object.category.translation, object.translation, locale: locale) - end - end - - def effective_layout_name - layout_prefix = @object.present? ? :category : :homepage - - @knowledge_base.send("#{layout_prefix}_layout") - end - - def custom_path_if_needed(path, knowledge_base = @knowledge_base) + def custom_path_if_needed(path, knowledge_base) return path if knowledge_base.custom_address_matches? request prefix = knowledge_base.custom_address_uri&.path @@ -117,43 +31,6 @@ module KnowledgeBaseHelper "edit #{suffix}" end - def kb_top_bar_tag(object) - case object - when KnowledgeBase::Answer - object.can_be_published_aasm.current_state - when KnowledgeBase::Category - kb_locale = object&.translation&.kb_locale - object.public_content?(kb_locale) ? 'Visible' : 'Invisible' - when KnowledgeBase - 'Published' - end - end - - def kb_top_bar_color(object) - case object - when KnowledgeBase::Answer - kb_answer_top_bar_color(object) - when KnowledgeBase::Category - kb_locale = object&.translation&.kb_locale - object.public_content?(kb_locale) ? 'green' : 'yellow' - when KnowledgeBase - 'green' - end - end - - def kb_answer_top_bar_color(answer) - case answer.can_be_published_aasm.current_state - when :draft - 'yellow' - when :internal - 'blue' - when :published - 'green' - when :archived - 'grey' - end - end - def build_kb_link(object) locale = params.fetch(:locale, object.translation.kb_locale) @@ -177,47 +54,4 @@ module KnowledgeBaseHelper .build(host: host, scheme: scheme, port: port, fragment: path) .to_s end - - def kb_public_page_title - title = @knowledge_base.translation.title - - if @page_title_error - suffix = case @page_title_error - when :not_found - 'Not Found' - when :alternatives - 'Alternative Translations' - end - - title + " - #{zt(suffix)}" - elsif @object - title + " - #{@object.translation.title}" - else - title - end - end - - def prepare_rich_text_links(input) - scrubber = Loofah::Scrubber.new do |node| - next if node.name != 'a' - next if !node.key? 'data-target-type' - - case node['data-target-type'] - when 'knowledge-base-answer' - if (translation = KnowledgeBase::Answer::Translation.find_by(id: node['data-target-id'])) - path = help_answer_path(translation.answer.category.translation_preferred(translation.kb_locale), - translation, - locale: translation.kb_locale.system_locale.locale) - - node['href'] = custom_path_if_needed path - else - node['href'] = '#' - end - end - end - - parsed = Loofah.scrub_fragment(input, scrubber).to_s.html_safe # rubocop:disable Rails/OutputSafety - - parsed - end end diff --git a/app/helpers/knowledge_base_public_page_title_helper.rb b/app/helpers/knowledge_base_public_page_title_helper.rb new file mode 100644 index 000000000..0bdf986eb --- /dev/null +++ b/app/helpers/knowledge_base_public_page_title_helper.rb @@ -0,0 +1,21 @@ +module KnowledgeBasePublicPageTitleHelper + def kb_public_page_title(leading, trailing, exception) + [ + leading&.translation&.title, + kb_public_page_title_suffix(trailing, exception) + ].compact.join(' - ') + end + + def kb_public_page_title_suffix(item, exception) + return item&.translation&.title if exception.blank? + + suffix = case exception + when :not_found + 'Not Found' + when :alternatives + 'Alternative Translations' + end + + zt(suffix) + end +end diff --git a/app/helpers/knowledge_base_rich_text_helper.rb b/app/helpers/knowledge_base_rich_text_helper.rb new file mode 100644 index 000000000..2589f3efe --- /dev/null +++ b/app/helpers/knowledge_base_rich_text_helper.rb @@ -0,0 +1,25 @@ +module KnowledgeBaseRichTextHelper + def prepare_rich_text_links(input) + scrubber = Loofah::Scrubber.new do |node| + next if node.name != 'a' + next if !node.key? 'data-target-type' + + case node['data-target-type'] + when 'knowledge-base-answer' + if (translation = KnowledgeBase::Answer::Translation.find_by(id: node['data-target-id'])) + path = help_answer_path(translation.answer.category.translation_preferred(translation.kb_locale), + translation, + locale: translation.kb_locale.system_locale.locale) + + node['href'] = custom_path_if_needed path, translation.kb_locale.knowledge_base + else + node['href'] = '#' + end + end + end + + parsed = Loofah.scrub_fragment(input, scrubber).to_s.html_safe # rubocop:disable Rails/OutputSafety + + parsed + end +end diff --git a/app/helpers/knowledge_base_top_bar_helper.rb b/app/helpers/knowledge_base_top_bar_helper.rb new file mode 100644 index 000000000..3c7a25487 --- /dev/null +++ b/app/helpers/knowledge_base_top_bar_helper.rb @@ -0,0 +1,38 @@ +module KnowledgeBaseTopBarHelper + def kb_top_bar_color(object) + case object + when KnowledgeBase::Answer + kb_answer_top_bar_color(object) + when KnowledgeBase::Category + kb_locale = object&.translation&.kb_locale + object.public_content?(kb_locale) ? 'green' : 'yellow' + when KnowledgeBase + 'green' + end + end + + def kb_answer_top_bar_color(answer) + case answer.can_be_published_aasm.current_state + when :draft + 'yellow' + when :internal + 'blue' + when :published + 'green' + when :archived + 'grey' + end + end + + def kb_top_bar_tag(object) + case object + when KnowledgeBase::Answer + object.can_be_published_aasm.current_state + when KnowledgeBase::Category + kb_locale = object&.translation&.kb_locale + object.public_content?(kb_locale) ? 'Visible' : 'Invisible' + when KnowledgeBase + 'Published' + end + end +end diff --git a/app/helpers/knowledge_base_visibility_note_helper.rb b/app/helpers/knowledge_base_visibility_note_helper.rb new file mode 100644 index 000000000..ba8fd86ec --- /dev/null +++ b/app/helpers/knowledge_base_visibility_note_helper.rb @@ -0,0 +1,41 @@ +module KnowledgeBaseVisibilityNoteHelper + def visibility_note(object) + return if !current_user&.permissions?('knowledge_base.editor') + + text = visibility_text(object) + + return if text.nil? + + render 'knowledge_base/public/visibility_note', text: text + end + + def visibility_text(object) + case object + when CanBePublished + visiblity_text_can_be_published(object) + when KnowledgeBase::Category + visiblity_text_category(object) + end + end + + def visiblity_text_can_be_published(object) + case object.can_be_published_aasm.current_state + when :internal + 'internal' + when :archived + 'archived' + when :draft + 'not published' + end + end + + def visiblity_text_category(object) + return if object.public_content? + + if object.self_with_children_answers.only_internal.any? + 'hidden, visible only internally' + else + 'hidden, no published answers' + end + end +end diff --git a/app/models/knowledge_base/answer.rb b/app/models/knowledge_base/answer.rb index bad515b6c..ed81f6190 100644 --- a/app/models/knowledge_base/answer.rb +++ b/app/models/knowledge_base/answer.rb @@ -18,6 +18,9 @@ class KnowledgeBase::Answer < ApplicationModel validates :category, presence: true + # provide consistent naming with KB category + alias_attribute :parent, :category + alias assets_essential assets def attributes_with_association_ids diff --git a/app/views/knowledge_base/public/_breadcrumb.html.erb b/app/views/knowledge_base/public/_breadcrumb.html.erb index 3c1481766..ab46c6b03 100644 --- a/app/views/knowledge_base/public/_breadcrumb.html.erb +++ b/app/views/knowledge_base/public/_breadcrumb.html.erb @@ -1,11 +1,11 @@