Merge pull request #9530 from opf/fix/34591/link-to-notification-settings

[34591] Dynamic text matcher to output base URL for formattables
pull/9591/head
Henriette Darge 3 years ago committed by GitHub
commit 5cef260185
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .rubocop.yml
  2. 2
      app/seeders/seeder.rb
  3. 2
      config/settings.yml
  4. 77
      lib/open_project/text_formatting/filters/setting_macros_filter.rb
  5. 1
      lib/open_project/text_formatting/formats/markdown/formatter.rb
  6. 2
      lib/open_project/text_formatting/formats/plain/formatter.rb
  7. 53
      spec/features/homescreen/index_spec.rb
  8. 74
      spec/lib/open_project/text_formatting/markdown/setting_variable_spec.rb

@ -163,6 +163,11 @@ RSpec/NestedGroups:
RSpec/DescribeMethod: RSpec/DescribeMethod:
Enabled: false Enabled: false
# Don't force the second argument of describe
# to match the exact file name
RSpec/FilePath:
SpecSuffixOnly: true
# We use let!() to ensure dependencies are created # We use let!() to ensure dependencies are created
# instead of let() and referencing them explicitly # instead of let() and referencing them explicitly
RSpec/LetSetup: RSpec/LetSetup:

@ -66,7 +66,7 @@ class Seeder
# Translate the given string with the fixed interpolation for base_url # Translate the given string with the fixed interpolation for base_url
# Deep interpolation is required in order for interpolations on hashes to work! # Deep interpolation is required in order for interpolations on hashes to work!
def translate_with_base_url(string) def translate_with_base_url(string)
I18n.t(string, deep_interpolation: true, base_url: OpenProject::Configuration.rails_relative_url_root) I18n.t(string, deep_interpolation: true, base_url: "{{opSetting:base_url}}")
end end
def edition_data_for(key) def edition_data_for(key)

@ -312,7 +312,7 @@ emails_footer:
default: default:
en: |- en: |-
You have received this notification because you have either subscribed to it, or are involved in it. You have received this notification because you have either subscribed to it, or are involved in it.
To change your notification preferences, please click here: http://hostname/my/account To change your notification preferences, please click here: {{opSetting:base_url/my/notifications}}
start_of_week: start_of_week:
default: '' default: ''
first_week_of_year: first_week_of_year:

@ -0,0 +1,77 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See docs/COPYRIGHT.rdoc for more details.
#++
module OpenProject::TextFormatting
module Filters
class SettingMacrosFilter < HTML::Pipeline::Filter
ALLOWED_SETTINGS = %w[
host_name
base_url
].freeze
def self.regexp
%r{
\{\{opSetting:(.+?)\}\}
}x
end
def call
return html unless applicable?
html.gsub(self.class.regexp) do |matched_string|
variable = $1.to_s
variable.gsub!('\\', '')
if ALLOWED_SETTINGS.include?(variable)
send variable
else
matched_string
end
end
end
private
def host_name
OpenProject::StaticRouting::UrlHelpers.host
end
def base_url
OpenProject::Application.root_url
end
##
# Faster inclusion check before the regex is being applied
def applicable?
html.include?('{{opSetting:')
end
end
end
end

@ -44,6 +44,7 @@ module OpenProject::TextFormatting::Formats::Markdown
def filters def filters
%i[ %i[
setting_macros
markdown markdown
sanitization sanitization
task_list task_list

@ -40,7 +40,7 @@ module OpenProject::TextFormatting::Formats
end end
def filters def filters
%i(plain pattern_matcher) %i(plain setting_macros pattern_matcher)
end end
def self.format def self.format

@ -0,0 +1,53 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See docs/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
describe 'Homescreen index', type: :feature do
let!(:user) { FactoryBot.build_stubbed(:user) }
let!(:project) { FactoryBot.create(:public_project, identifier: 'public-project') }
before do
login_as user
visit root_url
end
describe 'with a dynamic URL in the welcome text',
with_settings: {
welcome_text: "With [a link to the public project]({{opSetting:base_url}}/projects/public-project)",
welcome_on_homescreen?: true
} do
it 'renders the correct link' do
expect(page)
.to have_selector("a[href=\"#{OpenProject::Application.root_url}/projects/public-project\"]")
click_link "a link to the public project"
expect(page).to have_current_path project_path(project)
end
end
end

@ -0,0 +1,74 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See docs/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
require_relative './expected_markdown'
describe OpenProject::TextFormatting,
'Setting variable' do
include_context 'expected markdown modules'
describe 'attribute label macros' do
it_behaves_like 'format_text produces' do
let(:raw) do
<<~RAW
Inline reference to variable setting: {{opSetting:host_name}}
Inline reference to base_url variable: {{opSetting:base_url}}
[Link with setting]({{opSetting:base_url}}/foo/bar)
Inline reference to invalid variable: {{opSetting:smtp_password}}
Inline reference to missing variable: {{opSetting:does_not_exist}}
RAW
end
let(:expected) do
<<~EXPECTED
<p class="op-uc-p">
Inline reference to variable setting: #{OpenProject::StaticRouting::UrlHelpers.host}
</p>
<p class="op-uc-p">
Inline reference to base_url variable: #{OpenProject::Application.root_url}
</p>
<p class="op-uc-p">
<a href="#{OpenProject::Application.root_url}/foo/bar" rel="noopener noreferrer"
class="op-uc-link">Link with setting</a>
</p>
<p class="op-uc-p">
Inline reference to invalid variable: {{opSetting:smtp_password}}
</p>
<p class="op-uc-p">
Inline reference to missing variable: {{opSetting:does_not_exist}}
</p>
EXPECTED
end
end
end
end
Loading…
Cancel
Save