diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-22 15:14:34 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-22 15:14:34 +0300 |
commit | 26fa51816ab94df9c2f3db8c93da4d57f7bd6fc4 (patch) | |
tree | 3b29671cb4bc910500d8c7db4e2694b4c012387e /spec | |
parent | 6b0293c14dce817f72310127dd38562313321b1b (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
16 files changed, 192 insertions, 27 deletions
diff --git a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb index 033d69d29b9..fc0992973e8 100644 --- a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb +++ b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb @@ -94,7 +94,7 @@ RSpec.describe 'User visits the profile preferences page', :js, feature_category end def expect_preferences_saved_message - page.within('.flash-container') do + page.within('.b-toaster') do expect(page).to have_content('Preferences saved.') end end diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb index c931de92d1c..4cd3e13d4fa 100644 --- a/spec/finders/users_finder_spec.rb +++ b/spec/finders/users_finder_spec.rb @@ -180,6 +180,31 @@ RSpec.describe UsersFinder do let_it_be(:user) { create(:user) } it_behaves_like 'executes users finder as normal user' + + context 'with group argument is passed' do + let_it_be(:group) { create(:group, :private) } + let_it_be(:subgroup) { create(:group, :private, parent: group) } + let_it_be(:not_group_member) { create(:user) } + + let_it_be(:indirect_group_member) do + create(:user).tap { |u| subgroup.add_developer(u) } + end + + let_it_be(:direct_group_members) do + [user, omniauth_user, internal_user].each { |u| group.add_developer(u) } + end + + it 'filtered by search' do + users = described_class.new(user, group: group).execute + expect(users).to contain_exactly(indirect_group_member, *direct_group_members) + end + + context 'when user cannot read group' do + it 'filtered by search' do + expect { described_class.new(not_group_member, group: group).execute }.to raise_error(Gitlab::Access::AccessDeniedError) + end + end + end end context 'with an admin user' do diff --git a/spec/frontend/boards/board_list_helper.js b/spec/frontend/boards/board_list_helper.js index e3afd2dec2f..1ee4a7353ce 100644 --- a/spec/frontend/boards/board_list_helper.js +++ b/spec/frontend/boards/board_list_helper.js @@ -64,7 +64,6 @@ export default function createComponent({ disabled: false, boardType: 'group', issuableType: 'issue', - isApolloBoard: true, ...provide, }, stubs, diff --git a/spec/frontend/boards/components/board_app_spec.js b/spec/frontend/boards/components/board_app_spec.js index 157c76b4fff..9452e3e10c9 100644 --- a/spec/frontend/boards/components/board_app_spec.js +++ b/spec/frontend/boards/components/board_app_spec.js @@ -47,7 +47,7 @@ describe('BoardApp', () => { beforeEach(async () => { cacheUpdates.setError = jest.fn(); - createComponent({ isApolloBoard: true }); + createComponent(); await nextTick(); }); @@ -60,7 +60,7 @@ describe('BoardApp', () => { }); it('should not have is-compact class when no card is selected', async () => { - createComponent({ isApolloBoard: true, issue: {} }); + createComponent({ issue: {} }); await nextTick(); expect(wrapper.classes()).not.toContain('is-compact'); @@ -69,14 +69,14 @@ describe('BoardApp', () => { it('refetches lists when updateBoard event is received', async () => { jest.spyOn(eventHub, '$on').mockImplementation(() => {}); - createComponent({ isApolloBoard: true }); + createComponent(); await waitForPromises(); expect(eventHub.$on).toHaveBeenCalledWith('updateBoard', wrapper.vm.refetchLists); }); it('sets error on fetch lists failure', async () => { - createComponent({ isApolloBoard: true, handler: boardListQueryHandlerFailure }); + createComponent({ handler: boardListQueryHandlerFailure }); await waitForPromises(); diff --git a/spec/frontend/boards/components/board_card_move_to_position_spec.js b/spec/frontend/boards/components/board_card_move_to_position_spec.js index d3c43a4e054..23ac8e8f753 100644 --- a/spec/frontend/boards/components/board_card_move_to_position_spec.js +++ b/spec/frontend/boards/components/board_card_move_to_position_spec.js @@ -30,12 +30,9 @@ describe('Board Card Move to position', () => { let store; const itemIndex = 1; - const createComponent = (propsData, isApolloBoard = false) => { + const createComponent = (propsData) => { wrapper = shallowMount(BoardCardMoveToPosition, { store, - provide: { - isApolloBoard, - }, propsData: { item: mockIssue2, list: mockList, diff --git a/spec/frontend/boards/components/board_card_spec.js b/spec/frontend/boards/components/board_card_spec.js index dae0db27104..1781c58c11f 100644 --- a/spec/frontend/boards/components/board_card_spec.js +++ b/spec/frontend/boards/components/board_card_spec.js @@ -76,7 +76,6 @@ describe('Board card', () => { isGroupBoard: true, disabled: false, allowSubEpics: false, - isApolloBoard: true, ...provide, }, }); diff --git a/spec/frontend/boards/components/board_top_bar_spec.js b/spec/frontend/boards/components/board_top_bar_spec.js index 03526600114..477c504ecba 100644 --- a/spec/frontend/boards/components/board_top_bar_spec.js +++ b/spec/frontend/boards/components/board_top_bar_spec.js @@ -56,7 +56,6 @@ describe('BoardTopBar', () => { isIssueBoard: true, isEpicBoard: false, isGroupBoard: true, - // isApolloBoard: false, ...provide, }, stubs: { IssueBoardFilteredSearch }, diff --git a/spec/frontend/boards/components/boards_selector_spec.js b/spec/frontend/boards/components/boards_selector_spec.js index 8766b1c25f2..db5243732c6 100644 --- a/spec/frontend/boards/components/boards_selector_spec.js +++ b/spec/frontend/boards/components/boards_selector_spec.js @@ -94,7 +94,6 @@ describe('BoardsSelector', () => { boardType: isGroupBoard ? 'group' : 'project', isGroupBoard, isProjectBoard, - // isApolloBoard: false, ...provide, }, }); diff --git a/spec/frontend/profile/preferences/components/profile_preferences_spec.js b/spec/frontend/profile/preferences/components/profile_preferences_spec.js index 144d9e76869..83c4a7435a8 100644 --- a/spec/frontend/profile/preferences/components/profile_preferences_spec.js +++ b/spec/frontend/profile/preferences/components/profile_preferences_spec.js @@ -3,7 +3,7 @@ import { shallowMount } from '@vue/test-utils'; import { nextTick } from 'vue'; import { useMockLocationHelper } from 'helpers/mock_window_location_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import { createAlert, VARIANT_DANGER, VARIANT_INFO } from '~/alert'; +import { createAlert, VARIANT_DANGER } from '~/alert'; import IntegrationView from '~/profile/preferences/components/integration_view.vue'; import ProfilePreferences from '~/profile/preferences/components/profile_preferences.vue'; import { i18n } from '~/profile/preferences/constants'; @@ -32,11 +32,17 @@ describe('ProfilePreferences component', () => { profilePreferencesPath: '/update-profile', formEl: document.createElement('form'), }; + const showToast = jest.fn(); function createComponent(options = {}) { const { props = {}, provide = {}, attachTo } = options; return extendedWrapper( shallowMount(ProfilePreferences, { + mocks: { + $toast: { + show: showToast, + }, + }, provide: { ...defaultProvide, ...provide, @@ -136,10 +142,7 @@ describe('ProfilePreferences component', () => { const successEvent = new CustomEvent('ajax:success'); form.dispatchEvent(successEvent); - expect(createAlert).toHaveBeenCalledWith({ - message: i18n.defaultSuccess, - variant: VARIANT_INFO, - }); + expect(showToast).toHaveBeenCalledWith(i18n.defaultSuccess); }); it('displays the custom success message', () => { @@ -147,7 +150,7 @@ describe('ProfilePreferences component', () => { const successEvent = new CustomEvent('ajax:success', { detail: [{ message }] }); form.dispatchEvent(successEvent); - expect(createAlert).toHaveBeenCalledWith({ message, variant: VARIANT_INFO }); + expect(showToast).toHaveBeenCalledWith(message); }); it('displays the default error message', () => { diff --git a/spec/graphql/resolvers/users_resolver_spec.rb b/spec/graphql/resolvers/users_resolver_spec.rb index 2ae1b53c40f..ecb1bbb5618 100644 --- a/spec/graphql/resolvers/users_resolver_spec.rb +++ b/spec/graphql/resolvers/users_resolver_spec.rb @@ -62,6 +62,42 @@ RSpec.describe Resolvers::UsersResolver do end end + context 'when a set of group_id is passed' do + let_it_be(:group) { create(:group, :private) } + let_it_be(:subgroup) { create(:group, :private, parent: group) } + let_it_be(:group_member) { create(:user) } + + let_it_be(:indirect_group_member) do + create(:user).tap { |u| subgroup.add_developer(u) } + end + + let_it_be(:direct_group_members) do + [current_user, user1, group_member].each { |u| group.add_developer(u) } + end + + it 'returns direct and indirect members of the group' do + expect( + resolve_users(args: { group_id: group.to_global_id }) + ).to contain_exactly(indirect_group_member, *direct_group_members) + end + + it 'raise an no resource not available error if the group do not exist group' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do + resolve_users(args: { group_id: "gid://gitlab/Group/#{non_existing_record_id}" }) + end + end + + context 'when user cannot read group' do + let(:current_user) { create(:user) } + + it 'raise an no resource not available error the user cannot read the group' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do + resolve_users(args: { group_id: group.to_global_id }) + end + end + end + end + context 'with anonymous access' do let_it_be(:current_user) { nil } diff --git a/spec/migrations/20231204095802_change_i_code_review_create_mr_keys_from_redis_hll_to_redis_spec.rb b/spec/migrations/20231204095802_change_i_code_review_create_mr_keys_from_redis_hll_to_redis_spec.rb index 38d3af5a525..25ca0936dbe 100644 --- a/spec/migrations/20231204095802_change_i_code_review_create_mr_keys_from_redis_hll_to_redis_spec.rb +++ b/spec/migrations/20231204095802_change_i_code_review_create_mr_keys_from_redis_hll_to_redis_spec.rb @@ -14,13 +14,13 @@ RSpec.describe ChangeICodeReviewCreateMrKeysFromRedisHllToRedis, :migration, :cl describe "#up" do before do - set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-16', value: 1) - set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-16', value: 2) - set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-47', value: 3) - set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-48', value: 1) - set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-49', value: 2) - set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-49', value: 4) - set_redis_hll('{hll_counters}_some_other_event-2023-49', value: 7) + set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-16', 1) + set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-16', 2) + set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-47', 3) + set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-48', 1) + set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-49', 2) + set_redis_hll('{hll_counters}_i_code_review_create_mr-2023-49', 4) + set_redis_hll('{hll_counters}_some_other_event-2023-49', 7) end it 'migrates all RedisHLL keys for i_code_review_create_mr', :aggregate_failures do diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index db2ae319bc9..32303f76684 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -735,6 +735,30 @@ RSpec.describe Member, feature_category: :groups_and_projects do it { is_expected.to respond_to(:user_email) } end + describe 'callbacks' do + describe '#send_invite' do + context 'with an invited group member' do + it 'sends an invite email' do + expect_next_instance_of(NotificationService) do |instance| + expect(instance).to receive(:invite_member) + end + + create(:group_member, :invited) + end + end + + context 'with an uninvited member' do + it 'does not send an invite email' do + expect_next_instance_of(NotificationService) do |instance| + expect(instance).not_to receive(:invite_member) + end + + create(:group_member) + end + end + end + end + describe '.valid_email?' do it 'is a valid email format' do expect(described_class.valid_email?('foo')).to eq(false) diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb index bff9f73e44a..4a4cb1ae46a 100644 --- a/spec/models/release_spec.rb +++ b/spec/models/release_spec.rb @@ -156,6 +156,7 @@ RSpec.describe Release, feature_category: :release_orchestration do describe 'latest releases' do let_it_be(:yesterday) { Time.zone.now - 1.day } + let_it_be(:today) { Time.zone.now } let_it_be(:tomorrow) { Time.zone.now + 1.day } let_it_be(:project2) { create(:project) } @@ -176,6 +177,14 @@ RSpec.describe Release, feature_category: :release_orchestration do create(:release, project: project2, released_at: tomorrow, created_at: yesterday) end + let_it_be(:project2_release3) do + create(:release, project: project2, released_at: today, created_at: yesterday) + end + + let_it_be(:project2_release4) do + create(:release, project: project2, released_at: today, created_at: yesterday, release_published_at: today) + end + let(:args) { {} } describe '.latest' do @@ -240,6 +249,16 @@ RSpec.describe Release, feature_category: :release_orchestration do end end end + + describe '.waiting_for_publish_event' do + let(:releases) { [project2_release3] } + + subject(:waiting) { described_class.waiting_for_publish_event } + + it "find today's releases not yet published" do + expect(waiting).to match_array(releases) + end + end end describe '#assets_count' do diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 40597c30c4a..0012cc112c1 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -3179,6 +3179,22 @@ RSpec.describe NotificationService, :mailer, feature_category: :team_planning do end end + describe '#invite_member' do + let_it_be(:group_member) { create(:group_member) } + + subject(:invite_member) { notification.invite_member(group_member, 'token') } + + it 'sends exactly one email' do + expect(Notify) + .to receive(:member_invited_email).with('Group', group_member.id, 'token').at_least(:once).and_call_original + + invite_member + + expect_delivery_jobs_count(1) + expect_enqueud_email('Group', group_member.id, 'token', mail: 'member_invited_email') + end + end + describe '#new_instance_access_request', :deliver_mails_inline do let_it_be(:user) { create(:user, :blocked_pending_approval) } let_it_be(:admins) { create_list(:admin, 12, :with_sign_ins) } diff --git a/spec/support/rspec_run_time.rb b/spec/support/rspec_run_time.rb index 3491e5f733a..2cfa4008fd3 100644 --- a/spec/support/rspec_run_time.rb +++ b/spec/support/rspec_run_time.rb @@ -101,7 +101,11 @@ module Support end def load_average - `uptime`[/(load average:[^\n]+)/, 1] + if File.exist?('/proc/loadavg') + "load average: #{File.read('/proc/loadavg')}" + else + `uptime`[/(load average:[^\n]+)/, 1] || '(uptime failed)' + end end end end diff --git a/spec/workers/releases/publish_event_worker_spec.rb b/spec/workers/releases/publish_event_worker_spec.rb new file mode 100644 index 00000000000..86dd09a756f --- /dev/null +++ b/spec/workers/releases/publish_event_worker_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Releases::PublishEventWorker, feature_category: :release_evidence do + let_it_be(:project) { create(:project, :repository) } + let_it_be_with_reload(:release) { create(:release, project: project, released_at: Time.current) } + + before do + allow(Gitlab::EventStore).to receive(:publish).and_return(true) + end + + describe 'when the releases feature is not disabled' do + before do + project.update!(releases_access_level: 'enabled') + described_class.new.perform + end + + it 'broadcasts the published event' do + expect(Gitlab::EventStore).to have_received(:publish).with(Projects::ReleasePublishedEvent) + end + + it 'sets the release as published' do + expect(release.release_published_at).not_to be_nil + end + end + + describe 'when the releases feature is disabled' do + before do + project.update!(releases_access_level: 'disabled') + described_class.new.perform + end + + it 'does not broadcasts the published event' do + expect(Gitlab::EventStore).not_to have_received(:publish).with(Projects::ReleasePublishedEvent) + end + + # Having a release created with the releases feature disabled is a bogus state anyway. + # Setting it as published prevents having such releases piling up forever in the + # `unpublished` scope. + it 'sets the release as published' do + expect(release.release_published_at).not_to be_nil + end + end +end |