diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-04 18:10:27 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-04 18:10:27 +0300 |
commit | d984d4a092018d86eec724a06ce2e6c066c3fb44 (patch) | |
tree | b72454a613480658d9b2b14b74eb7b8c75858544 /spec | |
parent | 30a8e054751fe9020a9ed526434db83af35b4718 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
7 files changed, 287 insertions, 58 deletions
diff --git a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb index ecb899a7ca2..0c50b7b2475 100644 --- a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb +++ b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb @@ -112,6 +112,18 @@ RSpec.describe 'User creates branch and merge request on issue page', :js, featu expect(page).to have_selector('.ref-selector', text: branch_name) expect(page).to have_current_path project_tree_path(project, branch_name), ignore_query: true end + + context 'when source branch is non-default' do + let(:source_branch) { 'feature' } + + it 'creates a branch' do + select_dropdown_option('create-branch', branch_name, source_branch) + wait_for_requests + + expect(page).to have_selector('.ref-selector', text: branch_name) + expect(page).to have_current_path project_tree_path(project, branch_name), ignore_query: true + end + end end context 'when branch name is invalid' do @@ -231,12 +243,13 @@ RSpec.describe 'User creates branch and merge request on issue page', :js, featu private - def select_dropdown_option(option, branch_name = nil) + def select_dropdown_option(option, branch_name = nil, source_branch = nil) find('.create-mr-dropdown-wrap .dropdown-toggle').click find("li[data-value='#{option}']").click - if branch_name - find('.js-branch-name').set(branch_name) + if branch_name || source_branch + find('.js-branch-name').set(branch_name) if branch_name + find('.js-ref').set(source_branch) if source_branch # Javascript debounces AJAX calls. # So we have to wait until AJAX requests are started. diff --git a/spec/frontend/issues/create_merge_request_dropdown_spec.js b/spec/frontend/issues/create_merge_request_dropdown_spec.js index 21ae844e2dd..54dc07688df 100644 --- a/spec/frontend/issues/create_merge_request_dropdown_spec.js +++ b/spec/frontend/issues/create_merge_request_dropdown_spec.js @@ -51,31 +51,6 @@ describe('CreateMergeRequestDropdown', () => { }); }); - describe('updateCreatePaths', () => { - it('escapes branch names correctly', () => { - dropdown.createBranchPath = `${TEST_HOST}/branches?branch_name=some-branch&issue=42`; - dropdown.createMrPath = `${TEST_HOST}/create_merge_request?merge_request%5Bsource_branch%5D=test&merge_request%5Btarget_branch%5D=master&merge_request%5Bissue_iid%5D=42`; - - dropdown.updateCreatePaths('branch', 'contains#hash'); - - expect(dropdown.createBranchPath).toBe( - `${TEST_HOST}/branches?branch_name=contains%23hash&issue=42`, - ); - - expect(dropdown.createMrPath).toBe( - `${TEST_HOST}/create_merge_request?merge_request%5Bsource_branch%5D=contains%23hash&merge_request%5Btarget_branch%5D=master&merge_request%5Bissue_iid%5D=42`, - ); - - expect(dropdown.wrapperEl.dataset.createBranchPath).toBe( - `${TEST_HOST}/branches?branch_name=contains%23hash&issue=42`, - ); - - expect(dropdown.wrapperEl.dataset.createMrPath).toBe( - `${TEST_HOST}/create_merge_request?merge_request%5Bsource_branch%5D=contains%23hash&merge_request%5Btarget_branch%5D=master&merge_request%5Bissue_iid%5D=42`, - ); - }); - }); - describe('enable', () => { beforeEach(() => { dropdown.createMergeRequestButton.classList.add('disabled'); diff --git a/spec/frontend/vue_merge_request_widget/mock_data.js b/spec/frontend/vue_merge_request_widget/mock_data.js index 9da687c0ff8..5b3f533f34e 100644 --- a/spec/frontend/vue_merge_request_widget/mock_data.js +++ b/spec/frontend/vue_merge_request_widget/mock_data.js @@ -332,7 +332,7 @@ export default { base_path: 'blob_path', head_path: 'blob_path', }, - codequality_reports_path: 'codequality_reports.json', + codequality_reports_path: '', codequality_help_path: 'code_quality.html', target_branch_path: '/root/acets-app/branches/main', source_branch_path: '/root/acets-app/branches/daaaa', diff --git a/spec/frontend/vue_shared/components/groups_list/groups_list_item_spec.js b/spec/frontend/vue_shared/components/groups_list/groups_list_item_spec.js new file mode 100644 index 00000000000..877de4f4695 --- /dev/null +++ b/spec/frontend/vue_shared/components/groups_list/groups_list_item_spec.js @@ -0,0 +1,182 @@ +import { GlAvatarLabeled, GlIcon } from '@gitlab/ui'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; +import GroupsListItem from '~/vue_shared/components/groups_list/groups_list_item.vue'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import { + VISIBILITY_TYPE_ICON, + VISIBILITY_LEVEL_INTERNAL_STRING, + GROUP_VISIBILITY_TYPE, +} from '~/visibility_level/constants'; +import UserAccessRoleBadge from '~/vue_shared/components/user_access_role_badge.vue'; +import { ACCESS_LEVEL_LABELS } from '~/access_level/constants'; +import { groups } from './mock_data'; + +describe('GroupsListItem', () => { + let wrapper; + + const [group] = groups; + + const defaultPropsData = { group }; + + const createComponent = ({ propsData = {} } = {}) => { + wrapper = mountExtended(GroupsListItem, { + propsData: { ...defaultPropsData, ...propsData }, + directives: { + GlTooltip: createMockDirective('gl-tooltip'), + }, + }); + }; + + const findAvatarLabeled = () => wrapper.findComponent(GlAvatarLabeled); + const findGroupDescription = () => wrapper.findByTestId('group-description'); + const findVisibilityIcon = () => findAvatarLabeled().findComponent(GlIcon); + + it('renders group avatar', () => { + createComponent(); + + const avatarLabeled = findAvatarLabeled(); + + expect(avatarLabeled.props()).toMatchObject({ + label: group.fullName, + labelLink: group.webUrl, + }); + + expect(avatarLabeled.attributes()).toMatchObject({ + 'entity-id': group.id.toString(), + 'entity-name': group.fullName, + shape: 'rect', + }); + }); + + it('renders visibility icon with tooltip', () => { + createComponent(); + + const icon = findAvatarLabeled().findComponent(GlIcon); + const tooltip = getBinding(icon.element, 'gl-tooltip'); + + expect(icon.props('name')).toBe(VISIBILITY_TYPE_ICON[VISIBILITY_LEVEL_INTERNAL_STRING]); + expect(tooltip.value).toBe(GROUP_VISIBILITY_TYPE[VISIBILITY_LEVEL_INTERNAL_STRING]); + }); + + it('renders subgroup count', () => { + createComponent(); + + const countWrapper = wrapper.findByTestId('subgroups-count'); + const tooltip = getBinding(countWrapper.element, 'gl-tooltip'); + + expect(tooltip.value).toBe(GroupsListItem.i18n.subgroups); + expect(countWrapper.text()).toBe(group.descendantGroupsCount.toString()); + expect(countWrapper.findComponent(GlIcon).props('name')).toBe('subgroup'); + }); + + it('renders projects count', () => { + createComponent(); + + const countWrapper = wrapper.findByTestId('projects-count'); + const tooltip = getBinding(countWrapper.element, 'gl-tooltip'); + + expect(tooltip.value).toBe(GroupsListItem.i18n.projects); + expect(countWrapper.text()).toBe(group.projectsCount.toString()); + expect(countWrapper.findComponent(GlIcon).props('name')).toBe('project'); + }); + + it('renders members count', () => { + createComponent(); + + const countWrapper = wrapper.findByTestId('members-count'); + const tooltip = getBinding(countWrapper.element, 'gl-tooltip'); + + expect(tooltip.value).toBe(GroupsListItem.i18n.directMembers); + expect(countWrapper.text()).toBe(group.groupMembersCount.toString()); + expect(countWrapper.findComponent(GlIcon).props('name')).toBe('users'); + }); + + describe('when visibility is not provided', () => { + it('does not render visibility icon', () => { + const { visibility, ...groupWithoutVisibility } = group; + createComponent({ + propsData: { + group: groupWithoutVisibility, + }, + }); + + expect(findVisibilityIcon().exists()).toBe(false); + }); + }); + + it('renders access role badge', () => { + createComponent(); + + expect(findAvatarLabeled().findComponent(UserAccessRoleBadge).text()).toBe( + ACCESS_LEVEL_LABELS[group.accessLevel.integerValue], + ); + }); + + describe('when group has a description', () => { + it('renders description', () => { + const descriptionHtml = '<p>Foo bar</p>'; + + createComponent({ + propsData: { + group: { + ...group, + descriptionHtml, + }, + }, + }); + + expect(findGroupDescription().element.innerHTML).toBe(descriptionHtml); + }); + }); + + describe('when group does not have a description', () => { + it('does not render description', () => { + createComponent({ + propsData: { + group: { + ...group, + descriptionHtml: null, + }, + }, + }); + + expect(findGroupDescription().exists()).toBe(false); + }); + }); + + describe('when `showGroupIcon` prop is `true`', () => { + describe('when `parent` attribute is `null`', () => { + it('shows group icon', () => { + createComponent({ propsData: { showGroupIcon: true } }); + + expect(wrapper.findByTestId('group-icon').exists()).toBe(true); + }); + }); + + describe('when `parent` attribute is set', () => { + it('shows subgroup icon', () => { + createComponent({ + propsData: { + showGroupIcon: true, + group: { + ...group, + parent: { + id: 'gid://gitlab/Group/35', + }, + }, + }, + }); + + expect(wrapper.findByTestId('subgroup-icon').exists()).toBe(true); + }); + }); + }); + + describe('when `showGroupIcon` prop is `false`', () => { + it('does not show group icon', () => { + createComponent(); + + expect(wrapper.findByTestId('group-icon').exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/vue_shared/components/groups_list/groups_list_spec.js b/spec/frontend/vue_shared/components/groups_list/groups_list_spec.js new file mode 100644 index 00000000000..c65aa347bcf --- /dev/null +++ b/spec/frontend/vue_shared/components/groups_list/groups_list_spec.js @@ -0,0 +1,34 @@ +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import GroupsList from '~/vue_shared/components/groups_list/groups_list.vue'; +import GroupsListItem from '~/vue_shared/components/groups_list/groups_list_item.vue'; +import { groups } from './mock_data'; + +describe('GroupsList', () => { + let wrapper; + + const defaultPropsData = { + groups, + }; + + const createComponent = () => { + wrapper = shallowMountExtended(GroupsList, { + propsData: defaultPropsData, + }); + }; + + it('renders list with `GroupsListItem` component', () => { + createComponent(); + + const groupsListItemWrappers = wrapper.findAllComponents(GroupsListItem).wrappers; + const expectedProps = groupsListItemWrappers.map((groupsListItemWrapper) => + groupsListItemWrapper.props(), + ); + + expect(expectedProps).toEqual( + defaultPropsData.groups.map((group) => ({ + group, + showGroupIcon: false, + })), + ); + }); +}); diff --git a/spec/frontend/vue_shared/components/groups_list/mock_data.js b/spec/frontend/vue_shared/components/groups_list/mock_data.js new file mode 100644 index 00000000000..0dad27f8311 --- /dev/null +++ b/spec/frontend/vue_shared/components/groups_list/mock_data.js @@ -0,0 +1,35 @@ +export const groups = [ + { + id: 1, + fullName: 'Gitlab Org', + parent: null, + webUrl: 'http://127.0.0.1:3000/groups/gitlab-org', + descriptionHtml: + '<p data-sourcepos="1:1-1:64" dir="auto">Dolorem dolorem omnis impedit cupiditate pariatur officia velit. Fusce eget orci a ipsum tempus vehicula. Donec rhoncus ante sed lacus pharetra, vitae imperdiet felis lobortis. Donec maximus dapibus orci, sit amet euismod dolor rhoncus vel. In nec mauris nibh.</p>', + avatarUrl: null, + descendantGroupsCount: 1, + projectsCount: 1, + groupMembersCount: 2, + visibility: 'internal', + accessLevel: { + integerValue: 10, + }, + }, + { + id: 2, + fullName: 'Gitlab Org / test subgroup', + parent: { + id: 1, + }, + webUrl: 'http://127.0.0.1:3000/groups/gitlab-org/test-subgroup', + descriptionHtml: '', + avatarUrl: null, + descendantGroupsCount: 4, + projectsCount: 4, + groupMembersCount: 4, + visibility: 'private', + accessLevel: { + integerValue: 20, + }, + }, +]; diff --git a/spec/lib/gitlab/tracking/standard_context_spec.rb b/spec/lib/gitlab/tracking/standard_context_spec.rb index e1ae362e797..c44cfdea1cd 100644 --- a/spec/lib/gitlab/tracking/standard_context_spec.rb +++ b/spec/lib/gitlab/tracking/standard_context_spec.rb @@ -3,10 +3,6 @@ require 'spec_helper' RSpec.describe Gitlab::Tracking::StandardContext do - let_it_be(:project) { create(:project) } - let_it_be(:namespace) { create(:namespace) } - let_it_be(:user) { create(:user) } - let(:snowplow_context) { subject.to_context } describe '#to_context' do @@ -62,21 +58,27 @@ RSpec.describe Gitlab::Tracking::StandardContext do expect(snowplow_context.to_json.dig(:data, :context_generated_at)).to eq(Time.current) end - context 'plan' do - context 'when namespace is not available' do - it 'is nil' do - expect(snowplow_context.to_json.dig(:data, :plan)).to be_nil - end - end + it 'contains standard properties' do + standard_properties = [:user_id, :project_id, :namespace_id, :plan] + expect(snowplow_context.to_json[:data].keys).to include(*standard_properties) + end - context 'when namespace is available' do - let(:namespace) { create(:namespace) } + context 'with standard properties' do + let(:user_id) { 1 } + let(:project_id) { 2 } + let(:namespace_id) { 3 } + let(:plan_name) { "plan name" } - subject { described_class.new(namespace_id: namespace.id, plan_name: namespace.actual_plan_name) } + subject do + described_class.new(user_id: user_id, project_id: project_id, namespace_id: namespace_id, plan_name: plan_name) + end - it 'contains plan name' do - expect(snowplow_context.to_json.dig(:data, :plan)).to eq(Plan::DEFAULT) - end + it 'holds the correct values', :aggregate_failures do + json_data = snowplow_context.to_json.fetch(:data) + expect(json_data[:user_id]).to eq(user_id) + expect(json_data[:project_id]).to eq(project_id) + expect(json_data[:namespace_id]).to eq(namespace_id) + expect(json_data[:plan]).to eq(plan_name) end end @@ -95,24 +97,12 @@ RSpec.describe Gitlab::Tracking::StandardContext do end context 'with incorrect argument type' do - subject { described_class.new(project_id: create(:group)) } + subject { described_class.new(project_id: "a string") } it 'does call `track_and_raise_for_dev_exception`' do expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception) snowplow_context end end - - it 'contains user id' do - expect(snowplow_context.to_json[:data].keys).to include(:user_id) - end - - it 'contains namespace and project ids' do - expect(snowplow_context.to_json[:data].keys).to include(:project_id, :namespace_id) - end - - it 'accepts just project id as integer' do - expect { described_class.new(project: 1).to_context }.not_to raise_error - end end end |