diff --git a/app/components/users/public_activity_component.html.erb b/app/components/users/public_activity_component.html.erb new file mode 100644 index 000000000..03554e9a6 --- /dev/null +++ b/app/components/users/public_activity_component.html.erb @@ -0,0 +1,32 @@ +<% if valid_access? %> + <% if valid_filters.any? %> + + + <% if current_filter == "follows" %> + <%= render "users/following", user: user, follows: follows.group_by(&:followable_type) %> + <% else %> + <%= render_user_partial current_filter %> + <% end %> + <% else %> +
+ <%= t("users.show.no_activity") %> +
+ <% end %> +<% else %> +
+ <%= t("users.show.private_activity") %> +
+<% end %> diff --git a/app/components/users/public_activity_component.rb b/app/components/users/public_activity_component.rb new file mode 100644 index 000000000..61c1fbb8e --- /dev/null +++ b/app/components/users/public_activity_component.rb @@ -0,0 +1,84 @@ +class Users::PublicActivityComponent < ApplicationComponent + attr_reader :user + delegate :current_user, :valid_interests_access?, :current_path_with_query_params, to: :helpers + + def initialize(user) + @user = user + end + + def valid_access? + user.public_activity || authorized_current_user? + end + + def current_filter + if valid_filters.include?(params[:filter]) + params[:filter] + else + valid_filters.first + end + end + + def valid_filters + @valid_filters ||= [ + ("proposals" if feature?(:proposals)), + ("debates" if feature?(:debates)), + ("budget_investments" if feature?(:budgets)), + "comments", + ("follows" if valid_interests_access?(user)) + ].compact.select { |filter| send(filter).any? } + end + + private + + def authorized_current_user? + current_user == user || current_user&.moderator? || current_user&.administrator? + end + + def proposals + Proposal.where(author_id: user.id) + end + + def debates + Debate.where(author_id: user.id) + end + + def comments + Comment.not_valuations + .not_as_admin_or_moderator + .where(user_id: user.id) + .where.not(commentable_type: disabled_commentables) + .includes(:commentable) + end + + def budget_investments + Budget::Investment.where(author_id: user.id) + end + + def follows + @follows ||= user.follows.select { |follow| follow.followable.present? } + end + + def count(filter) + send(filter).count + end + + def render_user_partial(filter) + render "users/#{filter}", "#{filter}": send(filter).order(created_at: :desc).page(page) + end + + def page + params[:page] + end + + def disabled_commentables + [ + ("Debate" unless feature?(:debates)), + ("Budget::Investment" unless feature?(:budgets)), + (["Legislation::Question", + "Legislation::Proposal", + "Legislation::Annotation"] unless feature?(:legislation)), + (["Poll", "Poll::Question"] unless feature?(:polls)), + ("Proposal" unless feature?(:proposals)) + ].flatten.compact + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a50d55cf6..8ccee9692 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,104 +1,14 @@ class UsersController < ApplicationController - has_filters %w[proposals debates budget_investments comments follows], only: :show - load_and_authorize_resource - helper_method :author? helper_method :valid_interests_access? def show - load_filtered_activity if valid_access? + raise CanCan::AccessDenied if params[:filter] == "follows" && !valid_interests_access?(@user) end private - def set_activity_counts - @activity_counts = ActiveSupport::HashWithIndifferentAccess.new( - proposals: Proposal.where(author_id: @user.id).count, - debates: (Setting["process.debates"] ? Debate.where(author_id: @user.id).count : 0), - budget_investments: (Setting["process.budgets"] ? Budget::Investment.where(author_id: @user.id).count : 0), - comments: only_active_commentables.count, - follows: @user.follows.map(&:followable).compact.count) - end - - def load_filtered_activity - set_activity_counts - case params[:filter] - when "proposals" then load_proposals - when "debates" then load_debates - when "budget_investments" then load_budget_investments - when "comments" then load_comments - when "follows" then load_follows - else load_available_activity - end - end - - def load_available_activity - if @activity_counts[:proposals] > 0 - load_proposals - @current_filter = "proposals" - elsif @activity_counts[:debates] > 0 - load_debates - @current_filter = "debates" - elsif @activity_counts[:budget_investments] > 0 - load_budget_investments - @current_filter = "budget_investments" - elsif @activity_counts[:comments] > 0 - load_comments - @current_filter = "comments" - elsif @activity_counts[:follows] > 0 - load_follows - @current_filter = "follows" - end - end - - def load_proposals - @proposals = Proposal.created_by(@user).order(created_at: :desc).page(params[:page]) - end - - def load_debates - @debates = Debate.where(author_id: @user.id).order(created_at: :desc).page(params[:page]) - end - - def load_comments - @comments = only_active_commentables.includes(:commentable).order(created_at: :desc).page(params[:page]) - end - - def load_budget_investments - @budget_investments = Budget::Investment.where(author_id: @user.id).order(created_at: :desc).page(params[:page]) - end - - def load_follows - @follows = @user.follows.group_by(&:followable_type) - end - - def valid_access? - @user.public_activity || authorized_current_user? - end - - def valid_interests_access? - @user.public_interests || authorized_current_user? - end - - def author?(proposal) - proposal.author_id == current_user.id if current_user - end - - def authorized_current_user? - @authorized_current_user ||= current_user && (current_user == @user || current_user.moderator? || current_user.administrator?) - end - - def all_user_comments - Comment.not_valuations.not_as_admin_or_moderator.where(user_id: @user.id) - end - - def only_active_commentables - disabled_commentables = [] - disabled_commentables << "Debate" unless Setting["process.debates"] - disabled_commentables << "Budget::Investment" unless Setting["process.budgets"] - if disabled_commentables.present? - all_user_comments.where.not(commentable_type: disabled_commentables) - else - all_user_comments - end + def valid_interests_access?(user) + user.public_interests || user == current_user end end diff --git a/app/views/users/_activity_page.html.erb b/app/views/users/_activity_page.html.erb deleted file mode 100644 index eaa8a73b7..000000000 --- a/app/views/users/_activity_page.html.erb +++ /dev/null @@ -1,5 +0,0 @@ -<%= render "following" if @follows.present? %> -<%= render "proposals" if @proposals.present? && feature?(:proposals) %> -<%= render "debates" if @debates.present? && feature?(:debates) %> -<%= render "budget_investments" if @budget_investments.present? && feature?(:budgets) %> -<%= render "comments" if @comments.present? %> diff --git a/app/views/users/_budget_investments.html.erb b/app/views/users/_budget_investments.html.erb index 9c6775265..a2b523133 100644 --- a/app/views/users/_budget_investments.html.erb +++ b/app/views/users/_budget_investments.html.erb @@ -6,10 +6,10 @@ - <% @budget_investments.each do |budget_investment| %> + <% budget_investments.each do |budget_investment| %> <%= render "budget_investment", budget_investment: budget_investment %> <% end %> -<%= paginate @budget_investments %> +<%= paginate budget_investments %> diff --git a/app/views/users/_comments.html.erb b/app/views/users/_comments.html.erb index 7b7cf5165..be264ce05 100644 --- a/app/views/users/_comments.html.erb +++ b/app/views/users/_comments.html.erb @@ -5,7 +5,7 @@ - <% @comments.each do |comment| %> + <% comments.each do |comment| %> <%= comment_commentable_title(comment) %> @@ -17,4 +17,4 @@ -<%= paginate @comments %> +<%= paginate comments %> diff --git a/app/views/users/_debates.html.erb b/app/views/users/_debates.html.erb index 5b293b1a4..be8dbe7bc 100644 --- a/app/views/users/_debates.html.erb +++ b/app/views/users/_debates.html.erb @@ -5,7 +5,7 @@ - <% @debates.each do |debate| %> + <% debates.each do |debate| %> <%= link_to debate.title, debate %> @@ -15,4 +15,4 @@ -<%= paginate @debates %> +<%= paginate debates %> diff --git a/app/views/users/_following.html.erb b/app/views/users/_following.html.erb index 91fa8562a..d09f99fe6 100644 --- a/app/views/users/_following.html.erb +++ b/app/views/users/_following.html.erb @@ -1,12 +1,12 @@
- <% @follows.each do |followable_type, follows| %> + <% follows.each do |followable_type, follows| %>

@@ -22,6 +22,6 @@

- <%= render "interests", user: @user if valid_interests_access? %> + <%= render "interests", user: user %>
diff --git a/app/views/users/_proposals.html.erb b/app/views/users/_proposals.html.erb index 6604ac160..76758bfd3 100644 --- a/app/views/users/_proposals.html.erb +++ b/app/views/users/_proposals.html.erb @@ -7,10 +7,10 @@ - <% @proposals.each do |proposal| %> + <% proposals.each do |proposal| %> <%= render "proposal", proposal: proposal %> <% end %> -<%= paginate @proposals %> +<%= paginate proposals %> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 8186dbf3b..708b63275 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -22,36 +22,7 @@ <% end %> - <% if @user.public_activity || @authorized_current_user %> - - - <% if @activity_counts.values.inject(&:+) == 0 %> -
- <%= t("users.show.no_activity") %> -
- <% end %> - - <%= render "activity_page" %> - <% else %> -
- <%= t("users.show.private_activity") %> -
- <% end %> + <%= render Users::PublicActivityComponent.new(@user) %> diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml index c2057e07b..2613671b5 100644 --- a/config/locales/en/activerecord.yml +++ b/config/locales/en/activerecord.yml @@ -281,7 +281,7 @@ en: official_level: "Official level" phone_number: "Phone number" public_activity: "Keep my list of activities public" - public_interests: "Keep the labels of the elements I follow public" + public_interests: "Keep the elements I follow public" recommended_debates: "Show debates recommendations" recommended_proposals: "Show proposals recommendations" redeemable_code: "Verification code received via email" diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index a6454e6e3..8af18867c 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -281,7 +281,7 @@ es: official_level: "Nivel del cargo" phone_number: "Teléfono" public_activity: "Mostrar públicamente mi lista de actividades" - public_interests: "Mostrar públicamente las etiquetas de los elementos que sigo" + public_interests: "Mostrar públicamente los elementos que sigo" recommended_debates: "Mostrar recomendaciones en el listado de debates" recommended_proposals: "Mostrar recomendaciones en el listado de propuestas" redeemable_code: "Código de verificación por carta (opcional)" diff --git a/spec/components/users/public_activity_component_spec.rb b/spec/components/users/public_activity_component_spec.rb new file mode 100644 index 000000000..2f72c8495 --- /dev/null +++ b/spec/components/users/public_activity_component_spec.rb @@ -0,0 +1,107 @@ +require "rails_helper" + +describe Users::PublicActivityComponent, controller: UsersController do + around do |example| + with_request_url(Rails.application.routes.url_helpers.user_path(user)) { example.run } + end + + describe "follows tab" do + context "public interests is checked" do + let(:user) { create(:user, public_interests: true) } + let(:component) { Users::PublicActivityComponent.new(user) } + + it "is displayed for everyone" do + create(:proposal, author: user, followers: [user]) + + render_inline component + + expect(page).to have_content "1 Following" + end + + it "is not displayed when the user isn't following any followables" do + create(:proposal, author: user) + + render_inline component + + expect(page).not_to have_content "Following" + end + + it "is the active tab when the follows filters is selected" do + create(:proposal, author: user, followers: [user]) + controller.params["filter"] = "follows" + + render_inline component + + expect(page).to have_selector "li.is-active", text: "1 Following" + end + end + + context "public interests is not checked" do + let(:user) { create(:user, public_interests: false) } + let(:component) { Users::PublicActivityComponent.new(user) } + + it "is displayed for its owner" do + create(:proposal, followers: [user]) + sign_in(user) + + render_inline component + + expect(page).to have_content "1 Following" + end + + it "is not displayed for anonymous users" do + create(:proposal, author: user, followers: [user]) + + render_inline component + + expect(page).to have_content "1 Proposal" + expect(page).not_to have_content "Following" + end + + it "is not displayed for other users" do + create(:proposal, author: user, followers: [user]) + sign_in(create(:user)) + + render_inline component + + expect(page).to have_content "1 Proposal" + expect(page).not_to have_content "Following" + end + + it "is not displayed for administrators" do + create(:proposal, author: user, followers: [user]) + sign_in(create(:administrator).user) + + render_inline component + + expect(page).to have_content "1 Proposal" + expect(page).not_to have_content "Following" + end + end + end + + describe "comments" do + let(:user) { create(:user) } + let(:component) { Users::PublicActivityComponent.new(user) } + + it "doesn't show comments for disabled features" do + Setting["process.budgets"] = false + Setting["process.debates"] = false + Setting["process.legislation"] = false + Setting["process.polls"] = false + Setting["process.proposals"] = false + + create(:budget_investment_comment, user: user) + create(:debate_comment, user: user) + create(:legislation_annotation_comment, user: user) + create(:legislation_question_comment, user: user) + create(:legislation_proposal_comment, user: user) + create(:poll_comment, user: user) + create(:proposal_comment, user: user) + + render_inline component + + expect(page).not_to have_content "Comments" + end + end +end diff --git a/spec/factories/comments.rb b/spec/factories/comments.rb index 79402c448..f55581f88 100644 --- a/spec/factories/comments.rb +++ b/spec/factories/comments.rb @@ -4,7 +4,8 @@ FactoryBot.define do user sequence(:body) { |n| "Comment body #{n}" } - %i[budget_investment debate legislation_annotation legislation_question proposal topic_with_community].each do |model| + %i[budget_investment debate legislation_annotation legislation_question legislation_proposal + poll proposal topic_with_community].each do |model| factory :"#{model}_comment" do association :commentable, factory: model end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 3c6103c44..d24392549 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -739,6 +739,12 @@ describe User do end end + describe "#public_interests" do + it "is false by default" do + expect(User.new.public_interests).to be false + end + end + describe ".find_by_manager_login" do it "works with a low ID" do user = create(:user) diff --git a/spec/system/users_spec.rb b/spec/system/users_spec.rb index 646645983..127bb1b11 100644 --- a/spec/system/users_spec.rb +++ b/spec/system/users_spec.rb @@ -231,128 +231,6 @@ describe "Users" do end end - describe "Public interests" do - let(:user) { create(:user) } - - scenario "Display interests" do - create(:proposal, tag_list: "Sport", followers: [user]) - - login_as(user) - visit account_path - - check "account_public_interests" - click_button "Save changes" - - logout - - visit user_path(user) - expect(page).to have_content("Sport") - end - - scenario "Not display interests when proposal has been destroyed" do - proposal = create(:proposal, tag_list: "Sport", followers: [user]) - proposal.destroy! - - login_as(user) - visit account_path - - check "account_public_interests" - click_button "Save changes" - - logout - - visit user_path(user) - expect(page).not_to have_content("Sport") - end - - scenario "No visible by default" do - visit user_path(user) - - expect(page).to have_content(user.username) - expect(page).not_to have_css("#public_interests") - end - - scenario "User can display public page" do - create(:proposal, tag_list: "Sport", followers: [user]) - - login_as(user) - visit account_path - - check "account_public_interests" - click_button "Save changes" - - logout - - visit user_path(user, filter: "follows", page: "1") - - expect(page).to have_css("#public_interests") - end - - scenario "Is always visible for the owner" do - create(:proposal, tag_list: "Sport", followers: [user]) - - login_as(user) - visit account_path - - uncheck "account_public_interests" - click_button "Save changes" - - visit user_path(user, filter: "follows", page: "1") - expect(page).to have_css("#public_interests") - end - - scenario "Is always visible for admins" do - create(:proposal, tag_list: "Sport", followers: [user]) - - login_as(user) - visit account_path - - uncheck "account_public_interests" - click_button "Save changes" - - logout - - login_as(create(:administrator).user) - visit user_path(user, filter: "follows", page: "1") - expect(page).to have_css("#public_interests") - end - - scenario "Is always visible for moderators" do - create(:proposal, tag_list: "Sport", followers: [user]) - - login_as(user) - visit account_path - - uncheck "account_public_interests" - click_button "Save changes" - - logout - - login_as(create(:moderator).user) - visit user_path(user, filter: "follows", page: "1") - expect(page).to have_css("#public_interests") - end - - scenario "Should display generic interests title" do - create(:proposal, tag_list: "Sport", followers: [user]) - - user.update!(public_interests: true) - visit user_path(user, filter: "follows", page: "1") - - expect(page).to have_content("Tags of elements this user follows") - end - - scenario "Should display custom interests title when user is visiting own user page" do - create(:proposal, tag_list: "Sport", followers: [user]) - - user.update!(public_interests: true) - login_as(user) - visit user_path(user, filter: "follows", page: "1") - - expect(page).to have_content("Tags of elements you follow") - end - end - describe "Special comments" do scenario "comments posted as moderator are not visible in user activity" do moderator = create(:administrator).user @@ -408,117 +286,203 @@ describe "Users" do describe "Following (public page)" do let(:user) { create(:user) } - scenario "Do not display follows' tab when user is not following any followables" do - visit user_path(user) + context "public interests is checked" do + let(:user) { create(:user, public_interests: true) } - expect(page).not_to have_content("0 Following") + scenario "can be accessed by anyone" do + create(:proposal, followers: [user], title: "Others follow me") + + visit user_path(user, filter: "follows") + + expect(page).to have_content "1 Following" + expect(page).to have_content "Others follow me" + end + + scenario "Gracefully handle followables that have been hidden" do + create(:proposal, followers: [user]) + create(:proposal, followers: [user], &:hide) + + visit user_path(user) + + expect(page).to have_content("1 Following") + end + + scenario "displays generic interests title" do + create(:proposal, tag_list: "Sport", followers: [user]) + + visit user_path(user, filter: "follows", page: "1") + + expect(page).to have_content("Tags of elements this user follows") + end + + describe "Proposals" do + scenario "Display following tab when user is following one proposal at least" do + create(:proposal, followers: [user]) + + visit user_path(user) + + expect(page).to have_content("1 Following") + end + + scenario "Display proposal tab when user is following one proposal at least" do + create(:proposal, followers: [user]) + + visit user_path(user, filter: "follows") + + expect(page).to have_link("Citizen proposals", href: "#citizen_proposals") + end + + scenario "Do not display proposals' tab when user is not following any proposal" do + visit user_path(user, filter: "follows") + + expect(page).not_to have_link("Citizen proposals", href: "#citizen_proposals") + end + + scenario "Display proposals with link to proposal" do + proposal = create(:proposal, author: user, followers: [user]) + + login_as user + + visit user_path(user, filter: "follows") + + expect(page).to have_link "Citizen proposals", href: "#citizen_proposals" + expect(page).to have_content proposal.title + end + + scenario "Retired proposals do not have a link to the dashboard" do + proposal = create(:proposal, :retired, author: user) + login_as user + + visit user_path(user) + + expect(page).to have_content proposal.title + expect(page).not_to have_link "Dashboard" + expect(page).to have_content("Dashboard not available for retired proposals") + end + + scenario "Published proposals have a link to the dashboard" do + proposal = create(:proposal, :published, author: user) + login_as user + + visit user_path(user) + + expect(page).to have_content proposal.title + expect(page).to have_link "Dashboard" + end + end + + describe "Budget Investments" do + scenario "Display following tab when user is following one budget investment at least" do + create(:budget_investment, followers: [user]) + + visit user_path(user) + + expect(page).to have_content("1 Following") + end + + scenario "Display budget investment tab when user is following one budget investment at least" do + create(:budget_investment, followers: [user]) + + visit user_path(user, filter: "follows") + + expect(page).to have_link("Investments", href: "#investments") + end + + scenario "Do not display budget investment tab when user is not following any budget investment" do + visit user_path(user, filter: "follows") + + expect(page).not_to have_link("Investments", href: "#investments") + end + + scenario "Display budget investment with link to budget investment" do + budget_investment = create(:budget_investment, author: user, followers: [user]) + + visit user_path(user, filter: "follows") + + expect(page).to have_link "Investments", href: "#investments" + expect(page).to have_link budget_investment.title + end + end end - scenario "Active following tab by default when follows filters selected" do - create(:proposal, author: user, followers: [user]) + context "public interests is not checked" do + let(:user) { create(:user, public_interests: false) } + + scenario "can be accessed by its owner" do + create(:proposal, followers: [user], title: "Follow me!") + + login_as(user) + + visit user_path(user, filter: "follows") + + expect(page).to have_content "1 Following" + expect(page).to have_content "Follow me!" + expect(page).to have_content "Tags of elements you follow" + end + + scenario "cannot be accessed by anonymous users" do + create(:proposal, followers: [user]) + + visit user_path(user, filter: "follows") + + expect(page).to have_content "You do not have permission to access this page" + expect(page).to have_current_path root_path + end + + scenario "cannot be accessed by other users" do + create(:proposal, followers: [user]) + + login_as(create(:user)) + + visit user_path(user, filter: "follows") + + expect(page).to have_content "You do not have permission to access this page" + expect(page).to have_current_path root_path + end + + scenario "cannot be accessed by administrators" do + create(:proposal, followers: [user]) + + login_as(create(:administrator).user) + + visit user_path(user, filter: "follows") + + expect(page).to have_content "You do not have permission to access this page" + expect(page).to have_current_path root_path + end + end + + scenario "Display interests" do + create(:proposal, tag_list: "Sport", followers: [user]) + + login_as(user) + visit account_path + + check "account_public_interests" + click_button "Save changes" + + logout visit user_path(user, filter: "follows") - expect(page).to have_selector(".activity li.is-active", text: "1 Following") + expect(page).to have_css "#public_interests" + expect(page).to have_content "Sport" end - scenario "Gracefully handle followables that have been hidden" do - create(:proposal, followers: [user]) - create(:proposal, followers: [user], &:hide) + scenario "Do not display interests when proposal has been destroyed" do + proposal = create(:proposal, tag_list: "Sport", followers: [user]) + proposal.destroy! + + login_as(user) + visit account_path + + check "account_public_interests" + click_button "Save changes" + + logout visit user_path(user) - - expect(page).to have_content("1 Following") - end - - describe "Proposals" do - scenario "Display following tab when user is following one proposal at least" do - create(:proposal, followers: [user]) - - visit user_path(user) - - expect(page).to have_content("1 Following") - end - - scenario "Display proposal tab when user is following one proposal at least" do - create(:proposal, followers: [user]) - - visit user_path(user, filter: "follows") - - expect(page).to have_link("Citizen proposals", href: "#citizen_proposals") - end - - scenario "Do not display proposals' tab when user is not following any proposal" do - visit user_path(user, filter: "follows") - - expect(page).not_to have_link("Citizen proposals", href: "#citizen_proposals") - end - - scenario "Display proposals with link to proposal" do - proposal = create(:proposal, author: user, followers: [user]) - - login_as user - - visit user_path(user, filter: "follows") - click_link "Citizen proposals" - - expect(page).to have_content proposal.title - end - - scenario "Retired proposals do not have a link to the dashboard" do - proposal = create(:proposal, :retired, author: user) - login_as user - - visit user_path(user) - - expect(page).to have_content proposal.title - expect(page).not_to have_link "Dashboard" - expect(page).to have_content("Dashboard not available for retired proposals") - end - - scenario "Published proposals have a link to the dashboard" do - proposal = create(:proposal, :published, author: user) - login_as user - - visit user_path(user) - - expect(page).to have_content proposal.title - expect(page).to have_link "Dashboard" - end - end - - describe "Budget Investments" do - scenario "Display following tab when user is following one budget investment at least" do - create(:budget_investment, followers: [user]) - - visit user_path(user) - - expect(page).to have_content("1 Following") - end - - scenario "Display budget investment tab when user is following one budget investment at least" do - create(:budget_investment, followers: [user]) - - visit user_path(user, filter: "follows") - - expect(page).to have_link("Investments", href: "#investments") - end - - scenario "Not display budget investment tab when user is not following any budget investment" do - visit user_path(user, filter: "follows") - - expect(page).not_to have_link("Investments", href: "#investments") - end - - scenario "Display budget investment with link to budget investment" do - user = create(:user, :level_two) - budget_investment = create(:budget_investment, author: user, followers: [user]) - - visit user_path(user, filter: "follows") - click_link "Investments" - - expect(page).to have_link budget_investment.title - end + expect(page).not_to have_content("Sport") end end