Skip to content
Open
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
6 changes: 0 additions & 6 deletions app/assets/javascripts/discourse/controllers/user.js.es6
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ export default ObjectController.extend(CanCheckEmails, {

collapsedInfo: Em.computed.not('indexStream'),

websiteName: function() {
var website = this.get('model.website');
if (Em.isEmpty(website)) { return; }
return website.split("/")[2];
}.property('model.website'),

linkWebsite: Em.computed.not('model.isBasic'),

removeNoFollow: function() {
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/discourse/models/user.js.es6
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const User = RestModel.extend({
/**
This user's profile background(in CSS).

@property websiteName
@property profileBackground
@type {String}
**/
profileBackground: function() {
Expand Down
6 changes: 3 additions & 3 deletions app/assets/javascripts/discourse/templates/user/user.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@
{{/if}}
<h3>
{{#if model.location}}{{fa-icon "map-marker"}} {{model.location}}{{/if}}
{{#if websiteName}}
{{#if model.website_name}}
{{fa-icon "globe"}}
{{#if linkWebsite}}
<a href={{model.website}} rel={{unless removeNoFollow 'nofollow'}} target="_blank">{{websiteName}}</a>
<a href={{model.website}} rel={{unless removeNoFollow 'nofollow'}} target="_blank">{{model.website_name}}</a>
{{else}}
<span title={{model.website}}>{{websiteName}}</span>
<span title={{model.website}}>{{model.website_name}}</span>
{{/if}}
{{/if}}
</h3>
Expand Down
21 changes: 21 additions & 0 deletions app/serializers/user_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def self.untrusted_attributes(*attrs)
:bio_cooked,
:created_at,
:website,
:website_name,
:profile_background,
:card_background,
:location,
Expand Down Expand Up @@ -133,6 +134,26 @@ def website
object.user_profile.website
end

def website_name
website_host = URI(website.to_s).host rescue nil
discourse_host = Discourse.current_hostname
return if website_host.nil?
if website_host == discourse_host
# example.com == example.com
website_host + URI(website.to_s).path
elsif (website_host.split('.').length == discourse_host.split('.').length) && discourse_host.split('.').length > 2
# www.example.com == forum.example.com
website_host.split('.')[1..-1].join('.') == discourse_host.split('.')[1..-1].join('.') ? website_host + URI(website.to_s).path : website_host
else
# example.com == forum.example.com
discourse_host.ends_with?("." << website_host) ? website_host + URI(website.to_s).path : website_host
end
end
Comment on lines +137 to +151
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor to reduce complexity and improve readability.

The method has high cyclomatic complexity (8/7) and contains several style issues. Consider breaking this down into smaller, more focused methods.

def website_name
-  website_host = URI(website.to_s).host rescue nil
-  discourse_host = Discourse.current_hostname
-  return if website_host.nil?
-  if website_host == discourse_host
-    # example.com == example.com
-    website_host + URI(website.to_s).path
-  elsif (website_host.split('.').length == discourse_host.split('.').length) && discourse_host.split('.').length > 2
-    # www.example.com == forum.example.com
-    website_host.split('.')[1..-1].join('.') == discourse_host.split('.')[1..-1].join('.') ? website_host + URI(website.to_s).path : website_host
-  else
-    # example.com == forum.example.com
-    discourse_host.ends_with?("." << website_host) ? website_host + URI(website.to_s).path : website_host
-  end
+  return unless website_host = extract_website_host
+  
+  discourse_host = Discourse.current_hostname
+  
+  if should_show_full_path?(website_host, discourse_host)
+    website_host + website_path
+  else
+    website_host
+  end
+end
+
+private
+
+def extract_website_host
+  begin
+    URI(website.to_s).host
+  rescue URI::InvalidURIError
+    nil
+  end
+end
+
+def website_path
+  begin
+    URI(website.to_s).path
+  rescue URI::InvalidURIError
+    ""
+  end
+end
+
+def should_show_full_path?(website_host, discourse_host)
+  exact_domain_match?(website_host, discourse_host) ||
+    subdomain_of_same_domain?(website_host, discourse_host) ||
+    parent_domain_match?(website_host, discourse_host)
+end
+
+def exact_domain_match?(website_host, discourse_host)
+  website_host == discourse_host
+end
+
+def subdomain_of_same_domain?(website_host, discourse_host)
+  return false unless both_have_subdomains?(website_host, discourse_host)
+  
+  website_parts = website_host.split('.')
+  discourse_parts = discourse_host.split('.')
+  
+  website_parts[1..-1] == discourse_parts[1..-1]
+end
+
+def parent_domain_match?(website_host, discourse_host)
+  discourse_host.ends_with?(".#{website_host}")
+end
+
+def both_have_subdomains?(website_host, discourse_host)
+  website_host.split('.').length == discourse_host.split('.').length &&
+    discourse_host.split('.').length > 2
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def website_name
website_host = URI(website.to_s).host rescue nil
discourse_host = Discourse.current_hostname
return if website_host.nil?
if website_host == discourse_host
# example.com == example.com
website_host + URI(website.to_s).path
elsif (website_host.split('.').length == discourse_host.split('.').length) && discourse_host.split('.').length > 2
# www.example.com == forum.example.com
website_host.split('.')[1..-1].join('.') == discourse_host.split('.')[1..-1].join('.') ? website_host + URI(website.to_s).path : website_host
else
# example.com == forum.example.com
discourse_host.ends_with?("." << website_host) ? website_host + URI(website.to_s).path : website_host
end
end
def website_name
return unless website_host = extract_website_host
discourse_host = Discourse.current_hostname
if should_show_full_path?(website_host, discourse_host)
website_host + website_path
else
website_host
end
end
private
def extract_website_host
begin
URI(website.to_s).host
rescue URI::InvalidURIError
nil
end
end
def website_path
begin
URI(website.to_s).path
rescue URI::InvalidURIError
""
end
end
def should_show_full_path?(website_host, discourse_host)
exact_domain_match?(website_host, discourse_host) ||
subdomain_of_same_domain?(website_host, discourse_host) ||
parent_domain_match?(website_host, discourse_host)
end
def exact_domain_match?(website_host, discourse_host)
website_host == discourse_host
end
def subdomain_of_same_domain?(website_host, discourse_host)
return false unless both_have_subdomains?(website_host, discourse_host)
website_parts = website_host.split('.')
discourse_parts = discourse_host.split('.')
website_parts[1..-1] == discourse_parts[1..-1]
end
def parent_domain_match?(website_host, discourse_host)
discourse_host.ends_with?(".#{website_host}")
end
def both_have_subdomains?(website_host, discourse_host)
website_host.split('.').length == discourse_host.split('.').length &&
discourse_host.split('.').length > 2
end
🧰 Tools
🪛 RuboCop (1.76.1)

[convention] 137-151: Assignment Branch Condition size for website_name is too high. [<2, 35, 12> 37.05/23]

(Metrics/AbcSize)


[convention] 137-151: Cyclomatic complexity for website_name is too high. [8/7]

(Metrics/CyclomaticComplexity)


[convention] 137-151: Perceived complexity for website_name is too high. [9/8]

(Metrics/PerceivedComplexity)


[convention] 138-138: Avoid using rescue in its modifier form.

(Style/RescueModifier)

🤖 Prompt for AI Agents
In app/serializers/user_serializer.rb around lines 137 to 151, the website_name
method is too complex and hard to read due to multiple nested conditionals and
repeated URI parsing. Refactor by extracting URI parsing into a separate method,
and split the conditional logic into smaller helper methods that each handle one
comparison case. This will reduce cyclomatic complexity and improve readability
by making each method focused and easier to understand.


def include_website_name
website.present?
end

def card_image_badge_id
object.user_profile.card_image_badge.try(:id)
end
Expand Down
21 changes: 19 additions & 2 deletions spec/serializers/user_serializer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,28 @@

context "with filled out website" do
before do
user.user_profile.website = 'http://example.com'
user.user_profile.website = 'http://example.com/user'
end

it "has a website" do
expect(json[:website]).to eq 'http://example.com'
expect(json[:website]).to eq 'http://example.com/user'
end

context "has a website name" do
it "returns website host name when instance domain is not same as website domain" do
Discourse.stubs(:current_hostname).returns('discourse.org')
expect(json[:website_name]).to eq 'example.com'
end

it "returns complete website path when instance domain is same as website domain" do
Discourse.stubs(:current_hostname).returns('example.com')
expect(json[:website_name]).to eq 'example.com/user'
end

it "returns complete website path when website domain is parent of instance domain" do
Discourse.stubs(:current_hostname).returns('forums.example.com')
expect(json[:website_name]).to eq 'example.com/user'
end
end
end

Expand Down