diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-30 18:08:27 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-30 18:08:27 +0300 |
commit | 9376fdc13edb5fb822431df943fa088b6a273316 (patch) | |
tree | f12ac6debd2c3efc59f1629062628f40996e752f /spec | |
parent | 7c28a677895df5195ed6342921934734646c90c9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
16 files changed, 249 insertions, 36 deletions
diff --git a/spec/fast_spec_helper.rb b/spec/fast_spec_helper.rb index 0672a47c73c..597f2aa4362 100644 --- a/spec/fast_spec_helper.rb +++ b/spec/fast_spec_helper.rb @@ -25,6 +25,8 @@ ActiveSupport::XmlMini.backend = 'Nokogiri' RSpec.configure do |config| unless ENV['CI'] + # Allow running `:focus` examples locally, + # falling back to all tests when there is no `:focus` example. config.filter_run focus: true config.run_all_when_everything_filtered = true end diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb index b43b7b742f4..2d8c418b7d0 100644 --- a/spec/features/projects/settings/monitor_settings_spec.rb +++ b/spec/features/projects/settings/monitor_settings_spec.rb @@ -42,7 +42,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do expect(find_field(send_email)).to be_checked end - it 'updates form values' do + it 'updates form values', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333665' do check(create_issue) uncheck(send_email) click_on('No template selected') diff --git a/spec/features/projects/terraform_spec.rb b/spec/features/projects/terraform_spec.rb index 55b906c2bc5..d080d101285 100644 --- a/spec/features/projects/terraform_spec.rb +++ b/spec/features/projects/terraform_spec.rb @@ -58,7 +58,7 @@ RSpec.describe 'Terraform', :js do context 'when clicking on the delete button' do let(:additional_state) { create(:terraform_state, project: project) } - it 'removes the state', :aggregate_failures do + it 'removes the state', :aggregate_failures, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333640' do visit project_terraform_index_path(project) expect(page).to have_content(additional_state.name) diff --git a/spec/frontend/analytics/usage_trends/components/instance_counts_spec.js b/spec/frontend/analytics/usage_trends/components/usage_counts_spec.js index 707d2cc310f..703767dab47 100644 --- a/spec/frontend/analytics/usage_trends/components/instance_counts_spec.js +++ b/spec/frontend/analytics/usage_trends/components/usage_counts_spec.js @@ -1,5 +1,6 @@ +import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui'; +import { GlSingleStat } from '@gitlab/ui/dist/charts'; import { shallowMount } from '@vue/test-utils'; -import MetricCard from '~/analytics/shared/components/metric_card.vue'; import UsageCounts from '~/analytics/usage_trends/components/usage_counts.vue'; import { mockUsageCounts } from '../mock_data'; @@ -27,18 +28,18 @@ describe('UsageCounts', () => { afterEach(() => { wrapper.destroy(); - wrapper = null; }); - const findMetricCard = () => wrapper.find(MetricCard); + const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoading); + const findAllSingleStats = () => wrapper.findAllComponents(GlSingleStat); describe('while loading', () => { beforeEach(() => { createComponent({ loading: true }); }); - it('displays the metric card with isLoading=true', () => { - expect(findMetricCard().props('isLoading')).toBe(true); + it('displays a loading indicator', () => { + expect(findSkeletonLoader().exists()).toBe(true); }); }); @@ -47,8 +48,15 @@ describe('UsageCounts', () => { createComponent({ data: { counts: mockUsageCounts } }); }); - it('passes the counts data to the metric card', () => { - expect(findMetricCard().props('metrics')).toEqual(mockUsageCounts); + it.each` + index | value | title + ${0} | ${mockUsageCounts[0].value} | ${mockUsageCounts[0].label} + ${1} | ${mockUsageCounts[1].value} | ${mockUsageCounts[1].label} + `('renders a GlSingleStat for "$title"', ({ index, value, title }) => { + const singleStat = findAllSingleStats().at(index); + + expect(singleStat.props('value')).toBe(`${value}`); + expect(singleStat.props('title')).toBe(title); }); }); }); diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index b28412f2127..5f8af7cdc60 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -1111,16 +1111,13 @@ describe('updateIssueOrder', () => { describe('setAssignees', () => { const node = { username: 'name' }; - const projectPath = 'h/h'; - const refPath = `${projectPath}#3`; - const iid = '1'; describe('when succeeds', () => { it('calls the correct mutation with the correct values', (done) => { testAction( actions.setAssignees, - [node], - { activeBoardItem: { iid, referencePath: refPath }, commit: () => {} }, + { assignees: [node], iid: '1' }, + { commit: () => {} }, [ { type: 'UPDATE_BOARD_ITEM_BY_ID', diff --git a/spec/frontend/diffs/components/diff_view_spec.js b/spec/frontend/diffs/components/diff_view_spec.js index 2d68fd2bf43..3af66526050 100644 --- a/spec/frontend/diffs/components/diff_view_spec.js +++ b/spec/frontend/diffs/components/diff_view_spec.js @@ -41,7 +41,7 @@ describe('DiffView', () => { }); const propsData = { - diffFile: {}, + diffFile: { file_hash: '123' }, diffLines: [], ...props, }; @@ -85,7 +85,7 @@ describe('DiffView', () => { const wrapper = createWrapper({ diffLines: [{}] }); wrapper.findComponent(DiffRow).vm.$emit('startdragging', { line: { test: true } }); - expect(wrapper.vm.dragStart).toEqual({ test: true }); + expect(wrapper.vm.idState.dragStart).toEqual({ test: true }); }); it('does not call `setSelectedCommentPosition` on different chunks onDragOver', () => { @@ -123,10 +123,10 @@ describe('DiffView', () => { const diffRow = getDiffRow(wrapper); diffRow.$emit('startdragging', { line: { test: true } }); - expect(wrapper.vm.dragStart).toEqual({ test: true }); + expect(wrapper.vm.idState.dragStart).toEqual({ test: true }); diffRow.$emit('stopdragging'); - expect(wrapper.vm.dragStart).toBeNull(); + expect(wrapper.vm.idState.dragStart).toBeNull(); expect(showCommentForm).toHaveBeenCalled(); }); }); diff --git a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js index 0e052abffeb..8504684d23a 100644 --- a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js +++ b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js @@ -176,7 +176,7 @@ describe('Sidebar assignees widget', () => { ).toBe(true); }); - it('emits an event with assignees list on successful mutation', async () => { + it('emits an event with assignees list and issuable id on successful mutation', async () => { createComponent(); await waitForPromises(); @@ -193,18 +193,21 @@ describe('Sidebar assignees widget', () => { expect(wrapper.emitted('assignees-updated')).toEqual([ [ - [ - { - __typename: 'User', - avatarUrl: - 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', - id: 'gid://gitlab/User/1', - name: 'Administrator', - username: 'root', - webUrl: '/root', - status: null, - }, - ], + { + assignees: [ + { + __typename: 'User', + avatarUrl: + 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + id: 'gid://gitlab/User/1', + name: 'Administrator', + username: 'root', + webUrl: '/root', + status: null, + }, + ], + id: 1, + }, ], ]); }); @@ -285,6 +288,21 @@ describe('Sidebar assignees widget', () => { expect(updateIssueAssigneesMutationSuccess).not.toHaveBeenCalled(); expect(findUserSelect().isVisible()).toBe(true); }); + + it('calls the mutation old issuable id if `iid` prop was changed', async () => { + findUserSelect().vm.$emit('input', [{ username: 'francina.skiles' }]); + wrapper.setProps({ + iid: '2', + }); + await nextTick(); + findEditableItem().vm.$emit('close'); + + expect(updateIssueAssigneesMutationSuccess).toHaveBeenCalledWith({ + assigneeUsernames: ['francina.skiles'], + fullPath: '/mygroup/myProject', + iid: '1', + }); + }); }); it('shows an error if update assignees mutation is rejected', async () => { diff --git a/spec/lib/api/entities/basic_project_details_spec.rb b/spec/lib/api/entities/basic_project_details_spec.rb new file mode 100644 index 00000000000..dc7c4fdce4e --- /dev/null +++ b/spec/lib/api/entities/basic_project_details_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe API::Entities::BasicProjectDetails do + let_it_be(:project) { create(:project) } + + let(:current_user) { project.owner } + + subject(:output) { described_class.new(project, current_user: current_user).as_json } + + describe '#default_branch' do + it 'delegates to Project#default_branch_or_main' do + expect(project).to receive(:default_branch_or_main).twice.and_call_original + + expect(output).to include(default_branch: project.default_branch_or_main) + end + + context 'anonymous user' do + let(:current_user) { nil } + + it 'is not included' do + expect(output.keys).not_to include(:default_branch) + end + end + end +end diff --git a/spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb index d8a667ec92a..0126acb320b 100644 --- a/spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb +++ b/spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb @@ -63,6 +63,14 @@ RSpec.describe BulkImports::Groups::Pipelines::MembersPipeline do expect(member.updated_at).to eq('2020-01-01T00:00:00Z') expect(member.expires_at).to eq(nil) end + + context 'when user_id is current user id' do + it 'does not create new member' do + data = { 'user_id' => user.id } + + expect { subject.load(context, data) }.not_to change(GroupMember, :count) + end + end end describe 'pipeline parts' do diff --git a/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb b/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb index f3905a4b6e4..af99428e0c1 100644 --- a/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb +++ b/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb @@ -84,9 +84,34 @@ RSpec.describe BulkImports::Groups::Transformers::MemberAttributesTransformer do expect(subject.transform(context, data)).to be_nil end end + + context 'source user id caching' do + context 'when user gid is present' do + it 'caches source user id' do + gid = 'gid://gitlab/User/7' + data = member_data(email: user.email, gid: gid) + + expect_next_instance_of(BulkImports::UsersMapper) do |mapper| + expect(mapper).to receive(:cache_source_user_id).with('7', user.id) + end + + subject.transform(context, data) + end + end + + context 'when user gid is missing' do + it 'does not use caching' do + data = member_data(email: user.email) + + expect(BulkImports::UsersMapper).not_to receive(:new) + + subject.transform(context, data) + end + end + end end - def member_data(email: '', access_level: 30) + def member_data(email: '', gid: nil, access_level: 30) { 'created_at' => '2020-01-01T00:00:00Z', 'updated_at' => '2020-01-01T00:00:00Z', @@ -95,6 +120,7 @@ RSpec.describe BulkImports::Groups::Transformers::MemberAttributesTransformer do 'integer_value' => access_level }, 'user' => { + 'user_gid' => gid, 'public_email' => email } } diff --git a/spec/lib/bulk_imports/ndjson_pipeline_spec.rb b/spec/lib/bulk_imports/ndjson_pipeline_spec.rb index a5d1a5f7fbb..57a258b0d9f 100644 --- a/spec/lib/bulk_imports/ndjson_pipeline_spec.rb +++ b/spec/lib/bulk_imports/ndjson_pipeline_spec.rb @@ -106,8 +106,11 @@ RSpec.describe BulkImports::NdjsonPipeline do data = [hash, 1] user = double config = double(relation_excluded_keys: nil, top_relation_tree: []) - context = double(portable: group, current_user: user, import_export_config: config) + import_double = instance_double(BulkImport, id: 1) + entity_double = instance_double(BulkImports::Entity, id: 2) + context = double(portable: group, current_user: user, import_export_config: config, bulk_import: import_double, entity: entity_double) allow(subject).to receive(:import_export_config).and_return(config) + allow(subject).to receive(:context).and_return(context) expect(Gitlab::ImportExport::Group::RelationFactory) .to receive(:create) @@ -116,7 +119,7 @@ RSpec.describe BulkImports::NdjsonPipeline do relation_sym: :test, relation_hash: hash, importable: group, - members_mapper: instance_of(Gitlab::ImportExport::MembersMapper), + members_mapper: instance_of(BulkImports::UsersMapper), object_builder: Gitlab::ImportExport::Group::ObjectBuilder, user: user, excluded_keys: nil diff --git a/spec/lib/bulk_imports/users_mapper_spec.rb b/spec/lib/bulk_imports/users_mapper_spec.rb new file mode 100644 index 00000000000..e6357319d05 --- /dev/null +++ b/spec/lib/bulk_imports/users_mapper_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::UsersMapper do + let_it_be(:user) { create(:user) } + let_it_be(:import) { create(:bulk_import, user: user) } + let_it_be(:entity) { create(:bulk_import_entity, bulk_import: import) } + + let(:context) do + instance_double( + BulkImports::Pipeline::Context, + bulk_import: import, + entity: entity, + current_user: user + ) + end + + subject { described_class.new(context: context) } + + describe '#map' do + context 'when value for specified key exists' do + it 'returns a map of source & destination user ids from redis' do + allow(Gitlab::Cache::Import::Caching).to receive(:values_from_hash).and_return({ "1" => "2" }) + + expect(subject.map).to eq({ 1 => 2 }) + end + end + + context 'when value for specified key does not exist' do + it 'returns default value' do + expect(subject.map[:non_existent_key]).to eq(user.id) + end + end + end + + describe '#default_user_id' do + it 'returns current user id' do + expect(subject.default_user_id).to eq(user.id) + end + end + + describe '#include?' do + context 'when source user id is present in the map' do + it 'returns true' do + allow(subject).to receive(:map).and_return({ 1 => 2 }) + + expect(subject.include?(1)).to eq(true) + end + end + + context 'when source user id is missing in the map' do + it 'returns false' do + allow(subject).to receive(:map).and_return({}) + + expect(subject.include?(1)).to eq(false) + end + end + end + + describe '#cache_source_user_id' do + it 'caches provided source & destination user ids in redis' do + expect(Gitlab::Cache::Import::Caching).to receive(:hash_add).with("bulk_imports/#{import.id}/#{entity.id}/source_user_ids", 1, 2) + + subject.cache_source_user_id(1, 2) + end + end +end diff --git a/spec/lib/gitlab/cache/import/caching_spec.rb b/spec/lib/gitlab/cache/import/caching_spec.rb index 8ce12f5d32e..f770960e27a 100644 --- a/spec/lib/gitlab/cache/import/caching_spec.rb +++ b/spec/lib/gitlab/cache/import/caching_spec.rb @@ -100,6 +100,30 @@ RSpec.describe Gitlab::Cache::Import::Caching, :clean_gitlab_redis_cache do end end + describe '.hash_add' do + it 'adds a value to a hash' do + described_class.hash_add('foo', 1, 1) + described_class.hash_add('foo', 2, 2) + + key = described_class.cache_key_for('foo') + values = Gitlab::Redis::Cache.with { |r| r.hgetall(key) } + + expect(values).to eq({ '1' => '1', '2' => '2' }) + end + end + + describe '.values_from_hash' do + it 'returns empty hash when the hash is empty' do + expect(described_class.values_from_hash('foo')).to eq({}) + end + + it 'returns the set list of values' do + described_class.hash_add('foo', 1, 1) + + expect(described_class.values_from_hash('foo')).to eq({ '1' => '1' }) + end + end + describe '.write_multiple' do it 'sets multiple keys when key_prefix not set' do mapping = { 'foo' => 10, 'bar' => 20 } diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 09954569ff6..d09d0627053 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -1083,6 +1083,14 @@ RSpec.describe Namespace do end describe '#all_projects' do + context 'when recursive approach is disabled' do + before do + stub_feature_flags(recursive_approach_for_all_projects: false) + end + + include_examples '#all_projects' + end + context 'with use_traversal_ids feature flag enabled' do before do stub_feature_flags(use_traversal_ids: true) diff --git a/spec/services/git/wiki_push_service_spec.rb b/spec/services/git/wiki_push_service_spec.rb index ead15e6e022..7e5d7066e89 100644 --- a/spec/services/git/wiki_push_service_spec.rb +++ b/spec/services/git/wiki_push_service_spec.rb @@ -65,6 +65,26 @@ RSpec.describe Git::WikiPushService, services: true do expect(Event.last(count).pluck(:action)).to match_array(Event::WIKI_ACTIONS.map(&:to_s)) end + + context 'when wiki_page slug is not UTF-8 ' do + let(:binary_title) { Gitlab::EncodingHelper.encode_binary('编码') } + + def run_service + wiki_page = create(:wiki_page, wiki: wiki, title: "#{binary_title} 'foo'") + + process_changes do + # Test that new_path is converted to UTF-8 + create(:wiki_page, wiki: wiki, title: binary_title) + + # Test that old_path is also is converted to UTF-8 + update_page(wiki_page.title, 'foo') + end + end + + it 'does not raise an error' do + expect { run_service }.not_to raise_error + end + end end context 'two pages have been created' do @@ -346,9 +366,10 @@ RSpec.describe Git::WikiPushService, services: true do ::Wikis::CreateAttachmentService.new(container: wiki.container, current_user: current_user, params: params).execute end - def update_page(title) + def update_page(title, new_title = nil) + new_title = title unless new_title.present? page = git_wiki.page(title: title) - git_wiki.update_page(page.path, title, 'markdown', 'Hey', commit_details) + git_wiki.update_page(page.path, new_title, 'markdown', 'Hey', commit_details) end def delete_page(page) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6a2975e566a..6d0969e8688 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -110,8 +110,11 @@ RSpec.configure do |config| end unless ENV['CI'] + # Allow running `:focus` examples locally, + # falling back to all tests when there is no `:focus` example. config.filter_run focus: true config.run_all_when_everything_filtered = true + # Re-run failures locally with `--only-failures` config.example_status_persistence_file_path = './spec/examples.txt' end |