Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions app/controllers/links_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,18 @@ def external_url(type:, options: {})
'https://projects.theforeman.org/projects/foreman/issues'
when 'vmrc'
'https://www.vmware.com/go/download-vmrc'
when 'docs'
params.require(:section)
guide, chapter, flavor = params.permit(:section, :chapter, :flavor).values_at(:section, :chapter, :flavor)
flavor ||= self.class.new_docs_flavor
docs_url(guide: guide, chapter: chapter, flavor: flavor)
end
end

def self.new_docs_flavor
Foreman::Plugin.installed?('katello') ? 'katello' : SETTINGS[:docs_os_flavor]
end

private

def validate_root_url
Expand All @@ -49,6 +58,14 @@ def documentation_url(section = "", options = {})
root_url + (section || '')
end

# For new documentation at docs.theforeman.org
def docs_url(guide:, flavor:, chapter: nil)
version = SETTINGS[:version].tag == 'develop' ? 'nightly' : SETTINGS[:version].short
chapter_hash = "##{chapter}" if chapter

"https://docs.theforeman.org/#{version}/#{guide}/index-#{flavor}.html#{chapter_hash}"
end

def plugin_documentation_url
name, version, section, root_url = plugin_documentation_params.values_at(:name, :version, :section, :root_url)
path = root_url || foreman_org_path("plugins")
Expand Down
4 changes: 2 additions & 2 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@ def edit_inline(object, property, options = {})
editable(object, property, {:type => type, :title => title, :value => value, :class => klass, :source => select_values, :url => update_url, :placeholder => placeholder}.compact)
end

def documentation_url(section = "", options = {})
main_app.external_link_url(options.merge(type: 'manual', params: { section: section }))
def documentation_url(section = nil, type: 'manual', **options)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be safe, but I'm not 100% sure.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works fine!

main_app.external_link_url(type: type, section: section, params: options)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

external_link_url should receive only two parameters: type and options. I think splitting the section out of the options will cause a different output

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? The route is includes the section:

get 'links/:type(/:section)' => 'links#show', :as => 'external_link', :constraints => { section: %r{.*} }

Now I'll immediately admit my knowledge of Rails routing may be lacking, but I don't see a difference between type and section there, other than that section is optional.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, you are correct:

[9] pry(main)> external_link_path(type: 'foo', section: 'bar', zzz: 'qqq')
=> "/links/foo/bar?zzz=qqq"

As long as it works - I'm good :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check if passing it without a section also works, but I'm assuming it does.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does. When no section is passed, the final url does not contain a fragment.
So, as expected.

end

def spinner(text = '', options = {})
Expand Down
5 changes: 5 additions & 0 deletions config/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
# Load settings from env variables
SETTINGS.deep_merge!(Foreman::EnvSettingsLoader.new.to_h)

# foreman-documentation builds different flavors for Debian and Enterprise
# Linux. It also builds for Katello, but we can't detect that here so the key
# is docs_os_flavor instead of docs_flavor.
SETTINGS[:docs_os_flavor] ||= File.exist?('/etc/debian_version') ? 'foreman-deb' : 'foreman-el'

# Force setting to true until all code using it is removed
[:locations_enabled, :organizations_enabled, :unattended].each do |setting|
SETTINGS[setting] = true
Expand Down
45 changes: 45 additions & 0 deletions test/controllers/links_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,50 @@ class LinksControllerTest < ActionController::TestCase
assert_redirected_to /15.0/
assert_redirected_to /Usage/
end

test 'new docs on nightly' do
get :show, params: {
type: 'docs',
section: 'TestSection',
chapter: 'TestChapter',
}

assert_redirected_to %r{https://docs\.theforeman\.org/nightly/TestSection/index-(foreman-(deb|el)|katello)\.html#TestChapter}
end

test 'new docs on a stable release' do
with_temporary_settings(version: Foreman::Version.new('3.9.1')) do
get :show, params: {
type: 'docs',
section: 'TestSection',
chapter: 'TestChapter',
}

assert_redirected_to %r{https://docs\.theforeman\.org/3\.9/TestSection/index-(foreman-(deb|el)|katello)\.html#TestChapter}
end
end

describe '#new_docs_flavor' do
test 'on Enterprise Linux' do
Foreman::Plugin.stubs(:installed?).with('katello').returns(false)
with_temporary_settings(docs_os_flavor: 'foreman-el') do
assert_equal(LinksController.new_docs_flavor, 'foreman-el')
end
end

test 'on Debian' do
Foreman::Plugin.stubs(:installed?).with('katello').returns(false)
with_temporary_settings(docs_os_flavor: 'foreman-deb') do
assert_equal(LinksController.new_docs_flavor, 'foreman-deb')
end
end

test 'on Enterprise Linux with Katello' do
Foreman::Plugin.stubs(:installed?).with('katello').returns(true)
with_temporary_settings(docs_os_flavor: 'foreman-el') do
assert_equal(LinksController.new_docs_flavor, 'katello')
end
end
end
end
end
20 changes: 20 additions & 0 deletions test/helpers/application_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,33 @@ def test_generate_link_for
assert_match /my_plugin/, url
end

test '#documentation_url and new docs page' do
url = documentation_url('TestSection', { type: 'plugin_manual', name: 'foreman_my_plugin', version: '1.2' })

assert_match %r{links/plugin_manual/TestSection\?name=foreman_my_plugin&version=1\.2}, url
end

test '#documentation_url and new docs page' do
url = documentation_url('TestSection', { type: 'docs', chapter: 'test_chapter' })

assert_match %r{links/docs/TestSection\?chapter=test_chapter}, url
end

test '#documentation_button forwards options to #documentation_url' do
expects(:icon_text).returns('http://nowhere.com')
expects(:link_to).returns('<a>test</a>'.html_safe)
expects(:documentation_url).with('2.2PluginSection', { :root_url => 'http://www.theforeman.org/my_plugin/v0.1/index.html#' })

documentation_button '2.2PluginSection', :root_url => 'http://www.theforeman.org/my_plugin/v0.1/index.html#'
end

test '#documentation_button forwards plugin manual options to #documentation_url' do
expects(:icon_text).returns('http://nowhere.com')
expects(:link_to).returns('<a>test</a>'.html_safe)
expects(:documentation_url).with('2.2PluginSection', { type: 'plugin_manual', name: 'foreman_my_plugin', version: '1.2' })

documentation_button '2.2PluginSection', type: 'plugin_manual', name: 'foreman_my_plugin', version: '1.2'
end
end

describe 'accessible resources' do
Expand Down
11 changes: 11 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,17 @@ def set_basic_auth(user, password)
def disable_webpack
Webpack::Rails::Manifest.stubs(:asset_paths).returns([])
end

def with_temporary_settings(**kwargs)
old_settings = SETTINGS.slice(*kwargs.keys)
begin
SETTINGS.update(kwargs)

yield
ensure
SETTINGS.update(old_settings)
end
end
end

class GraphQLQueryTestCase < ActiveSupport::TestCase
Expand Down
13 changes: 12 additions & 1 deletion webpack/assets/javascripts/react_app/common/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,22 @@ export const stringIsPositiveNumber = value => {

/**
* Get manual url based on version
* @param {String} section - section id for foreman documetation
* @param {String} section - section id for foreman documentation
*/
export const getManualURL = section => foremanUrl(`/links/manual/${section}`);
export const getWikiURL = section => foremanUrl(`/links/wiki/${section}`);

/**
* Get the documentation URL
* @param {String} guide - The guide containing the documentation
* @param {String} chapter - Optional chapter within the guide
* @returns {String}
*/
export const getDocsURL = (guide, chapter = null) => {
const url = foremanUrl(`/links/docs/${guide}`);
return chapter ? `{url}?chapter={encodeURIComponent(chapter)}` : url;
};

/**
* Transform the Date object to date string accepted in the server
* @param {Date}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {
} from '@patternfly/react-core';

import { translate as __ } from '../../../common/I18n';
import { getDocsURL } from '../../../common/helpers';
import {
useForemanOrganization,
useForemanLocation,
useForemanVersion,
} from '../../../Root/Context/ForemanContext';
import { STATUS } from '../../../constants';
import PageLayout from '../../common/PageLayout/PageLayout';
Expand All @@ -38,7 +38,6 @@ import {
selectPluginData,
} from './RegistrationCommandsPageSelectors';
import { dataAction, commandAction } from './RegistrationCommandsPageActions';
import { docUrl } from './RegistrationCommandsPageConstants';

import General from './components/General';
import Advanced from './components/Advanced';
Expand All @@ -52,7 +51,6 @@ const RegistrationCommandsPage = () => {
// Context
const currentOrganization = useForemanOrganization();
const currentLocation = useForemanLocation();
const foremanVersion = useForemanVersion();

// Form tabs
const [activeTab, setActiveTab] = useState(0);
Expand Down Expand Up @@ -180,7 +178,10 @@ const RegistrationCommandsPage = () => {
ouiaId="register-host-documentation-button"
component="a"
className="btn-docs"
href={docUrl(foremanVersion)}
href={getDocsURL(
'Managing_Hosts',
'registering-a-host_managing-hosts'
)}
rel="noreferrer"
target="_blank"
variant="secondary"
Expand Down