diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-16 12:09:38 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-16 12:09:38 +0300 |
commit | bc9b43904d491c7b864c8fb6ba06ae0f6625db0d (patch) | |
tree | ca0a5ae3bbbf98530707b96a7db08d1bd773b429 /spec | |
parent | 10476ea7d8253d8462e092ed95aedc01204238bc (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
13 files changed, 444 insertions, 120 deletions
diff --git a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb index fb68195362a..eb370cfc1fc 100644 --- a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb +++ b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb @@ -5,7 +5,8 @@ require 'spec_helper' RSpec.describe 'New Branch Ref Dropdown', :js, feature_category: :projects do let(:user) { create(:user) } let(:project) { create(:project, :public, :repository) } - let(:toggle) { find('.create-from .dropdown-menu-toggle') } + let(:sha) { project.commit.sha } + let(:toggle) { find('.ref-selector') } before do project.add_maintainer(user) @@ -14,37 +15,75 @@ RSpec.describe 'New Branch Ref Dropdown', :js, feature_category: :projects do visit new_project_branch_path(project) end - it 'filters a list of branches and tags' do + it 'finds a tag in a list' do + tag_name = 'v1.0.0' + toggle.click - filter_by('v1.0.0') + filter_by(tag_name) + + wait_for_requests + + expect(items_count(tag_name)).to be(1) - expect(items_count).to be(1) + item(tag_name).click - filter_by('video') + expect(toggle).to have_content tag_name + end + + it 'finds a branch in a list' do + branch_name = 'audio' - expect(items_count).to be(1) + toggle.click - find('.create-from .dropdown-content li').click + filter_by(branch_name) - expect(toggle).to have_content 'video' + wait_for_requests + + expect(items_count(branch_name)).to be(1) + + item(branch_name).click + + expect(toggle).to have_content branch_name end - it 'accepts a manually entered commit SHA' do + it 'finds a commit in a list' do toggle.click - filter_by('somecommitsha') + filter_by(sha) + + wait_for_requests + + sha_short = sha[0, 7] - find('.create-from input[type=search]').send_keys(:enter) + expect(items_count(sha_short)).to be(1) + + item(sha_short).click + + expect(toggle).to have_content sha_short + end + + it 'shows no results when there is no branch, tag or commit sha found' do + non_existing_ref = 'non_existing_branch_name' + + toggle.click + + filter_by(non_existing_ref) + + wait_for_requests + + expect(find('.gl-dropdown-contents')).not_to have_content(non_existing_ref) + end - expect(toggle).to have_content 'somecommitsha' + def item(ref_name) + find('li', text: ref_name, match: :prefer_exact) end - def items_count - all('.create-from .dropdown-content li').length + def items_count(ref_name) + all('li', text: ref_name, match: :prefer_exact).length end def filter_by(filter_text) - fill_in 'Filter by Git revision', with: filter_text + fill_in _('Search by Git revision'), with: filter_text end end diff --git a/spec/features/projects/branches/user_creates_branch_spec.rb b/spec/features/projects/branches/user_creates_branch_spec.rb index bf7669e9d0c..60bd77393e9 100644 --- a/spec/features/projects/branches/user_creates_branch_spec.rb +++ b/spec/features/projects/branches/user_creates_branch_spec.rb @@ -81,11 +81,7 @@ RSpec.describe 'User creates branch', :js, feature_category: :projects do it 'does not create new branch' do invalid_branch_name = '1.0 stable' - fill_in('branch_name', with: invalid_branch_name) - page.find('body').click # defocus the branch_name input - - select_branch('master') - click_button('Create branch') + create_branch(invalid_branch_name) expect(page).to have_content('Branch name is invalid') expect(page).to have_content("can't contain spaces") diff --git a/spec/frontend/work_items/components/work_item_links/work_item_link_child_metadata_spec.js b/spec/frontend/work_items/components/work_item_links/work_item_link_child_metadata_spec.js new file mode 100644 index 00000000000..47489d4796b --- /dev/null +++ b/spec/frontend/work_items/components/work_item_links/work_item_link_child_metadata_spec.js @@ -0,0 +1,67 @@ +import { GlLabel, GlAvatarsInline } from '@gitlab/ui'; + +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; + +import ItemMilestone from '~/issuable/components/issue_milestone.vue'; +import WorkItemLinkChildMetadata from '~/work_items/components/work_item_links/work_item_link_child_metadata.vue'; + +import { mockMilestone, mockAssignees, mockLabels } from '../../mock_data'; + +describe('WorkItemLinkChildMetadata', () => { + let wrapper; + + const createComponent = ({ + allowsScopedLabels = true, + milestone = mockMilestone, + assignees = mockAssignees, + labels = mockLabels, + } = {}) => { + wrapper = shallowMountExtended(WorkItemLinkChildMetadata, { + propsData: { + allowsScopedLabels, + milestone, + assignees, + labels, + }, + }); + }; + + beforeEach(() => { + createComponent(); + }); + + it('renders milestone link button', () => { + const milestoneLink = wrapper.findComponent(ItemMilestone); + + expect(milestoneLink.exists()).toBe(true); + expect(milestoneLink.props('milestone')).toEqual(mockMilestone); + }); + + it('renders avatars for assignees', () => { + const avatars = wrapper.findComponent(GlAvatarsInline); + + expect(avatars.exists()).toBe(true); + expect(avatars.props()).toMatchObject({ + avatars: mockAssignees, + collapsed: true, + maxVisible: 2, + avatarSize: 24, + badgeTooltipProp: 'name', + badgeSrOnlyText: '', + }); + }); + + it('renders labels', () => { + const labels = wrapper.findAllComponents(GlLabel); + const mockLabel = mockLabels[0]; + + expect(labels).toHaveLength(mockLabels.length); + expect(labels.at(0).props()).toMatchObject({ + title: mockLabel.title, + backgroundColor: mockLabel.color, + description: mockLabel.description, + scoped: false, + }); + expect(labels.at(1).props('scoped')).toBe(true); // Second label is scoped + }); +}); diff --git a/spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js b/spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js index 3a8e785bc80..73d498ad055 100644 --- a/spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js +++ b/spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js @@ -1,4 +1,4 @@ -import { GlButton, GlIcon } from '@gitlab/ui'; +import { GlIcon } from '@gitlab/ui'; import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; @@ -9,6 +9,7 @@ import { createAlert } from '~/flash'; import RichTimestampTooltip from '~/vue_shared/components/rich_timestamp_tooltip.vue'; import getWorkItemTreeQuery from '~/work_items/graphql/work_item_tree.query.graphql'; +import WorkItemLinkChildMetadata from '~/work_items/components/work_item_links/work_item_link_child_metadata.vue'; import WorkItemLinkChild from '~/work_items/components/work_item_links/work_item_link_child.vue'; import WorkItemLinksMenu from '~/work_items/components/work_item_links/work_item_links_menu.vue'; import WorkItemTreeChildren from '~/work_items/components/work_item_links/work_item_tree_children.vue'; @@ -21,8 +22,12 @@ import { import { workItemTask, workItemObjectiveWithChild, + workItemObjectiveNoMetadata, confidentialWorkItemTask, closedWorkItemTask, + mockMilestone, + mockAssignees, + mockLabels, workItemHierarchyTreeResponse, workItemHierarchyTreeFailureResponse, } from '../../mock_data'; @@ -101,7 +106,7 @@ describe('WorkItemLinkChild', () => { beforeEach(() => { createComponent(); - titleEl = wrapper.findComponent(GlButton); + titleEl = wrapper.findByTestId('item-title'); }); it('renders item title', () => { @@ -129,6 +134,37 @@ describe('WorkItemLinkChild', () => { }); }); + describe('item metadata', () => { + const findMetadataComponent = () => wrapper.findComponent(WorkItemLinkChildMetadata); + + beforeEach(() => { + createComponent({ + childItem: workItemObjectiveWithChild, + workItemType: WORK_ITEM_TYPE_VALUE_OBJECTIVE, + }); + }); + + it('renders item metadata component when item has metadata present', () => { + const metadataEl = findMetadataComponent(); + expect(metadataEl.exists()).toBe(true); + expect(metadataEl.props()).toMatchObject({ + allowsScopedLabels: true, + milestone: mockMilestone, + assignees: mockAssignees, + labels: mockLabels, + }); + }); + + it('does not render item metadata component when item has no metadata present', () => { + createComponent({ + childItem: workItemObjectiveNoMetadata, + workItemType: WORK_ITEM_TYPE_VALUE_OBJECTIVE, + }); + + expect(findMetadataComponent().exists()).toBe(false); + }); + }); + describe('item menu', () => { let itemMenuEl; diff --git a/spec/frontend/work_items/components/work_item_links/work_item_tree_spec.js b/spec/frontend/work_items/components/work_item_links/work_item_tree_spec.js index cc2e174dfda..96211e12755 100644 --- a/spec/frontend/work_items/components/work_item_links/work_item_tree_spec.js +++ b/spec/frontend/work_items/components/work_item_links/work_item_tree_spec.js @@ -1,17 +1,26 @@ -import { nextTick } from 'vue'; +import Vue, { nextTick } from 'vue'; +import VueApollo from 'vue-apollo'; + +import createMockApollo from 'helpers/mock_apollo_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import waitForPromises from 'helpers/wait_for_promises'; import WorkItemTree from '~/work_items/components/work_item_links/work_item_tree.vue'; import WorkItemLinksForm from '~/work_items/components/work_item_links/work_item_links_form.vue'; import WorkItemLinkChild from '~/work_items/components/work_item_links/work_item_link_child.vue'; import OkrActionsSplitButton from '~/work_items/components/work_item_links/okr_actions_split_button.vue'; +import workItemQuery from '~/work_items/graphql/work_item.query.graphql'; + +import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; + import { FORM_TYPES, WORK_ITEM_TYPE_ENUM_OBJECTIVE, WORK_ITEM_TYPE_ENUM_KEY_RESULT, } from '~/work_items/constants'; -import { childrenWorkItems } from '../../mock_data'; +import { childrenWorkItems, workItemObjectiveWithChild } from '../../mock_data'; describe('WorkItemTree', () => { + let getWorkItemQueryHandler; let wrapper; const findToggleButton = () => wrapper.findByTestId('toggle-tree'); @@ -21,10 +30,31 @@ describe('WorkItemTree', () => { const findForm = () => wrapper.findComponent(WorkItemLinksForm); const findWorkItemLinkChildItems = () => wrapper.findAllComponents(WorkItemLinkChild); - const createComponent = ({ children = childrenWorkItems } = {}) => { + Vue.use(VueApollo); + + const createComponent = ({ + workItemType = 'Objective', + children = childrenWorkItems, + apolloProvider = null, + } = {}) => { + const mockWorkItemResponse = { + data: { + workItem: { + ...workItemObjectiveWithChild, + workItemType: { + ...workItemObjectiveWithChild.workItemType, + name: workItemType, + }, + }, + }, + }; + getWorkItemQueryHandler = jest.fn().mockResolvedValue(mockWorkItemResponse); + wrapper = shallowMountExtended(WorkItemTree, { + apolloProvider: + apolloProvider || createMockApollo([[workItemQuery, getWorkItemQueryHandler]]), propsData: { - workItemType: 'Objective', + workItemType, workItemId: 'gid://gitlab/WorkItem/515', children, projectPath: 'test/project', @@ -91,4 +121,27 @@ describe('WorkItemTree', () => { expect(wrapper.emitted('removeChild')).toEqual([['gid://gitlab/WorkItem/2']]); }); + + it.each` + description | workItemType | prefetch + ${'prefetches'} | ${'Issue'} | ${true} + ${'does not prefetch'} | ${'Objective'} | ${false} + `( + '$description work-item-link-child on mouseover when workItemType is "$workItemType"', + async ({ workItemType, prefetch }) => { + createComponent({ workItemType }); + const firstChild = findWorkItemLinkChildItems().at(0); + firstChild.vm.$emit('mouseover', childrenWorkItems[0]); + await nextTick(); + await waitForPromises(); + + jest.advanceTimersByTime(DEFAULT_DEBOUNCE_AND_THROTTLE_MS); + + if (prefetch) { + expect(getWorkItemQueryHandler).toHaveBeenCalled(); + } else { + expect(getWorkItemQueryHandler).not.toHaveBeenCalled(); + } + }, + ); }); diff --git a/spec/frontend/work_items/mock_data.js b/spec/frontend/work_items/mock_data.js index ed9c3f906b9..f7301701dc3 100644 --- a/spec/frontend/work_items/mock_data.js +++ b/spec/frontend/work_items/mock_data.js @@ -36,6 +36,16 @@ export const mockLabels = [ }, ]; +export const mockMilestone = { + __typename: 'Milestone', + id: 'gid://gitlab/Milestone/30', + title: 'v4.0', + state: 'active', + expired: false, + startDate: '2022-10-17', + dueDate: '2022-10-24', +}; + export const workItemQueryResponse = { data: { workItem: { @@ -359,11 +369,7 @@ export const workItemResponseFactory = ({ ? { __typename: 'WorkItemWidgetMilestone', type: 'MILESTONE', - milestone: { - expired: false, - id: 'gid://gitlab/Milestone/30', - title: 'v4.0', - }, + milestone: mockMilestone, } : { type: 'MOCK TYPE' }, { @@ -937,7 +943,17 @@ export const workItemObjectiveWithChild = { iconName: 'issue-type-objective', __typename: 'WorkItemType', }, + project: { + __typename: 'Project', + id: '1', + fullPath: 'test-project-path', + }, + userPermissions: { + deleteWorkItem: true, + updateWorkItem: true, + }, title: 'Objective', + description: 'Objective description', state: 'OPEN', confidential: false, createdAt: '2022-08-03T12:41:54Z', @@ -946,12 +962,51 @@ export const workItemObjectiveWithChild = { { type: 'HIERARCHY', hasChildren: true, + parent: null, + children: { + nodes: [], + }, __typename: 'WorkItemWidgetHierarchy', }, + { + type: 'MILESTONE', + __typename: 'WorkItemWidgetMilestone', + milestone: mockMilestone, + }, + { + type: 'ASSIGNEES', + __typename: 'WorkItemWidgetAssignees', + canInviteMembers: true, + allowsMultipleAssignees: true, + assignees: { + __typename: 'UserCoreConnection', + nodes: mockAssignees, + }, + }, + { + type: 'LABELS', + __typename: 'WorkItemWidgetLabels', + allowsScopedLabels: true, + labels: { + __typename: 'LabelConnection', + nodes: mockLabels, + }, + }, ], __typename: 'WorkItem', }; +export const workItemObjectiveNoMetadata = { + ...workItemObjectiveWithChild, + widgets: [ + { + type: 'HIERARCHY', + hasChildren: true, + __typename: 'WorkItemWidgetHierarchy', + }, + ], +}; + export const workItemHierarchyTreeResponse = { data: { workItem: { diff --git a/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb b/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb index 1bcb7fec327..73ba49bf4ed 100644 --- a/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb @@ -35,7 +35,8 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_fail end_line: end_line, github_id: 1, diff_hunk: diff_hunk, - side: 'RIGHT' + side: 'RIGHT', + discussion_id: discussion_id ) end @@ -114,10 +115,6 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_fail .to receive(:database_id) .and_return(merge_request.id) end - - expect(Discussion) - .to receive(:discussion_id) - .and_return(discussion_id) end it_behaves_like 'diff notes without suggestion' diff --git a/spec/lib/gitlab/github_import/representation/diff_note_spec.rb b/spec/lib/gitlab/github_import/representation/diff_note_spec.rb index a656cd0d056..56fabe854f9 100644 --- a/spec/lib/gitlab/github_import/representation/diff_note_spec.rb +++ b/spec/lib/gitlab/github_import/representation/diff_note_spec.rb @@ -128,64 +128,6 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote, :clean_gitlab_red end end - describe '#discussion_id' do - before do - note.project = project - note.merge_request = merge_request - end - - context 'when the note is a reply to a discussion' do - it 'uses the cached value as the discussion_id only when responding an existing discussion' do - expect(Discussion) - .to receive(:discussion_id) - .and_return('FIRST_DISCUSSION_ID', 'SECOND_DISCUSSION_ID') - - # Creates the first discussion id and caches its value - expect(note.discussion_id) - .to eq('FIRST_DISCUSSION_ID') - - reply_note = described_class.from_json_hash( - 'note_id' => note.note_id + 1, - 'in_reply_to_id' => note.note_id - ) - reply_note.project = project - reply_note.merge_request = merge_request - - # Reading from the cached value - expect(reply_note.discussion_id) - .to eq('FIRST_DISCUSSION_ID') - - new_discussion_note = described_class.from_json_hash( - 'note_id' => note.note_id + 2, - 'in_reply_to_id' => nil - ) - new_discussion_note.project = project - new_discussion_note.merge_request = merge_request - - # Because it's a new discussion, it must not use the cached value - expect(new_discussion_note.discussion_id) - .to eq('SECOND_DISCUSSION_ID') - end - - context 'when cached value does not exist' do - it 'falls back to generating a new discussion_id' do - expect(Discussion) - .to receive(:discussion_id) - .and_return('NEW_DISCUSSION_ID') - - reply_note = described_class.from_json_hash( - 'note_id' => note.note_id + 1, - 'in_reply_to_id' => note.note_id - ) - reply_note.project = project - reply_note.merge_request = merge_request - - expect(reply_note.discussion_id).to eq('NEW_DISCUSSION_ID') - end - end - end - end - describe '#github_identifiers' do it 'returns a hash with needed identifiers' do expect(note.github_identifiers).to eq( @@ -273,27 +215,40 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote, :clean_gitlab_red end describe '.from_api_response' do - it_behaves_like 'a DiffNote representation' do - let(:response) do - { - id: note_id, - html_url: 'https://github.com/foo/bar/pull/42', - path: 'README.md', - commit_id: '123abc', - original_commit_id: 'original123abc', - side: side, - user: user_data, - diff_hunk: hunk, - body: note_body, - created_at: created_at, - updated_at: updated_at, - line: end_line, - start_line: start_line, - in_reply_to_id: in_reply_to_id - } - end + let(:response) do + { + id: note_id, + html_url: 'https://github.com/foo/bar/pull/42', + path: 'README.md', + commit_id: '123abc', + original_commit_id: 'original123abc', + side: side, + user: user_data, + diff_hunk: hunk, + body: note_body, + created_at: created_at, + updated_at: updated_at, + line: end_line, + start_line: start_line, + in_reply_to_id: in_reply_to_id + } + end + + subject(:note) { described_class.from_api_response(response) } + + it_behaves_like 'a DiffNote representation' + + describe '#discussion_id' do + it 'finds or generates discussion_id value' do + discussion_id = 'discussion_id' + discussion_id_class = Gitlab::GithubImport::Representation::DiffNotes::DiscussionId - subject(:note) { described_class.from_api_response(response) } + expect_next_instance_of(discussion_id_class, response) do |discussion_id_object| + expect(discussion_id_object).to receive(:find_or_generate).and_return(discussion_id) + end + + expect(note.discussion_id).to eq(discussion_id) + end end end @@ -302,6 +257,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote, :clean_gitlab_red let(:hash) do { 'note_id' => note_id, + 'html_url' => 'https://github.com/foo/bar/pull/42', 'noteable_type' => 'MergeRequest', 'noteable_id' => 42, 'file_path' => 'README.md', @@ -315,7 +271,8 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote, :clean_gitlab_red 'updated_at' => updated_at.to_s, 'end_line' => end_line, 'start_line' => start_line, - 'in_reply_to_id' => in_reply_to_id + 'in_reply_to_id' => in_reply_to_id, + 'discussion_id' => 'FIRST_DISCUSSION_ID' } end diff --git a/spec/lib/gitlab/github_import/representation/diff_notes/discussion_id_spec.rb b/spec/lib/gitlab/github_import/representation/diff_notes/discussion_id_spec.rb new file mode 100644 index 00000000000..64a16516e07 --- /dev/null +++ b/spec/lib/gitlab/github_import/representation/diff_notes/discussion_id_spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::GithubImport::Representation::DiffNotes::DiscussionId, :clean_gitlab_redis_cache, + feature_category: :importers do + describe '#discussion_id' do + let(:hunk) do + '@@ -1 +1 @@ + -Hello + +Hello world' + end + + let(:note_id) { 1 } + let(:html_url) { 'https://github.com/foo/project_name/pull/42' } + let(:note) do + { + id: note_id, + html_url: html_url, + path: 'README.md', + commit_id: '123abc', + original_commit_id: 'original123abc', + side: 'RIGHT', + user: { id: 4, login: 'alice' }, + diff_hunk: hunk, + body: 'Hello world', + created_at: Time.new(2017, 1, 1, 12, 10).utc, + updated_at: Time.new(2017, 1, 1, 12, 15).utc, + line: 23, + start_line: nil, + in_reply_to_id: nil + } + end + + context 'when the note is not a reply to a discussion' do + subject(:discussion_id) { described_class.new(note).find_or_generate } + + it 'generates and caches new discussion_id' do + expect(Discussion) + .to receive(:discussion_id) + .and_return('FIRST_DISCUSSION_ID') + + expect(Gitlab::Cache::Import::Caching).to receive(:write).with( + "github-importer/discussion-id-map/project_name/42/#{note_id}", + 'FIRST_DISCUSSION_ID' + ).and_return('FIRST_DISCUSSION_ID') + + expect(discussion_id).to eq('FIRST_DISCUSSION_ID') + end + end + + context 'when the note is a reply to a discussion' do + let(:reply_note) do + { + note_id: note_id + 1, + in_reply_to_id: note_id, + html_url: html_url + } + end + + subject(:discussion_id) { described_class.new(reply_note).find_or_generate } + + it 'uses the cached value as the discussion_id' do + expect(Discussion) + .to receive(:discussion_id) + .and_return('FIRST_DISCUSSION_ID') + + described_class.new(note).find_or_generate + + expect(discussion_id).to eq('FIRST_DISCUSSION_ID') + end + + context 'when cached value does not exist' do + it 'falls back to generating a new discussion_id' do + expect(Discussion) + .to receive(:discussion_id) + .and_return('NEW_DISCUSSION_ID') + + expect(discussion_id).to eq('NEW_DISCUSSION_ID') + end + end + end + end +end diff --git a/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb b/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb index 6c6121c70e4..899074399a1 100644 --- a/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb +++ b/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb @@ -10,11 +10,12 @@ RSpec.describe UpdateImportSourcesOnApplicationSettings, feature_category: :migr describe "#up" do it 'removes google_code and preserves existing valid import sources' do - settings.create!(import_sources: import_sources_with_google) + record = settings.create!(import_sources: import_sources_with_google.to_yaml) migrate! - expect(YAML.safe_load(ApplicationSetting.last.import_sources)).to eq(import_sources_without_google) + expect(record.reload.import_sources).to start_with('---') + expect(ApplicationSetting.last.import_sources).to eq(import_sources_without_google) end end end diff --git a/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb b/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb new file mode 100644 index 00000000000..e5b20b2d48a --- /dev/null +++ b/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixUpdateImportSourcesOnApplicationSettings, feature_category: :migration do + let(:settings) { table(:application_settings) } + let(:import_sources) { %w[github git bitbucket bitbucket_server] } + + describe "#up" do + shared_examples 'fixes import_sources on application_settings' do + it 'ensures YAML is stored' do + record = settings.create!(import_sources: data) + + migrate! + + expect(record.reload.import_sources).to start_with('---') + expect(ApplicationSetting.last.import_sources).to eq(import_sources) + end + end + + context 'when import_sources is a String' do + let(:data) { import_sources.to_s } + + it_behaves_like 'fixes import_sources on application_settings' + end + + context 'when import_sources is already YAML' do + let(:data) { import_sources.to_yaml } + + it_behaves_like 'fixes import_sources on application_settings' + end + end +end diff --git a/spec/support/helpers/features/branches_helpers.rb b/spec/support/helpers/features/branches_helpers.rb index 2a50b41cb4e..d4f96718cc0 100644 --- a/spec/support/helpers/features/branches_helpers.rb +++ b/spec/support/helpers/features/branches_helpers.rb @@ -22,10 +22,14 @@ module Spec end def select_branch(branch_name) - find(".js-branch-select").click + ref_selector = '.ref-selector' + find(ref_selector).click + wait_for_requests - page.within("#new-branch-form .dropdown-menu") do - click_link(branch_name) + page.within(ref_selector) do + fill_in _('Search by Git revision'), with: branch_name + wait_for_requests + find('li', text: branch_name, match: :prefer_exact).click end end end diff --git a/spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb b/spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb index 15bc55c1526..c92741e8f10 100644 --- a/spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb +++ b/spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb @@ -14,6 +14,7 @@ RSpec.describe Gitlab::GithubImport::ImportDiffNoteWorker do hash = { 'noteable_id' => 42, 'github_id' => 42, + 'html_url' => 'https://github.com/foo/bar/pull/42', 'path' => 'README.md', 'commit_id' => '123abc', 'diff_hunk' => "@@ -1 +1 @@\n-Hello\n+Hello world", |