Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-09-19 09:10:17 +00:00
parent 8b13b280f5
commit 236caf4b92
37 changed files with 187 additions and 218 deletions

View File

@ -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.

View File

@ -1 +1 @@
c7099d645d162a8760f7f84e9f3e0c45229240c1
e450c7ca1115ddc16b3db84a5400b781ed81e2e6

View File

@ -1 +1 @@
14.27.0
14.28.0

View File

@ -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'),

View File

@ -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"
/>

View File

@ -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>

View File

@ -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">

View File

@ -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 = {

View File

@ -0,0 +1,9 @@
query testCaseConfidential($fullPath: ID!, $iid: String) {
workspace: project(fullPath: $fullPath) {
id
issuable: issue(iid: $iid) {
id
confidential
}
}
}

View File

@ -0,0 +1,9 @@
mutation updateTestCaseConfidential($input: IssueSetConfidentialInput!) {
issuableSetConfidential: issueSetConfidential(input: $input) {
issuable: issue {
id
confidential
}
errors
}
}

View File

@ -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')

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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])

View File

@ -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' }

View File

@ -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

View File

@ -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
}
]
```

View File

@ -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:

View File

@ -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/).

View File

@ -29,3 +29,5 @@ module API
end
end
end
API::Entities::ProjectIntegrationBasic.prepend_mod

View File

@ -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

View File

@ -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

View File

@ -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}."

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -65,6 +65,9 @@
},
"comment_on_event_enabled": {
"type": "boolean"
},
"vulnerability_events": {
"type": "boolean"
}
},
"additionalProperties": false

View File

@ -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' }),
);
});
});
});

View File

@ -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: {

View File

@ -38,6 +38,7 @@ export const mockIssuableShowProps = {
showFieldTitle: false,
statusIcon: 'issues',
statusIconClass: 'gl-sm-display-none',
workspaceType: 'project',
taskCompletionStatus: {
completedCount: 0,
count: 5,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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|

View File

@ -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,