From a3a2068c9413bb60542c7f5705b8ea9e4df14ce8 Mon Sep 17 00:00:00 2001 From: Donald Cook Date: Fri, 23 Aug 2024 15:42:54 -0700 Subject: [PATCH 1/8] Rubocop lint fixes --- app/controllers/profiles/preferences_controller.rb | 3 ++- app/graphql/mutations/user_preferences/update.rb | 3 +++ app/graphql/types/user_interface.rb | 5 +++++ app/graphql/types/user_preferences_type.rb | 6 +++++- app/models/user.rb | 1 + app/models/user_preference.rb | 1 + ...13_add_use_work_items_view_to_user_preferences.rb | 12 ++++++++++++ db/schema_migrations/20240522141913 | 1 + db/structure.sql | 1 + spec/graphql/types/user_preferences_type_spec.rb | 1 + spec/models/user_spec.rb | 3 +++ 11 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20240522141913_add_use_work_items_view_to_user_preferences.rb create mode 100644 db/schema_migrations/20240522141913 diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb index c793d866182164..c173ae40879f79 100644 --- a/app/controllers/profiles/preferences_controller.rb +++ b/app/controllers/profiles/preferences_controller.rb @@ -63,7 +63,8 @@ def preferences_param_names :markdown_surround_selection, :markdown_automatic_lists, :use_new_navigation, - :enabled_following + :enabled_following, + :use_work_items_view ] end end diff --git a/app/graphql/mutations/user_preferences/update.rb b/app/graphql/mutations/user_preferences/update.rb index a87ad0cead0b58..ec79d88aa6952f 100644 --- a/app/graphql/mutations/user_preferences/update.rb +++ b/app/graphql/mutations/user_preferences/update.rb @@ -21,6 +21,9 @@ class Update < BaseMutation argument :use_web_ide_extension_marketplace, GraphQL::Types::Boolean, required: false, description: 'Whether Web IDE Extension Marketplace is enabled for the user.' + argument :use_work_items_view, GraphQL::Types::Boolean, + required: false, + description: 'Use work item view instead of legacy issue view.' argument :visibility_pipeline_id_type, Types::VisibilityPipelineIdTypeEnum, required: false, description: 'Determines whether the pipeline list shows ID or IID.' diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb index 40999aa79c33e0..263b06d97943cb 100644 --- a/app/graphql/types/user_interface.rb +++ b/app/graphql/types/user_interface.rb @@ -151,6 +151,11 @@ module UserInterface field :gitpod_enabled, GraphQL::Types::Boolean, null: true, description: 'Whether Gitpod is enabled at the user level.' + field :user_preferences, ::Types::UserPreferencesType, + null: true, + description: 'Preferences for the user.', + method: :itself + field :preferences_gitpod_path, GraphQL::Types::String, null: true, diff --git a/app/graphql/types/user_preferences_type.rb b/app/graphql/types/user_preferences_type.rb index f77bba6b651730..d9f58122e4141c 100644 --- a/app/graphql/types/user_preferences_type.rb +++ b/app/graphql/types/user_preferences_type.rb @@ -20,12 +20,16 @@ class UserPreferencesType < BaseObject description: 'Determines whether the pipeline list shows ID or IID.', null: true + # rubocop:disable GraphQL/ExtractType -- These are stored as user preferences field :use_web_ide_extension_marketplace, GraphQL::Types::Boolean, description: 'Whether Web IDE Extension Marketplace is enabled for the user.', null: false, deprecated: { reason: 'Use `extensions_marketplace_opt_in_status` instead', milestone: '16.11' } - # rubocop:disable GraphQL/ExtractType -- These are stored as user preferences + field :use_work_items_view, GraphQL::Types::Boolean, + description: 'Use work item view instead of legacy issue view.', + null: true + field :organization_groups_projects_sort, Types::Organizations::GroupsProjectsSortEnum, description: 'Sort order for organization groups and projects.', diff --git a/app/models/user.rb b/app/models/user.rb index fc3ab15bb17c89..7ed601db4715e2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -434,6 +434,7 @@ def update_tracked_fields!(request) :enabled_following, :enabled_following=, :home_organization, :home_organization_id, :home_organization_id=, :dpop_enabled, :dpop_enabled=, + :use_work_items_view, :use_work_items_view=, to: :user_preference delegate :path, to: :namespace, allow_nil: true, prefix: true diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index ce438fd8a542fe..bb1f6652d4ace2 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -45,6 +45,7 @@ class UserPreference < ApplicationRecord attribute :keyboard_shortcuts_enabled, default: true attribute :use_web_ide_extension_marketplace, default: false attribute :dpop_enabled, default: false + attribute :use_work_items_view, default: false enum :visibility_pipeline_id_type, { id: 0, iid: 1 }, scopes: false diff --git a/db/migrate/20240522141913_add_use_work_items_view_to_user_preferences.rb b/db/migrate/20240522141913_add_use_work_items_view_to_user_preferences.rb new file mode 100644 index 00000000000000..8a30cb6b241705 --- /dev/null +++ b/db/migrate/20240522141913_add_use_work_items_view_to_user_preferences.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# See https://docs.gitlab.com/ee/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddUseWorkItemsViewToUserPreferences < Gitlab::Database::Migration[2.2] + milestone '17.4' + + def change + add_column :user_preferences, :use_work_items_view, :boolean, default: false, null: false + end +end diff --git a/db/schema_migrations/20240522141913 b/db/schema_migrations/20240522141913 new file mode 100644 index 00000000000000..a001dccb7f9b73 --- /dev/null +++ b/db/schema_migrations/20240522141913 @@ -0,0 +1 @@ +4d360baf0e12d723ebd34059b3dc44039573d1bfcaf0a3bd1edfab360191f3db \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 6ca4b98c2d6388..c17cb398b75a98 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -19286,6 +19286,7 @@ CREATE TABLE user_preferences ( home_organization_id bigint, early_access_program_participant boolean DEFAULT false NOT NULL, early_access_program_tracking boolean DEFAULT false NOT NULL, + use_work_items_view boolean DEFAULT false NOT NULL, extensions_marketplace_opt_in_status smallint DEFAULT 0 NOT NULL, organization_groups_projects_sort text, organization_groups_projects_display smallint DEFAULT 0 NOT NULL, diff --git a/spec/graphql/types/user_preferences_type_spec.rb b/spec/graphql/types/user_preferences_type_spec.rb index 622605c35accef..919a8e08e340f6 100644 --- a/spec/graphql/types/user_preferences_type_spec.rb +++ b/spec/graphql/types/user_preferences_type_spec.rb @@ -8,6 +8,7 @@ it 'exposes the expected fields' do expected_fields = %i[ issues_sort + use_work_items_view visibility_pipeline_id_type use_web_ide_extension_marketplace extensions_marketplace_opt_in_status diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index caa23a5bb638a9..4b470fa0e133c2 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -111,6 +111,9 @@ it { is_expected.to delegate_method(:dpop_enabled).to(:user_preference) } it { is_expected.to delegate_method(:dpop_enabled=).to(:user_preference).with_arguments(:args) } + it { is_expected.to delegate_method(:use_work_items_view).to(:user_preference) } + it { is_expected.to delegate_method(:use_work_items_view=).to(:user_preference).with_arguments(:args) } + it { is_expected.to delegate_method(:job_title).to(:user_detail).allow_nil } it { is_expected.to delegate_method(:job_title=).to(:user_detail).with_arguments(:args).allow_nil } -- GitLab From 0fdcc17f4603ff91f4e047d83d051580315f0ace Mon Sep 17 00:00:00 2001 From: Donald Cook Date: Fri, 23 Aug 2024 15:45:45 -0700 Subject: [PATCH 2/8] Updated graphql docs --- doc/api/graphql/reference/index.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 1e2cdd3d7d1f1c..83fff96f28f534 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -10014,6 +10014,7 @@ Input type: `UserPreferencesUpdateInput` | `organizationGroupsProjectsDisplay` **{warning-solid}** | [`OrganizationGroupProjectDisplay`](#organizationgroupprojectdisplay) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.2. | | `organizationGroupsProjectsSort` **{warning-solid}** | [`OrganizationGroupProjectSort`](#organizationgroupprojectsort) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.2. | | `useWebIdeExtensionMarketplace` | [`Boolean`](#boolean) | Whether Web IDE Extension Marketplace is enabled for the user. | +| `useWorkItemsView` | [`Boolean`](#boolean) | Use work item view instead of legacy issue view. | | `visibilityPipelineIdType` | [`VisibilityPipelineIdType`](#visibilitypipelineidtype) | Determines whether the pipeline list shows ID or IID. | #### Fields @@ -16895,6 +16896,7 @@ A user with add-on data. | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | @@ -17766,6 +17768,7 @@ Core representation of a GitLab user. | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | @@ -20072,6 +20075,7 @@ The currently authenticated GitLab user. | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | @@ -25640,6 +25644,7 @@ A user assigned to a merge request. | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | @@ -26019,6 +26024,7 @@ The author of the merge request. | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | @@ -26444,6 +26450,7 @@ A user participating in a merge request. | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | @@ -26842,6 +26849,7 @@ A user assigned to a merge request as a reviewer. | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | @@ -33201,6 +33209,7 @@ Core representation of a GitLab user. | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | @@ -33574,6 +33583,7 @@ fields relate to interactions between the two entities. | `organizationGroupsProjectsDisplay` **{warning-solid}** | [`OrganizationGroupProjectDisplay!`](#organizationgroupprojectdisplay) | **Introduced** in GitLab 17.2. **Status**: Experiment. Default list view for organization groups and projects. | | `organizationGroupsProjectsSort` **{warning-solid}** | [`OrganizationGroupProjectSort`](#organizationgroupprojectsort) | **Introduced** in GitLab 17.2. **Status**: Experiment. Sort order for organization groups and projects. | | `useWebIdeExtensionMarketplace` **{warning-solid}** | [`Boolean!`](#boolean) | **Deprecated** in GitLab 16.11. Use `extensions_marketplace_opt_in_status` instead. | +| `useWorkItemsView` | [`Boolean`](#boolean) | Use work item view instead of legacy issue view. | | `visibilityPipelineIdType` | [`VisibilityPipelineIdType`](#visibilitypipelineidtype) | Determines whether the pipeline list shows ID or IID. | ### `UserStatus` @@ -40058,6 +40068,7 @@ Implementations: | `status` | [`UserStatus`](#userstatus) | User status. | | `twitter` | [`String`](#string) | X (formerly Twitter) username of the user. | | `userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. | +| `userPreferences` | [`UserPreferences`](#userpreferences) | Preferences for the user. | | `username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. | | `webPath` | [`String!`](#string) | Web path of the user. | | `webUrl` | [`String!`](#string) | Web URL of the user. | -- GitLab From 74db96177e3957753b058b07b8e2945ac4b9a551 Mon Sep 17 00:00:00 2001 From: Donald Cook Date: Mon, 26 Aug 2024 13:46:01 -0700 Subject: [PATCH 3/8] Fixed structure.sql diff --- db/structure.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/structure.sql b/db/structure.sql index c17cb398b75a98..9d7ff768f01523 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -19286,11 +19286,11 @@ CREATE TABLE user_preferences ( home_organization_id bigint, early_access_program_participant boolean DEFAULT false NOT NULL, early_access_program_tracking boolean DEFAULT false NOT NULL, - use_work_items_view boolean DEFAULT false NOT NULL, extensions_marketplace_opt_in_status smallint DEFAULT 0 NOT NULL, organization_groups_projects_sort text, organization_groups_projects_display smallint DEFAULT 0 NOT NULL, dpop_enabled boolean DEFAULT false NOT NULL, + use_work_items_view boolean DEFAULT false NOT NULL, CONSTRAINT check_1d670edc68 CHECK ((time_display_relative IS NOT NULL)), CONSTRAINT check_89bf269f41 CHECK ((char_length(diffs_deletion_color) <= 7)), CONSTRAINT check_b1306f8875 CHECK ((char_length(organization_groups_projects_sort) <= 64)), -- GitLab From f568b693ed0960a6e380ef64d44affffea758e85 Mon Sep 17 00:00:00 2001 From: Donald Cook Date: Tue, 27 Aug 2024 10:34:45 -0700 Subject: [PATCH 4/8] Added property to merge_request specs --- .../types/merge_request_interactions_type_shared_examples.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb b/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb index 137aff63e9e188..a516e22015d107 100644 --- a/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb +++ b/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb @@ -57,6 +57,7 @@ lastActivityOn pronouns ide + userPreferences ] # TODO: 'workspaces' needs to be included, but only when this spec is run in EE context, to account for the -- GitLab From 395e821eab237c8de6f0d42a6afa03303609775d Mon Sep 17 00:00:00 2001 From: Donald Cook Date: Tue, 27 Aug 2024 15:51:19 -0700 Subject: [PATCH 5/8] Added policy to user preferences --- .rubocop_todo/gitlab/bounded_contexts.yml | 1 + .rubocop_todo/gitlab/namespaced_class.yml | 1 + app/graphql/types/user_interface.rb | 6 +++--- app/graphql/types/user_preferences_type.rb | 4 ++-- app/policies/user_policy.rb | 1 + app/policies/user_preference_policy.rb | 5 +++++ ...522141913_add_use_work_items_view_to_user_preferences.rb | 3 --- 7 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 app/policies/user_preference_policy.rb diff --git a/.rubocop_todo/gitlab/bounded_contexts.yml b/.rubocop_todo/gitlab/bounded_contexts.yml index f71123465497ad..6cce1071975c4a 100644 --- a/.rubocop_todo/gitlab/bounded_contexts.yml +++ b/.rubocop_todo/gitlab/bounded_contexts.yml @@ -1390,6 +1390,7 @@ Gitlab/BoundedContexts: - 'app/policies/todo_policy.rb' - 'app/policies/upload_policy.rb' - 'app/policies/user_policy.rb' + - 'app/policies/user_preference_policy.rb' - 'app/policies/wiki_page/meta_policy.rb' - 'app/policies/wiki_page_policy.rb' - 'app/policies/wiki_policy.rb' diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml index f413a88a07a429..133c3a2ca41dba 100644 --- a/.rubocop_todo/gitlab/namespaced_class.yml +++ b/.rubocop_todo/gitlab/namespaced_class.yml @@ -396,6 +396,7 @@ Gitlab/NamespacedClass: - 'app/policies/timelog_policy.rb' - 'app/policies/todo_policy.rb' - 'app/policies/user_policy.rb' + - 'app/policies/user_preference_policy.rb' - 'app/policies/wiki_page_policy.rb' - 'app/policies/wiki_policy.rb' - 'app/policies/work_item_policy.rb' diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb index 263b06d97943cb..c05e43a85efd94 100644 --- a/app/graphql/types/user_interface.rb +++ b/app/graphql/types/user_interface.rb @@ -31,7 +31,7 @@ module UserInterface null: false, resolver_method: :redacted_name, description: 'Human-readable name of the user. ' \ - 'Returns `****` if the user is a project bot and the requester does not have permission to view the project.' + 'Returns `****` if the user is a project bot and the requester does not have permission to view the project.' field :state, type: Types::UserStateEnum, @@ -154,7 +154,7 @@ module UserInterface field :user_preferences, ::Types::UserPreferencesType, null: true, description: 'Preferences for the user.', - method: :itself + method: :user_preference field :preferences_gitpod_path, GraphQL::Types::String, @@ -169,7 +169,7 @@ module UserInterface null: true, alpha: { milestone: '15.10' }, description: "Achievements for the user. " \ - "Only returns for namespaces where the `achievements` feature flag is enabled.", + "Only returns for namespaces where the `achievements` feature flag is enabled.", extras: [:lookahead], resolver: ::Resolvers::Achievements::UserAchievementsForUserResolver diff --git a/app/graphql/types/user_preferences_type.rb b/app/graphql/types/user_preferences_type.rb index d9f58122e4141c..586e9e302cbd09 100644 --- a/app/graphql/types/user_preferences_type.rb +++ b/app/graphql/types/user_preferences_type.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true module Types - # rubocop: disable Graphql/AuthorizeTypes - # Only used to render the current user's own preferences class UserPreferencesType < BaseObject graphql_name 'UserPreferences' + authorize :read_user_preference + alias_method :user_preference, :object field :extensions_marketplace_opt_in_status, Types::ExtensionsMarketplaceOptInStatusEnum, diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index ccab3d9f02d5d3..293fb86f760d56 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -34,6 +34,7 @@ class UserPolicy < BasePolicy enable :read_user_email_address enable :admin_user_email_address enable :make_profile_private + enable :read_user_preference end rule { default }.enable :read_user_profile diff --git a/app/policies/user_preference_policy.rb b/app/policies/user_preference_policy.rb new file mode 100644 index 00000000000000..3f74409cd7bc44 --- /dev/null +++ b/app/policies/user_preference_policy.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class UserPreferencePolicy < BasePolicy + delegate { @subject.user } +end diff --git a/db/migrate/20240522141913_add_use_work_items_view_to_user_preferences.rb b/db/migrate/20240522141913_add_use_work_items_view_to_user_preferences.rb index 8a30cb6b241705..6424d0cdf48104 100644 --- a/db/migrate/20240522141913_add_use_work_items_view_to_user_preferences.rb +++ b/db/migrate/20240522141913_add_use_work_items_view_to_user_preferences.rb @@ -1,8 +1,5 @@ # frozen_string_literal: true -# See https://docs.gitlab.com/ee/development/migration_style_guide.html -# for more information on how to write migrations for GitLab. - class AddUseWorkItemsViewToUserPreferences < Gitlab::Database::Migration[2.2] milestone '17.4' -- GitLab From 361b9ed64c6ae5a9c348e6e4c92dbac7f82b5051 Mon Sep 17 00:00:00 2001 From: Donald Cook Date: Wed, 28 Aug 2024 11:18:57 -0700 Subject: [PATCH 6/8] Rubocop lint fixes --- .../mutations/user_preferences/update.rb | 3 +- spec/graphql/types/user_type_spec.rb | 13 +++++++- spec/policies/user_policy_spec.rb | 30 +++++++++++++++++-- .../mutations/user_preferences/update_spec.rb | 15 +++++++--- 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/app/graphql/mutations/user_preferences/update.rb b/app/graphql/mutations/user_preferences/update.rb index ec79d88aa6952f..d051ab82171f6a 100644 --- a/app/graphql/mutations/user_preferences/update.rb +++ b/app/graphql/mutations/user_preferences/update.rb @@ -9,7 +9,8 @@ class Update < BaseMutation :extensions_marketplace_opt_in_status, :organization_groups_projects_display, :use_web_ide_extension_marketplace, - :visibility_pipeline_id_type + :visibility_pipeline_id_type, + :use_work_items_view ].freeze argument :extensions_marketplace_opt_in_status, Types::ExtensionsMarketplaceOptInStatusEnum, diff --git a/spec/graphql/types/user_type_spec.rb b/spec/graphql/types/user_type_spec.rb index 3ab7e797231498..3fa592f9160501 100644 --- a/spec/graphql/types/user_type_spec.rb +++ b/spec/graphql/types/user_type_spec.rb @@ -61,6 +61,7 @@ lastActivityOn pronouns ide + userPreferences ] expect(described_class).to include_graphql_fields(*expected_fields) @@ -94,7 +95,9 @@ GQL end - subject(:user_name) { GitlabSchema.execute(query, context: { current_user: current_user }).as_json.dig('data', 'user', 'name') } + subject(:user_name) do + GitlabSchema.execute(query, context: { current_user: current_user }).as_json.dig('data', 'user', 'name') + end context 'user requests' do let(:current_user) { user } @@ -386,4 +389,12 @@ end end end + + describe 'userPreferences field' do + subject { described_class.fields['userPreferences'] } + + it 'returns userPreferences field' do + is_expected.to have_graphql_type(Types::UserPreferencesType) + end + end end diff --git a/spec/policies/user_policy_spec.rb b/spec/policies/user_policy_spec.rb index 200c69484a9234..3f0eb09f19c0ec 100644 --- a/spec/policies/user_policy_spec.rb +++ b/spec/policies/user_policy_spec.rb @@ -90,7 +90,7 @@ subject { described_class.new(current_user, current_user) } context 'when current_user is not blocked' do - it { is_expected.to be_allowed(:get_user_associations_count ) } + it { is_expected.to be_allowed(:get_user_associations_count) } end context 'when current_user is blocked' do @@ -112,7 +112,7 @@ subject { described_class.new(current_user, current_user) } context 'when current_user is not blocked' do - it { is_expected.to be_allowed(:get_user_associations_count ) } + it { is_expected.to be_allowed(:get_user_associations_count) } end context 'when current_user is blocked' do @@ -302,4 +302,30 @@ end end end + + describe ':read_user_preference' do + context 'when user is admin' do + let(:current_user) { admin } + + context 'when admin mode is enabled', :enable_admin_mode do + it { is_expected.to be_allowed(:read_user_preference) } + end + + context 'when admin mode is disabled' do + it { is_expected.not_to be_allowed(:read_user_preference) } + end + end + + context 'when user is not an admin' do + context 'requesting their own' do + subject { described_class.new(current_user, current_user) } + + it { is_expected.to be_allowed(:read_user_preference) } + end + + context "requesting a different user's" do + it { is_expected.not_to be_allowed(:read_user_preference) } + end + end + end end diff --git a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb index b0c8fc7e2ba49e..d74b788ec78b6d 100644 --- a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb +++ b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb @@ -16,7 +16,8 @@ 'organizationGroupsProjectsDisplay' => 'GROUPS', 'organizationGroupsProjectsSort' => 'NAME_DESC', 'visibilityPipelineIdType' => 'IID', - 'useWebIdeExtensionMarketplace' => true + 'useWebIdeExtensionMarketplace' => true, + 'useWorkItemsView' => true } end @@ -34,12 +35,14 @@ expect(mutation_response['userPreferences']['organizationGroupsProjectsSort']).to eq('NAME_DESC') expect(mutation_response['userPreferences']['visibilityPipelineIdType']).to eq('IID') expect(mutation_response['userPreferences']['useWebIdeExtensionMarketplace']).to eq(true) + expect(mutation_response['userPreferences']['useWorkItemsView']).to eq(true) expect(current_user.user_preference.persisted?).to eq(true) expect(current_user.user_preference.extensions_marketplace_opt_in_status).to eq('enabled') expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s) expect(current_user.user_preference.visibility_pipeline_id_type).to eq('iid') expect(current_user.user_preference.use_web_ide_extension_marketplace).to eq(false) + expect(current_user.user_preference.use_work_items_view).to eq(true) end end @@ -51,7 +54,8 @@ organization_groups_projects_display: Types::Organizations::GroupsProjectsDisplayEnum.values['GROUPS'].value, organization_groups_projects_sort: 'NAME_DESC', visibility_pipeline_id_type: 'id', - use_web_ide_extension_marketplace: false + use_web_ide_extension_marketplace: false, + use_work_items_view: false } end @@ -72,6 +76,7 @@ expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s) expect(current_user.user_preference.visibility_pipeline_id_type).to eq('iid') + expect(current_user.user_preference.use_work_items_view).to eq(true) end context 'when input has nil attributes' do @@ -82,7 +87,8 @@ 'organizationGroupsProjectsDisplay' => nil, 'organizationGroupsProjectsSort' => nil, 'visibilityPipelineIdType' => nil, - 'useWebIdeExtensionMarketplace' => nil + 'useWebIdeExtensionMarketplace' => nil, + 'useWorkItemsView' => nil } end @@ -101,7 +107,8 @@ organization_groups_projects_display: init_user_preference[:organization_groups_projects_display], extensions_marketplace_opt_in_status: init_user_preference[:extensions_marketplace_opt_in_status], visibility_pipeline_id_type: init_user_preference[:visibility_pipeline_id_type], - use_web_ide_extension_marketplace: init_user_preference[:use_web_ide_extension_marketplace] + use_web_ide_extension_marketplace: init_user_preference[:use_web_ide_extension_marketplace], + use_work_items_view: init_user_preference[:use_work_items_view] }) end end -- GitLab From d8978aacdc88e03698a8629943dc5ce43681a55b Mon Sep 17 00:00:00 2001 From: Donald Cook Date: Fri, 30 Aug 2024 12:39:20 -0700 Subject: [PATCH 7/8] Removed unneeded attribute --- app/models/user_preference.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index bb1f6652d4ace2..ce438fd8a542fe 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -45,7 +45,6 @@ class UserPreference < ApplicationRecord attribute :keyboard_shortcuts_enabled, default: true attribute :use_web_ide_extension_marketplace, default: false attribute :dpop_enabled, default: false - attribute :use_work_items_view, default: false enum :visibility_pipeline_id_type, { id: 0, iid: 1 }, scopes: false -- GitLab From 0e94a387c2ae55199e845c3b34f35d5bd98652e2 Mon Sep 17 00:00:00 2001 From: Donald Cook Date: Mon, 2 Sep 2024 11:50:18 -0700 Subject: [PATCH 8/8] Moved rubocop cops to inline --- .rubocop_todo/gitlab/bounded_contexts.yml | 1 - .rubocop_todo/gitlab/namespaced_class.yml | 1 - app/policies/user_preference_policy.rb | 4 +++- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.rubocop_todo/gitlab/bounded_contexts.yml b/.rubocop_todo/gitlab/bounded_contexts.yml index 6cce1071975c4a..f71123465497ad 100644 --- a/.rubocop_todo/gitlab/bounded_contexts.yml +++ b/.rubocop_todo/gitlab/bounded_contexts.yml @@ -1390,7 +1390,6 @@ Gitlab/BoundedContexts: - 'app/policies/todo_policy.rb' - 'app/policies/upload_policy.rb' - 'app/policies/user_policy.rb' - - 'app/policies/user_preference_policy.rb' - 'app/policies/wiki_page/meta_policy.rb' - 'app/policies/wiki_page_policy.rb' - 'app/policies/wiki_policy.rb' diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml index 133c3a2ca41dba..f413a88a07a429 100644 --- a/.rubocop_todo/gitlab/namespaced_class.yml +++ b/.rubocop_todo/gitlab/namespaced_class.yml @@ -396,7 +396,6 @@ Gitlab/NamespacedClass: - 'app/policies/timelog_policy.rb' - 'app/policies/todo_policy.rb' - 'app/policies/user_policy.rb' - - 'app/policies/user_preference_policy.rb' - 'app/policies/wiki_page_policy.rb' - 'app/policies/wiki_policy.rb' - 'app/policies/work_item_policy.rb' diff --git a/app/policies/user_preference_policy.rb b/app/policies/user_preference_policy.rb index 3f74409cd7bc44..eef67684122d60 100644 --- a/app/policies/user_preference_policy.rb +++ b/app/policies/user_preference_policy.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true -class UserPreferencePolicy < BasePolicy +# rubocop:disable Gitlab/BoundedContexts -- Updating this would involve updating multiple dependencies, so should be done with the User module +class UserPreferencePolicy < BasePolicy # rubocop:disable Gitlab/NamespacedClass -- Updating this would involve updating multiple dependencies, so should be done with the User module delegate { @subject.user } end +# rubocop:enable Gitlab/BoundedContexts -- GitLab