Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-04 18:10:27 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-04 18:10:27 +0300
commitd984d4a092018d86eec724a06ce2e6c066c3fb44 (patch)
treeb72454a613480658d9b2b14b74eb7b8c75858544 /spec
parent30a8e054751fe9020a9ed526434db83af35b4718 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/issues/user_creates_branch_and_merge_request_spec.rb19
-rw-r--r--spec/frontend/issues/create_merge_request_dropdown_spec.js25
-rw-r--r--spec/frontend/vue_merge_request_widget/mock_data.js2
-rw-r--r--spec/frontend/vue_shared/components/groups_list/groups_list_item_spec.js182
-rw-r--r--spec/frontend/vue_shared/components/groups_list/groups_list_spec.js34
-rw-r--r--spec/frontend/vue_shared/components/groups_list/mock_data.js35
-rw-r--r--spec/lib/gitlab/tracking/standard_context_spec.rb48
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