Browse Source

Fixes #3231 - KnowledgeBase Broken 500

Mantas 4 years ago
parent
commit
7937f7b39e

+ 1 - 1
app/helpers/knowledge_base_helper.rb

@@ -12,7 +12,7 @@ module KnowledgeBaseHelper
     return path if !custom_address
 
     custom_path = path.gsub(%r{^/help}, custom_address.path || '').presence || '/'
-    prefix      = full ? knowledge_base.custom_path_prefix(request) : ''
+    prefix      = full ? knowledge_base.custom_address_prefix(request) : ''
 
     "#{prefix}#{custom_path}"
   end

+ 6 - 2
app/models/knowledge_base.rb

@@ -94,8 +94,12 @@ class KnowledgeBase < ApplicationModel
   end
 
   def custom_address_prefix(request)
-    host = custom_address.host || request.headers.env['SERVER_NAME']
-    "#{custom_address.scheme}://#{host}"
+    host        = custom_address_uri.host || request.headers.env['SERVER_NAME']
+    port        = request.headers.env['SERVER_PORT']
+    port_silent = request.ssl? && port == '443' || !request.ssl? && port == '80'
+    port_string = port_silent ? '' : ":#{port}"
+
+    "#{custom_address_uri.scheme}://#{host}#{port_string}"
   end
 
   def full_destroy!

+ 1 - 1
app/models/knowledge_base/locale.rb

@@ -27,7 +27,7 @@ class KnowledgeBase::Locale < ApplicationModel
                                          dependent:   :destroy
 
   def self.system_with_kb_locales(knowledge_base)
-    Locale
+    ::Locale
       .joins(:knowledge_base_locales)
       .where(knowledge_base_locales: { knowledge_base: knowledge_base })
       .select('locales.*, knowledge_base_locales.id as kb_locale_id, knowledge_base_locales.primary as primary_locale')

+ 89 - 0
spec/requests/knowledge_base_public/custom_path_spec.rb

@@ -0,0 +1,89 @@
+require 'rails_helper'
+
+# Custom subdomain is handled by rewriting at web server
+# Calling the original /help URL with a custom URL in header to simulate
+RSpec.describe 'KnowledgeBase public custom path', type: :request do
+  let!(:knowledge_base) { create(:knowledge_base, custom_address: custom_address) }
+  let(:path)            { '/path' }
+  let(:subdomain)       { 'subdomain.example.net' }
+  let(:locale)          { knowledge_base.kb_locales.first.system_locale.locale }
+
+  shared_examples 'accepting original URL' do
+    before { fetch }
+
+    it { expect(response).to have_http_status(:found) }
+    it { expect(response).to redirect_to "/help/#{locale}" }
+  end
+
+  context 'with no custom path' do
+    let(:custom_address) { nil }
+
+    it_behaves_like 'accepting original URL'
+
+    context 'when called with the subdomain' do
+      before { fetch subdomain: subdomain, path: '/' }
+
+      it { expect(response).to have_http_status(:found) }
+      it { expect(response).to redirect_to "/help/#{locale}" }
+    end
+  end
+
+  context 'with custom path' do
+    let(:custom_address) { path }
+
+    it_behaves_like 'accepting original URL'
+
+    context 'when called with the path' do
+      before { fetch path: path }
+
+      it { expect(response).to have_http_status(:found) }
+      it { expect(response).to redirect_to "/path/#{locale}" }
+    end
+
+    context 'when called with a custom port' do
+      before { fetch path: path, port: 8080 }
+
+      it { expect(response).to have_http_status(:found) }
+      it { expect(response).to redirect_to ":8080/path/#{locale}" }
+    end
+
+    context 'when called with the path and subdomain' do
+      before { fetch path: path, subdomain: subdomain }
+
+      it { expect(response).to have_http_status(:found) }
+      it { expect(response).to redirect_to "http://subdomain.example.net/path/#{locale}" }
+    end
+  end
+
+  context 'with custom subdomain' do
+    let(:custom_address) { subdomain }
+
+    it_behaves_like 'accepting original URL'
+
+    context 'when called with the subdomain' do
+      before { fetch subdomain: subdomain, path: '/' }
+
+      it { expect(response).to have_http_status(:found) }
+      it { expect(response).to redirect_to "http://subdomain.example.net/#{locale}" }
+    end
+  end
+
+  context 'with custom subdomain and path' do
+    let(:custom_address) { "#{subdomain}#{path}" }
+
+    it_behaves_like 'accepting original URL'
+
+    context 'when called with the path and subdomain' do
+      before { fetch path: path, subdomain: subdomain }
+
+      it { expect(response).to have_http_status(:found) }
+      it { expect(response).to redirect_to "http://subdomain.example.net/path/#{locale}" }
+    end
+  end
+
+  def fetch(path: nil, subdomain: nil, port: nil)
+    headers = { HTTP_X_ORIGINAL_URL: path, SERVER_NAME: subdomain, SERVER_PORT: port }.compact
+
+    get '/help', headers: headers
+  end
+end