mirror of
https://github.com/gitlabhq/gitlabhq.git
synced 2025-08-15 23:30:46 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
@ -316,7 +316,6 @@ Layout/EmptyLineAfterMagicComment:
|
||||
- 'ee/spec/graphql/mutations/vulnerabilities/revert_to_detected_spec.rb'
|
||||
- 'ee/spec/helpers/ee/auth_helper_spec.rb'
|
||||
- 'ee/spec/helpers/ee/geo_helper_spec.rb'
|
||||
- 'ee/spec/helpers/ee/invite_members_helper_spec.rb'
|
||||
- 'ee/spec/helpers/ee/namespaces_helper_spec.rb'
|
||||
- 'ee/spec/helpers/ee/saml_providers_helper_spec.rb'
|
||||
- 'ee/spec/helpers/roadmaps_helper_spec.rb'
|
||||
|
@ -1,28 +1,14 @@
|
||||
<script>
|
||||
import {
|
||||
GlAlert,
|
||||
GlCollapsibleListbox,
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
GlFormCheckboxGroup,
|
||||
GlButton,
|
||||
GlCollapse,
|
||||
GlIcon,
|
||||
} from '@gitlab/ui';
|
||||
import { GlAlert, GlButton, GlCollapse, GlIcon } from '@gitlab/ui';
|
||||
import { partition, isString, uniqueId, isEmpty } from 'lodash';
|
||||
import InviteModalBase from 'ee_else_ce/invite_members/components/invite_modal_base.vue';
|
||||
import Api from '~/api';
|
||||
import Tracking from '~/tracking';
|
||||
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
|
||||
import { n__, sprintf } from '~/locale';
|
||||
import {
|
||||
memberName,
|
||||
triggerExternalAlert,
|
||||
qualifiesForTasksToBeDone,
|
||||
} from 'ee_else_ce/invite_members/utils/member_utils';
|
||||
import { memberName, triggerExternalAlert } from 'ee_else_ce/invite_members/utils/member_utils';
|
||||
import {
|
||||
USERS_FILTER_ALL,
|
||||
INVITE_MEMBERS_FOR_TASK,
|
||||
MEMBER_MODAL_LABELS,
|
||||
INVITE_MEMBER_MODAL_TRACKING_CATEGORY,
|
||||
} from '../constants';
|
||||
@ -41,10 +27,6 @@ export default {
|
||||
name: 'InviteMembersModal',
|
||||
components: {
|
||||
GlAlert,
|
||||
GlLink,
|
||||
GlCollapsibleListbox,
|
||||
GlSprintf,
|
||||
GlFormCheckboxGroup,
|
||||
GlButton,
|
||||
GlCollapse,
|
||||
GlIcon,
|
||||
@ -56,7 +38,6 @@ export default {
|
||||
import('ee_component/invite_members/components/active_trial_notification.vue'),
|
||||
},
|
||||
mixins: [Tracking.mixin({ category: INVITE_MEMBER_MODAL_TRACKING_CATEGORY })],
|
||||
inject: ['newProjectPath'],
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
@ -96,14 +77,6 @@ export default {
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
tasksToBeDoneOptions: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
projects: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
fullPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
@ -131,9 +104,6 @@ export default {
|
||||
modalId: uniqueId('invite-members-modal-'),
|
||||
newUsersToInvite: [],
|
||||
invalidMembers: {},
|
||||
selectedTasksToBeDone: [],
|
||||
selectedTaskProject: this.projects[0],
|
||||
selectedTaskProjectId: this.projects[0]?.id,
|
||||
source: 'unknown',
|
||||
mode: 'default',
|
||||
// Kept in sync with "base"
|
||||
@ -141,7 +111,6 @@ export default {
|
||||
errorsLimit: 2,
|
||||
isErrorsSectionExpanded: false,
|
||||
shouldShowEmptyInvitesAlert: false,
|
||||
projectsForDropdown: this.projects.map((p) => ({ value: p.id, text: p.title, ...p })),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -170,26 +139,6 @@ export default {
|
||||
this.errorList.length,
|
||||
);
|
||||
},
|
||||
tasksToBeDoneEnabled() {
|
||||
return qualifiesForTasksToBeDone(this.source) && this.tasksToBeDoneOptions.length;
|
||||
},
|
||||
showTasksToBeDone() {
|
||||
return (
|
||||
this.tasksToBeDoneEnabled &&
|
||||
this.selectedAccessLevel >= INVITE_MEMBERS_FOR_TASK.minimum_access_level
|
||||
);
|
||||
},
|
||||
showTaskProjects() {
|
||||
return !this.isProject && this.selectedTasksToBeDone.length;
|
||||
},
|
||||
tasksToBeDoneForPost() {
|
||||
return this.showTasksToBeDone ? this.selectedTasksToBeDone : [];
|
||||
},
|
||||
tasksProjectForPost() {
|
||||
return this.showTasksToBeDone && this.selectedTasksToBeDone.length
|
||||
? this.selectedTaskProject.id
|
||||
: '';
|
||||
},
|
||||
showUserLimitNotification() {
|
||||
return !isEmpty(this.usersLimitDataset.alertVariant);
|
||||
},
|
||||
@ -285,8 +234,6 @@ export default {
|
||||
expires_at: expiresAt,
|
||||
access_level: accessLevel,
|
||||
invite_source: this.source,
|
||||
tasks_to_be_done: this.tasksToBeDoneForPost,
|
||||
tasks_project_id: this.tasksProjectForPost,
|
||||
...email,
|
||||
...userId,
|
||||
};
|
||||
@ -300,8 +247,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.trackInviteMembersForTask();
|
||||
|
||||
const apiAddByInvite = this.isProject
|
||||
? Api.inviteProjectMembers.bind(Api)
|
||||
: Api.inviteGroupMembers.bind(Api);
|
||||
@ -335,11 +280,6 @@ export default {
|
||||
// initial token creation hits this and nothing is found... so safe navigation
|
||||
return this.newUsersToInvite.find((member) => memberName(member) === username)?.name;
|
||||
},
|
||||
trackInviteMembersForTask() {
|
||||
const label = 'selected_tasks_to_be_done';
|
||||
const property = this.selectedTasksToBeDone.join(',');
|
||||
this.track(INVITE_MEMBERS_FOR_TASK.submit, { label, property });
|
||||
},
|
||||
onCancel() {
|
||||
this.track('click_cancel', { label: this.source });
|
||||
},
|
||||
@ -351,11 +291,6 @@ export default {
|
||||
this.isLoading = false;
|
||||
this.shouldShowEmptyInvitesAlert = false;
|
||||
this.newUsersToInvite = [];
|
||||
this.selectedTasksToBeDone = [];
|
||||
[this.selectedTaskProject] = this.projects;
|
||||
},
|
||||
changeSelectedTaskProject(projectId) {
|
||||
this.selectedTaskProject = this.projects.find((project) => project.id === projectId);
|
||||
},
|
||||
onInviteSuccess() {
|
||||
this.track('invite_successful', { label: this.source });
|
||||
@ -513,46 +448,5 @@ export default {
|
||||
@token-remove="removeToken"
|
||||
/>
|
||||
</template>
|
||||
<template #form-after>
|
||||
<div v-if="showTasksToBeDone" data-testid="invite-members-modal-tasks-to-be-done">
|
||||
<label class="gl-mt-5">
|
||||
{{ $options.labels.tasksToBeDone.title }}
|
||||
</label>
|
||||
<template v-if="projects.length">
|
||||
<gl-form-checkbox-group
|
||||
v-model="selectedTasksToBeDone"
|
||||
:options="tasksToBeDoneOptions"
|
||||
data-testid="invite-members-modal-tasks"
|
||||
/>
|
||||
<template v-if="showTaskProjects">
|
||||
<label class="gl-mt-5 gl-display-block">
|
||||
{{ $options.labels.tasksProject.title }}
|
||||
</label>
|
||||
<gl-collapsible-listbox
|
||||
v-model="selectedTaskProjectId"
|
||||
:items="projectsForDropdown"
|
||||
:block="true"
|
||||
class="gl-w-half gl-xs-w-full"
|
||||
data-testid="invite-members-modal-project-select"
|
||||
@select="changeSelectedTaskProject"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
<gl-alert
|
||||
v-else-if="tasksToBeDoneEnabled"
|
||||
variant="tip"
|
||||
:dismissible="false"
|
||||
data-testid="invite-members-modal-no-projects-alert"
|
||||
>
|
||||
<gl-sprintf :message="$options.labels.tasksToBeDone.noProjects">
|
||||
<template #link="{ content }">
|
||||
<gl-link :href="newProjectPath" target="_blank" class="gl-label-link">
|
||||
{{ content }}
|
||||
</gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</gl-alert>
|
||||
</div>
|
||||
</template>
|
||||
</invite-modal-base>
|
||||
</template>
|
||||
|
@ -330,8 +330,6 @@ export default {
|
||||
:target="null"
|
||||
/>
|
||||
</gl-form-group>
|
||||
|
||||
<slot name="form-after"></slot>
|
||||
</template>
|
||||
|
||||
<template v-for="{ key } in extraSlots" #[key]>
|
||||
|
@ -5,10 +5,6 @@ export const PROJECT_SELECT_LABEL_ID = 'project-select';
|
||||
export const SEARCH_DELAY = 200;
|
||||
export const VALID_TOKEN_BACKGROUND = 'gl-bg-green-100';
|
||||
export const INVALID_TOKEN_BACKGROUND = 'gl-bg-red-100';
|
||||
export const INVITE_MEMBERS_FOR_TASK = {
|
||||
minimum_access_level: 30,
|
||||
submit: 'submit',
|
||||
};
|
||||
export const TOAST_MESSAGE_LOCALSTORAGE_KEY = 'members_invited_successfully';
|
||||
|
||||
export const GROUP_FILTERS = {
|
||||
@ -46,15 +42,6 @@ export const MEMBERS_TO_PROJECT_CELEBRATE_INTRO_TEXT = s__(
|
||||
);
|
||||
export const MEMBERS_SEARCH_FIELD = s__('InviteMembersModal|Username or email address');
|
||||
export const MEMBERS_PLACEHOLDER = s__('InviteMembersModal|Select members or type email addresses');
|
||||
export const MEMBERS_TASKS_TO_BE_DONE_TITLE = s__(
|
||||
'InviteMembersModal|Create issues for your new team member to work on (optional)',
|
||||
);
|
||||
export const MEMBERS_TASKS_TO_BE_DONE_NO_PROJECTS = s__(
|
||||
'InviteMembersModal|To assign issues to a new team member, you need a project for the issues. %{linkStart}Create a project to get started.%{linkEnd}',
|
||||
);
|
||||
export const MEMBERS_TASKS_PROJECTS_TITLE = s__(
|
||||
'InviteMembersModal|Choose a project for the issues',
|
||||
);
|
||||
|
||||
export const GROUP_MODAL_DEFAULT_TITLE = s__('InviteMembersModal|Invite a group');
|
||||
export const GROUP_MODAL_TO_GROUP_DEFAULT_INTRO_TEXT = s__(
|
||||
@ -123,13 +110,6 @@ export const MEMBER_MODAL_LABELS = {
|
||||
},
|
||||
searchField: MEMBERS_SEARCH_FIELD,
|
||||
placeHolder: MEMBERS_PLACEHOLDER,
|
||||
tasksToBeDone: {
|
||||
title: MEMBERS_TASKS_TO_BE_DONE_TITLE,
|
||||
noProjects: MEMBERS_TASKS_TO_BE_DONE_NO_PROJECTS,
|
||||
},
|
||||
tasksProject: {
|
||||
title: MEMBERS_TASKS_PROJECTS_TITLE,
|
||||
},
|
||||
toastMessageSuccessful: TOAST_MESSAGE_SUCCESSFUL,
|
||||
memberErrorListText: MEMBER_ERROR_LIST_TEXT,
|
||||
collapsedErrors: COLLAPSED_ERRORS,
|
||||
|
@ -25,7 +25,6 @@ export default (function initInviteMembersModal() {
|
||||
name: 'InviteMembersModalRoot',
|
||||
provide: {
|
||||
name: el.dataset.name,
|
||||
newProjectPath: el.dataset.newProjectPath,
|
||||
},
|
||||
render: (createElement) =>
|
||||
createElement(InviteMembersModal, {
|
||||
@ -34,8 +33,6 @@ export default (function initInviteMembersModal() {
|
||||
isProject: parseBoolean(el.dataset.isProject),
|
||||
accessLevels: JSON.parse(el.dataset.accessLevels),
|
||||
defaultAccessLevel: parseInt(el.dataset.defaultAccessLevel, 10),
|
||||
tasksToBeDoneOptions: JSON.parse(el.dataset.tasksToBeDoneOptions || '[]'),
|
||||
projects: JSON.parse(el.dataset.projects || '[]'),
|
||||
usersFilter: el.dataset.usersFilter,
|
||||
filterId: parseInt(el.dataset.filterId, 10),
|
||||
usersLimitDataset: convertObjectPropsToCamelCase(
|
||||
|
@ -6,7 +6,3 @@ export function memberName(member) {
|
||||
export function triggerExternalAlert() {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function qualifiesForTasksToBeDone() {
|
||||
return false;
|
||||
}
|
||||
|
@ -21,5 +21,5 @@ export const LOAD_PIPELINES_FAILURE = 'load_analytics_failure';
|
||||
export const UNSUPPORTED_DATA = 'unsupported_data';
|
||||
|
||||
export const SNOWPLOW_LABEL = 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly';
|
||||
export const SNOWPLOW_SCHEMA = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-0';
|
||||
export const SNOWPLOW_SCHEMA = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-1';
|
||||
export const SNOWPLOW_DATA_SOURCE = 'redis_hll';
|
||||
|
@ -30,7 +30,7 @@ export const GOOGLE_ANALYTICS_ID_COOKIE_NAME = '_ga';
|
||||
|
||||
export const GITLAB_INTERNAL_EVENT_CATEGORY = 'InternalEventTracking';
|
||||
|
||||
export const SERVICE_PING_SCHEMA = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-0';
|
||||
export const SERVICE_PING_SCHEMA = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-1';
|
||||
|
||||
export const SERVICE_PING_SECURITY_CONFIGURATION_THREAT_MANAGEMENT_VISIT =
|
||||
'users_visiting_security_configuration_threat_management';
|
||||
|
@ -37,23 +37,13 @@ module InviteMembersHelper
|
||||
|
||||
# Overridden in EE
|
||||
def common_invite_modal_dataset(source)
|
||||
dataset = {
|
||||
{
|
||||
id: source.id,
|
||||
root_id: source.root_ancestor&.id,
|
||||
name: source.name,
|
||||
default_access_level: Gitlab::Access::GUEST,
|
||||
full_path: source.full_path
|
||||
}
|
||||
|
||||
if current_user && show_invite_members_for_task?
|
||||
dataset.merge!(
|
||||
tasks_to_be_done_options: tasks_to_be_done_options.to_json,
|
||||
projects: projects_for_source(source).to_json,
|
||||
new_project_path: source.is_a?(Group) ? new_project_path(namespace_id: source.id) : ''
|
||||
)
|
||||
end
|
||||
|
||||
dataset
|
||||
end
|
||||
|
||||
private
|
||||
@ -70,19 +60,6 @@ module InviteMembersHelper
|
||||
def users_filter_data(group)
|
||||
{}
|
||||
end
|
||||
|
||||
def show_invite_members_for_task?
|
||||
params[:open_modal] == 'invite_members_for_task'
|
||||
end
|
||||
|
||||
def tasks_to_be_done_options
|
||||
::MemberTask::TASKS.keys.map { |task| { value: task, text: localized_tasks_to_be_done_choices[task] } }
|
||||
end
|
||||
|
||||
def projects_for_source(source)
|
||||
projects = source.is_a?(Project) ? [source] : source.projects
|
||||
projects.map { |project| { id: project.id, title: project.title } }
|
||||
end
|
||||
end
|
||||
|
||||
InviteMembersHelper.prepend_mod_with('InviteMembersHelper')
|
||||
|
@ -54,14 +54,6 @@ module MembersHelper
|
||||
end
|
||||
end
|
||||
|
||||
def localized_tasks_to_be_done_choices
|
||||
{
|
||||
code: s_('TasksToBeDone|Create/import code into a project (repository)'),
|
||||
ci: s_('TasksToBeDone|Set up CI/CD pipelines to build, test, deploy, and monitor code'),
|
||||
issues: s_('TasksToBeDone|Create/import issues (tickets) to collaborate on ideas and plan work')
|
||||
}.freeze
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def source_text(member)
|
||||
|
@ -94,7 +94,9 @@ module MergeRequests
|
||||
)
|
||||
|
||||
merge_requests.each do |merge_request|
|
||||
merge_request.merge_commit_sha = analyzer.get_merge_commit(merge_request.diff_head_sha)
|
||||
sha = analyzer.get_merge_commit(merge_request.diff_head_sha)
|
||||
merge_request.merge_commit_sha = sha
|
||||
merge_request.merged_commit_sha = sha
|
||||
|
||||
MergeRequests::PostMergeService
|
||||
.new(project: merge_request.target_project, current_user: @current_user)
|
||||
|
@ -3,7 +3,7 @@
|
||||
module Gitlab
|
||||
module Tracking
|
||||
class ServicePingContext
|
||||
SCHEMA_URL = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-0'
|
||||
SCHEMA_URL = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-1'
|
||||
REDISHLL_SOURCE = :redis_hll
|
||||
REDIS_SOURCE = :redis
|
||||
|
||||
|
@ -25548,18 +25548,12 @@ msgstr ""
|
||||
msgid "InviteMembersModal|Cancel"
|
||||
msgstr ""
|
||||
|
||||
msgid "InviteMembersModal|Choose a project for the issues"
|
||||
msgstr ""
|
||||
|
||||
msgid "InviteMembersModal|Close invite team members"
|
||||
msgstr ""
|
||||
|
||||
msgid "InviteMembersModal|Congratulations on creating your project, you're almost there!"
|
||||
msgstr ""
|
||||
|
||||
msgid "InviteMembersModal|Create issues for your new team member to work on (optional)"
|
||||
msgstr ""
|
||||
|
||||
msgid "InviteMembersModal|During your trial, you can invite as many members to %{groupName} as you like. When the trial ends, you'll have a maximum of %{dashboardLimit} members on the Free tier. To get more members, %{linkStart}upgrade to a paid plan%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
@ -25625,9 +25619,6 @@ msgid_plural "InviteMembersModal|The following %d members couldn't be invited"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "InviteMembersModal|To assign issues to a new team member, you need a project for the issues. %{linkStart}Create a project to get started.%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "InviteMembersModal|To get more members an owner of the group can %{trialLinkStart}start a trial%{trialLinkEnd} or %{upgradeLinkStart}upgrade%{upgradeLinkEnd} to a paid tier."
|
||||
msgstr ""
|
||||
|
||||
@ -46702,15 +46693,6 @@ msgstr ""
|
||||
msgid "Task list"
|
||||
msgstr ""
|
||||
|
||||
msgid "TasksToBeDone|Create/import code into a project (repository)"
|
||||
msgstr ""
|
||||
|
||||
msgid "TasksToBeDone|Create/import issues (tickets) to collaborate on ideas and plan work"
|
||||
msgstr ""
|
||||
|
||||
msgid "TasksToBeDone|Set up CI/CD pipelines to build, test, deploy, and monitor code"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tasks|%{complete_count} of %{total_count} %{checklist_item_noun} completed"
|
||||
msgstr ""
|
||||
|
||||
|
13
qa/qa/factories/snippets.rb
Normal file
13
qa/qa/factories/snippets.rb
Normal file
@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
FactoryBot.define do
|
||||
factory :snippet, class: 'QA::Resource::Snippet' do
|
||||
trait :private do
|
||||
visibility { 'Private' }
|
||||
end
|
||||
|
||||
factory :project_snippet, class: 'QA::Resource::ProjectSnippet'
|
||||
end
|
||||
end
|
||||
end
|
@ -42,12 +42,6 @@ module QA
|
||||
@id = Page::Dashboard::Snippet::Show.perform(&:snippet_id)
|
||||
end
|
||||
|
||||
def fabricate_via_api!
|
||||
resource_web_url(api_post)
|
||||
rescue ResourceNotFoundError
|
||||
super
|
||||
end
|
||||
|
||||
def api_get_path
|
||||
"/snippets/#{id}"
|
||||
end
|
||||
|
@ -7,12 +7,11 @@ module QA
|
||||
let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.additional_repository_storage } }
|
||||
|
||||
let(:snippet) do
|
||||
Resource::Snippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = 'Snippet to move storage of'
|
||||
snippet.file_name = 'original_file'
|
||||
snippet.file_content = 'Original file content'
|
||||
snippet.api_client = Runtime::API::Client.as_admin
|
||||
end
|
||||
create(:snippet,
|
||||
title: 'Snippet to move storage of',
|
||||
file_name: 'original_file',
|
||||
file_content: 'Original file content',
|
||||
api_client: Runtime::API::Client.as_admin)
|
||||
end
|
||||
|
||||
praefect_manager = Service::PraefectManager.new
|
||||
|
@ -4,19 +4,17 @@ module QA
|
||||
RSpec.describe 'Create', product_group: :source_code do
|
||||
describe 'Multiple file snippet' do
|
||||
let(:personal_snippet) do
|
||||
Resource::Snippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = 'Personal snippet to add file to'
|
||||
snippet.file_name = 'Original file name'
|
||||
snippet.file_content = 'Original file content'
|
||||
end
|
||||
create(:snippet,
|
||||
title: 'Personal snippet to add file to',
|
||||
file_name: 'Original file name',
|
||||
file_content: 'Original file content')
|
||||
end
|
||||
|
||||
let(:project_snippet) do
|
||||
Resource::ProjectSnippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = 'Project snippet to add file to'
|
||||
snippet.file_name = 'Original file name'
|
||||
snippet.file_content = 'Original file content'
|
||||
end
|
||||
create(:project_snippet,
|
||||
title: 'Project snippet to add file to',
|
||||
file_name: 'Original file name',
|
||||
file_content: 'Original file content')
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -8,29 +8,25 @@ module QA
|
||||
let(:third_file_content) { 'Third file content' }
|
||||
|
||||
let(:personal_snippet) do
|
||||
Resource::Snippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = 'Personal snippet to copy file contents from'
|
||||
snippet.file_name = 'First file name'
|
||||
snippet.file_content = first_file_content
|
||||
|
||||
snippet.add_files do |files|
|
||||
files.append(name: 'Second file name', content: second_file_content)
|
||||
files.append(name: 'Third file name', content: third_file_content)
|
||||
end
|
||||
end
|
||||
create(:snippet,
|
||||
title: 'Personal snippet to copy file contents from',
|
||||
file_name: 'First file name',
|
||||
file_content: first_file_content,
|
||||
files: [
|
||||
{ name: 'Second file name', content: second_file_content },
|
||||
{ name: 'Third file name', content: third_file_content }
|
||||
])
|
||||
end
|
||||
|
||||
let(:project_snippet) do
|
||||
Resource::ProjectSnippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = 'Project snippet to copy file contents from'
|
||||
snippet.file_name = 'First file name'
|
||||
snippet.file_content = first_file_content
|
||||
|
||||
snippet.add_files do |files|
|
||||
files.append(name: 'Second file name', content: second_file_content)
|
||||
files.append(name: 'Third file name', content: third_file_content)
|
||||
end
|
||||
end
|
||||
create(:project_snippet,
|
||||
title: 'Project snippet to copy file contents from',
|
||||
file_name: 'First file name',
|
||||
file_content: first_file_content,
|
||||
files: [
|
||||
{ name: 'Second file name', content: second_file_content },
|
||||
{ name: 'Third file name', content: third_file_content }
|
||||
])
|
||||
end
|
||||
|
||||
let(:files) do
|
||||
|
@ -4,27 +4,23 @@ module QA
|
||||
RSpec.describe 'Create' do
|
||||
describe 'Multiple file snippet', :reliable, product_group: :source_code do
|
||||
let(:personal_snippet) do
|
||||
Resource::Snippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = 'Personal snippet to delete file from'
|
||||
snippet.file_name = 'Original file name'
|
||||
snippet.file_content = 'Original file content'
|
||||
|
||||
snippet.add_files do |files|
|
||||
files.append(name: 'Second file name', content: 'Second file content')
|
||||
end
|
||||
end
|
||||
create(:snippet,
|
||||
title: 'Personal snippet to delete file from',
|
||||
file_name: 'Original file name',
|
||||
file_content: 'Original file content',
|
||||
files: [
|
||||
{ name: 'Second file name', content: 'Second file content' }
|
||||
])
|
||||
end
|
||||
|
||||
let(:project_snippet) do
|
||||
Resource::ProjectSnippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = 'Project snippet to delete file from'
|
||||
snippet.file_name = 'Original file name'
|
||||
snippet.file_content = 'Original file content'
|
||||
|
||||
snippet.add_files do |files|
|
||||
files.append(name: 'Second file name', content: 'Second file content')
|
||||
end
|
||||
end
|
||||
create(:project_snippet,
|
||||
title: 'Project snippet to delete file from',
|
||||
file_name: 'Original file name',
|
||||
file_content: 'Original file content',
|
||||
files: [
|
||||
{ name: 'Second file name', content: 'Second file content' }
|
||||
])
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -4,45 +4,34 @@ module QA
|
||||
RSpec.describe 'Create', product_group: :source_code do
|
||||
describe 'Snippet index page' do
|
||||
let(:personal_snippet_with_single_file) do
|
||||
Resource::Snippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = "Personal snippet with one file-#{SecureRandom.hex(8)}"
|
||||
snippet.visibility = 'Public'
|
||||
end
|
||||
create(:snippet, title: "Personal snippet with one file-#{SecureRandom.hex(8)}")
|
||||
end
|
||||
|
||||
let(:personal_snippet_with_multiple_files) do
|
||||
Resource::Snippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = "Personal snippet with multiple files-#{SecureRandom.hex(8)}"
|
||||
snippet.visibility = 'Private'
|
||||
snippet.file_name = 'First file name'
|
||||
snippet.file_content = 'first file content'
|
||||
|
||||
snippet.add_files do |files|
|
||||
files.append(name: 'Second file name', content: 'second file content')
|
||||
files.append(name: 'Third file name', content: 'third file content')
|
||||
end
|
||||
end
|
||||
create(:snippet,
|
||||
:private,
|
||||
title: "Personal snippet with multiple files-#{SecureRandom.hex(8)}",
|
||||
file_name: 'First file name',
|
||||
file_content: 'first file content',
|
||||
files: [
|
||||
{ name: 'Second file name', content: 'second file content' },
|
||||
{ name: 'Third file name', content: 'third file content' }
|
||||
])
|
||||
end
|
||||
|
||||
let(:project_snippet_with_single_file) do
|
||||
Resource::ProjectSnippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = "Project snippet with one file-#{SecureRandom.hex(8)}"
|
||||
snippet.visibility = 'Private'
|
||||
end
|
||||
create(:project_snippet, :private, title: "Project snippet with one file-#{SecureRandom.hex(8)}")
|
||||
end
|
||||
|
||||
let(:project_snippet_with_multiple_files) do
|
||||
Resource::ProjectSnippet.fabricate_via_api! do |snippet|
|
||||
snippet.title = "Project snippet with multiple files-#{SecureRandom.hex(8)}"
|
||||
snippet.visibility = 'Public'
|
||||
snippet.file_name = 'First file name'
|
||||
snippet.file_content = 'first file content'
|
||||
|
||||
snippet.add_files do |files|
|
||||
files.append(name: 'Second file name', content: 'second file content')
|
||||
files.append(name: 'Third file name', content: 'third file content')
|
||||
end
|
||||
end
|
||||
create(:project_snippet,
|
||||
title: "Project snippet with multiple files-#{SecureRandom.hex(8)}",
|
||||
file_name: 'First file name',
|
||||
file_content: 'first file content',
|
||||
files: [
|
||||
{ name: 'Second file name', content: 'second file content' },
|
||||
{ name: 'Third file name', content: 'third file content' }
|
||||
])
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -6,14 +6,6 @@ export const propsData = {
|
||||
accessLevels: { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, Owner: 50 },
|
||||
defaultAccessLevel: 30,
|
||||
helpLink: 'https://example.com',
|
||||
tasksToBeDoneOptions: [
|
||||
{ text: 'First task', value: 'first' },
|
||||
{ text: 'Second task', value: 'second' },
|
||||
],
|
||||
projects: [
|
||||
{ text: 'First project', value: '1' },
|
||||
{ text: 'Second project', value: '2' },
|
||||
],
|
||||
};
|
||||
|
||||
export const inviteSource = 'unknown';
|
||||
@ -51,8 +43,6 @@ export const postData = {
|
||||
expires_at: undefined,
|
||||
invite_source: inviteSource,
|
||||
format: 'json',
|
||||
tasks_to_be_done: [],
|
||||
tasks_project_id: '',
|
||||
};
|
||||
|
||||
export const emailPostData = {
|
||||
@ -60,8 +50,6 @@ export const emailPostData = {
|
||||
expires_at: undefined,
|
||||
email: `${user3.name}`,
|
||||
invite_source: inviteSource,
|
||||
tasks_to_be_done: [],
|
||||
tasks_project_id: '',
|
||||
format: 'json',
|
||||
};
|
||||
|
||||
@ -71,8 +59,6 @@ export const singleUserPostData = {
|
||||
user_id: `${user1.id}`,
|
||||
email: `${user3.name}`,
|
||||
invite_source: inviteSource,
|
||||
tasks_to_be_done: [],
|
||||
tasks_project_id: '',
|
||||
format: 'json',
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,4 @@
|
||||
import {
|
||||
memberName,
|
||||
triggerExternalAlert,
|
||||
qualifiesForTasksToBeDone,
|
||||
} from '~/invite_members/utils/member_utils';
|
||||
import { memberName, triggerExternalAlert } from '~/invite_members/utils/member_utils';
|
||||
|
||||
jest.mock('~/lib/utils/url_utility');
|
||||
|
||||
@ -22,9 +18,3 @@ describe('Trigger External Alert', () => {
|
||||
expect(triggerExternalAlert()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Qualifies For Tasks To Be Done', () => {
|
||||
it('returns false', () => {
|
||||
expect(qualifiesForTasksToBeDone()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ export const extraContext = {
|
||||
};
|
||||
|
||||
export const servicePingContext = {
|
||||
schema: 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-0',
|
||||
schema: 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-1',
|
||||
data: {
|
||||
event_name: 'track_incident_event',
|
||||
data_source: 'redis_hll',
|
||||
|
@ -65,62 +65,6 @@ RSpec.describe InviteMembersHelper do
|
||||
|
||||
expect(helper.common_invite_modal_dataset(project)).to include(attributes)
|
||||
end
|
||||
|
||||
context 'with tasks_to_be_done' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
subject(:output) { helper.common_invite_modal_dataset(source) }
|
||||
|
||||
shared_examples_for 'including the tasks to be done attributes' do
|
||||
it 'includes the tasks to be done attributes when expected' do
|
||||
if expected?
|
||||
expect(output[:tasks_to_be_done_options]).to eq(
|
||||
[
|
||||
{ value: :code, text: 'Create/import code into a project (repository)' },
|
||||
{ value: :ci, text: 'Set up CI/CD pipelines to build, test, deploy, and monitor code' },
|
||||
{ value: :issues, text: 'Create/import issues (tickets) to collaborate on ideas and plan work' }
|
||||
].to_json
|
||||
)
|
||||
expect(output[:projects]).to eq([{ id: project.id, title: project.title }].to_json)
|
||||
expect(output[:new_project_path]).to eq(
|
||||
source.is_a?(Project) ? '' : new_project_path(namespace_id: group.id)
|
||||
)
|
||||
else
|
||||
expect(output[:tasks_to_be_done_options]).to be_nil
|
||||
expect(output[:projects]).to be_nil
|
||||
expect(output[:new_project_path]).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when inviting members for tasks' do
|
||||
where(:open_modal_param?, :logged_in?, :expected?) do
|
||||
true | true | true
|
||||
true | false | false
|
||||
false | true | false
|
||||
false | false | false
|
||||
end
|
||||
|
||||
with_them do
|
||||
before do
|
||||
allow(helper).to receive(:current_user).and_return(developer) if logged_in?
|
||||
allow(helper).to receive(:params).and_return({ open_modal: 'invite_members_for_task' }) if open_modal_param?
|
||||
end
|
||||
|
||||
context 'when the source is a project' do
|
||||
let_it_be(:source) { project }
|
||||
|
||||
it_behaves_like 'including the tasks to be done attributes'
|
||||
end
|
||||
|
||||
context 'when the source is a group' do
|
||||
let_it_be(:source) { group }
|
||||
|
||||
it_behaves_like 'including the tasks to be done attributes'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with project' do
|
||||
|
@ -69,12 +69,6 @@ RSpec.describe MembersHelper do
|
||||
it { expect(leave_confirmation_message(group)).to eq "Are you sure you want to leave the \"#{group.name}\" group?" }
|
||||
end
|
||||
|
||||
describe '#localized_tasks_to_be_done_choices' do
|
||||
it 'has a translation for all `TASKS_TO_BE_DONE` keys' do
|
||||
expect(localized_tasks_to_be_done_choices).to include(*MemberTask::TASKS.keys)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#member_request_access_link' do
|
||||
let(:project) { create(:project) }
|
||||
let(:group) { create(:group) }
|
||||
|
@ -913,7 +913,7 @@ RSpec.describe MergeRequests::RefreshService, feature_category: :code_review_wor
|
||||
subject { service.execute(oldrev, newrev, 'refs/heads/merge-commit-analyze-before') }
|
||||
|
||||
context 'feature enabled' do
|
||||
it "updates merge requests' merge_commits" do
|
||||
it "updates merge requests' merge_commit and merged_commit values", :aggregate_failures do
|
||||
expect(Gitlab::BranchPushMergeCommitAnalyzer).to receive(:new).and_wrap_original do |original_method, commits|
|
||||
expect(commits.map(&:id)).to eq(%w{646ece5cfed840eca0a4feb21bcd6a81bb19bda3 29284d9bcc350bcae005872d0be6edd016e2efb5 5f82584f0a907f3b30cfce5bb8df371454a90051 8a994512e8c8f0dfcf22bb16df6e876be7a61036 689600b91aabec706e657e38ea706ece1ee8268f db46a1c5a5e474aa169b6cdb7a522d891bc4c5f9})
|
||||
|
||||
@ -927,6 +927,11 @@ RSpec.describe MergeRequests::RefreshService, feature_category: :code_review_wor
|
||||
|
||||
expect(merge_request.merge_commit.id).to eq('646ece5cfed840eca0a4feb21bcd6a81bb19bda3')
|
||||
expect(merge_request_side_branch.merge_commit.id).to eq('29284d9bcc350bcae005872d0be6edd016e2efb5')
|
||||
# we need to use read_attribute to bypass the overridden
|
||||
# #merged_commit_sha method, which contains a fallback to
|
||||
# #merge_commit_sha
|
||||
expect(merge_request.read_attribute(:merged_commit_sha)).to eq('646ece5cfed840eca0a4feb21bcd6a81bb19bda3')
|
||||
expect(merge_request_side_branch.read_attribute(:merged_commit_sha)).to eq('29284d9bcc350bcae005872d0be6edd016e2efb5')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -244,7 +244,8 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi
|
||||
end
|
||||
end
|
||||
|
||||
it 'expands the link, updates the link attributes and text if text is updated' do
|
||||
it 'expands the link, updates the link attributes and text if text is updated',
|
||||
quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/419684' do
|
||||
page.within '[data-testid="link-bubble-menu"]' do
|
||||
fill_in 'link-text', with: 'new text'
|
||||
fill_in 'link-href', with: 'https://about.gitlab.com'
|
||||
|
@ -31,7 +31,8 @@ RSpec.shared_examples "protected branches > access control > CE" do
|
||||
expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to eq([access_type_id])
|
||||
end
|
||||
|
||||
it "allows updating protected branches so that #{access_type_name} can push to them" do
|
||||
it "allows updating protected branches so that #{access_type_name} can push to them",
|
||||
quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/425080' do
|
||||
visit project_protected_branches_path(project)
|
||||
|
||||
show_add_form
|
||||
|
Reference in New Issue
Block a user