+ {{ modelVersion.description }} +
+ +Target
+ + `); }); it('adds "is-expanded" class to target element', () => { diff --git a/spec/frontend/super_sidebar/components/user_menu_spec.js b/spec/frontend/super_sidebar/components/user_menu_spec.js index ba675c8b3f5..4af3247693b 100644 --- a/spec/frontend/super_sidebar/components/user_menu_spec.js +++ b/spec/frontend/super_sidebar/components/user_menu_spec.js @@ -78,6 +78,20 @@ describe('UserMenu component', () => { }); }); + it('updates avatar url on custom avatar update event', async () => { + const url = `${userMenuMockData.avatar_url}-new-avatar`; + + document.dispatchEvent(new CustomEvent('userAvatar:update', { detail: { url } })); + await nextTick(); + + const avatar = toggle.findComponent(GlAvatar); + expect(avatar.exists()).toBe(true); + expect(avatar.props()).toMatchObject({ + entityName: userMenuMockData.name, + src: url, + }); + }); + it('renders screen reader text', () => { expect(toggle.find('.gl-sr-only').text()).toBe(`${userMenuMockData.name} user’s menu`); }); diff --git a/spec/frontend/super_sidebar/utils_spec.js b/spec/frontend/super_sidebar/utils_spec.js index 690d34a966b..3e99099b663 100644 --- a/spec/frontend/super_sidebar/utils_spec.js +++ b/spec/frontend/super_sidebar/utils_spec.js @@ -1,18 +1,42 @@ import MockAdapter from 'axios-mock-adapter'; import * as Sentry from '~/sentry/sentry_browser_wrapper'; -import { trackContextAccess, ariaCurrent } from '~/super_sidebar/utils'; +import { getTopFrequentItems, trackContextAccess, ariaCurrent } from '~/super_sidebar/utils'; import axios from '~/lib/utils/axios_utils'; import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import AccessorUtilities from '~/lib/utils/accessor'; import { FREQUENT_ITEMS, FIFTEEN_MINUTES_IN_MS } from '~/frequent_items/constants'; import { HTTP_STATUS_OK, HTTP_STATUS_INTERNAL_SERVER_ERROR } from '~/lib/utils/http_status'; import waitForPromises from 'helpers/wait_for_promises'; +import { unsortedFrequentItems, sortedFrequentItems } from '../frequent_items/mock_data'; jest.mock('~/sentry/sentry_browser_wrapper'); useLocalStorageSpy(); describe('Super sidebar utils spec', () => { + describe('getTopFrequentItems', () => { + const maxItems = 3; + + it.each([undefined, null, []])('returns empty array if `items` is %s', (items) => { + const result = getTopFrequentItems(items); + + expect(result.length).toBe(0); + }); + + it('returns the requested amount of items', () => { + const result = getTopFrequentItems(unsortedFrequentItems, maxItems); + + expect(result.length).toBe(maxItems); + }); + + it('sorts frequent items in order of frequency and lastAccessedOn', () => { + const result = getTopFrequentItems(unsortedFrequentItems, maxItems); + const expectedResult = sortedFrequentItems.slice(0, maxItems); + + expect(result).toEqual(expectedResult); + }); + }); + describe('trackContextAccess', () => { useLocalStorageSpy(); diff --git a/spec/frontend/vue_merge_request_widget/components/merge_checks_spec.js b/spec/frontend/vue_merge_request_widget/components/merge_checks_spec.js index d39098b27c2..b19095cc686 100644 --- a/spec/frontend/vue_merge_request_widget/components/merge_checks_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/merge_checks_spec.js @@ -138,7 +138,7 @@ describe('Merge request merge checks component', () => { it.each` identifier ${'conflict'} - ${'unresolved_discussions'} + ${'discussions_not_resolved'} ${'need_rebase'} ${'default'} `('renders $identifier merge check', async ({ identifier }) => { diff --git a/spec/helpers/stat_anchors_helper_spec.rb b/spec/helpers/stat_anchors_helper_spec.rb index f3830bf4172..41ac7509c39 100644 --- a/spec/helpers/stat_anchors_helper_spec.rb +++ b/spec/helpers/stat_anchors_helper_spec.rb @@ -8,6 +8,10 @@ RSpec.describe StatAnchorsHelper do describe '#stat_anchor_attrs' do subject { helper.stat_anchor_attrs(anchor) } + before do + stub_feature_flags(project_overview_reorg: false) + end + context 'when anchor is a link' do let(:anchor) { anchor_klass.new(true) } diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb index f70b38377d8..ffede2b6759 100644 --- a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb +++ b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb @@ -911,4 +911,18 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m expect(actual).to contain_exactly(migration) end end + + describe '#finalize_command' do + let_it_be(:migration) do + create( + :batched_background_migration, + gitlab_schema: :gitlab_main, + job_arguments: [['column_1'], ['column_1_convert_to_bigint']] + ) + end + + it 'generates the correct finalize command' do + expect(migration.finalize_command).to eq("sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,events,id,'[[\"column_1\"]\\,[\"column_1_convert_to_bigint\"]]']") + end + end end diff --git a/spec/migrations/fix_broken_user_achievements_awarded_spec.rb b/spec/migrations/fix_broken_user_achievements_awarded_spec.rb new file mode 100644 index 00000000000..cb31ca44a9f --- /dev/null +++ b/spec/migrations/fix_broken_user_achievements_awarded_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixBrokenUserAchievementsAwarded, migration: :gitlab_main, feature_category: :user_profile do + let(:migration) { described_class.new } + + let(:users_table) { table(:users) } + let(:namespaces_table) { table(:namespaces) } + let(:achievements_table) { table(:achievements) } + let(:user_achievements_table) { table(:user_achievements) } + let(:namespace) { namespaces_table.create!(name: 'something', path: generate(:username)) } + let(:achievement) { achievements_table.create!(name: 'something', namespace_id: namespace.id) } + let(:user) { users_table.create!(username: generate(:username), projects_limit: 0) } + let(:awarding_user) do + users_table.create!(username: generate(:username), email: generate(:email), projects_limit: 0) + end + + let!(:user_achievement_invalid) do + user_achievements_table.create!(user_id: user.id, achievement_id: achievement.id, + awarded_by_user_id: awarding_user.id) + end + + let!(:user_achievement_valid) do + user_achievements_table.create!(user_id: user.id, achievement_id: achievement.id, + awarded_by_user_id: user.id) + end + + describe '#up' do + before do + awarding_user.delete + end + + it 'migrates the invalid user achievement' do + expect { migrate! } + .to change { user_achievement_invalid.reload.awarded_by_user_id } + .from(nil).to(Users::Internal.ghost.id) + end + + it 'does not migrate the valid user achievement' do + expect { migrate! } + .not_to change { user_achievement_valid.reload.awarded_by_user_id } + end + end +end diff --git a/spec/migrations/fix_broken_user_achievements_revoked_spec.rb b/spec/migrations/fix_broken_user_achievements_revoked_spec.rb new file mode 100644 index 00000000000..34517ae67b4 --- /dev/null +++ b/spec/migrations/fix_broken_user_achievements_revoked_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixBrokenUserAchievementsRevoked, migration: :gitlab_main, feature_category: :user_profile do + let(:migration) { described_class.new } + + let(:users_table) { table(:users) } + let(:namespaces_table) { table(:namespaces) } + let(:achievements_table) { table(:achievements) } + let(:user_achievements_table) { table(:user_achievements) } + let(:namespace) { namespaces_table.create!(name: 'something', path: generate(:username)) } + let(:achievement) { achievements_table.create!(name: 'something', namespace_id: namespace.id) } + let(:user) { users_table.create!(username: generate(:username), projects_limit: 0) } + let(:revoked_invalid) do + user_achievements_table.create!(user_id: user.id, achievement_id: achievement.id, revoked_at: Time.current) + end + + let(:revoked_valid) do + user_achievements_table.create!(user_id: user.id, achievement_id: achievement.id, revoked_at: Time.current, + revoked_by_user_id: user.id) + end + + let(:not_revoked) { user_achievements_table.create!(user_id: user.id, achievement_id: achievement.id) } + + describe '#up' do + it 'migrates the invalid user achievement' do + expect { migrate! } + .to change { revoked_invalid.reload.revoked_by_user_id } + .from(nil).to(Users::Internal.ghost.id) + end + + it 'does not migrate valid revoked user achievement' do + expect { migrate! } + .not_to change { revoked_valid.reload.revoked_by_user_id } + end + + it 'does not migrate the not revoked user achievement' do + expect { migrate! } + .not_to change { not_revoked.reload.revoked_by_user_id } + end + end +end diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb index a9725a796bf..70f843be0e1 100644 --- a/spec/models/members/project_member_spec.rb +++ b/spec/models/members/project_member_spec.rb @@ -57,6 +57,7 @@ RSpec.describe ProjectMember, feature_category: :groups_and_projects do let_it_be(:developer) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } + let_it_be(:admin) { create(:admin) } before do project.add_owner(owner) @@ -74,6 +75,30 @@ RSpec.describe ProjectMember, feature_category: :groups_and_projects do end end + context 'when member can manage owners via admin' do + let(:user) { admin } + + context 'with admin mode', :enable_admin_mode do + it 'returns Gitlab::Access.options_with_owner' do + expect(access_levels).to eq(Gitlab::Access.options_with_owner) + end + end + + context 'without admin mode' do + it 'returns empty hash' do + expect(access_levels).to eq({}) + end + end + end + + context 'when user is not a project member' do + let(:user) { create(:user) } + + it 'return an empty hash' do + expect(access_levels).to eq({}) + end + end + context 'when member cannot manage owners' do let(:user) { maintainer } diff --git a/spec/presenters/project_presenter_spec.rb b/spec/presenters/project_presenter_spec.rb index 48db41ea8e3..d7738023805 100644 --- a/spec/presenters/project_presenter_spec.rb +++ b/spec/presenters/project_presenter_spec.rb @@ -428,6 +428,10 @@ RSpec.describe ProjectPresenter do end describe '#new_file_anchor_data' do + before do + stub_feature_flags(project_overview_reorg: false) + end + it 'returns new file data if user can push' do project.add_developer(user) @@ -751,6 +755,7 @@ RSpec.describe ProjectPresenter do subject(:empty_repo_statistics_buttons) { presenter.empty_repo_statistics_buttons } before do + stub_feature_flags(project_overview_reorg: false) allow(project).to receive(:auto_devops_enabled?).and_return(false) end diff --git a/spec/services/users/migrate_records_to_ghost_user_service_spec.rb b/spec/services/users/migrate_records_to_ghost_user_service_spec.rb index d6fb7a2954d..57378c07dd7 100644 --- a/spec/services/users/migrate_records_to_ghost_user_service_spec.rb +++ b/spec/services/users/migrate_records_to_ghost_user_service_spec.rb @@ -143,6 +143,13 @@ RSpec.describe Users::MigrateRecordsToGhostUserService, feature_category: :user_ let(:created_record) { create(:release, author: user) } end end + + context 'for user achievements' do + include_examples 'migrating records to the ghost user', Achievements::UserAchievement, + [:awarded_by_user, :revoked_by_user] do + let(:created_record) { create(:user_achievement, awarded_by_user: user, revoked_by_user: user) } + end + end end context 'on post-migrate cleanups' do @@ -358,6 +365,16 @@ RSpec.describe Users::MigrateRecordsToGhostUserService, feature_category: :user_ expect(Issue).not_to exist(issue.id) end + + it 'migrates awarded and revoked fields of user achievements' do + user_achievement = create(:user_achievement, awarded_by_user: user, revoked_by_user: user) + + service.execute(hard_delete: true) + user_achievement.reload + + expect(user_achievement.revoked_by_user).to eq(Users::Internal.ghost) + expect(user_achievement.awarded_by_user).to eq(Users::Internal.ghost) + end end end end diff --git a/spec/support/helpers/features/top_nav_spec_helpers.rb b/spec/support/helpers/features/top_nav_spec_helpers.rb deleted file mode 100644 index ecc05189fb4..00000000000 --- a/spec/support/helpers/features/top_nav_spec_helpers.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -# These helpers help you interact within the Source Editor (single-file editor, snippets, etc.). -# -module Features - module TopNavSpecHelpers - def open_top_nav - find('.js-top-nav-dropdown-toggle').click - end - - def within_top_nav - within('.js-top-nav-dropdown-menu') do - yield - end - end - - def open_top_nav_projects - open_top_nav - - within_top_nav do - click_button('Projects') - end - end - - def open_top_nav_groups - open_top_nav - - within_top_nav do - click_button('Groups') - end - end - end -end diff --git a/spec/views/projects/_files.html.haml_spec.rb b/spec/views/projects/_files.html.haml_spec.rb index 96c6c2bdfab..870d436ca88 100644 --- a/spec/views/projects/_files.html.haml_spec.rb +++ b/spec/views/projects/_files.html.haml_spec.rb @@ -35,6 +35,8 @@ RSpec.describe 'projects/_files', feature_category: :groups_and_projects do before do allow(view).to receive(:current_user).and_return(user) allow(user).to receive(:project_shortcut_buttons).and_return(true) + + stub_feature_flags(project_overview_reorg: false) end it 'renders buttons' do @@ -45,6 +47,10 @@ RSpec.describe 'projects/_files', feature_category: :groups_and_projects do end context 'when rendered in the project overview page and there is no current user' do + before do + stub_feature_flags(project_overview_reorg: false) + end + it 'renders buttons' do render(template, is_project_overview: true) diff --git a/spec/views/projects/_home_panel.html.haml_spec.rb b/spec/views/projects/_home_panel.html.haml_spec.rb index e5081df4c22..a35c87cb4b3 100644 --- a/spec/views/projects/_home_panel.html.haml_spec.rb +++ b/spec/views/projects/_home_panel.html.haml_spec.rb @@ -100,6 +100,8 @@ RSpec.describe 'projects/_home_panel' do allow(view).to receive(:current_user).and_return(user) allow(view).to receive(:can?).with(user, :read_project, project).and_return(false) allow(project).to receive(:license_anchor_data).and_return(false) + + stub_feature_flags(project_overview_reorg: false) end context 'has no badges' do diff --git a/workhorse/gitaly_test.go b/workhorse/gitaly_test.go index 270c40cb4bc..db3b76787aa 100644 --- a/workhorse/gitaly_test.go +++ b/workhorse/gitaly_test.go @@ -17,11 +17,11 @@ import ( "testing" "time" - "github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868 - "github.com/golang/protobuf/proto" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868 "github.com/stretchr/testify/require" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb" @@ -107,7 +107,7 @@ func TestGetInfoRefsProxiedToGitalySuccessfully(t *testing.T) { require.Len(t, bodySplit, 3) gitalyRequest := &gitalypb.InfoRefsRequest{} - require.NoError(t, jsonpb.UnmarshalString(bodySplit[0], gitalyRequest)) + require.NoError(t, protojson.Unmarshal([]byte(bodySplit[0]), gitalyRequest)) require.Equal(t, gitProtocol, gitalyRequest.GitProtocol) if tc.showAllRefs { @@ -263,7 +263,7 @@ func TestPostReceivePackProxiedToGitalySuccessfully(t *testing.T) { require.Len(t, split, 2) gitalyRequest := &gitalypb.PostReceivePackRequest{} - require.NoError(t, jsonpb.UnmarshalString(split[0], gitalyRequest)) + require.NoError(t, protojson.Unmarshal([]byte(split[0]), gitalyRequest)) require.Equal(t, apiResponse.Repository.StorageName, gitalyRequest.Repository.StorageName) require.Equal(t, apiResponse.Repository.RelativePath, gitalyRequest.Repository.RelativePath) @@ -437,7 +437,7 @@ func TestPostUploadPackProxiedToGitalySuccessfully(t *testing.T) { require.Len(t, bodySplit, 2) gitalyRequest := &gitalypb.PostUploadPackWithSidechannelRequest{} - require.NoError(t, jsonpb.UnmarshalString(bodySplit[0], gitalyRequest)) + require.NoError(t, protojson.Unmarshal([]byte(bodySplit[0]), gitalyRequest)) require.Equal(t, apiResponse.Repository.StorageName, gitalyRequest.Repository.StorageName) require.Equal(t, apiResponse.Repository.RelativePath, gitalyRequest.Repository.RelativePath) @@ -822,13 +822,12 @@ func buildPbRepo(storageName, relativePath string) *gitalypb.Repository { } func serializedMessage(name string, arg proto.Message) rpcArg { - m := &jsonpb.Marshaler{} - str, err := m.MarshalToString(arg) + data, err := protojson.Marshal(arg) if err != nil { panic(err) } - return rpcArg{name, str} + return rpcArg{name, string(data)} } func serializedProtoMessage(name string, arg proto.Message) rpcArg { diff --git a/workhorse/go.mod b/workhorse/go.mod index 8afe0f049aa..00fddbe2323 100644 --- a/workhorse/go.mod +++ b/workhorse/go.mod @@ -11,7 +11,6 @@ require ( github.com/getsentry/raven-go v0.2.0 github.com/golang-jwt/jwt/v5 v5.0.0 github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f - github.com/golang/protobuf v1.5.3 github.com/gorilla/websocket v1.5.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/johannesboyne/gofakes3 v0.0.0-20230914150226-f005f5cc03aa @@ -68,6 +67,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/google/s2a-go v0.1.4 // indirect diff --git a/workhorse/internal/git/archive.go b/workhorse/internal/git/archive.go index acccd937038..58048c31834 100644 --- a/workhorse/internal/git/archive.go +++ b/workhorse/internal/git/archive.go @@ -14,7 +14,7 @@ import ( "regexp" "time" - "github.com/golang/protobuf/proto" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868 + "google.golang.org/protobuf/proto" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" diff --git a/workhorse/internal/gitaly/gitaly.go b/workhorse/internal/gitaly/gitaly.go index e4fbad17017..98f73b40a9d 100644 --- a/workhorse/internal/gitaly/gitaly.go +++ b/workhorse/internal/gitaly/gitaly.go @@ -5,14 +5,14 @@ import ( "strings" "sync" - "github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868 - "github.com/golang/protobuf/proto" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868 grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" gitalyauth "gitlab.com/gitlab-org/gitaly/v16/auth" gitalyclient "gitlab.com/gitlab-org/gitaly/v16/client" @@ -38,7 +38,6 @@ type connectionsCache struct { } var ( - jsonUnMarshaler = jsonpb.Unmarshaler{AllowUnknownFields: true} // This connection cache map contains two types of connections: // - Normal gRPC connections // - Sidechannel connections. When client dials to the Gitaly server, the @@ -201,5 +200,5 @@ func newConnection(server api.GitalyServer) (*grpc.ClientConn, error) { } func UnmarshalJSON(s string, msg proto.Message) error { - return jsonUnMarshaler.Unmarshal(strings.NewReader(s), msg) + return protojson.UnmarshalOptions{DiscardUnknown: true}.Unmarshal([]byte(s), msg) } diff --git a/workhorse/internal/gitaly/unmarshal_test.go b/workhorse/internal/gitaly/unmarshal_test.go index 39e3a3f2502..bd9d5dc3bd5 100644 --- a/workhorse/internal/gitaly/unmarshal_test.go +++ b/workhorse/internal/gitaly/unmarshal_test.go @@ -3,9 +3,9 @@ package gitaly import ( "testing" - "github.com/golang/protobuf/proto" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868 "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb" + "google.golang.org/protobuf/proto" ) func TestUnmarshalJSON(t *testing.T) { diff --git a/workhorse/internal/redis/redis.go b/workhorse/internal/redis/redis.go index b528255d25b..e21dae916e4 100644 --- a/workhorse/internal/redis/redis.go +++ b/workhorse/internal/redis/redis.go @@ -2,6 +2,7 @@ package redis import ( "context" + "crypto/tls" "errors" "fmt" "net" @@ -55,7 +56,7 @@ const ( // createDialer references https://github.com/redis/go-redis/blob/b1103e3d436b6fe98813ecbbe1f99dc8d59b06c9/options.go#L214 // it intercepts the error and tracks it via a Prometheus counter -func createDialer(sentinels []string) func(ctx context.Context, network, addr string) (net.Conn, error) { +func createDialer(sentinels []string, tlsConfig *tls.Config) func(ctx context.Context, network, addr string) (net.Conn, error) { return func(ctx context.Context, network, addr string) (net.Conn, error) { var isSentinel bool for _, sentinelAddr := range sentinels { @@ -81,7 +82,15 @@ func createDialer(sentinels []string) func(ctx context.Context, network, addr st KeepAlive: 5 * time.Minute, } - conn, err := netDialer.DialContext(ctx, network, addr) + var conn net.Conn + var err error + + if tlsConfig != nil { + conn, err = tls.DialWithDialer(netDialer, network, addr, tlsConfig) + } else { + conn, err = netDialer.DialContext(ctx, network, addr) + } + if err != nil { ErrorCounter.WithLabelValues("dial", destination).Inc() } else { @@ -160,7 +169,8 @@ func configureRedis(cfg *config.RedisConfig) (*redis.Client, error) { opt.ReadTimeout = defaultReadTimeout opt.WriteTimeout = defaultWriteTimeout - opt.Dialer = createDialer([]string{}) + // ParseURL seeds TLSConfig if schems is rediss + opt.Dialer = createDialer([]string{}, opt.TLSConfig) return redis.NewClient(opt), nil } @@ -181,7 +191,7 @@ func configureSentinel(cfg *config.RedisConfig) *redis.Client { ReadTimeout: defaultReadTimeout, WriteTimeout: defaultWriteTimeout, - Dialer: createDialer(sentinels), + Dialer: createDialer(sentinels, nil), }) client.AddHook(sentinelInstrumentationHook{}) diff --git a/workhorse/internal/redis/redis_test.go b/workhorse/internal/redis/redis_test.go index 6fd6ecbae11..d16a7a02761 100644 --- a/workhorse/internal/redis/redis_test.go +++ b/workhorse/internal/redis/redis_test.go @@ -41,6 +41,9 @@ func TestConfigureValidConfigX(t *testing.T) { { scheme: "redis", }, + { + scheme: "rediss", + }, { scheme: "tcp", }, diff --git a/workhorse/internal/testhelper/gitaly.go b/workhorse/internal/testhelper/gitaly.go index b468f0941de..e8f30a043f7 100644 --- a/workhorse/internal/testhelper/gitaly.go +++ b/workhorse/internal/testhelper/gitaly.go @@ -9,8 +9,6 @@ import ( "strings" "sync" - "github.com/golang/protobuf/jsonpb" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868 - "github.com/golang/protobuf/proto" //lint:ignore SA1019 https://gitlab.com/gitlab-org/gitlab/-/issues/324868 "github.com/sirupsen/logrus" "golang.org/x/net/context" "google.golang.org/grpc" @@ -18,6 +16,8 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" "gitlab.com/gitlab-org/gitaly/v16/client" "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb" @@ -71,8 +71,7 @@ func (s *GitalyTestServer) InfoRefsUploadPack(in *gitalypb.InfoRefsRequest, stre fmt.Printf("Result: %+v\n", in) - marshaler := &jsonpb.Marshaler{} - jsonString, err := marshaler.MarshalToString(in) + jsonString, err := marshalJSON(in) if err != nil { return err } @@ -116,8 +115,11 @@ func (s *GitalyTestServer) InfoRefsReceivePack(in *gitalypb.InfoRefsRequest, str } func marshalJSON(msg proto.Message) (string, error) { - marshaler := &jsonpb.Marshaler{} - return marshaler.MarshalToString(msg) + b, err := protojson.Marshal(msg) + if err != nil { + return "", err + } + return string(b), nil } type infoRefsSender interface { @@ -198,14 +200,13 @@ func (s *GitalyTestServer) PostUploadPackWithSidechannel(ctx context.Context, re } defer conn.Close() - marshaler := &jsonpb.Marshaler{} - jsonBytes := &bytes.Buffer{} - if err := marshaler.Marshal(jsonBytes, req); err != nil { + jsonBytes, err := protojson.Marshal(req) + if err != nil { return nil, err } if _, err := io.Copy(conn, io.MultiReader( - bytes.NewReader(append(jsonBytes.Bytes(), 0)), + bytes.NewReader(append(jsonBytes, 0)), conn, )); err != nil { return nil, err diff --git a/yarn.lock b/yarn.lock index 980a696b51a..b6e575d4fb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1274,10 +1274,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.71.0.tgz#ff4a3cf22cd12b3c861ef2065583cc49923cf5f8" integrity sha512-aYjC9uef5Q3CDg4Zu9fh0mce4jO2LANaEgRLutoAYRXG4ymWwRmgP8SZmZyQY0B4hcZjBfUsyVykIhVnlNcRLw== -"@gitlab/ui@^70.0.1": - version "70.0.1" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-70.0.1.tgz#450eb4c99fd7f28d9458aa8455aa41ae823f13b0" - integrity sha512-kkiQfbK0PxgI+rqAl2yDpSgLjPHSkkH6veLFMX5C6/DS6WnJqfnnnkjjet5jilzOJ1fJ7+WgwP+Q7X7BVKyUWg== +"@gitlab/ui@^71.1.1": + version "71.1.1" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-71.1.1.tgz#3853fc98287736992aae2464de8ba0f482a68f27" + integrity sha512-yhKjn0TJ5kI+If3T5mSQfmWkhXtzFWjr4+Qi6FTN9f3vJTOYXtzsFXtZr66V8202peJWbif4A5KpoNZIJdo8YQ== dependencies: "@floating-ui/dom" "1.2.9" bootstrap-vue "2.23.1" @@ -8085,7 +8085,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.0, istanbul-reports@^3.1.3: +istanbul-reports@^3.1.3: version "3.1.4" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==