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

def include_website_name
website.present?
end
Comment on lines +153 to +155

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Missing ? suffix on include method.

ActiveModelSerializers expects the method to be named include_website_name? with a trailing ? for the conditional inclusion to work. Without this, the attribute will always be serialized regardless of whether website is present.

🐛 Proposed fix
-  def include_website_name
+  def include_website_name?
     website.present?
   end
🤖 Prompt for AI Agents
In @app/serializers/user_serializer.rb around lines 153 - 155, Rename the
conditional serializer method include_website_name to include_website_name? so
ActiveModelSerializers recognizes it as a conditional include; keep the
implementation returning website.present? (i.e., have include_website_name?
return website.present?) and update any references to the old method name if
present.


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
Comment on lines +76 to 91

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Tests may not work as expected due to let memoization order.

The json variable is memoized via let at line 21, which calls serializer.as_json. The stubs for Discourse.current_hostname are set up after json would be evaluated on first access. Depending on when json is first accessed, the stub might not be in effect.

Consider using let! to force eager evaluation after stubbing, or restructure to ensure stubs are in place before serialization:

🐛 Proposed fix
       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'
+          serialized = UserSerializer.new(user, scope: Guardian.new, root: false).as_json
+          expect(serialized[: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'
+          serialized = UserSerializer.new(user, scope: Guardian.new, root: false).as_json
+          expect(serialized[: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'
+          serialized = UserSerializer.new(user, scope: Guardian.new, root: false).as_json
+          expect(serialized[:website_name]).to eq 'example.com/user'
         end
       end

end

Expand Down