From 2b144e85427e9efd3da8bfb084fe6550e423362b Mon Sep 17 00:00:00 2001 From: Alexander Brandon Coles Date: Mon, 8 Sep 2025 16:23:19 +0100 Subject: [PATCH] Fix wording: Change "Favored" to "Favorited" Favorite is the correct term in the context of expressing a preference for a particular project / other OpenProject domain object. Updates `ActsAsFavorable` to `ActsAsFavoritable`, as well as filenames, identifiers and strings to: favored => favorited favorable => favoritable favoring => favoriting --- .../common/submenu_component.html.erb | 2 +- .../index_page_header_component.html.erb | 4 +- .../projects/index_page_header_component.rb | 4 +- .../projects/projects_filters_component.rb | 2 +- app/components/projects/row_component.rb | 28 +-- app/components/projects/table_component.rb | 4 +- app/controllers/favorites_controller.rb | 20 +-- app/controllers/homescreen_controller.rb | 2 +- app/helpers/sort_helper.rb | 4 +- app/menus/projects/menu.rb | 14 +- app/menus/submenu.rb | 7 +- app/models/application_record.rb | 2 +- app/models/favorite.rb | 4 +- app/models/project.rb | 2 +- app/models/project_queries/static.rb | 12 +- app/models/project_query.rb | 2 +- .../formatters/{favored.rb => favorited.rb} | 8 +- .../projects/exports/pdf_export/report.rb | 2 +- app/models/queries/projects.rb | 4 +- ...{favored_filter.rb => favorited_filter.rb} | 14 +- .../selects/{favored.rb => favorited.rb} | 4 +- .../project_queries/set_attributes_service.rb | 2 +- .../homescreen/blocks/_projects.html.erb | 2 +- config/constants/settings/definition.rb | 2 +- ...as_favorable.rb => acts_as_favoritable.rb} | 4 +- config/initializers/export_formats.rb | 2 +- config/locales/en.yml | 2 +- config/routes.rb | 2 +- .../configuration/environment/README.md | 2 +- .../widget-project-favorites.component.ts | 2 +- .../header-project-select.component.html | 12 +- .../header-project-select.component.ts | 12 +- .../header-project-select-list.component.html | 4 +- .../header-project-select-list.component.ts | 16 +- lib/open_project/menu.rb | 4 +- .../acts/{favorable.rb => favoritable.rb} | 38 ++--- .../{favorable => favoritable}/registry.rb | 2 +- .../route_constraint.rb | 2 +- .../patterns/07-menu-and-navigation.md.erb | 4 +- .../common/submenu_component_preview.rb | 6 +- .../submenu_preview/playground.html.erb | 2 +- .../views/overviews/overviews/show.html.erb | 14 +- .../components/projects/row_component_spec.rb | 2 +- spec/features/projects/favorite_spec.rb | 16 +- spec/features/projects/lists/table_spec.rb | 8 +- .../features/projects/persisted_lists_spec.rb | 10 +- .../route_constraint_spec.rb | 2 +- spec/menus/projects/menu_spec.rb | 24 +-- spec/models/project_spec.rb | 2 +- .../queries/factory_project_query_spec.rb | 12 +- .../queries/projects/project_query_spec.rb | 6 +- .../api/v3/projects/index_resource_spec.rb | 30 ++-- .../set_attributes_service_spec.rb | 4 +- spec/support/components/common/submenu.rb | 6 +- spec/support/pages/projects/index.rb | 10 +- spec/support/shared/acts_as_favorable.rb | 161 ------------------ spec/support/shared/acts_as_favoritable.rb | 161 ++++++++++++++++++ .../principals/delete_job_integration_spec.rb | 4 +- 58 files changed, 370 insertions(+), 369 deletions(-) rename app/models/projects/exports/formatters/{favored.rb => favorited.rb} (86%) rename app/models/queries/projects/filters/{favored_filter.rb => favorited_filter.rb} (84%) rename app/models/queries/projects/selects/{favored.rb => favorited.rb} (94%) rename config/initializers/{acts_as_favorable.rb => acts_as_favoritable.rb} (94%) rename lib_static/open_project/acts/{favorable.rb => favoritable.rb} (68%) rename lib_static/open_project/acts/{favorable => favoritable}/registry.rb (98%) rename lib_static/open_project/acts/{favorable => favoritable}/route_constraint.rb (98%) rename spec/lib/acts_as_watchable/lib/open_project/acts/{favorable => favoritable}/route_constraint_spec.rb (97%) delete mode 100644 spec/support/shared/acts_as_favorable.rb create mode 100644 spec/support/shared/acts_as_favoritable.rb diff --git a/app/components/open_project/common/submenu_component.html.erb b/app/components/open_project/common/submenu_component.html.erb index 5a82089c8cb..f671b80a712 100644 --- a/app/components/open_project/common/submenu_component.html.erb +++ b/app/components/open_project/common/submenu_component.html.erb @@ -84,7 +84,7 @@ <%= render Primer::Beta::Octicon.new(icon: "op-enterprise-addons", "aria-label": I18n.t(:label_enterprise_edition), classes: "upsell-colored", ml: 2) %> <% end %> - <% if child_item.favored %> + <% if child_item.favorited %> <%= render Primer::Beta::Octicon.new(icon: "star-fill", "aria-label": I18n.t(:label_favorite), classes: %w[op-submenu--item-mark op-primer--star-icon], ml: 2) %> <% end %> diff --git a/app/components/projects/index_page_header_component.html.erb b/app/components/projects/index_page_header_component.html.erb index a9fff8eebaa..4bcee7d9c0a 100644 --- a/app/components/projects/index_page_header_component.html.erb +++ b/app/components/projects/index_page_header_component.html.erb @@ -45,8 +45,8 @@ ) end - if can_toggle_favor? - if currently_favored? + if can_toggle_favorite? + if currently_favorited? header.with_action_icon_button( icon: "star-fill", mobile_icon: "star-fill", diff --git a/app/components/projects/index_page_header_component.rb b/app/components/projects/index_page_header_component.rb index 43474279bc1..e793a12fc46 100644 --- a/app/components/projects/index_page_header_component.rb +++ b/app/components/projects/index_page_header_component.rb @@ -106,9 +106,9 @@ class Projects::IndexPageHeaderComponent < ApplicationComponent query.persisted? end - def can_toggle_favor? = query.persisted? + def can_toggle_favorite? = query.persisted? - def currently_favored? = query.favored_by?(current_user) + def currently_favorited? = query.favorited_by?(current_user) def breadcrumb_items [ diff --git a/app/components/projects/projects_filters_component.rb b/app/components/projects/projects_filters_component.rb index e9e7993e15c..35b284cd572 100644 --- a/app/components/projects/projects_filters_component.rb +++ b/app/components/projects/projects_filters_component.rb @@ -48,7 +48,7 @@ class Projects::ProjectsFiltersComponent < Filter::FilterComponent Queries::Filters::Shared::CustomFields::Base, Queries::Projects::Filters::ActiveFilter, Queries::Projects::Filters::CreatedAtFilter, - Queries::Projects::Filters::FavoredFilter, + Queries::Projects::Filters::FavoritedFilter, Queries::Projects::Filters::IdFilter, Queries::Projects::Filters::LatestActivityAtFilter, Queries::Projects::Filters::ProjectPhaseAnyFilter, diff --git a/app/components/projects/row_component.rb b/app/components/projects/row_component.rb index 89b88b3587d..4fe26d5335c 100644 --- a/app/components/projects/row_component.rb +++ b/app/components/projects/row_component.rb @@ -30,7 +30,7 @@ module Projects class RowComponent < ::RowComponent delegate :identifier, to: :project - delegate :favored_project_ids, + delegate :favorited_project_ids, :project_phase_by_definition, to: :table @@ -47,25 +47,25 @@ module Projects "" end - def favored + def favorited render(Primer::Beta::IconButton.new( - icon: currently_favored? ? "star-fill" : "star", + icon: currently_favorited? ? "star-fill" : "star", scheme: :invisible, - mobile_icon: currently_favored? ? "star-fill" : "star", + mobile_icon: currently_favorited? ? "star-fill" : "star", size: :medium, tag: :a, tooltip_direction: :e, href: helpers.build_favorite_path(project, format: :html), - data: { "turbo-method": currently_favored? ? :delete : :post }, - classes: currently_favored? ? "op-primer--star-icon " : "op-project-row-component--favorite", - label: currently_favored? ? I18n.t(:button_unfavorite) : I18n.t(:button_favorite), - aria: { label: currently_favored? ? I18n.t(:button_unfavorite) : I18n.t(:button_favorite) }, + data: { "turbo-method": currently_favorited? ? :delete : :post }, + classes: currently_favorited? ? "op-primer--star-icon " : "op-project-row-component--favorite", + label: currently_favorited? ? I18n.t(:button_unfavorite) : I18n.t(:button_favorite), + aria: { label: currently_favorited? ? I18n.t(:button_unfavorite) : I18n.t(:button_favorite) }, test_selector: "project-list-favorite-button" )) end - def currently_favored? - @currently_favored ||= favored_project_ids.include?(project.id) + def currently_favorited? + @currently_favorited ||= favorited_project_ids.include?(project.id) end def column_value(column) @@ -215,10 +215,10 @@ module Projects def additional_css_class(column) if column.attribute == :name - "project--hierarchy #{project.archived? ? 'archived' : ''}" + "project--hierarchy #{'archived' if project.archived?}" elsif %i[status_explanation description].include?(column.attribute) "project-long-text-container" - elsif column.attribute == :favored + elsif column.attribute == :favorited "-w-abs-45" elsif custom_field_column?(column) cf = column.custom_field @@ -267,7 +267,7 @@ module Projects end def more_menu_favorite_item - return if currently_favored? + return if currently_favorited? { scheme: :default, @@ -280,7 +280,7 @@ module Projects end def more_menu_unfavorite_item - return unless currently_favored? + return unless currently_favorited? { scheme: :default, diff --git a/app/components/projects/table_component.rb b/app/components/projects/table_component.rb index f0ef1202dff..d6a115fc5e3 100644 --- a/app/components/projects/table_component.rb +++ b/app/components/projects/table_component.rb @@ -191,8 +191,8 @@ module Projects end end - def favored_project_ids - @favored_project_ids ||= Favorite.where(user: current_user, favored_type: "Project").pluck(:favored_id) + def favorited_project_ids + @favorited_project_ids ||= Favorite.where(user: current_user, favorited_type: "Project").pluck(:favorited_id) end def project_phase_by_definition(definition, project) diff --git a/app/controllers/favorites_controller.rb b/app/controllers/favorites_controller.rb index f1acf4f3e2d..a448606ff97 100644 --- a/app/controllers/favorites_controller.rb +++ b/app/controllers/favorites_controller.rb @@ -29,33 +29,33 @@ #++ class FavoritesController < ApplicationController - before_action :find_favored_by_object + before_action :find_favorited_by_object before_action :require_login no_authorization_required! :favorite, :unfavorite def favorite - if @favored.visible?(User.current) - set_favored(User.current, true) + if @favorited.visible?(User.current) + set_favorited(User.current, true) else render_403 end end def unfavorite - set_favored(User.current, false) + set_favorited(User.current, false) end private - def find_favored_by_object + def find_favorited_by_object model_name = params[:object_type] - klass = ::OpenProject::Acts::Favorable::Registry.instance(model_name) - @favored = klass&.find(params[:object_id]) - render_404 unless @favored + klass = ::OpenProject::Acts::Favoritable::Registry.instance(model_name) + @favorited = klass&.find(params[:object_id]) + render_404 unless @favorited end - def set_favored(user, favored) - @favored.set_favored(user, favored:) + def set_favorited(user, favorited) + @favorited.set_favorited(user, favorited:) respond_to do |format| format.html { redirect_back(fallback_location: home_url, status: 303) } diff --git a/app/controllers/homescreen_controller.rb b/app/controllers/homescreen_controller.rb index ed7f9a66a9c..aaa7e6090f5 100644 --- a/app/controllers/homescreen_controller.rb +++ b/app/controllers/homescreen_controller.rb @@ -37,7 +37,7 @@ class HomescreenController < ApplicationController def index @newest_projects = Project.visible.newest.take(3) - @favorite_projects = Project.visible.active.favored_by(User.current) + @favorite_projects = Project.visible.active.favorited_by(User.current) @newest_users = User.active.newest.take(3) @news = News.latest(count: 3) @announcement = Announcement.active_and_current diff --git a/app/helpers/sort_helper.rb b/app/helpers/sort_helper.rb index eded417bd26..3fd55d4e29a 100644 --- a/app/helpers/sort_helper.rb +++ b/app/helpers/sort_helper.rb @@ -347,7 +347,7 @@ module SortHelper data = options.delete(:data) || {} options[:title] = sort_header_title(column, caption, options) if with_title - options[:icon_only_header] = column == :favored + options[:icon_only_header] = column == :favorited within_sort_header_tag_hierarchy(options, sort_class(column)) do yield(column, caption, default_order, allowed_params:, param:, lang:, title: options[:title], @@ -401,7 +401,7 @@ module SortHelper content_args = html_options.merge(rel: :nofollow, param: nil) render Primer::Alpha::ActionMenu.new(menu_id: "menu-#{attribute}") do |menu| - action_button(menu, column, caption, favorite: column == :favored) + action_button(menu, column, caption, favorite: column == :favorited) # Some columns are not sortable or do not offer a suitable filter. Omit those actions for them. sort_actions(menu, attribute, default_order, content_args:, allowed_params:, **html_options) if sortable diff --git a/app/menus/projects/menu.rb b/app/menus/projects/menu.rb index f2c4a7c5ae2..da98c81728e 100644 --- a/app/menus/projects/menu.rb +++ b/app/menus/projects/menu.rb @@ -68,8 +68,8 @@ module Projects end end - def favored?(query_params) - query_params[:query_id].in?(favored_ids) + def favorited?(query_params) + query_params[:query_id].in?(favorited_ids) end def query_path(query_params) @@ -82,7 +82,7 @@ module Projects static_filters [ ProjectQueries::Static::ACTIVE, current_user.logged? ? ProjectQueries::Static::MY : nil, - current_user.logged? ? ProjectQueries::Static::FAVORED : nil, + current_user.logged? ? ProjectQueries::Static::FAVORITED : nil, current_user.admin? ? ProjectQueries::Static::ARCHIVED : nil ].compact end @@ -116,12 +116,12 @@ module Projects def persisted_filters @persisted_filters ||= ::ProjectQuery .visible(current_user) - .with_favored_by_user(current_user) - .order(favored: :desc, name: :asc) + .with_favorited_by_user(current_user) + .order(favorited: :desc, name: :asc) end - def favored_ids - @favored_ids ||= persisted_filters.select(&:favored).to_set(&:id) + def favorited_ids + @favorited_ids ||= persisted_filters.select(&:favorited).to_set(&:id) end def modification_params? diff --git a/app/menus/submenu.rb b/app/menus/submenu.rb index bd070dbefbf..80e2859d3be 100644 --- a/app/menus/submenu.rb +++ b/app/menus/submenu.rb @@ -29,6 +29,7 @@ # ++ class Submenu include Rails.application.routes.url_helpers + attr_reader :view_type, :project, :params def initialize(view_type:, params:, project: nil) @@ -117,7 +118,7 @@ class Submenu icon: icon_map.fetch(icon_key, icon_key), count:, selected:, - favored: favored?(query_params), + favorited: favorited?(query_params), show_enterprise_icon:) end @@ -129,14 +130,14 @@ class Submenu end end - if query_params.empty? && (%i[filters query_props query_id name].any? { |k| params.key? k }) + if query_params.empty? && %i[filters query_props query_id name].any? { |k| params.key? k } return false end true end - def favored?(_query_params) + def favorited?(_query_params) false end diff --git a/app/models/application_record.rb b/app/models/application_record.rb index b32fff78d3d..cbd61c00513 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -30,7 +30,7 @@ class ApplicationRecord < ActiveRecord::Base include ::OpenProject::Acts::Watchable - include ::OpenProject::Acts::Favorable + include ::OpenProject::Acts::Favoritable self.abstract_class = true diff --git a/app/models/favorite.rb b/app/models/favorite.rb index 2acfda0e245..cdfadef06f4 100644 --- a/app/models/favorite.rb +++ b/app/models/favorite.rb @@ -30,8 +30,8 @@ class Favorite < ApplicationRecord belongs_to :user - belongs_to :favored, polymorphic: true + belongs_to :favorited, polymorphic: true validates :user, presence: true - validates :favored, presence: true + validates :favorited, presence: true end diff --git a/app/models/project.rb b/app/models/project.rb index e033cba919e..1d7733dc638 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -108,7 +108,7 @@ class Project < ApplicationRecord store_attribute :settings, :deactivate_work_package_attachments, :boolean store_attribute :settings, :enabled_internal_comments, :boolean - acts_as_favorable + acts_as_favoritable acts_as_customizable validate_on: :saving_custom_fields # extended in Projects::CustomFields in order to support sections diff --git a/app/models/project_queries/static.rb b/app/models/project_queries/static.rb index 6c2d9e6d136..be3097f4d8a 100644 --- a/app/models/project_queries/static.rb +++ b/app/models/project_queries/static.rb @@ -31,7 +31,7 @@ class ProjectQueries::Static ACTIVE = "active" MY = "my" - FAVORED = "favored" + FAVORITED = "favorited" ARCHIVED = "archived" ON_TRACK = "on_track" OFF_TRACK = "off_track" @@ -46,8 +46,8 @@ class ProjectQueries::Static static_query_active when MY static_query_my - when FAVORED - static_query_favored + when FAVORITED + static_query_favorited when ARCHIVED static_query_archived when ON_TRACK @@ -73,9 +73,9 @@ class ProjectQueries::Static end end - def static_query_favored - list_with(:"projects.lists.favored") do |query| - query.where("favored", "=", OpenProject::Database::DB_VALUE_TRUE) + def static_query_favorited + list_with(:"projects.lists.favorited") do |query| + query.where("favorited", "=", OpenProject::Database::DB_VALUE_TRUE) end end diff --git a/app/models/project_query.rb b/app/models/project_query.rb index 72c1dac815a..1b667eec810 100644 --- a/app/models/project_query.rb +++ b/app/models/project_query.rb @@ -36,7 +36,7 @@ class ProjectQuery < ApplicationRecord belongs_to :user - acts_as_favorable + acts_as_favoritable serialize :filters, coder: Queries::Serialization::Filters.new(self) serialize :orders, coder: Queries::Serialization::Orders.new(self) diff --git a/app/models/projects/exports/formatters/favored.rb b/app/models/projects/exports/formatters/favorited.rb similarity index 86% rename from app/models/projects/exports/formatters/favored.rb rename to app/models/projects/exports/formatters/favorited.rb index 12909e98891..cd90af0737b 100644 --- a/app/models/projects/exports/formatters/favored.rb +++ b/app/models/projects/exports/formatters/favorited.rb @@ -29,15 +29,15 @@ #++ module Projects::Exports module Formatters - class Favored < ::Exports::Formatters::Default + class Favorited < ::Exports::Formatters::Default def self.apply?(attribute, export_format) - export_format == :pdf && attribute.to_sym == :favored + export_format == :pdf && attribute.to_sym == :favorited end ## - # Takes a project and returns yes/no depending on the favored attribute + # Takes a project and returns yes/no depending on the favorited attribute def format(project, **) - project.favored_by?(User.current) ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) + project.favorited_by?(User.current) ? I18n.t(:general_text_Yes) : I18n.t(:general_text_No) end end end diff --git a/app/models/projects/exports/pdf_export/report.rb b/app/models/projects/exports/pdf_export/report.rb index 00b3366ab51..bb57847abc3 100644 --- a/app/models/projects/exports/pdf_export/report.rb +++ b/app/models/projects/exports/pdf_export/report.rb @@ -170,7 +170,7 @@ module Projects::Exports::PDFExport end def can_view_attribute?(_project, attribute) - attribute && %i[name favored].exclude?(attribute) + attribute && %i[name favorited].exclude?(attribute) end def user_can_view_project_phases?(project) diff --git a/app/models/queries/projects.rb b/app/models/queries/projects.rb index d5f185fb634..93ba0f9cffd 100644 --- a/app/models/queries/projects.rb +++ b/app/models/queries/projects.rb @@ -36,7 +36,7 @@ module Queries::Projects filter Filters::AvailableProjectAttributesFilter filter Filters::CreatedAtFilter filter Filters::CustomFieldFilter - filter Filters::FavoredFilter + filter Filters::FavoritedFilter filter Filters::IdFilter filter Filters::LatestActivityAtFilter filter Filters::ProjectPhaseAnyFilter @@ -67,7 +67,7 @@ module Queries::Projects select Selects::CreatedAt select Selects::CustomField select Selects::Default - select Selects::Favored + select Selects::Favorited select Selects::LatestActivityAt select Selects::ProjectPhase select Selects::RequiredDiskSpace diff --git a/app/models/queries/projects/filters/favored_filter.rb b/app/models/queries/projects/filters/favorited_filter.rb similarity index 84% rename from app/models/queries/projects/filters/favored_filter.rb rename to app/models/queries/projects/filters/favorited_filter.rb index 7aa23218431..11039427f73 100644 --- a/app/models/queries/projects/filters/favored_filter.rb +++ b/app/models/queries/projects/filters/favorited_filter.rb @@ -28,11 +28,11 @@ # See COPYRIGHT and LICENSE files for more details. #++ -class Queries::Projects::Filters::FavoredFilter < Queries::Projects::Filters::Base +class Queries::Projects::Filters::FavoritedFilter < Queries::Projects::Filters::Base include Queries::Filters::Shared::BooleanFilter def self.key - :favored + :favorited end def human_name @@ -46,9 +46,9 @@ class Queries::Projects::Filters::FavoredFilter < Queries::Projects::Filters::Ba def apply_to(_query_scope) if (values.first == OpenProject::Database::DB_VALUE_TRUE && operator_strategy == Queries::Operators::BooleanEquals) || (values.first == OpenProject::Database::DB_VALUE_FALSE && operator_strategy == Queries::Operators::BooleanNotEquals) - super.where(id: favored_project_ids) + super.where(id: favorited_project_ids) else - super.where.not(id: favored_project_ids) + super.where.not(id: favorited_project_ids) end end @@ -57,9 +57,9 @@ class Queries::Projects::Filters::FavoredFilter < Queries::Projects::Filters::Ba nil end - def favored_project_ids + def favorited_project_ids Favorite - .where(favored_type: "Project", user_id: User.current.id) - .select(:favored_id) + .where(favorited_type: "Project", user_id: User.current.id) + .select(:favorited_id) end end diff --git a/app/models/queries/projects/selects/favored.rb b/app/models/queries/projects/selects/favorited.rb similarity index 94% rename from app/models/queries/projects/selects/favored.rb rename to app/models/queries/projects/selects/favorited.rb index 35a2ae1f9a0..a68c585e8b3 100644 --- a/app/models/queries/projects/selects/favored.rb +++ b/app/models/queries/projects/selects/favorited.rb @@ -28,9 +28,9 @@ # See COPYRIGHT and LICENSE files for more details. # ++ -class Queries::Projects::Selects::Favored < Queries::Selects::Base +class Queries::Projects::Selects::Favorited < Queries::Selects::Base def self.key - :favored + :favorited end def self.available? diff --git a/app/services/project_queries/set_attributes_service.rb b/app/services/project_queries/set_attributes_service.rb index dcc31c97adb..0fb8890141a 100644 --- a/app/services/project_queries/set_attributes_service.rb +++ b/app/services/project_queries/set_attributes_service.rb @@ -94,6 +94,6 @@ class ProjectQueries::SetAttributesService < BaseServices::SetAttributes end def default_columns - (["favored", "name"] + Setting.enabled_projects_columns).uniq + (["favorited", "name"] + Setting.enabled_projects_columns).uniq end end diff --git a/app/views/homescreen/blocks/_projects.html.erb b/app/views/homescreen/blocks/_projects.html.erb index 52f0e92b869..580e817021d 100644 --- a/app/views/homescreen/blocks/_projects.html.erb +++ b/app/views/homescreen/blocks/_projects.html.erb @@ -2,7 +2,7 @@
<% if @favorite_projects.any? %> -

<%= t("projects.lists.favored") %>

+

<%= t("projects.lists.favorited") %>

-

- - {{ displayMode === 'favored' ? text.no_favorite_results : text.no_results }} + {{ displayMode === 'favorited' ? text.no_favorite_results : text.no_results }}
diff --git a/frontend/src/app/shared/components/header-project-select/header-project-select.component.ts b/frontend/src/app/shared/components/header-project-select/header-project-select.component.ts index 8bb34e216e2..82fc6766f0f 100644 --- a/frontend/src/app/shared/components/header-project-select/header-project-select.component.ts +++ b/frontend/src/app/shared/components/header-project-select/header-project-select.component.ts @@ -110,7 +110,7 @@ export class OpHeaderProjectSelectComponent extends UntilDestroyedMixin implemen .apiV3Service .projects .signalled( - ApiV3Filter('favored', '=', true), + ApiV3Filter('favorited', '=', true), [ 'elements/id', ], @@ -125,7 +125,7 @@ export class OpHeaderProjectSelectComponent extends UntilDestroyedMixin implemen public text = { all: this.I18n.t('js.label_all_uppercase'), - favored: this.I18n.t('js.label_favorites'), + favorited: this.I18n.t('js.label_favorites'), no_favorites: this.I18n.t('js.favorite_projects.no_results'), no_favorites_subtext: this.I18n.t('js.favorite_projects.no_results_subtext'), project: { @@ -140,11 +140,11 @@ export class OpHeaderProjectSelectComponent extends UntilDestroyedMixin implemen no_favorite_results: this.I18n.t('js.include_projects.no_favorite_results'), }; - public displayMode:'all'|'favored'; + public displayMode:'all'|'favorited'; public displayModeOptions = [ { value: 'all', title: this.text.all }, - { value: 'favored', title: this.text.favored }, + { value: 'favorited', title: this.text.favorited }, ]; /* This seems like a way too convoluted loading check, but there's a good reason we need it. @@ -197,7 +197,7 @@ export class OpHeaderProjectSelectComponent extends UntilDestroyedMixin implemen } ngOnInit():void { - const stored = window.OpenProject.guardedLocalStorage(this.displayModeLocalStorageKey) as 'all'|'favored'|undefined; + const stored = window.OpenProject.guardedLocalStorage(this.displayModeLocalStorageKey) as 'all'|'favorited'|undefined; this.displayMode = stored || 'all'; } @@ -211,7 +211,7 @@ export class OpHeaderProjectSelectComponent extends UntilDestroyedMixin implemen }); } - displayModeChange(mode:'all'|'favored'):void { + displayModeChange(mode:'all'|'favorited'):void { this.displayMode = mode; window.OpenProject.guardedLocalStorage(this.displayModeLocalStorageKey, mode); diff --git a/frontend/src/app/shared/components/header-project-select/list/header-project-select-list.component.html b/frontend/src/app/shared/components/header-project-select/list/header-project-select-list.component.html index 17ea499a23b..a8fbfc6c522 100644 --- a/frontend/src/app/shared/components/header-project-select/list/header-project-select-list.component.html +++ b/frontend/src/app/shared/components/header-project-select/list/header-project-select-list.component.html @@ -26,7 +26,7 @@ [textContent]="project.name"> diff --git a/frontend/src/app/shared/components/header-project-select/list/header-project-select-list.component.ts b/frontend/src/app/shared/components/header-project-select/list/header-project-select-list.component.ts index 23955df8197..1b7a237c8fd 100644 --- a/frontend/src/app/shared/components/header-project-select/list/header-project-select-list.component.ts +++ b/frontend/src/app/shared/components/header-project-select/list/header-project-select-list.component.ts @@ -38,7 +38,7 @@ export class OpHeaderProjectSelectListComponent implements OnInit, OnChanges { @Input() projects:IProjectData[] = []; - @Input() favored:string[] = []; + @Input() favorited:string[] = []; @Input() displayMode:string; @@ -78,7 +78,7 @@ export class OpHeaderProjectSelectListComponent implements OnInit, OnChanges { } ngOnChanges(changes:SimpleChanges) { - if (changes.displayMode || changes.projects || changes.favored) { + if (changes.displayMode || changes.projects || changes.favorited) { this.updateProjectFilter(); } } @@ -89,20 +89,20 @@ export class OpHeaderProjectSelectListComponent implements OnInit, OnChanges { return true; } - return this.showWhenFavored(project); + return this.showWhenFavorited(project); }); } - showWhenFavored(project:IProjectData):boolean { - if (this.isFavored(project)) { + showWhenFavorited(project:IProjectData):boolean { + if (this.isFavorited(project)) { return true; } - return project.children.length > 0 && project.children.some((child) => this.showWhenFavored(child)); + return project.children.length > 0 && project.children.some((child) => this.showWhenFavorited(child)); } - isFavored(project:IProjectData):boolean { - return this.favored.includes(project.id.toString()); + isFavorited(project:IProjectData):boolean { + return this.favorited.includes(project.id.toString()); } extendedUrl(projectId:string|null):string { diff --git a/lib/open_project/menu.rb b/lib/open_project/menu.rb index 04324a4b155..a59c5c82910 100644 --- a/lib/open_project/menu.rb +++ b/lib/open_project/menu.rb @@ -31,8 +31,8 @@ module OpenProject module Menu MenuGroup = Data.define(:header, :children) - MenuItem = Data.define(:title, :href, :selected, :favored, :icon, :count, :show_enterprise_icon) do - def initialize(title:, href:, selected:, favored: false, icon: nil, count: nil, show_enterprise_icon: false) + MenuItem = Data.define(:title, :href, :selected, :favorited, :icon, :count, :show_enterprise_icon) do + def initialize(title:, href:, selected:, favorited: false, icon: nil, count: nil, show_enterprise_icon: false) super end end diff --git a/lib_static/open_project/acts/favorable.rb b/lib_static/open_project/acts/favoritable.rb similarity index 68% rename from lib_static/open_project/acts/favorable.rb rename to lib_static/open_project/acts/favoritable.rb index 3e00be1156b..6b56a9ff7de 100644 --- a/lib_static/open_project/acts/favorable.rb +++ b/lib_static/open_project/acts/favoritable.rb @@ -28,50 +28,50 @@ module OpenProject module Acts - module Favorable + module Favoritable def self.included(base) base.extend ClassMethods end module ClassMethods - # Marks an ActiveRecord::Model as favorable - # A favorable model has association with users (watchers) that marked it as favorite. + # Marks an ActiveRecord::Model as favoritable + # A favoritable model has association with users (watchers) that marked it as favorite. # - # This also creates the routes necessary for favoring/unfavoring by + # This also creates the routes necessary for favoriting/unfavoriting by # adding the model's name to routes. This e.g leads to the following # routes when marking issues as watchable: # POST: projects/identifier/favorite # DELETE: projects/identifier/favorite # - # acts_as_favorable expects that the including module defines a +visible?(user)+ method, + # acts_as_favoritable expects that the including module defines a +visible?(user)+ method, # as it's used to identify whether a user can actually favorite the object. - def acts_as_favorable # rubocop:disable Metrics/AbcSize + def acts_as_favoritable # rubocop:disable Metrics/AbcSize return if included_modules.include?(InstanceMethods) class_eval do prepend InstanceMethods - has_many :favorites, as: :favored, dependent: :delete_all, validate: false - has_many :favoring_users, through: :favorites, source: :user, validate: false + has_many :favorites, as: :favorited, dependent: :delete_all, validate: false + has_many :favoriting_users, through: :favorites, source: :user, validate: false - scope :favored_by, ->(user_id) { + scope :favorited_by, ->(user_id) { includes(:favorites) .where(favorites: { user_id: }) } - scope :with_favored_by_user, ->(user) { + scope :with_favorited_by_user, ->(user) { favorite = ::Favorite.arel_table join = arel_table .join(favorite, Arel::Nodes::OuterJoin) .on( - favorite[:favored_type].eq(base_class.name), - favorite[:favored_id].eq(arel_table[:id]), + favorite[:favorited_type].eq(base_class.name), + favorite[:favorited_id].eq(arel_table[:id]), favorite[:user_id].eq(user.id) ) .join_sources - select(arel_table[Arel.star], "(favorites.id IS NOT NULL) AS favored").joins(join) + select(arel_table[Arel.star], "(favorites.id IS NOT NULL) AS favorited").joins(join) } end @@ -80,21 +80,21 @@ module OpenProject end module InstanceMethods - def add_favoring_user(user) + def add_favoriting_user(user) return if favorites.exists?(user_id: user.id) - favorites << Favorite.new(user:, favored: self) + favorites << Favorite.new(user:, favorited: self) end - def remove_favoring_user(user) + def remove_favoriting_user(user) favorites.where(user:).delete_all end - def set_favored(user, favored: true) - favored ? add_favoring_user(user) : remove_favoring_user(user) + def set_favorited(user, favorited: true) + favorited ? add_favoriting_user(user) : remove_favoriting_user(user) end - def favored_by?(user) + def favorited_by?(user) favorites.exists?(user:) end end diff --git a/lib_static/open_project/acts/favorable/registry.rb b/lib_static/open_project/acts/favoritable/registry.rb similarity index 98% rename from lib_static/open_project/acts/favorable/registry.rb rename to lib_static/open_project/acts/favoritable/registry.rb index cf5b15f3956..dc059751951 100644 --- a/lib_static/open_project/acts/favorable/registry.rb +++ b/lib_static/open_project/acts/favoritable/registry.rb @@ -28,7 +28,7 @@ module OpenProject module Acts - module Favorable + module Favoritable module Registry extend RegistryMethods end diff --git a/lib_static/open_project/acts/favorable/route_constraint.rb b/lib_static/open_project/acts/favoritable/route_constraint.rb similarity index 98% rename from lib_static/open_project/acts/favorable/route_constraint.rb rename to lib_static/open_project/acts/favoritable/route_constraint.rb index 637f569fbde..211da1b0bfe 100644 --- a/lib_static/open_project/acts/favorable/route_constraint.rb +++ b/lib_static/open_project/acts/favoritable/route_constraint.rb @@ -28,7 +28,7 @@ module OpenProject module Acts - module Favorable + module Favoritable module RouteConstraint def self.matches?(request) params = request.path_parameters diff --git a/lookbook/docs/patterns/07-menu-and-navigation.md.erb b/lookbook/docs/patterns/07-menu-and-navigation.md.erb index ae7d104f3f9..f78e2f3c74b 100644 --- a/lookbook/docs/patterns/07-menu-and-navigation.md.erb +++ b/lookbook/docs/patterns/07-menu-and-navigation.md.erb @@ -27,8 +27,8 @@ MenuGroup = Data.define(:header, :children) * `OpenProject::Menu::MenuItem`: A concrete Item with all options it supports ```ruby -MenuItem = Data.define(:title, :href, :selected, :favored, :icon, :count, :show_enterprise_icon) do - def initialize(title:, href:, selected:, favored: false, icon: nil, count: nil, show_enterprise_icon: false) +MenuItem = Data.define(:title, :href, :selected, :favorited, :icon, :count, :show_enterprise_icon) do + def initialize(title:, href:, selected:, favorited: false, icon: nil, count: nil, show_enterprise_icon: false) super end end diff --git a/lookbook/previews/open_project/common/submenu_component_preview.rb b/lookbook/previews/open_project/common/submenu_component_preview.rb index 4b8b7063392..c1b357c606e 100644 --- a/lookbook/previews/open_project/common/submenu_component_preview.rb +++ b/lookbook/previews/open_project/common/submenu_component_preview.rb @@ -42,13 +42,13 @@ module OpenProject # @display min_height 450px # @param searchable [Boolean] # @param with_create_button [Boolean] - # @param favored [Boolean] + # @param favorited [Boolean] # @param count [Integer] # @param show_enterprise_icon [Boolean] # @param icon [Symbol] octicon def playground(searchable: false, with_create_button: false, - favored: false, + favorited: false, count: nil, show_enterprise_icon: false, icon: nil) @@ -56,7 +56,7 @@ module OpenProject locals: { searchable:, create_btn_options: with_create_button ? { href: "/#", module_key: "user" } : nil, - favored:, + favorited:, count:, show_enterprise_icon:, icon: diff --git a/lookbook/previews/open_project/common/submenu_preview/playground.html.erb b/lookbook/previews/open_project/common/submenu_preview/playground.html.erb index 3d6e13e1e7d..760b06f5143 100644 --- a/lookbook/previews/open_project/common/submenu_preview/playground.html.erb +++ b/lookbook/previews/open_project/common/submenu_preview/playground.html.erb @@ -3,7 +3,7 @@ OpenProject::Menu::MenuGroup.new( header: "Private", children: [ - OpenProject::Menu::MenuItem.new(title: "My query", href: "", selected: false, favored: favored), + OpenProject::Menu::MenuItem.new(title: "My query", href: "", selected: false, favorited: favorited), OpenProject::Menu::MenuItem.new(title: "An awesome query", href: "", selected: false, count: count, icon: icon), OpenProject::Menu::MenuItem.new(title: "A third query", href: "", selected: false, show_enterprise_icon: show_enterprise_icon) ] diff --git a/modules/overviews/app/views/overviews/overviews/show.html.erb b/modules/overviews/app/views/overviews/overviews/show.html.erb index 40c8baa9128..ddce0ffd615 100644 --- a/modules/overviews/app/views/overviews/overviews/show.html.erb +++ b/modules/overviews/app/views/overviews/overviews/show.html.erb @@ -7,17 +7,17 @@ t("overviews.label") ] ) - favored = @project.favored_by?(User.current) + favorited = @project.favorited_by?(User.current) header.with_action_icon_button( - icon: favored ? "star-fill" : "star", - mobile_icon: favored ? "star-fill" : "star", + icon: favorited ? "star-fill" : "star", + mobile_icon: favorited ? "star-fill" : "star", size: :medium, tag: :a, href: build_favorite_path(@project, format: :html), - data: { method: favored ? :delete : :post }, - classes: favored ? "op-primer--star-icon" : "", - label: favored ? I18n.t(:button_unfavorite) : I18n.t(:button_favorite), - aria: { label: favored ? I18n.t(:button_unfavorite) : I18n.t(:button_favorite) }, + data: { method: favorited ? :delete : :post }, + classes: favorited ? "op-primer--star-icon" : "", + label: favorited ? I18n.t(:button_unfavorite) : I18n.t(:button_favorite), + aria: { label: favorited ? I18n.t(:button_unfavorite) : I18n.t(:button_favorite) }, test_selector: "project-favorite-button" ) diff --git a/spec/components/projects/row_component_spec.rb b/spec/components/projects/row_component_spec.rb index 9c2a63e420d..b058bb3e0fb 100644 --- a/spec/components/projects/row_component_spec.rb +++ b/spec/components/projects/row_component_spec.rb @@ -40,7 +40,7 @@ RSpec.describe Projects::RowComponent, type: :component do let(:project) { build_stubbed(:project, name: "My Project No. 1", identifier: "myproject_no_1") } let(:table) do instance_double(Projects::TableComponent, columns: [Queries::Projects::Selects::Default.new(:name)], - favored_project_ids: []) + favorited_project_ids: []) end let(:user) { build_stubbed(:user) } diff --git a/spec/features/projects/favorite_spec.rb b/spec/features/projects/favorite_spec.rb index 7ba60e28b05..9b9be931dea 100644 --- a/spec/features/projects/favorite_spec.rb +++ b/spec/features/projects/favorite_spec.rb @@ -66,17 +66,17 @@ RSpec.describe "Favorite projects", :js, :selenium do expect(page).to have_css "a", accessible_name: "Remove from favorite" project.reload - expect(project).to be_favored_by(user) + expect(project).to be_favorited_by(user) projects_page.visit! projects_page.open_filters - projects_page.filter_by_favored "yes" + projects_page.filter_by_favorited "yes" expect(page).to have_text "My favorite!" projects_page.visit! projects_page.open_filters - projects_page.filter_by_favored "no" + projects_page.filter_by_favorited "no" expect(page).to have_no_text "My favorite!" @@ -114,10 +114,10 @@ RSpec.describe "Favorite projects", :js, :selenium do top_menu.expect_current_mode "All" end - context "when project is favored" do + context "when project is favorited" do before do - project.add_favoring_user(user) - other_project.add_favoring_user(user) + project.add_favoriting_user(user) + other_project.add_favoriting_user(user) other_project.update! active: false end @@ -137,7 +137,7 @@ RSpec.describe "Favorite projects", :js, :selenium do context "when favoriting only one subproject" do before do project.update! parent: other_project - project.add_favoring_user(user) + project.add_favoriting_user(user) end it "still shows up in top menu (Regression #54729)" do @@ -171,7 +171,7 @@ RSpec.describe "Favorite projects", :js, :selenium do ProjectRole.anonymous.update permissions: [:view_project] end - it "does not shows favored projects" do + it "does not shows favorited projects" do visit project_path(project) retry_block do diff --git a/spec/features/projects/lists/table_spec.rb b/spec/features/projects/lists/table_spec.rb index b28e6ca9a20..c6cf949ef1f 100644 --- a/spec/features/projects/lists/table_spec.rb +++ b/spec/features/projects/lists/table_spec.rb @@ -239,7 +239,7 @@ RSpec.describe "Projects lists table display and actions", :js, with_settings: { end visit project_path(project) - expect(project).to be_favored_by(admin) + expect(project).to be_favorited_by(admin) visit projects_path projects_page.activate_menu_of(project) do |menu| @@ -248,7 +248,7 @@ RSpec.describe "Projects lists table display and actions", :js, with_settings: { end visit project_path(project) - expect(project).not_to be_favored_by(admin) + expect(project).not_to be_favorited_by(admin) visit projects_path projects_page.within_row(project) do @@ -260,7 +260,7 @@ RSpec.describe "Projects lists table display and actions", :js, with_settings: { projects_page.activate_menu_of(project) do |menu| expect(menu).to have_text("Remove from favorites") end - expect(project).to be_favored_by(admin) + expect(project).to be_favorited_by(admin) projects_page.within_row(project) do page.find_test_selector("project-list-favorite-button").click @@ -269,7 +269,7 @@ RSpec.describe "Projects lists table display and actions", :js, with_settings: { projects_page.activate_menu_of(project) do |menu| expect(menu).to have_text("Add to favorites") end - expect(project).not_to be_favored_by(admin) + expect(project).not_to be_favorited_by(admin) end specify "project can be deleted" do diff --git a/spec/features/projects/persisted_lists_spec.rb b/spec/features/projects/persisted_lists_spec.rb index e3283e25e08..fccdcef9e6c 100644 --- a/spec/features/projects/persisted_lists_spec.rb +++ b/spec/features/projects/persisted_lists_spec.rb @@ -411,17 +411,17 @@ RSpec.describe "Persisted lists on projects index page", projects_page.expect_no_columns("Public") end - it "allows favoring persisted query" do - projects_page.expect_sidebar_filter("Persisted query", favored: false) + it "allows favoriting persisted query" do + projects_page.expect_sidebar_filter("Persisted query", favorited: false) projects_page.set_sidebar_filter("Persisted query") - projects_page.expect_sidebar_filter("Persisted query", selected: true, favored: false) + projects_page.expect_sidebar_filter("Persisted query", selected: true, favorited: false) projects_page.mark_query_favorite - projects_page.expect_sidebar_filter("Persisted query", selected: true, favored: true) + projects_page.expect_sidebar_filter("Persisted query", selected: true, favorited: true) projects_page.unmark_query_favorite - projects_page.expect_sidebar_filter("Persisted query", selected: true, favored: false) + projects_page.expect_sidebar_filter("Persisted query", selected: true, favorited: false) end it "loads the query with a custom field filter (Regression#57298)" do diff --git a/spec/lib/acts_as_watchable/lib/open_project/acts/favorable/route_constraint_spec.rb b/spec/lib/acts_as_watchable/lib/open_project/acts/favoritable/route_constraint_spec.rb similarity index 97% rename from spec/lib/acts_as_watchable/lib/open_project/acts/favorable/route_constraint_spec.rb rename to spec/lib/acts_as_watchable/lib/open_project/acts/favoritable/route_constraint_spec.rb index c80dab4e216..71a04e800a2 100644 --- a/spec/lib/acts_as_watchable/lib/open_project/acts/favorable/route_constraint_spec.rb +++ b/spec/lib/acts_as_watchable/lib/open_project/acts/favoritable/route_constraint_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe OpenProject::Acts::Favorable::RouteConstraint do +RSpec.describe OpenProject::Acts::Favoritable::RouteConstraint do let(:request) { instance_double(ActionDispatch::Request, path_parameters:) } let(:path_parameters) { { object_id: id, object_type: type } } diff --git a/spec/menus/projects/menu_spec.rb b/spec/menus/projects/menu_spec.rb index 1d393ee460d..3fba0abe035 100644 --- a/spec/menus/projects/menu_spec.rb +++ b/spec/menus/projects/menu_spec.rb @@ -78,7 +78,7 @@ RSpec.describe Projects::Menu do end it "has the favorite projects item" do - expect(children_menu_items).to include(have_attributes(title: I18n.t("projects.lists.favored"))) + expect(children_menu_items).to include(have_attributes(title: I18n.t("projects.lists.favorited"))) end it "has an archived projects item" do @@ -96,7 +96,7 @@ RSpec.describe Projects::Menu do end it "has the favorite projects item" do - expect(children_menu_items).to include(have_attributes(title: I18n.t("projects.lists.favored"))) + expect(children_menu_items).to include(have_attributes(title: I18n.t("projects.lists.favorited"))) end it "has no archived projects item" do @@ -136,7 +136,7 @@ RSpec.describe Projects::Menu do end it "has no favorite projects item" do - expect(children_menu_items).not_to include(have_attributes(title: I18n.t("projects.lists.favored"))) + expect(children_menu_items).not_to include(have_attributes(title: I18n.t("projects.lists.favorited"))) end it "has no archived projects item" do @@ -163,13 +163,13 @@ RSpec.describe Projects::Menu do end before do - favored_queries.each do |query| - query.add_favoring_user(current_user) + favorited_queries.each do |query| + query.add_favoriting_user(current_user) end end - context "when no queries are favored" do - let(:favored_queries) { [] } + context "when no queries are favorited" do + let(:favorited_queries) { [] } it "orders persisted titles alphabetically" do expect(titles).to eq( @@ -183,8 +183,8 @@ RSpec.describe Projects::Menu do end end - context "when some queries are favored" do - let(:favored_queries) do + context "when some queries are favorited" do + let(:favorited_queries) do [ current_user_query, public_query, @@ -192,7 +192,7 @@ RSpec.describe Projects::Menu do ] end - it "orders persisted titles by favor then alphabetically" do + it "orders persisted titles by favorite then alphabetically" do expect(titles).to eq( [ ["Active projects", "My projects", "Favorite projects"], @@ -204,8 +204,8 @@ RSpec.describe Projects::Menu do end end - context "when all queries are favored" do - let(:favored_queries) do + context "when all queries are favorited" do + let(:favorited_queries) do [ current_user_query, another_current_user_query, diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 47dc30aa1f6..8afecf13a70 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -472,7 +472,7 @@ RSpec.describe Project do end end - it_behaves_like "acts_as_favorable included" do + it_behaves_like "acts_as_favoritable included" do let(:instance) { project } end diff --git a/spec/models/queries/factory_project_query_spec.rb b/spec/models/queries/factory_project_query_spec.rb index 7491a2387f4..636cef8bcb0 100644 --- a/spec/models/queries/factory_project_query_spec.rb +++ b/spec/models/queries/factory_project_query_spec.rb @@ -33,7 +33,7 @@ require "services/base_services/behaves_like_create_service" RSpec.describe Queries::Factory, "ProjectQuery", - with_settings: { enabled_projects_columns: %w[favored name project_status] } do + with_settings: { enabled_projects_columns: %w[favorited name project_status] } do before do scope = instance_double(ActiveRecord::Relation) @@ -52,7 +52,7 @@ RSpec.describe Queries::Factory, build_stubbed(:project_query, name: "My query") do |query| query.order(id: :asc) query.where(:project_status_code, "=", [Project.status_codes[:on_track].to_s]) - query.select(:project_status, :name, :favored) + query.select(:project_status, :name, :favorited) end end let(:custom_field) do @@ -343,7 +343,7 @@ RSpec.describe Queries::Factory, it "has the enabled_project_columns columns as selects" do expect(find.selects.map(&:attribute)) - .to eq(%i[project_status name favored]) + .to eq(%i[project_status name favorited]) end it { is_expected.not_to be_changed } @@ -654,7 +654,7 @@ RSpec.describe Queries::Factory, it "has the selects of the persisted query" do expect(find.selects.map(&:attribute)) - .to eq(%i[project_status name favored]) + .to eq(%i[project_status name favorited]) end it { is_expected.to be_changed } @@ -699,7 +699,7 @@ RSpec.describe Queries::Factory, it "has the selects of the persisted query" do expect(find.selects.map(&:attribute)) - .to eq(%i[project_status name favored]) + .to eq(%i[project_status name favorited]) end it { is_expected.to be_changed } @@ -805,7 +805,7 @@ RSpec.describe Queries::Factory, it "keeps selects" do expect(find.selects.map(&:attribute)) - .to eq(%i[project_status name favored]) + .to eq(%i[project_status name favorited]) end it { is_expected.to be_changed } diff --git a/spec/models/queries/projects/project_query_spec.rb b/spec/models/queries/projects/project_query_spec.rb index 5bc9ae43991..54ec11ad873 100644 --- a/spec/models/queries/projects/project_query_spec.rb +++ b/spec/models/queries/projects/project_query_spec.rb @@ -36,7 +36,7 @@ RSpec.describe ProjectQuery do shared_let(:user) { create(:user) } shared_let(:admin) { create(:admin) } - it_behaves_like "acts_as_favorable included" do + it_behaves_like "acts_as_favoritable included" do let(:instance) { create(:project_query) } end @@ -137,7 +137,7 @@ RSpec.describe ProjectQuery do id identifier name - favored + favorited public description hierarchy @@ -162,7 +162,7 @@ RSpec.describe ProjectQuery do id identifier name - favored + favorited public description hierarchy diff --git a/spec/requests/api/v3/projects/index_resource_spec.rb b/spec/requests/api/v3/projects/index_resource_spec.rb index 3402c1826db..43604319d29 100644 --- a/spec/requests/api/v3/projects/index_resource_spec.rb +++ b/spec/requests/api/v3/projects/index_resource_spec.rb @@ -230,56 +230,56 @@ RSpec.describe "API v3 Project resource index", content_type: :json do end end - context "when filtering for favored" do - let(:favored_project) { create(:project) } - let(:unfavored_project) { create(:project) } + context "when filtering for favorited" do + let(:favorited_project) { create(:project) } + let(:unfavorited_project) { create(:project) } - let(:projects) { [favored_project, unfavored_project] } + let(:projects) { [favorited_project, unfavorited_project] } current_user do - create(:user, member_with_roles: { favored_project => role, - unfavored_project => role }) do |user| - favored_project.set_favored(user) + create(:user, member_with_roles: { favorited_project => role, + unfavorited_project => role }) do |user| + favorited_project.set_favorited(user) end end context "when filtering for favorite projects" do let(:filters) do - [{ favored: { operator: "=", values: ["t"] } }] + [{ favorited: { operator: "=", values: ["t"] } }] end it_behaves_like "API V3 collection response", 1, 1, "Project" do - let(:elements) { [favored_project] } + let(:elements) { [favorited_project] } end end context "when filtering for nonfavorite projects" do let(:filters) do - [{ favored: { operator: "=", values: ["f"] } }] + [{ favorited: { operator: "=", values: ["f"] } }] end it_behaves_like "API V3 collection response", 1, 1, "Project" do - let(:elements) { [unfavored_project] } + let(:elements) { [unfavorited_project] } end end context "when not filtering for favorite projects" do let(:filters) do - [{ favored: { operator: "!", values: ["t"] } }] + [{ favorited: { operator: "!", values: ["t"] } }] end it_behaves_like "API V3 collection response", 1, 1, "Project" do - let(:elements) { [unfavored_project] } + let(:elements) { [unfavorited_project] } end end context "when not filtering for nonfavorite projects" do let(:filters) do - [{ favored: { operator: "!", values: ["f"] } }] + [{ favorited: { operator: "!", values: ["f"] } }] end it_behaves_like "API V3 collection response", 1, 1, "Project" do - let(:elements) { [favored_project] } + let(:elements) { [favorited_project] } end end end diff --git a/spec/services/project_queries/set_attributes_service_spec.rb b/spec/services/project_queries/set_attributes_service_spec.rb index ac45b83a4b6..320db7e1444 100644 --- a/spec/services/project_queries/set_attributes_service_spec.rb +++ b/spec/services/project_queries/set_attributes_service_spec.rb @@ -179,7 +179,7 @@ RSpec.describe ProjectQueries::SetAttributesService, type: :model do subject expect(model_instance.selects.map(&:attribute)) - .to eql %i[favored name cf_1] + .to eql %i[favorited name cf_1] end it "assigns default selects for admin", @@ -191,7 +191,7 @@ RSpec.describe ProjectQueries::SetAttributesService, type: :model do subject expect(model_instance.selects.map(&:attribute)) - .to eql %i[favored name created_at cf_1] + .to eql %i[favorited name created_at cf_1] end # rubocop:enable Naming/VariableNumber end diff --git a/spec/support/components/common/submenu.rb b/spec/support/components/common/submenu.rb index b59509f4266..2072d083a83 100644 --- a/spec/support/components/common/submenu.rb +++ b/spec/support/components/common/submenu.rb @@ -38,16 +38,16 @@ module Components expect(page).to have_css('[data-test-selector="op-submenu"]') end - def expect_item(name, selected: false, favored: nil, visible: true) + def expect_item(name, selected: false, favorited: nil, visible: true) within "#main-menu" do selected_specifier = selected ? ".selected" : ":not(.selected)" - if favored.nil? + if favorited.nil? expect(page).to have_css(".op-submenu--item-action#{selected_specifier}", text: name, visible:) else item = page.find(".op-submenu--item-action#{selected_specifier}", text: name, visible:) - if favored + if favorited expect(item).to have_css(".op-primer--star-icon") else expect(item).to have_no_css(".op-primer--star-icon") diff --git a/spec/support/pages/projects/index.rb b/spec/support/pages/projects/index.rb index cdb390213ed..345202716a8 100644 --- a/spec/support/pages/projects/index.rb +++ b/spec/support/pages/projects/index.rb @@ -86,8 +86,8 @@ module Pages expect(page).to have_css('[data-test-selector="project-query-name"]', text: name) end - def expect_sidebar_filter(filter_name, selected: false, favored: false, visible: true) - submenu.expect_item(filter_name, selected:, favored:, visible:) + def expect_sidebar_filter(filter_name, selected: false, favorited: false, visible: true) + submenu.expect_item(filter_name, selected:, favorited:, visible:) end def expect_no_sidebar_filter(filter_name) @@ -221,8 +221,8 @@ module Pages wait_for_reload end - def filter_by_favored(value) - set_filter("favored", "Favorite", "is", [value]) + def filter_by_favorited(value) + set_filter("favorited", "Favorite", "is", [value]) wait_for_reload end @@ -520,7 +520,7 @@ module Pages private def boolean_filter?(filter) - %w[active member_of favored public templated].include?(filter.to_s) + %w[active member_of favorited public templated].include?(filter.to_s) end def submenu diff --git a/spec/support/shared/acts_as_favorable.rb b/spec/support/shared/acts_as_favorable.rb deleted file mode 100644 index dd9dac0e9d8..00000000000 --- a/spec/support/shared/acts_as_favorable.rb +++ /dev/null @@ -1,161 +0,0 @@ -# frozen_string_literal: true - -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) the OpenProject GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2013 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See COPYRIGHT and LICENSE files for more details. -#++ - -RSpec.shared_examples_for "acts_as_favorable included" do - shared_let(:favoring_user) { create(:user) } - shared_let(:other_user) { create(:user) } - - before do - Favorite.create(user: favoring_user, favored: instance) - end - - it { is_expected.to have_many(:favorites).dependent(:delete_all) } - it { is_expected.to have_many(:favoring_users).through(:favorites) } - - describe ".favored_by" do - it "returns instance for favoring user" do - expect(described_class.favored_by(favoring_user).to_a).to eq [instance] - end - - it "returns no instance for non favoring user" do - expect(described_class.favored_by(other_user).to_a).not_to eq [instance] - end - end - - describe ".with_favored_by_user" do - subject { described_class.with_favored_by_user(user).to_a } - - context "for favoring user" do - let(:user) { favoring_user } - - it "returns instance for favoring user" do - expect(subject).to eq [instance] - end - - it "marks instance as favored" do - expect(subject).to all(have_attributes(favored: true)) - end - end - - context "for non favoring user" do - let(:user) { other_user } - - it "returns instance for favoring user" do - expect(subject).to eq [instance] - end - - it "marks instance as not favored" do - expect(subject).to all(have_attributes(favored: false)) - end - end - end - - describe "#add_favoring_user" do - context "for favoring user" do - let(:user) { favoring_user } - - it "does nothing" do - expect do - instance.add_favoring_user(user) - end.not_to change { described_class.favored_by(user).to_a }.from([instance]) - end - end - - context "for non favoring user" do - let(:user) { other_user } - - it "adds to favorites" do - expect do - instance.add_favoring_user(user) - end.to change { described_class.favored_by(user).to_a }.from([]).to([instance]) - end - end - end - - describe "#remove_favoring_user" do - context "for favoring user" do - let(:user) { favoring_user } - - it "removes from favorites" do - expect do - instance.remove_favoring_user(user) - end.to change { described_class.favored_by(user).to_a }.from([instance]).to([]) - end - end - - context "for non favoring user" do - let(:user) { other_user } - - it "does nothing" do - expect do - instance.remove_favoring_user(user) - end.not_to change { described_class.favored_by(user).to_a } - end - end - end - - describe "#set_favored" do - before do - allow(instance).to receive(:add_favoring_user) - allow(instance).to receive(:remove_favoring_user) - end - - it "calls add_favoring_user by default" do - instance.set_favored(favoring_user) - - expect(instance).to have_received(:add_favoring_user).with(favoring_user) - expect(instance).not_to have_received(:remove_favoring_user) - end - - it "calls add_favoring_user when called with favored: true" do - instance.set_favored(favoring_user, favored: true) - - expect(instance).to have_received(:add_favoring_user).with(favoring_user) - expect(instance).not_to have_received(:remove_favoring_user) - end - - it "calls remove_favoring_user when called with favored: false" do - instance.set_favored(favoring_user, favored: false) - - expect(instance).not_to have_received(:add_favoring_user) - expect(instance).to have_received(:remove_favoring_user).with(favoring_user) - end - end - - describe "#favored_by?" do - it "returns true for favoring user" do - expect(instance).to be_favored_by(favoring_user) - end - - it "returns false for non favoring user" do - expect(instance).not_to be_favored_by(other_user) - end - end -end diff --git a/spec/support/shared/acts_as_favoritable.rb b/spec/support/shared/acts_as_favoritable.rb new file mode 100644 index 00000000000..02062dce6e8 --- /dev/null +++ b/spec/support/shared/acts_as_favoritable.rb @@ -0,0 +1,161 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +RSpec.shared_examples_for "acts_as_favoritable included" do + shared_let(:favoriting_user) { create(:user) } + shared_let(:other_user) { create(:user) } + + before do + Favorite.create(user: favoriting_user, favorited: instance) + end + + it { is_expected.to have_many(:favorites).dependent(:delete_all) } + it { is_expected.to have_many(:favoriting_users).through(:favorites) } + + describe ".favorited_by" do + it "returns instance for favoriting user" do + expect(described_class.favorited_by(favoriting_user).to_a).to eq [instance] + end + + it "returns no instance for non favoriting user" do + expect(described_class.favorited_by(other_user).to_a).not_to eq [instance] + end + end + + describe ".with_favorited_by_user" do + subject { described_class.with_favorited_by_user(user).to_a } + + context "for favoriting user" do + let(:user) { favoriting_user } + + it "returns instance for favoriting user" do + expect(subject).to eq [instance] + end + + it "marks instance as favorited" do + expect(subject).to all(have_attributes(favorited: true)) + end + end + + context "for non favoriting user" do + let(:user) { other_user } + + it "returns instance for favoriting user" do + expect(subject).to eq [instance] + end + + it "marks instance as not favorited" do + expect(subject).to all(have_attributes(favorited: false)) + end + end + end + + describe "#add_favoriting_user" do + context "for favoriting user" do + let(:user) { favoriting_user } + + it "does nothing" do + expect do + instance.add_favoriting_user(user) + end.not_to change { described_class.favorited_by(user).to_a }.from([instance]) + end + end + + context "for non favoriting user" do + let(:user) { other_user } + + it "adds to favorites" do + expect do + instance.add_favoriting_user(user) + end.to change { described_class.favorited_by(user).to_a }.from([]).to([instance]) + end + end + end + + describe "#remove_favoriting_user" do + context "for favoriting user" do + let(:user) { favoriting_user } + + it "removes from favorites" do + expect do + instance.remove_favoriting_user(user) + end.to change { described_class.favorited_by(user).to_a }.from([instance]).to([]) + end + end + + context "for non favoriting user" do + let(:user) { other_user } + + it "does nothing" do + expect do + instance.remove_favoriting_user(user) + end.not_to change { described_class.favorited_by(user).to_a } + end + end + end + + describe "#set_favorited" do + before do + allow(instance).to receive(:add_favoriting_user) + allow(instance).to receive(:remove_favoriting_user) + end + + it "calls add_favoriting_user by default" do + instance.set_favorited(favoriting_user) + + expect(instance).to have_received(:add_favoriting_user).with(favoriting_user) + expect(instance).not_to have_received(:remove_favoriting_user) + end + + it "calls add_favoriting_user when called with favorited: true" do + instance.set_favorited(favoriting_user, favorited: true) + + expect(instance).to have_received(:add_favoriting_user).with(favoriting_user) + expect(instance).not_to have_received(:remove_favoriting_user) + end + + it "calls remove_favoriting_user when called with favorited: false" do + instance.set_favorited(favoriting_user, favorited: false) + + expect(instance).not_to have_received(:add_favoriting_user) + expect(instance).to have_received(:remove_favoriting_user).with(favoriting_user) + end + end + + describe "#favorited_by?" do + it "returns true for favoriting user" do + expect(instance).to be_favorited_by(favoriting_user) + end + + it "returns false for non favoriting user" do + expect(instance).not_to be_favorited_by(other_user) + end + end +end diff --git a/spec/workers/principals/delete_job_integration_spec.rb b/spec/workers/principals/delete_job_integration_spec.rb index 3703c94c4e1..31c33b197b0 100644 --- a/spec/workers/principals/delete_job_integration_spec.rb +++ b/spec/workers/principals/delete_job_integration_spec.rb @@ -477,12 +477,12 @@ RSpec.describe Principals::DeleteJob, type: :model do describe "favorites" do before do - project.add_favoring_user(principal) + project.add_favoriting_user(principal) job end it "removes the assigned_to association to the principal" do - expect(project.favoring_users.reload).to be_empty + expect(project.favoriting_users.reload).to be_empty end end end