Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
8b13b280f5
commit
236caf4b92
|
|
@ -41,6 +41,7 @@ After your merge request has been approved according to our [approval guidelines
|
|||
|
||||
## Documentation and final details
|
||||
|
||||
- [ ] When you believe this issue is ready for release (Backports are approved and ready to be merged), apply the ~"security-target" label (This label does not have an effect yet, but will in upcoming releases. See <https://gitlab.com/gitlab-com/gl-infra/delivery/-/issues/19611#computer-developer-process> for more information).
|
||||
- [ ] To avoid release delays, please nominate a developer in a different timezone who will be able to respond to any pipeline or merge failures in your absence `@gitlab-username`
|
||||
- [ ] Ensure `~severity::x` label is on this issue, all associated issues, and merge requests
|
||||
- [ ] Ensure the [Links section](#links) is completed.
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
c7099d645d162a8760f7f84e9f3e0c45229240c1
|
||||
e450c7ca1115ddc16b3db84a5400b781ed81e2e6
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
14.27.0
|
||||
14.28.0
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ export const issuableStatusText = {
|
|||
|
||||
export const IssuableTypeText = {
|
||||
[TYPE_ISSUE]: __('issue'),
|
||||
[TYPE_EPIC]: __('epic'),
|
||||
[TYPE_MERGE_REQUEST]: __('merge request'),
|
||||
[TYPE_ALERT]: __('alert'),
|
||||
[TYPE_INCIDENT]: __('incident'),
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export default {
|
|||
v-gl-tooltip.hover
|
||||
:title="$options.title"
|
||||
:aria-label="$options.title"
|
||||
data-qa-selector="approve_access_request_button"
|
||||
data-testid="approve-access-request-button"
|
||||
icon="check"
|
||||
type="submit"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ export default {
|
|||
:title="title"
|
||||
:aria-label="title"
|
||||
icon="remove"
|
||||
data-qa-selector="delete_member_button"
|
||||
data-testid="delete-member-button"
|
||||
@click="showRemoveMemberModal(modalData)"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { GlSprintf, GlButton } from '@gitlab/ui';
|
||||
import { createAlert } from '~/alert';
|
||||
import { TYPE_ISSUE } from '~/issues/constants';
|
||||
import { TYPE_ISSUE, TYPE_TEST_CASE, IssuableTypeText } from '~/issues/constants';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import { confidentialityQueries } from '../../queries/constants';
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ export default {
|
|||
'You are going to turn on confidentiality. Only %{context} members with %{strongStart}%{permissions}%{strongEnd} can view or be notified about this %{issuableType}.',
|
||||
),
|
||||
confidentialityOffWarning: __(
|
||||
'You are going to turn off the confidentiality. This means %{strongStart}everyone%{strongEnd} will be able to see and leave a comment on this %{issuableType}.',
|
||||
'You are going to turn off the confidentiality. This means %{strongStart}everyone%{strongEnd} will be able to see%{commentText} this %{issuableType}.',
|
||||
),
|
||||
},
|
||||
components: {
|
||||
|
|
@ -56,11 +56,17 @@ export default {
|
|||
isIssue() {
|
||||
return this.issuableType === TYPE_ISSUE;
|
||||
},
|
||||
isTestCase() {
|
||||
return this.issuableType === TYPE_TEST_CASE;
|
||||
},
|
||||
isIssueOrTestCase() {
|
||||
return this.isIssue || this.isTestCase;
|
||||
},
|
||||
context() {
|
||||
return this.isIssue ? __('project') : __('group');
|
||||
return this.isIssueOrTestCase ? __('project') : __('group');
|
||||
},
|
||||
workspacePath() {
|
||||
return this.isIssue
|
||||
return this.isIssueOrTestCase
|
||||
? {
|
||||
projectPath: this.fullPath,
|
||||
}
|
||||
|
|
@ -73,6 +79,12 @@ export default {
|
|||
? __('at least the Reporter role, the author, and assignees')
|
||||
: __('at least the Reporter role');
|
||||
},
|
||||
issuableTypeText() {
|
||||
return IssuableTypeText[this.issuableType];
|
||||
},
|
||||
commentText() {
|
||||
return this.isTestCase ? '' : __(' and leave a comment on');
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
submitForm() {
|
||||
|
|
@ -108,7 +120,7 @@ export default {
|
|||
message: sprintf(
|
||||
__('Something went wrong while setting %{issuableType} confidentiality.'),
|
||||
{
|
||||
issuableType: this.issuableType,
|
||||
issuableType: this.issuableTypeText,
|
||||
},
|
||||
),
|
||||
});
|
||||
|
|
@ -135,7 +147,8 @@ export default {
|
|||
</strong>
|
||||
</template>
|
||||
<template #context>{{ context }}</template>
|
||||
<template #issuableType>{{ issuableType }}</template>
|
||||
<template #commentText>{{ commentText }}</template>
|
||||
<template #issuableType>{{ issuableTypeText }}</template>
|
||||
</gl-sprintf>
|
||||
</p>
|
||||
<div class="sidebar-item-warning-message-actions">
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ import groupMilestonesQuery from './group_milestones.query.graphql';
|
|||
import projectIssueMilestoneMutation from './project_issue_milestone.mutation.graphql';
|
||||
import projectIssueMilestoneQuery from './project_issue_milestone.query.graphql';
|
||||
import projectMilestonesQuery from './project_milestones.query.graphql';
|
||||
import testCaseConfidentialQuery from './test_case_confidential.query.graphql';
|
||||
import updateTestCaseConfidentialMutation from './update_test_case_confidential.mutation.graphql';
|
||||
|
||||
export const assigneesQueries = {
|
||||
[TYPE_ISSUE]: {
|
||||
|
|
@ -120,6 +122,10 @@ export const confidentialityQueries = {
|
|||
query: epicConfidentialQuery,
|
||||
mutation: updateEpicConfidentialMutation,
|
||||
},
|
||||
[TYPE_TEST_CASE]: {
|
||||
query: testCaseConfidentialQuery,
|
||||
mutation: updateTestCaseConfidentialMutation,
|
||||
},
|
||||
};
|
||||
|
||||
export const referenceQueries = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
query testCaseConfidential($fullPath: ID!, $iid: String) {
|
||||
workspace: project(fullPath: $fullPath) {
|
||||
id
|
||||
issuable: issue(iid: $iid) {
|
||||
id
|
||||
confidential
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
mutation updateTestCaseConfidential($input: IssueSetConfidentialInput!) {
|
||||
issuableSetConfidential: issueSetConfidential(input: $input) {
|
||||
issuable: issue {
|
||||
id
|
||||
confidential
|
||||
}
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ export const confidentialityInfoText = (workspaceType, issuableType) =>
|
|||
),
|
||||
{
|
||||
workspaceType: workspaceType === WORKSPACE_PROJECT ? __('project') : __('group'),
|
||||
issuableType: issuableType.toLowerCase(),
|
||||
issuableType: issuableType.toLowerCase().replaceAll('_', ' '),
|
||||
permissions:
|
||||
issuableType === TYPE_ISSUE
|
||||
? __('at least the Reporter role, the author, and assignees')
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
workspaceType: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleKeydownTitle(e, issuableMeta) {
|
||||
|
|
@ -116,6 +121,7 @@ export default {
|
|||
:author="issuable.author"
|
||||
:task-completion-status="taskCompletionStatus"
|
||||
:issuable-type="issuable.type"
|
||||
:workspace-type="workspaceType"
|
||||
:show-work-item-type-icon="showWorkItemTypeIcon"
|
||||
>
|
||||
<template #status-badge>
|
||||
|
|
|
|||
|
|
@ -343,9 +343,12 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def check_password_expiration
|
||||
return if session[:impersonator_id] || !current_user&.allow_password_authentication?
|
||||
return if session[:impersonator_id]
|
||||
return if current_user.nil?
|
||||
|
||||
redirect_to new_profile_password_path if current_user&.password_expired?
|
||||
if current_user.password_expired? && current_user.allow_password_authentication?
|
||||
redirect_to new_profile_password_path
|
||||
end
|
||||
end
|
||||
|
||||
def active_user_check
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
%li.todo.gl-hover-border-blue-200.gl-hover-bg-blue-50.gl-hover-cursor-pointer.gl-relative{ class: "todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo) }
|
||||
.gl-display-flex.gl-flex-direction-column.gl-sm-flex-direction-row.gl-sm-align-items-center
|
||||
.todo-item.gl-overflow-hidden.gl-overflow-x-auto.gl-align-self-center.gl-w-full{ data: { qa_selector: "todo_item_container" } }
|
||||
.todo-item.gl-overflow-hidden.gl-overflow-x-auto.gl-align-self-center.gl-w-full{ data: { testid: "todo-item-container" } }
|
||||
.todo-title.gl-pt-2.gl-pb-3.gl-px-2.gl-md-mb-1.gl-font-sm.gl-text-secondary
|
||||
|
||||
= todo_target_state_pill(todo)
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
= author_avatar(todo, size: 24)
|
||||
.todo-note
|
||||
- if todo_author_display?(todo)
|
||||
.author-name.bold.gl-display-inline{ data: { qa_selector: "todo_author_name_content" } }<
|
||||
.author-name.bold.gl-display-inline{ data: { testid: "todo-author-name-content" } }<
|
||||
- if todo.author
|
||||
= link_to_author(todo, self_added: todo.self_added?)
|
||||
- else
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
.filter-item.gl-m-2
|
||||
- if params[:group_id].present?
|
||||
= hidden_field_tag(:group_id, params[:group_id])
|
||||
= dropdown_tag(group_dropdown_label(params[:group_id], _("Group")), options: { toggle_class: 'js-group-search js-filter-submit gl-xs-w-full!', title: s_("Todos|Filter by group"), filter: true, filterInput: 'input#group-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-group js-filter-submit', placeholder: _("Search groups"), data: { default_label: _("Group"), display: 'static', qa_selector: 'group_dropdown' } })
|
||||
= dropdown_tag(group_dropdown_label(params[:group_id], _("Group")), options: { toggle_class: 'js-group-search js-filter-submit gl-xs-w-full!', title: s_("Todos|Filter by group"), filter: true, filterInput: 'input#group-search', dropdown_class: 'dropdown-menu-selectable dropdown-menu-group js-filter-submit', placeholder: _("Search groups"), data: { default_label: _("Group"), display: 'static', testid: 'group-dropdown' } })
|
||||
.filter-item.gl-m-2
|
||||
- if params[:project_id].present?
|
||||
= hidden_field_tag(:project_id, params[:project_id])
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@
|
|||
- elsif source.request_access_enabled && can?(current_user, :request_access, source)
|
||||
= link_to _('Request Access'), polymorphic_path([:request_access, source, :members]),
|
||||
method: :post,
|
||||
data: { qa_selector: 'request_access_link' }
|
||||
data: { testid: 'request-access-link' }
|
||||
|
|
|
|||
|
|
@ -307,6 +307,8 @@
|
|||
- 1
|
||||
- - groups_create_event
|
||||
- 1
|
||||
- - groups_enterprise_users_associate
|
||||
- 1
|
||||
- - groups_enterprise_users_disassociate
|
||||
- 1
|
||||
- - groups_export_memberships
|
||||
|
|
@ -373,6 +375,8 @@
|
|||
- 2
|
||||
- - llm_completion
|
||||
- 1
|
||||
- - llm_embedding_gitlab_documentation_create_db_embeddings_per_doc_file
|
||||
- 1
|
||||
- - llm_embedding_gitlab_documentation_set_embeddings_on_the_record
|
||||
- 1
|
||||
- - llm_tanuki_bot_update
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ This API requires an access token with the Maintainer or Owner role.
|
|||
|
||||
## List all active integrations
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21330) in GitLab 12.7.
|
||||
> `vulnerability_events` field [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131831) in GitLab 16.5.
|
||||
|
||||
Get a list of all active project integrations.
|
||||
Get a list of all active project integrations. The `vulnerability_events` field is only available for GitLab Enterprise Edition.
|
||||
|
||||
```plaintext
|
||||
GET /projects/:id/integrations
|
||||
|
|
@ -49,7 +49,8 @@ Example response:
|
|||
"pipeline_events": true,
|
||||
"wiki_page_events": true,
|
||||
"job_events": true,
|
||||
"comment_on_event_enabled": true
|
||||
"comment_on_event_enabled": true,
|
||||
"vulnerability_events": true
|
||||
},
|
||||
{
|
||||
"id": 76,
|
||||
|
|
@ -71,7 +72,8 @@ Example response:
|
|||
"pipeline_events": true,
|
||||
"wiki_page_events": true,
|
||||
"job_events": true,
|
||||
"comment_on_event_enabled": true
|
||||
"comment_on_event_enabled": true,
|
||||
"vulnerability_events": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
|
|
|||
|
|
@ -20,9 +20,8 @@ You can create [Personal access tokens](../user/profile/personal_access_tokens.m
|
|||
You can limit the scope and expiration date of your personal access tokens. By default,
|
||||
they inherit permissions from the user who created them.
|
||||
|
||||
You can use the [personal access tokens API](../api/personal_access_tokens.md) to
|
||||
programmatically take action, such as
|
||||
[rotating a personal access token](../api/personal_access_tokens.md#rotate-a-personal-access-token).
|
||||
You can use the personal access tokens API to programmatically take action,
|
||||
such as [rotating a personal access token](../api/personal_access_tokens.md#rotate-a-personal-access-token).
|
||||
|
||||
You will receive an email when personal access tokens are 7 days or less from expiration.
|
||||
|
||||
|
|
@ -121,6 +120,9 @@ Malicious access to a runner's file system may expose the `config.toml` file and
|
|||
runner authentication token. The attacker could use the runner authentication
|
||||
to [clone the runner](https://docs.gitlab.com/runner/security/#cloning-a-runner).
|
||||
|
||||
You can use the `runners` API to
|
||||
programmatically [rotate or revoke a runner authentication token](../api/runners.md#reset-runners-authentication-token-by-using-the-current-token).
|
||||
|
||||
## Runner registration tokens (deprecated)
|
||||
|
||||
WARNING:
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ GitLab is creating AI-assisted features across our DevSecOps platform. These fea
|
|||
| [Vulnerability summary](application_security/vulnerabilities/index.md#explaining-a-vulnerability) | Helps you remediate vulnerabilities more efficiently, uplevel your skills, and write more secure code. | [Google Vertex Codey APIs](https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview) <br><br> Anthropic's claude model if degraded performance | SaaS only <br><br> Ultimate tier | [Beta](../policy/experiment-beta-support.md#beta) |
|
||||
| [Code explanation](#explain-code-in-the-web-ui-with-code-explanation) | Helps you understand code by explaining it in English language. | [Google Vertex Codey APIs](https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview) | SaaS only <br><br> Ultimate tier | [Experiment](../policy/experiment-beta-support.md#experiment) |
|
||||
| [Chat](#answer-questions-with-chat) | Process and generate text and code in a conversational manner. Helps you quickly identify useful information in large volumes of text in issues, epics, code, and GitLab documentation. | Anthropic's claude model <br><br> OpenAI Embeddings | SaaS only | [Experiment](../policy/experiment-beta-support.md#experiment) |
|
||||
| [Value stream forecasting](analytics/value_streams_dashboard.md) | Assists you with predicting productivity metrics and identifying anomalies across your software development lifecycle. | Statistical forecasting | SaaS only | [Experiment](../policy/experiment-beta-support.md#experiment) |
|
||||
| [Value stream forecasting](#forecast-deployment-frequency-with-value-stream-forecasting) | Assists you with predicting productivity metrics and identifying anomalies across your software development lifecycle. | Statistical forecasting | SaaS only | [Experiment](../policy/experiment-beta-support.md#experiment) |
|
||||
| [Discussion summary](#summarize-issue-discussions-with-discussion-summary) | Assists with quickly getting everyone up to speed on lengthy conversations to help ensure you are all on the same page. | [Google Vertex Codey APIs](https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview) | SaaS only | [Experiment](../policy/experiment-beta-support.md#experiment) |
|
||||
| [Merge request summary](project/merge_requests/ai_in_merge_requests.md#summarize-merge-request-changes) | Efficiently communicate the impact of your merge request changes. | [Google Vertex Codey APIs](https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview) | SaaS only | [Experiment](../policy/experiment-beta-support.md#experiment) |
|
||||
| [Code review summary](project/merge_requests/ai_in_merge_requests.md#summarize-my-merge-request-review) | Helps ease merge request handoff between authors and reviewers and help reviewers efficiently understand suggestions. | [Google Vertex Codey APIs](https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview) | SaaS only | [Experiment](../policy/experiment-beta-support.md#experiment) |
|
||||
|
|
@ -28,7 +28,7 @@ GitLab is creating AI-assisted features across our DevSecOps platform. These fea
|
|||
|
||||
## Enable AI/ML features
|
||||
|
||||
The [Generally Available features](../policy/experiment-beta-support.md#generally-available-ga) listed in the previous table do not need to be enabled.
|
||||
The [Generally Available](../policy/experiment-beta-support.md#generally-available-ga) features listed in the previous table do not need to be enabled.
|
||||
|
||||
[Experiment features](../policy/experiment-beta-support.md#experiment) and [Beta features](../policy/experiment-beta-support.md#beta) (besides Code Suggestions) on SaaS must be enabled by a user who has the Owner role in the group. Their usage is subject to the [Testing Terms of Use](https://about.gitlab.com/handbook/legal/testing-agreement/).
|
||||
|
||||
|
|
|
|||
|
|
@ -29,3 +29,5 @@ module API
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
API::Entities::ProjectIntegrationBasic.prepend_mod
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Prometheus
|
||||
module Queries
|
||||
class AdditionalMetricsDeploymentQuery < BaseQuery
|
||||
include QueryAdditionalMetrics
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def query(deployment_id)
|
||||
Deployment.find_by(id: deployment_id).try do |deployment|
|
||||
query_metrics(
|
||||
deployment.project,
|
||||
deployment.environment,
|
||||
common_query_context(
|
||||
deployment.environment,
|
||||
timeframe_start: (deployment.created_at - 30.minutes).to_f,
|
||||
timeframe_end: (deployment.created_at + 30.minutes).to_f
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Prometheus
|
||||
module Queries
|
||||
class AdditionalMetricsEnvironmentQuery < BaseQuery
|
||||
include QueryAdditionalMetrics
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def query(environment_id, timeframe_start = 8.hours.ago, timeframe_end = Time.now)
|
||||
::Environment.find_by(id: environment_id).try do |environment|
|
||||
query_metrics(
|
||||
environment.project,
|
||||
environment,
|
||||
common_query_context(
|
||||
environment,
|
||||
timeframe_start: timeframe_start.to_f,
|
||||
timeframe_end: timeframe_end.to_f
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -45,6 +45,9 @@ msgstr ""
|
|||
msgid " and %{sliced}"
|
||||
msgstr ""
|
||||
|
||||
msgid " and leave a comment on"
|
||||
msgstr ""
|
||||
|
||||
msgid " except branch:"
|
||||
msgid_plural " except branches:"
|
||||
msgstr[0] ""
|
||||
|
|
@ -18241,9 +18244,6 @@ msgstr ""
|
|||
msgid "Enterprise User Account on GitLab"
|
||||
msgstr ""
|
||||
|
||||
msgid "EnterpriseUsers|The user detail cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
msgid "EnterpriseUsers|The user does not match the \"Enterprise User\" definition for the group"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -54065,7 +54065,7 @@ msgstr ""
|
|||
msgid "You are going to transfer %{project_full_name} to another namespace. Are you ABSOLUTELY sure?"
|
||||
msgstr ""
|
||||
|
||||
msgid "You are going to turn off the confidentiality. This means %{strongStart}everyone%{strongEnd} will be able to see and leave a comment on this %{issuableType}."
|
||||
msgid "You are going to turn off the confidentiality. This means %{strongStart}everyone%{strongEnd} will be able to see%{commentText} this %{issuableType}."
|
||||
msgstr ""
|
||||
|
||||
msgid "You are going to turn on confidentiality. Only %{context} members with %{strongStart}%{permissions}%{strongEnd} can view or be notified about this %{issuableType}."
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ module QA
|
|||
end
|
||||
|
||||
base.view 'app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue' do
|
||||
element :approve_access_request_button
|
||||
element 'approve-access-request-button'
|
||||
end
|
||||
|
||||
base.view 'app/assets/javascripts/members/components/members_tabs.vue' do
|
||||
|
|
@ -69,13 +69,13 @@ module QA
|
|||
|
||||
def approve_access_request(username)
|
||||
within_element(:member_row, text: username) do
|
||||
click_element :approve_access_request_button
|
||||
click_element 'approve-access-request-button'
|
||||
end
|
||||
end
|
||||
|
||||
def deny_access_request(username)
|
||||
within_element(:member_row, text: username) do
|
||||
click_element :delete_member_button
|
||||
click_element 'delete-member-button'
|
||||
end
|
||||
|
||||
confirm_remove_member
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ module QA
|
|||
|
||||
view 'app/views/dashboard/todos/index.html.haml' do
|
||||
element :todos_list_container, required: true
|
||||
element :group_dropdown
|
||||
element 'group-dropdown'
|
||||
end
|
||||
|
||||
view 'app/views/dashboard/todos/_todo.html.haml' do
|
||||
element :todo_item_container
|
||||
element 'todo-item-container'
|
||||
element :todo_action_name_content
|
||||
element :todo_author_name_content
|
||||
element 'todo-author-name-content'
|
||||
end
|
||||
|
||||
view 'app/helpers/dropdowns_helper.rb' do
|
||||
|
|
@ -23,15 +23,15 @@ module QA
|
|||
end
|
||||
|
||||
def has_todo_list?
|
||||
has_element?(:todo_item_container)
|
||||
has_element?('todo-item-container')
|
||||
end
|
||||
|
||||
def has_no_todo_list?
|
||||
has_no_element?(:todo_item_container)
|
||||
has_no_element?('todo-item-container')
|
||||
end
|
||||
|
||||
def filter_todos_by_group(group)
|
||||
click_element :group_dropdown
|
||||
click_element 'group-dropdown'
|
||||
|
||||
fill_element(:dropdown_input_field, group.path)
|
||||
|
||||
|
|
@ -43,11 +43,11 @@ module QA
|
|||
end
|
||||
|
||||
def click_todo_with_content(content)
|
||||
click_element(:todo_item_container, text: content)
|
||||
click_element('todo-item-container', text: content)
|
||||
end
|
||||
|
||||
def has_latest_todo_with_author?(author:, action:)
|
||||
content = { selector: :todo_author_name_content, text: author }
|
||||
content = { selector: 'todo-author-name-content', text: author }
|
||||
has_latest_todo_with_content?(action, **content)
|
||||
end
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ module QA
|
|||
|
||||
def has_latest_todo_with_content?(action, **kwargs)
|
||||
within_element(:todos_list_container) do
|
||||
within_element_by_index(:todo_item_container, 0) do
|
||||
within_element_by_index('todo-item-container', 0) do
|
||||
has_element?(:todo_action_name_content, text: action) &&
|
||||
has_element?(kwargs[:selector], text: kwargs[:text])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ module QA
|
|||
|
||||
view 'app/views/shared/members/_access_request_links.html.haml' do
|
||||
element :leave_group_link
|
||||
element :request_access_link
|
||||
element 'request-access-link'
|
||||
end
|
||||
|
||||
def click_subgroup(name)
|
||||
|
|
@ -49,7 +49,7 @@ module QA
|
|||
end
|
||||
|
||||
def click_request_access
|
||||
click_element :request_access_link
|
||||
click_element 'request-access-link'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@
|
|||
},
|
||||
"comment_on_event_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"vulnerability_events": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
|||
|
|
@ -38,6 +38,23 @@ describe('Sidebar Confidentiality Form', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const confidentialityMutation = (confidential, workspacePath) => {
|
||||
return {
|
||||
mutation: confidentialityQueries[wrapper.vm.issuableType].mutation,
|
||||
variables: {
|
||||
input: {
|
||||
confidential,
|
||||
iid: '1',
|
||||
...workspacePath,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const clickConfidentialToggle = () => {
|
||||
findConfidentialToggle().vm.$emit('click', new MouseEvent('click'));
|
||||
};
|
||||
|
||||
it('emits a `closeForm` event when Cancel button is clicked', () => {
|
||||
createComponent();
|
||||
findCancelButton().vm.$emit('click');
|
||||
|
|
@ -94,17 +111,10 @@ describe('Sidebar Confidentiality Form', () => {
|
|||
});
|
||||
|
||||
it('calls a mutation to set confidential to true on button click', () => {
|
||||
findConfidentialToggle().vm.$emit('click', new MouseEvent('click'));
|
||||
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
|
||||
mutation: confidentialityQueries[wrapper.vm.issuableType].mutation,
|
||||
variables: {
|
||||
input: {
|
||||
confidential: true,
|
||||
iid: '1',
|
||||
projectPath: 'group/project',
|
||||
},
|
||||
},
|
||||
});
|
||||
clickConfidentialToggle();
|
||||
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith(
|
||||
confidentialityMutation(true, { projectPath: 'group/project' }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -150,17 +160,49 @@ describe('Sidebar Confidentiality Form', () => {
|
|||
});
|
||||
|
||||
it('calls a mutation to set epic confidentiality with correct parameters', () => {
|
||||
findConfidentialToggle().vm.$emit('click', new MouseEvent('click'));
|
||||
clickConfidentialToggle();
|
||||
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith(
|
||||
confidentialityMutation(false, { groupPath: 'group/project' }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
|
||||
mutation: confidentialityQueries[wrapper.vm.issuableType].mutation,
|
||||
variables: {
|
||||
input: {
|
||||
confidential: false,
|
||||
iid: '1',
|
||||
groupPath: 'group/project',
|
||||
},
|
||||
},
|
||||
describe('when issuable type is `test_case`', () => {
|
||||
describe('when test case is confidential', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ props: { confidential: true, issuableType: 'test_case' } });
|
||||
});
|
||||
|
||||
it('renders a message about making a test case non-confidential', () => {
|
||||
expect(findWarningMessage().text()).toBe(
|
||||
'You are going to turn off the confidentiality. This means everyone will be able to see this test case.',
|
||||
);
|
||||
});
|
||||
|
||||
it('calls a mutation to set confidential to false on button click', () => {
|
||||
clickConfidentialToggle();
|
||||
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith(
|
||||
confidentialityMutation(false, { projectPath: 'group/project' }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when test case is not confidential', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ props: { issuableType: 'test_case' } });
|
||||
});
|
||||
|
||||
it('renders a message about making a test case confidential', () => {
|
||||
expect(findWarningMessage().text()).toBe(
|
||||
'You are going to turn on confidentiality. Only project members with at least the Reporter role can view or be notified about this test case.',
|
||||
);
|
||||
});
|
||||
|
||||
it('calls a mutation to set confidential to true on button click', () => {
|
||||
clickConfidentialToggle();
|
||||
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith(
|
||||
confidentialityMutation(true, { projectPath: 'group/project' }),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,13 +2,7 @@ import { GlBadge, GlButton, GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import { resetHTMLFixture, setHTMLFixture } from 'helpers/fixtures';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import {
|
||||
STATUS_CLOSED,
|
||||
STATUS_OPEN,
|
||||
STATUS_REOPENED,
|
||||
TYPE_ISSUE,
|
||||
WORKSPACE_PROJECT,
|
||||
} from '~/issues/constants';
|
||||
import { STATUS_CLOSED, STATUS_OPEN, STATUS_REOPENED, TYPE_ISSUE } from '~/issues/constants';
|
||||
import { __ } from '~/locale';
|
||||
import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
|
|
@ -45,7 +39,6 @@ describe('IssuableHeader component', () => {
|
|||
...mockIssuableShowProps,
|
||||
issuableState: STATUS_OPEN,
|
||||
issuableType: TYPE_ISSUE,
|
||||
workspaceType: WORKSPACE_PROJECT,
|
||||
...props,
|
||||
},
|
||||
slots: {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ export const mockIssuableShowProps = {
|
|||
showFieldTitle: false,
|
||||
statusIcon: 'issues',
|
||||
statusIconClass: 'gl-sm-display-none',
|
||||
workspaceType: 'project',
|
||||
taskCompletionStatus: {
|
||||
completedCount: 0,
|
||||
count: 5,
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Prometheus::Queries::AdditionalMetricsDeploymentQuery do
|
||||
around do |example|
|
||||
travel_to(Time.local(2008, 9, 1, 12, 0, 0)) { example.run }
|
||||
end
|
||||
|
||||
include_examples 'additional metrics query' do
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:deployment) { create(:deployment, environment: environment, project: project) }
|
||||
let(:query_params) { [deployment.id] }
|
||||
|
||||
it 'queries using specific time' do
|
||||
expect(client).to receive(:query_range).with(anything,
|
||||
start_time: (deployment.created_at - 30.minutes).to_f,
|
||||
end_time: (deployment.created_at + 30.minutes).to_f)
|
||||
|
||||
expect(query_result).not_to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
|
||||
around do |example|
|
||||
freeze_time { example.run }
|
||||
end
|
||||
|
||||
include_examples 'additional metrics query' do
|
||||
let(:query_params) { [environment.id] }
|
||||
|
||||
it 'queries using specific time' do
|
||||
expect(client).to receive(:query_range)
|
||||
.with(anything, start_time: 8.hours.ago.to_f, end_time: Time.now.to_f)
|
||||
expect(query_result).not_to be_nil
|
||||
end
|
||||
|
||||
context 'when start and end time parameters are provided' do
|
||||
let(:query_params) { [environment.id, start_time, end_time] }
|
||||
|
||||
context 'as unix timestamps' do
|
||||
let(:start_time) { 4.hours.ago.to_f }
|
||||
let(:end_time) { 2.hours.ago.to_f }
|
||||
|
||||
it 'queries using the provided times' do
|
||||
expect(client).to receive(:query_range)
|
||||
.with(anything, start_time: start_time, end_time: end_time)
|
||||
expect(query_result).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'as Date/Time objects' do
|
||||
let(:start_time) { 4.hours.ago }
|
||||
let(:end_time) { 2.hours.ago }
|
||||
|
||||
it 'queries using the provided times converted to unix' do
|
||||
expect(client).to receive(:query_range)
|
||||
.with(anything, start_time: start_time.to_f, end_time: end_time.to_f)
|
||||
expect(query_result).not_to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -100,28 +100,6 @@ RSpec.describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'additional_metrics' do
|
||||
let(:additional_metrics_environment_query) { Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery }
|
||||
let(:environment) { build_stubbed(:environment, slug: 'env-slug') }
|
||||
let(:time_window) { [1552642245.067, 1552642095.831] }
|
||||
|
||||
around do |example|
|
||||
freeze_time { example.run }
|
||||
end
|
||||
|
||||
context 'with valid data' do
|
||||
subject { integration.query(:additional_metrics_environment, environment, *time_window) }
|
||||
|
||||
before do
|
||||
stub_reactive_cache(integration, prometheus_data, additional_metrics_environment_query, environment.id, *time_window)
|
||||
end
|
||||
|
||||
it 'returns reactive data' do
|
||||
expect(subject).to eq(prometheus_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#calculate_reactive_cache' do
|
||||
|
|
|
|||
|
|
@ -288,4 +288,18 @@ RSpec.describe GroupMember, feature_category: :cell do
|
|||
it_behaves_like 'calls AuthorizedProjectsWorker inline to recalculate authorizations'
|
||||
end
|
||||
end
|
||||
|
||||
context 'group member welcome email', :sidekiq_inline, :saas do
|
||||
let_it_be(:group) { create(:group) }
|
||||
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'schedules plain welcome to the group email' do
|
||||
expect_next_instance_of(NotificationService) do |notification|
|
||||
expect(notification).to receive(:new_group_member)
|
||||
end
|
||||
|
||||
group.add_developer(user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2095,6 +2095,7 @@ RSpec.describe User, feature_category: :user_profile do
|
|||
it 'uses SecureRandom to generate the incoming email token' do
|
||||
allow_next_instance_of(User) do |user|
|
||||
allow(user).to receive(:update_highest_role)
|
||||
allow(user).to receive(:associate_with_enterprise_group)
|
||||
end
|
||||
|
||||
allow_next_instance_of(Namespaces::UserNamespace) do |namespace|
|
||||
|
|
|
|||
|
|
@ -346,8 +346,9 @@ RSpec.describe 'Every Sidekiq worker', feature_category: :shared do
|
|||
'JiraConnect::SyncProjectWorker' => 3,
|
||||
'LdapGroupSyncWorker' => 3,
|
||||
'Licenses::ResetSubmitLicenseUsageDataBannerWorker' => 13,
|
||||
'Llm::Embedding::GitlabDocumentation::SetEmbeddingsOnTheRecordWorker' => 1,
|
||||
'Llm::Embedding::GitlabDocumentation::SetEmbeddingsOnTheRecordWorker' => 5,
|
||||
'Llm::Embedding::GitlabDocumentation::CreateEmptyEmbeddingsRecordsWorker' => 3,
|
||||
'Llm::Embedding::GitlabDocumentation::CreateDbEmbeddingsPerDocFileWorker' => 5,
|
||||
'Llm::TanukiBot::UpdateWorker' => 1,
|
||||
'Llm::TanukiBot::RecreateRecordsWorker' => 3,
|
||||
'MailScheduler::IssueDueWorker' => 3,
|
||||
|
|
|
|||
Loading…
Reference in New Issue