diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-03-03 18:10:53 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-03-03 18:10:53 +0300 |
commit | 7fcda12793acc54ba8de037f50cc3696dbd0f002 (patch) | |
tree | 044fbc2b142e6c82ee6b2a5df4b37d000c0e2d1f /spec | |
parent | b5820a6bcd083c878a085aa288757e8dc2d35fec (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
20 files changed, 347 insertions, 111 deletions
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb index 71abf3191b8..2b562e2dd64 100644 --- a/spec/controllers/admin/application_settings_controller_spec.rb +++ b/spec/controllers/admin/application_settings_controller_spec.rb @@ -144,10 +144,10 @@ RSpec.describe Admin::ApplicationSettingsController do end it 'updates repository_storages_weighted setting' do - put :update, params: { application_setting: { repository_storages_weighted_default: 75 } } + put :update, params: { application_setting: { repository_storages_weighted: { default: 75 } } } expect(response).to redirect_to(general_admin_application_settings_path) - expect(ApplicationSetting.current.repository_storages_weighted_default).to eq(75) + expect(ApplicationSetting.current.repository_storages_weighted).to eq('default' => 75) end it 'updates kroki_formats setting' do diff --git a/spec/factories/ci/build_trace_chunks.rb b/spec/factories/ci/build_trace_chunks.rb index d996b41b648..115eb32111c 100644 --- a/spec/factories/ci/build_trace_chunks.rb +++ b/spec/factories/ci/build_trace_chunks.rb @@ -3,7 +3,7 @@ FactoryBot.define do factory :ci_build_trace_chunk, class: 'Ci::BuildTraceChunk' do build factory: :ci_build - chunk_index { 0 } + chunk_index { generate(:iid) } data_store { :redis } trait :redis_with_data do diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 52f39f65bd0..249621f5835 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -384,7 +384,20 @@ RSpec.describe 'Admin updates settings' do click_button 'Save changes' end - expect(current_settings.repository_storages_weighted_default).to be 50 + expect(current_settings.repository_storages_weighted).to eq('default' => 50) + end + + it 'still saves when settings are outdated' do + current_settings.update_attribute :repository_storages_weighted, { 'default' => 100, 'outdated' => 100 } + + visit repository_admin_application_settings_path + + page.within('.as-repository-storage') do + fill_in 'application_setting_repository_storages_weighted_default', with: 50 + click_button 'Save changes' + end + + expect(current_settings.repository_storages_weighted).to eq('default' => 50) end end diff --git a/spec/frontend/boards/components/board_list_header_spec.js b/spec/frontend/boards/components/board_list_header_spec.js index f30e3792435..7472eeb4396 100644 --- a/spec/frontend/boards/components/board_list_header_spec.js +++ b/spec/frontend/boards/components/board_list_header_spec.js @@ -1,5 +1,6 @@ import { shallowMount, createLocalVue } from '@vue/test-utils'; import Vuex from 'vuex'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { mockLabelList } from 'jest/boards/mock_data'; import BoardListHeader from '~/boards/components/board_list_header.vue'; @@ -14,6 +15,7 @@ describe('Board List Header Component', () => { let store; const updateListSpy = jest.fn(); + const toggleListCollapsedSpy = jest.fn(); afterEach(() => { wrapper.destroy(); @@ -43,38 +45,39 @@ describe('Board List Header Component', () => { if (withLocalStorage) { localStorage.setItem( - `boards.${boardId}.${listMock.listType}.${listMock.id}.expanded`, - (!collapsed).toString(), + `boards.${boardId}.${listMock.listType}.${listMock.id}.collapsed`, + collapsed.toString(), ); } store = new Vuex.Store({ state: {}, - actions: { updateList: updateListSpy }, + actions: { updateList: updateListSpy, toggleListCollapsed: toggleListCollapsedSpy }, getters: {}, }); - wrapper = shallowMount(BoardListHeader, { - store, - localVue, - propsData: { - disabled: false, - list: listMock, - }, - provide: { - boardId, - weightFeatureAvailable: false, - currentUserId, - }, - }); + wrapper = extendedWrapper( + shallowMount(BoardListHeader, { + store, + localVue, + propsData: { + disabled: false, + list: listMock, + }, + provide: { + boardId, + weightFeatureAvailable: false, + currentUserId, + }, + }), + ); }; const isCollapsed = () => wrapper.vm.list.collapsed; - const isExpanded = () => !isCollapsed; const findAddIssueButton = () => wrapper.find({ ref: 'newIssueBtn' }); const findTitle = () => wrapper.find('.board-title'); - const findCaret = () => wrapper.find('.board-title-caret'); + const findCaret = () => wrapper.findByTestId('board-title-caret'); describe('Add issue button', () => { const hasNoAddButton = [ListType.closed]; @@ -114,40 +117,29 @@ describe('Board List Header Component', () => { }); describe('expanding / collapsing the column', () => { - it('does not collapse when clicking the header', async () => { + it('should display collapse icon when column is expanded', async () => { createComponent(); - expect(isCollapsed()).toBe(false); - - wrapper.find('[data-testid="board-list-header"]').trigger('click'); + const icon = findCaret(); - await wrapper.vm.$nextTick(); - - expect(isCollapsed()).toBe(false); + expect(icon.props('icon')).toBe('chevron-right'); }); - it('collapses expanded Column when clicking the collapse icon', async () => { - createComponent(); - - expect(isCollapsed()).toBe(false); - - findCaret().vm.$emit('click'); + it('should display expand icon when column is collapsed', async () => { + createComponent({ collapsed: true }); - await wrapper.vm.$nextTick(); + const icon = findCaret(); - expect(isCollapsed()).toBe(true); + expect(icon.props('icon')).toBe('chevron-down'); }); - it('expands collapsed Column when clicking the expand icon', async () => { - createComponent({ collapsed: true }); - - expect(isCollapsed()).toBe(true); + it('should dispatch toggleListCollapse when clicking the collapse icon', async () => { + createComponent(); findCaret().vm.$emit('click'); await wrapper.vm.$nextTick(); - - expect(isCollapsed()).toBe(false); + expect(toggleListCollapsedSpy).toHaveBeenCalledTimes(1); }); it("when logged in it calls list update and doesn't set localStorage", async () => { @@ -157,7 +149,7 @@ describe('Board List Header Component', () => { await wrapper.vm.$nextTick(); expect(updateListSpy).toHaveBeenCalledTimes(1); - expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(null); + expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.collapsed`)).toBe(null); }); it("when logged out it doesn't call list update and sets localStorage", async () => { @@ -167,7 +159,7 @@ describe('Board List Header Component', () => { await wrapper.vm.$nextTick(); expect(updateListSpy).not.toHaveBeenCalled(); - expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(String(isExpanded())); + expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.collapsed`)).toBe(String(isCollapsed())); }); }); diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index 622401c1c09..9e1b5018cc1 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -452,6 +452,22 @@ describe('updateList', () => { }); }); +describe('toggleListCollapsed', () => { + it('should commit TOGGLE_LIST_COLLAPSED mutation', async () => { + const payload = { listId: 'gid://gitlab/List/1', collapsed: true }; + await testAction({ + action: actions.toggleListCollapsed, + payload, + expectedMutations: [ + { + type: types.TOGGLE_LIST_COLLAPSED, + payload, + }, + ], + }); + }); +}); + describe('removeList', () => { let state; const list = mockLists[0]; diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js index 3a94bd9160f..29a205e2ffb 100644 --- a/spec/frontend/boards/stores/mutations_spec.js +++ b/spec/frontend/boards/stores/mutations_spec.js @@ -202,6 +202,24 @@ describe('Board Store Mutations', () => { }); }); + describe('TOGGLE_LIST_COLLAPSED', () => { + it('updates collapsed attribute of list in boardLists state', () => { + const listId = 'gid://gitlab/List/1'; + state = { + ...state, + boardLists: { + [listId]: mockLists[0], + }, + }; + + expect(state.boardLists[listId].collapsed).toEqual(false); + + mutations.TOGGLE_LIST_COLLAPSED(state, { listId, collapsed: true }); + + expect(state.boardLists[listId].collapsed).toEqual(true); + }); + }); + describe('REMOVE_LIST', () => { it('removes list from boardLists', () => { const [list, secondList] = mockLists; diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap index 8446f0f50c4..95da67c2bbf 100644 --- a/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap +++ b/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap @@ -46,6 +46,8 @@ exports[`Snippet Visibility Edit component rendering matches the snapshot 1`] = <span class="font-weight-bold ml-1 js-visibility-option" + data-qa-selector="visibility_content" + data-qa-visibility="Private" > Private </span> @@ -65,6 +67,8 @@ exports[`Snippet Visibility Edit component rendering matches the snapshot 1`] = <span class="font-weight-bold ml-1 js-visibility-option" + data-qa-selector="visibility_content" + data-qa-visibility="Internal" > Internal </span> @@ -84,6 +88,8 @@ exports[`Snippet Visibility Edit component rendering matches the snapshot 1`] = <span class="font-weight-bold ml-1 js-visibility-option" + data-qa-selector="visibility_content" + data-qa-visibility="Public" > Public </span> diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index 2cd01451e0d..c74ee3ce0ec 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -130,20 +130,15 @@ RSpec.describe ApplicationSettingsHelper do before do helper.instance_variable_set(:@application_setting, application_setting) stub_storage_settings({ 'default': {}, 'storage_1': {}, 'storage_2': {} }) - allow(ApplicationSetting).to receive(:repository_storages_weighted_attributes).and_return( - [:repository_storages_weighted_default, - :repository_storages_weighted_storage_1, - :repository_storages_weighted_storage_2]) - stub_application_setting(repository_storages_weighted: { 'default' => 100, 'storage_1' => 50, 'storage_2' => nil }) end it 'returns storages correctly' do - expect(helper.storage_weights).to eq([ - { name: :repository_storages_weighted_default, label: 'default', value: 100 }, - { name: :repository_storages_weighted_storage_1, label: 'storage_1', value: 50 }, - { name: :repository_storages_weighted_storage_2, label: 'storage_2', value: 0 } - ]) + expect(helper.storage_weights).to eq(OpenStruct.new( + default: 100, + storage_1: 50, + storage_2: 0 + )) end end diff --git a/spec/lib/gitlab/ci/reports/codequality_reports_comparer_spec.rb b/spec/lib/gitlab/ci/reports/codequality_reports_comparer_spec.rb index 90188b56f5a..b322e55cb5a 100644 --- a/spec/lib/gitlab/ci/reports/codequality_reports_comparer_spec.rb +++ b/spec/lib/gitlab/ci/reports/codequality_reports_comparer_spec.rb @@ -27,6 +27,22 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do expect(report_status).to eq(described_class::STATUS_SUCCESS) end end + + context 'when head report does not exist' do + let(:head_report) { nil } + + it 'returns status not found' do + expect(report_status).to eq(described_class::STATUS_NOT_FOUND) + end + end + + context 'when base report does not exist' do + let(:base_report) { nil } + + it 'returns status success' do + expect(report_status).to eq(described_class::STATUS_NOT_FOUND) + end + end end describe '#errors_count' do @@ -93,6 +109,14 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do expect(resolved_count).to be_zero end end + + context 'when base report is nil' do + let(:base_report) { nil } + + it 'returns zero' do + expect(resolved_count).to be_zero + end + end end describe '#total_count' do @@ -140,6 +164,14 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do expect(total_count).to eq(2) end end + + context 'when base report is nil' do + let(:base_report) { nil } + + it 'returns zero' do + expect(total_count).to be_zero + end + end end describe '#existing_errors' do @@ -177,6 +209,14 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do expect(existing_errors).to be_empty end end + + context 'when base report is nil' do + let(:base_report) { nil } + + it 'returns an empty array' do + expect(existing_errors).to be_empty + end + end end describe '#new_errors' do @@ -213,6 +253,14 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do expect(new_errors).to eq([degradation_1]) end end + + context 'when base report is nil' do + let(:base_report) { nil } + + it 'returns an empty array' do + expect(new_errors).to be_empty + end + end end describe '#resolved_errors' do @@ -250,5 +298,13 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do expect(resolved_errors).to be_empty end end + + context 'when base report is nil' do + let(:base_report) { nil } + + it 'returns an empty array' do + expect(resolved_errors).to be_empty + end + end end end diff --git a/spec/lib/gitlab/ci/reports/reports_comparer_spec.rb b/spec/lib/gitlab/ci/reports/reports_comparer_spec.rb index 8eb2258a335..7ed9270e9a0 100644 --- a/spec/lib/gitlab/ci/reports/reports_comparer_spec.rb +++ b/spec/lib/gitlab/ci/reports/reports_comparer_spec.rb @@ -49,10 +49,6 @@ RSpec.describe Gitlab::Ci::Reports::ReportsComparer do context 'when base_report is nil' do let(:base_report) { nil } - before do - allow(comparer).to receive(:success?).and_return(false) - end - it 'returns status not_found' do expect(status).to eq('not_found') end @@ -61,10 +57,6 @@ RSpec.describe Gitlab::Ci::Reports::ReportsComparer do context 'when head_report is nil' do let(:head_report) { nil } - before do - allow(comparer).to receive(:success?).and_return(false) - end - it 'returns status not_found' do expect(status).to eq('not_found') end @@ -118,4 +110,22 @@ RSpec.describe Gitlab::Ci::Reports::ReportsComparer do expect { total_count }.to raise_error(NotImplementedError) end end + + describe '#not_found?' do + subject(:not_found) { comparer.not_found? } + + context 'when base report is nil' do + let(:base_report) { nil } + + it { is_expected.to be_truthy } + end + + context 'when base report exists' do + before do + allow(comparer).to receive(:success?).and_return(true) + end + + it { is_expected.to be_falsey } + end + end end diff --git a/spec/lib/gitlab/github_import/importer/pull_request_review_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_request_review_importer_spec.rb index b2f993ac47c..290f3f51202 100644 --- a/spec/lib/gitlab/github_import/importer/pull_request_review_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/pull_request_review_importer_spec.rb @@ -19,8 +19,10 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestReviewImporter, :clean context 'when the review is "APPROVED"' do let(:review) { create_review(type: 'APPROVED', note: '') } - it 'creates a note for the review' do - expect { subject.execute }.to change(Note, :count) + it 'creates a note for the review and approves the Merge Request' do + expect { subject.execute } + .to change(Note, :count).by(1) + .and change(Approval, :count).by(1) last_note = merge_request.notes.last expect(last_note.note).to eq('approved this merge request') @@ -31,6 +33,14 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestReviewImporter, :clean expect(merge_request.approved_by_users.reload).to include(author) expect(merge_request.approvals.last.created_at).to eq(submitted_at) end + + it 'does nothing if the user already approved the merge request' do + create(:approval, merge_request: merge_request, user: author) + + expect { subject.execute } + .to change(Note, :count).by(0) + .and change(Approval, :count).by(0) + end end context 'when the review is "COMMENTED"' do diff --git a/spec/lib/gitlab/import_export/import_export_spec.rb b/spec/lib/gitlab/import_export/import_export_spec.rb index 62b4717fc96..87757b07572 100644 --- a/spec/lib/gitlab/import_export/import_export_spec.rb +++ b/spec/lib/gitlab/import_export/import_export_spec.rb @@ -4,8 +4,8 @@ require 'spec_helper' RSpec.describe Gitlab::ImportExport do describe 'export filename' do - let(:group) { create(:group, :nested) } - let(:project) { create(:project, :public, path: 'project-path', namespace: group) } + let(:group) { build(:group, path: 'child', parent: build(:group, path: 'parent')) } + let(:project) { build(:project, :public, path: 'project-path', namespace: group) } it 'contains the project path' do expect(described_class.export_filename(exportable: project)).to include(project.path) diff --git a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb index 6bc42430889..d740e19ae7b 100644 --- a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb @@ -300,4 +300,20 @@ RSpec.describe Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter, :cl let(:action) { described_class::MR_DISCUSSION_UNLOCKED_ACTION } end end + + describe '.track_time_estimate_changed_action' do + subject { described_class.track_time_estimate_changed_action(user: user) } + + it_behaves_like 'a tracked merge request unique event' do + let(:action) { described_class::MR_TIME_ESTIMATE_CHANGED_ACTION } + end + end + + describe '.track_time_spent_changed_action' do + subject { described_class.track_time_spent_changed_action(user: user) } + + it_behaves_like 'a tracked merge request unique event' do + let(:action) { described_class::MR_TIME_SPENT_CHANGED_ACTION } + end + end end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 602f6640d72..1aa2cbb5485 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -1129,12 +1129,40 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do end end + describe ".operating_system" do + let(:ohai_data) { { "platform" => "ubuntu", "platform_version" => "20.04" } } + + before do + allow_next_instance_of(Ohai::System) do |ohai| + allow(ohai).to receive(:data).and_return(ohai_data) + end + end + + subject { described_class.operating_system } + + it { is_expected.to eq("ubuntu-20.04") } + + context 'when on Debian with armv architecture' do + let(:ohai_data) { { "platform" => "debian", "platform_version" => "10", 'kernel' => { 'machine' => 'armv' } } } + + it { is_expected.to eq("raspbian-10") } + end + end + describe ".system_usage_data_settings" do + before do + allow(described_class).to receive(:operating_system).and_return('ubuntu-20.04') + end + subject { described_class.system_usage_data_settings } it 'gathers settings usage data', :aggregate_failures do expect(subject[:settings][:ldap_encrypted_secrets_enabled]).to eq(Gitlab::Auth::Ldap::Config.encrypted_secrets.active?) end + + it 'populates operating system information' do + expect(subject[:settings][:operating_system]).to eq('ubuntu-20.04') + end end end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 8f63f44e8af..808932ce7e4 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -105,14 +105,14 @@ RSpec.describe ApplicationSetting do it { is_expected.not_to allow_value(false).for(:hashed_storage_enabled) } - it { is_expected.not_to allow_value(101).for(:repository_storages_weighted_default) } - it { is_expected.to allow_value('90').for(:repository_storages_weighted_default) } - it { is_expected.not_to allow_value(-1).for(:repository_storages_weighted_default) } - it { is_expected.to allow_value(100).for(:repository_storages_weighted_default) } - it { is_expected.to allow_value(0).for(:repository_storages_weighted_default) } - it { is_expected.to allow_value(50).for(:repository_storages_weighted_default) } - it { is_expected.to allow_value(nil).for(:repository_storages_weighted_default) } - it { is_expected.not_to allow_value({ default: 100, shouldntexist: 50 }).for(:repository_storages_weighted) } + it { is_expected.to allow_value('default' => 0).for(:repository_storages_weighted) } + it { is_expected.to allow_value('default' => 50).for(:repository_storages_weighted) } + it { is_expected.to allow_value('default' => 100).for(:repository_storages_weighted) } + it { is_expected.to allow_value('default' => '90').for(:repository_storages_weighted) } + it { is_expected.to allow_value('default' => nil).for(:repository_storages_weighted) } + it { is_expected.not_to allow_value('default' => -1).for(:repository_storages_weighted).with_message("value for 'default' must be between 0 and 100") } + it { is_expected.not_to allow_value('default' => 101).for(:repository_storages_weighted).with_message("value for 'default' must be between 0 and 100") } + it { is_expected.not_to allow_value('default' => 100, shouldntexist: 50).for(:repository_storages_weighted).with_message("can't include: shouldntexist") } it { is_expected.to allow_value(400).for(:notes_create_limit) } it { is_expected.not_to allow_value('two').for(:notes_create_limit) } @@ -650,6 +650,32 @@ RSpec.describe ApplicationSetting do end end + describe '#asset_proxy_whitelist' do + context 'when given an Array' do + it 'sets the domains and adds current running host' do + setting.asset_proxy_whitelist = ['example.com', 'assets.example.com'] + expect(setting.asset_proxy_whitelist).to eq(['example.com', 'assets.example.com', 'localhost']) + end + end + + context 'when given a String' do + it 'sets multiple domains with spaces' do + setting.asset_proxy_whitelist = 'example.com *.example.com' + expect(setting.asset_proxy_whitelist).to eq(['example.com', '*.example.com', 'localhost']) + end + + it 'sets multiple domains with newlines and a space' do + setting.asset_proxy_whitelist = "example.com\n *.example.com" + expect(setting.asset_proxy_whitelist).to eq(['example.com', '*.example.com', 'localhost']) + end + + it 'sets multiple domains with commas' do + setting.asset_proxy_whitelist = "example.com, *.example.com" + expect(setting.asset_proxy_whitelist).to eq(['example.com', '*.example.com', 'localhost']) + end + end + end + describe '#asset_proxy_allowlist' do context 'when given an Array' do it 'sets the domains and adds current running host' do @@ -958,12 +984,6 @@ RSpec.describe ApplicationSetting do it_behaves_like 'application settings examples' - describe 'repository_storages_weighted_attributes' do - it 'returns the keys for repository_storages_weighted' do - expect(subject.class.repository_storages_weighted_attributes).to eq([:repository_storages_weighted_default]) - end - end - describe 'kroki_format_supported?' do it 'returns true when Excalidraw is enabled' do subject.kroki_formats_excalidraw = true @@ -1007,11 +1027,4 @@ RSpec.describe ApplicationSetting do expect(subject.kroki_formats_excalidraw).to eq(true) end end - - it 'does not allow to set weight for non existing storage' do - setting.repository_storages_weighted = { invalid_storage: 100 } - - expect(setting).not_to be_valid - expect(setting.errors.messages[:repository_storages_weighted]).to match_array(["can't include: invalid_storage"]) - end end diff --git a/spec/services/application_settings/update_service_spec.rb b/spec/services/application_settings/update_service_spec.rb index 1352a595ba4..258b3d25aee 100644 --- a/spec/services/application_settings/update_service_spec.rb +++ b/spec/services/application_settings/update_service_spec.rb @@ -123,6 +123,7 @@ RSpec.describe ApplicationSettings::UpdateService do it_behaves_like 'invalidates markdown cache', { asset_proxy_url: 'http://test.com' } it_behaves_like 'invalidates markdown cache', { asset_proxy_secret_key: 'another secret' } it_behaves_like 'invalidates markdown cache', { asset_proxy_allowlist: ['domain.com'] } + it_behaves_like 'invalidates markdown cache', { asset_proxy_whitelist: ['domain.com'] } context 'when also setting the local_markdown_version' do let(:params) { { asset_proxy_enabled: true, local_markdown_version: 12 } } diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index e9ec3bccda3..30d94a2e948 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -169,6 +169,23 @@ RSpec.describe MergeRequests::UpdateService, :mailer do end end end + + it 'tracks time estimate and spend time changes' do + expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter) + .to receive(:track_time_estimate_changed_action).once.with(user: user) + + expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter) + .to receive(:track_time_spent_changed_action).once.with(user: user) + + opts[:time_estimate] = 86400 + opts[:spend_time] = { + duration: 3600, + user_id: user.id, + spent_at: Date.parse('2021-02-24') + } + + MergeRequests::UpdateService.new(project, user, opts).execute(merge_request) + end end context 'updating milestone' do diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb index 75d1c98923a..6fa3d6efbb5 100644 --- a/spec/services/projects/destroy_service_spec.rb +++ b/spec/services/projects/destroy_service_spec.rb @@ -31,9 +31,34 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do end shared_examples 'deleting the project with pipeline and build' do - context 'with pipeline and build', :sidekiq_inline do # which has optimistic locking + context 'with pipeline and build related records', :sidekiq_inline do # which has optimistic locking let!(:pipeline) { create(:ci_pipeline, project: project) } - let!(:build) { create(:ci_build, :artifacts, pipeline: pipeline) } + let!(:build) { create(:ci_build, :artifacts, :with_runner_session, pipeline: pipeline) } + let!(:trace_chunks) { create(:ci_build_trace_chunk, build: build) } + let!(:job_variables) { create(:ci_job_variable, job: build) } + let!(:report_result) { create(:ci_build_report_result, build: build) } + let!(:pending_state) { create(:ci_build_pending_state, build: build) } + + it 'deletes build related records' do + expect { destroy_project(project, user, {}) }.to change { Ci::Build.count }.by(-1) + .and change { Ci::BuildTraceChunk.count }.by(-1) + .and change { Ci::JobArtifact.count }.by(-2) + .and change { Ci::JobVariable.count }.by(-1) + .and change { Ci::BuildPendingState.count }.by(-1) + .and change { Ci::BuildReportResult.count }.by(-1) + .and change { Ci::BuildRunnerSession.count }.by(-1) + end + + it 'avoids N+1 queries', skip: 'skipped until fixed in https://gitlab.com/gitlab-org/gitlab/-/issues/24644' do + recorder = ActiveRecord::QueryRecorder.new { destroy_project(project, user, {}) } + + project = create(:project, :repository, namespace: user.namespace) + pipeline = create(:ci_pipeline, project: project) + builds = create_list(:ci_build, 3, :artifacts, pipeline: pipeline) + create_list(:ci_build_trace_chunk, 3, build: builds[0]) + + expect { destroy_project(project, project.owner, {}) }.not_to exceed_query_limit(recorder) + end it_behaves_like 'deleting the project' end diff --git a/spec/support/shared_examples/models/application_setting_shared_examples.rb b/spec/support/shared_examples/models/application_setting_shared_examples.rb index 92fd4363134..60a02d85a1e 100644 --- a/spec/support/shared_examples/models/application_setting_shared_examples.rb +++ b/spec/support/shared_examples/models/application_setting_shared_examples.rb @@ -289,6 +289,7 @@ RSpec.shared_examples 'application settings examples' do describe '#pick_repository_storage' do before do + allow(Gitlab.config.repositories.storages).to receive(:keys).and_return(%w(default backup)) allow(setting).to receive(:repository_storages_weighted).and_return({ 'default' => 20, 'backup' => 80 }) end @@ -304,15 +305,19 @@ RSpec.shared_examples 'application settings examples' do describe '#normalized_repository_storage_weights' do using RSpec::Parameterized::TableSyntax - where(:storages, :normalized) do - { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0, 'backup' => 1.0 } - { 'default' => 100, 'backup' => 100 } | { 'default' => 0.5, 'backup' => 0.5 } - { 'default' => 20, 'backup' => 80 } | { 'default' => 0.2, 'backup' => 0.8 } - { 'default' => 0, 'backup' => 0 } | { 'default' => 0.0, 'backup' => 0.0 } + where(:config_storages, :storages, :normalized) do + %w(default backup) | { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0, 'backup' => 1.0 } + %w(default backup) | { 'default' => 100, 'backup' => 100 } | { 'default' => 0.5, 'backup' => 0.5 } + %w(default backup) | { 'default' => 20, 'backup' => 80 } | { 'default' => 0.2, 'backup' => 0.8 } + %w(default backup) | { 'default' => 0, 'backup' => 0 } | { 'default' => 0.0, 'backup' => 0.0 } + %w(default) | { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0 } + %w(default) | { 'default' => 100, 'backup' => 100 } | { 'default' => 1.0 } + %w(default) | { 'default' => 20, 'backup' => 80 } | { 'default' => 1.0 } end with_them do before do + allow(Gitlab.config.repositories.storages).to receive(:keys).and_return(config_storages) allow(setting).to receive(:repository_storages_weighted).and_return(storages) end diff --git a/spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb b/spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb index 2915fe1964f..dc8f259eb56 100644 --- a/spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb +++ b/spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb @@ -3,34 +3,49 @@ require 'spec_helper' RSpec.describe 'admin/application_settings/_repository_storage.html.haml' do - let(:app_settings) { create(:application_setting) } - let(:repository_storages_weighted_attributes) { [:repository_storages_weighted_default, :repository_storages_weighted_mepmep, :repository_storages_weighted_foobar]} - let(:repository_storages_weighted) do - { - "default" => 100, - "mepmep" => 50 - } - end + let(:app_settings) { build(:application_setting, repository_storages_weighted: repository_storages_weighted) } before do - allow(app_settings).to receive(:repository_storages_weighted).and_return(repository_storages_weighted) - allow(app_settings).to receive(:repository_storages_weighted_mepmep).and_return(100) - allow(app_settings).to receive(:repository_storages_weighted_foobar).and_return(50) + stub_storage_settings({ 'default': {}, 'mepmep': {}, 'foobar': {} }) assign(:application_setting, app_settings) - allow(ApplicationSetting).to receive(:repository_storages_weighted_attributes).and_return(repository_storages_weighted_attributes) end - context 'when multiple storages are available' do + context 'additional storage config' do + let(:repository_storages_weighted) do + { + 'default' => 100, + 'mepmep' => 50 + } + end + it 'lists them all' do render - # lists storages that are saved with weights - repository_storages_weighted.each do |storage_name, storage_weight| + Gitlab.config.repositories.storages.keys.each do |storage_name| expect(rendered).to have_content(storage_name) end - # lists storage not saved with weight expect(rendered).to have_content('foobar') end end + + context 'fewer storage configs' do + let(:repository_storages_weighted) do + { + 'default' => 100, + 'mepmep' => 50, + 'something_old' => 100 + } + end + + it 'lists only configured storages' do + render + + Gitlab.config.repositories.storages.keys.each do |storage_name| + expect(rendered).to have_content(storage_name) + end + + expect(rendered).not_to have_content('something_old') + end + end end |