From f5d4d3cb60b8393a797eaeb1e407fed5668f7360 Mon Sep 17 00:00:00 2001 From: Paul Slaughter Date: Wed, 6 Dec 2023 13:13:28 -0600 Subject: [PATCH 1/2] Add use_web_ide_extension_marketplace to user_pref - Also adds to GraphQL mutation - Next commit will add feature flag and pass to Web IDE Changelog: other --- app/graphql/mutations/user_preferences/update.rb | 3 +++ app/graphql/types/user_preferences_type.rb | 4 ++++ app/models/user.rb | 1 + app/models/user_preference.rb | 1 + ...eb_ide_extension_marketplace_to_user_preferences.rb | 10 ++++++++++ db/schema_migrations/20231206183312 | 1 + db/structure.sql | 1 + doc/api/graphql/reference/index.md | 2 ++ spec/graphql/types/user_preferences_type_spec.rb | 1 + .../graphql/mutations/user_preferences/update_spec.rb | 4 +++- 10 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20231206183312_add_use_web_ide_extension_marketplace_to_user_preferences.rb create mode 100644 db/schema_migrations/20231206183312 diff --git a/app/graphql/mutations/user_preferences/update.rb b/app/graphql/mutations/user_preferences/update.rb index 16c7b37532c5d3..0b19cb7ce31053 100644 --- a/app/graphql/mutations/user_preferences/update.rb +++ b/app/graphql/mutations/user_preferences/update.rb @@ -8,6 +8,9 @@ class Update < BaseMutation argument :issues_sort, Types::IssueSortEnum, required: false, description: 'Sort order for issue lists.' + argument :use_web_ide_extension_marketplace, GraphQL::Types::Boolean, + required: false, + description: 'Whether Web IDE Extension Marketplace is enabled for the user.' 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_preferences_type.rb b/app/graphql/types/user_preferences_type.rb index 094c7352c96b67..e9ac3a28a5303c 100644 --- a/app/graphql/types/user_preferences_type.rb +++ b/app/graphql/types/user_preferences_type.rb @@ -14,6 +14,10 @@ class UserPreferencesType < BaseObject description: 'Determines whether the pipeline list shows ID or IID.', null: true + field :use_web_ide_extension_marketplace, GraphQL::Types::Boolean, + description: 'Whether Web IDE Extension Marketplace is enabled for the user.', + null: false + def issues_sort object.issues_sort.to_sym end diff --git a/app/models/user.rb b/app/models/user.rb index d7880579092823..87249f7cf1b811 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -388,6 +388,7 @@ def update_tracked_fields!(request) :tab_width, :tab_width=, :sourcegraph_enabled, :sourcegraph_enabled=, :gitpod_enabled, :gitpod_enabled=, + :use_web_ide_extension_marketplace, :use_web_ide_extension_marketplace=, :setup_for_company, :setup_for_company=, :project_shortcut_buttons, :project_shortcut_buttons=, :keyboard_shortcuts_enabled, :keyboard_shortcuts_enabled=, diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index b8c4c8597a47be..70ffe0c85f8269 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -42,6 +42,7 @@ class UserPreference < MainClusterwide::ApplicationRecord attribute :render_whitespace_in_code, default: false attribute :project_shortcut_buttons, default: true attribute :keyboard_shortcuts_enabled, default: true + attribute :use_web_ide_extension_marketplace, default: false enum visibility_pipeline_id_type: { id: 0, iid: 1 } diff --git a/db/migrate/20231206183312_add_use_web_ide_extension_marketplace_to_user_preferences.rb b/db/migrate/20231206183312_add_use_web_ide_extension_marketplace_to_user_preferences.rb new file mode 100644 index 00000000000000..1ea85760dbca96 --- /dev/null +++ b/db/migrate/20231206183312_add_use_web_ide_extension_marketplace_to_user_preferences.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class AddUseWebIdeExtensionMarketplaceToUserPreferences < Gitlab::Database::Migration[2.2] + milestone '16.7' + enable_lock_retries! + + def change + add_column :user_preferences, :use_web_ide_extension_marketplace, :boolean, default: false, null: false + end +end diff --git a/db/schema_migrations/20231206183312 b/db/schema_migrations/20231206183312 new file mode 100644 index 00000000000000..639acbcf395790 --- /dev/null +++ b/db/schema_migrations/20231206183312 @@ -0,0 +1 @@ +6b1b75bc747a32ef9b360c4077579e8979eda1f81783c58b213a23803799ae31 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 1f2ed208630eaf..cb9877ecb67634 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -24664,6 +24664,7 @@ CREATE TABLE user_preferences ( keyboard_shortcuts_enabled boolean DEFAULT true NOT NULL, time_display_format smallint DEFAULT 0 NOT NULL, home_organization_id bigint, + use_web_ide_extension_marketplace boolean DEFAULT false NOT NULL, CONSTRAINT check_89bf269f41 CHECK ((char_length(diffs_deletion_color) <= 7)), CONSTRAINT check_d07ccd35f7 CHECK ((char_length(diffs_addition_color) <= 7)) ); diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 3f998bdef31554..ccab04338899dd 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -8012,6 +8012,7 @@ Input type: `UserPreferencesUpdateInput` | ---- | ---- | ----------- | | `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | `issuesSort` | [`IssueSort`](#issuesort) | Sort order for issue lists. | +| `useWebIdeExtensionMarketplace` | [`Boolean`](#boolean) | Whether Web IDE Extension Marketplace is enabled for the user. | | `visibilityPipelineIdType` | [`VisibilityPipelineIdType`](#visibilitypipelineidtype) | Determines whether the pipeline list shows ID or IID. | #### Fields @@ -27923,6 +27924,7 @@ fields relate to interactions between the two entities. | Name | Type | Description | | ---- | ---- | ----------- | | `issuesSort` | [`IssueSort`](#issuesort) | Sort order for issue lists. | +| `useWebIdeExtensionMarketplace` | [`Boolean!`](#boolean) | Whether Web IDE Extension Marketplace is enabled for the user. | | `visibilityPipelineIdType` | [`VisibilityPipelineIdType`](#visibilitypipelineidtype) | Determines whether the pipeline list shows ID or IID. | ### `UserStatus` diff --git a/spec/graphql/types/user_preferences_type_spec.rb b/spec/graphql/types/user_preferences_type_spec.rb index 06749dda239ca8..87fac17a5ba6b7 100644 --- a/spec/graphql/types/user_preferences_type_spec.rb +++ b/spec/graphql/types/user_preferences_type_spec.rb @@ -9,6 +9,7 @@ expected_fields = %i[ issues_sort visibility_pipeline_id_type + use_web_ide_extension_marketplace ] expect(described_class).to have_graphql_fields(*expected_fields) 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 65b8083c74f402..490bfdd6660dc2 100644 --- a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb +++ b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb @@ -12,7 +12,8 @@ let(:input) do { 'issuesSort' => sort_value, - 'visibilityPipelineIdType' => 'IID' + 'visibilityPipelineIdType' => 'IID', + 'useWebIdeExtensionMarketplace' => true } end @@ -30,6 +31,7 @@ expect(current_user.user_preference.persisted?).to eq(true) 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(true) end end -- GitLab From 736d4c99cd6c2c04911c49e97830ac8f3ff819e3 Mon Sep 17 00:00:00 2001 From: Paul Slaughter Date: Fri, 8 Dec 2023 10:07:03 -0600 Subject: [PATCH 2/2] Fix null values in UserPreferencesUpdate mutation - Previously this would cause a 500 --- .../mutations/user_preferences/update.rb | 6 +++ .../mutations/user_preferences/update_spec.rb | 38 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/app/graphql/mutations/user_preferences/update.rb b/app/graphql/mutations/user_preferences/update.rb index 0b19cb7ce31053..111bd2587757e7 100644 --- a/app/graphql/mutations/user_preferences/update.rb +++ b/app/graphql/mutations/user_preferences/update.rb @@ -5,6 +5,11 @@ module UserPreferences class Update < BaseMutation graphql_name 'UserPreferencesUpdate' + NON_NULLABLE_ARGS = [ + :use_web_ide_extension_marketplace, + :visibility_pipeline_id_type + ].freeze + argument :issues_sort, Types::IssueSortEnum, required: false, description: 'Sort order for issue lists.' @@ -21,6 +26,7 @@ class Update < BaseMutation description: 'User preferences after mutation.' def resolve(**attributes) + attributes.delete_if { |key, value| NON_NULLABLE_ARGS.include?(key) && value.nil? } user_preferences = current_user.user_preference user_preferences.update(attributes) 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 490bfdd6660dc2..b1cd3259eebe8f 100644 --- a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb +++ b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb @@ -27,6 +27,7 @@ expect(response).to have_gitlab_http_status(:success) expect(mutation_response['userPreferences']['issuesSort']).to eq(sort_value) expect(mutation_response['userPreferences']['visibilityPipelineIdType']).to eq('IID') + expect(mutation_response['userPreferences']['useWebIdeExtensionMarketplace']).to eq(true) expect(current_user.user_preference.persisted?).to eq(true) expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s) @@ -36,11 +37,16 @@ end context 'when user has existing preference' do - before do - current_user.create_user_preference!( + let(:init_user_preference) do + { issues_sort: Types::IssueSortEnum.values['TITLE_DESC'].value, - visibility_pipeline_id_type: 'id' - ) + visibility_pipeline_id_type: 'id', + use_web_ide_extension_marketplace: true + } + end + + before do + current_user.create_user_preference!(init_user_preference) end it 'updates the existing value' do @@ -55,5 +61,29 @@ 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') end + + context 'when input has nil attributes' do + let(:input) do + { + 'issuesSort' => nil, + 'visibilityPipelineIdType' => nil, + 'useWebIdeExtensionMarketplace' => nil + } + end + + it 'updates only nullable attributes' do + post_graphql_mutation(mutation, current_user: current_user) + + current_user.user_preference.reload + + expect(current_user.user_preference).to have_attributes({ + # These are nullable and are exepcted to change + issues_sort: nil, + # These should not have changed + visibility_pipeline_id_type: init_user_preference[:visibility_pipeline_id_type], + use_web_ide_extension_marketplace: init_user_preference[:use_web_ide_extension_marketplace] + }) + end + end end end -- GitLab