Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f33d86ffac
commit
0dd9f7b364
|
|
@ -44,10 +44,10 @@ export function createProject(projectData) {
|
|||
});
|
||||
}
|
||||
|
||||
export function deleteProject(projectId) {
|
||||
export function deleteProject(projectId, params) {
|
||||
const url = buildApiUrl(PROJECT_PATH).replace(':id', projectId);
|
||||
|
||||
return axios.delete(url);
|
||||
return axios.delete(url, { params });
|
||||
}
|
||||
|
||||
export function importProjectMembers(sourceId, targetId) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
export const organizationProjects = [
|
||||
{
|
||||
id: 'gid://gitlab/Project/8',
|
||||
fullPath: 'project/8',
|
||||
nameWithNamespace: 'Twitter / Typeahead.Js',
|
||||
organizationEditPath: '/-/organizations/default/projects/twitter/Typeahead.Js/edit',
|
||||
webUrl: 'http://127.0.0.1:3000/twitter/Typeahead.Js',
|
||||
|
|
@ -40,6 +41,7 @@ export const organizationProjects = [
|
|||
},
|
||||
{
|
||||
id: 'gid://gitlab/Project/7',
|
||||
fullPath: 'project/7',
|
||||
nameWithNamespace: 'Flightjs / Flight',
|
||||
organizationEditPath: '/-/organizations/default/projects/flightjs/Flight/edit',
|
||||
webUrl: 'http://127.0.0.1:3000/flightjs/Flight',
|
||||
|
|
@ -73,6 +75,7 @@ export const organizationProjects = [
|
|||
},
|
||||
{
|
||||
id: 'gid://gitlab/Project/6',
|
||||
fullPath: 'project/6',
|
||||
nameWithNamespace: 'Jashkenas / Underscore',
|
||||
organizationEditPath: '/-/organizations/default/projects/jashkenas/Underscore/edit',
|
||||
webUrl: 'http://127.0.0.1:3000/jashkenas/Underscore',
|
||||
|
|
@ -106,6 +109,7 @@ export const organizationProjects = [
|
|||
},
|
||||
{
|
||||
id: 'gid://gitlab/Project/5',
|
||||
fullPath: 'project/5',
|
||||
nameWithNamespace: 'Commit451 / Lab Coat',
|
||||
organizationEditPath: '/-/organizations/default/projects/Commit451/lab-coat/edit',
|
||||
webUrl: 'http://127.0.0.1:3000/Commit451/lab-coat',
|
||||
|
|
@ -139,6 +143,7 @@ export const organizationProjects = [
|
|||
},
|
||||
{
|
||||
id: 'gid://gitlab/Project/1',
|
||||
fullPath: 'project/1',
|
||||
nameWithNamespace: 'Toolbox / Gitlab Smoke Tests',
|
||||
organizationEditPath: '/-/organizations/default/projects/toolbox/gitlab-smoke-tests/edit',
|
||||
webUrl: 'http://127.0.0.1:3000/toolbox/gitlab-smoke-tests',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
fragment BaseProject on Project {
|
||||
id
|
||||
fullPath
|
||||
archived
|
||||
nameWithNamespace
|
||||
organizationEditPath
|
||||
|
|
|
|||
|
|
@ -113,10 +113,7 @@ export default {
|
|||
<div class="hide-collapsed gl-line-height-20 gl-font-weight-bold">
|
||||
{{ contactsLabel }}
|
||||
</div>
|
||||
<div
|
||||
class="hide-collapsed gl-display-flex gl-flex-wrap"
|
||||
:class="contacts.length > 0 ? 'gl-mt-2' : ''"
|
||||
>
|
||||
<div v-if="shouldShowContacts" class="hide-collapsed gl-display-flex gl-flex-wrap gl-mt-2">
|
||||
<div
|
||||
v-for="(contact, index) in contacts"
|
||||
:id="`contact_container_${index}`"
|
||||
|
|
@ -137,5 +134,12 @@ export default {
|
|||
</gl-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
data-testid="crm-empty-message"
|
||||
class="gl-display-flex gl-align-items-center hide-collapsed gl-text-gray-500"
|
||||
>
|
||||
{{ __('To add active contacts, use /add_contacts.') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import {
|
|||
GlSprintf,
|
||||
GlModal,
|
||||
GlAlert,
|
||||
GlLoadingIcon,
|
||||
GlDisclosureDropdown,
|
||||
GlDisclosureDropdownGroup,
|
||||
GlDisclosureDropdownItem,
|
||||
|
|
@ -40,7 +39,6 @@ export default {
|
|||
GlSprintf,
|
||||
GlModal,
|
||||
GlAlert,
|
||||
GlLoadingIcon,
|
||||
GlDisclosureDropdown,
|
||||
GlDisclosureDropdownGroup,
|
||||
GlDisclosureDropdownItem,
|
||||
|
|
@ -347,7 +345,6 @@ export default {
|
|||
</div>
|
||||
|
||||
<gl-modal
|
||||
ref="deleteModal"
|
||||
v-model="isDeleteModalVisible"
|
||||
modal-id="delete-modal"
|
||||
:title="__('Delete snippet modal')"
|
||||
|
|
@ -374,11 +371,10 @@ export default {
|
|||
<gl-button
|
||||
variant="danger"
|
||||
category="primary"
|
||||
:disabled="isLoading"
|
||||
:loading="isLoading"
|
||||
data-testid="delete-snippet-button"
|
||||
@click="deleteSnippet"
|
||||
>
|
||||
<gl-loading-icon v-if="isLoading" size="sm" inline />
|
||||
{{ __('Delete snippet') }}
|
||||
</gl-button>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ export default {
|
|||
</template>
|
||||
</template>
|
||||
<span v-else class="gl-text-secondary">
|
||||
{{ s__('TimeTracking|Use /spend or /estimate to manage time.') }}
|
||||
{{ s__('TimeTracking|To manage time, use /spend or /estimate.') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
# Use this template to announce a feature deprecation or other
|
||||
# important planned changes at least three releases prior to removal.
|
||||
# Breaking changes must happen in a major release.
|
||||
#
|
||||
# See the deprecation guidelines to confirm your understanding of GitLab's definitions:
|
||||
# https://docs.gitlab.com/ee/development/deprecation_guidelines/#terminology
|
||||
#
|
||||
# If an End of Support period applies, see the OPTIONAL section below.
|
||||
#
|
||||
# For more information, see the handbook:
|
||||
# https://handbook.gitlab.com/handbook/marketing/blog/release-posts/#deprecations-and-other-planned-breaking-change-announcements
|
||||
|
||||
# ===================
|
||||
# REQUIRED FIELDS
|
||||
# ===================
|
||||
|
||||
# ----- DELETE EVERYTHING ABOVE THIS LINE -----
|
||||
|
||||
- title: "Hosted Runners on Linux operating system upgrade"
|
||||
# The milestones for the deprecation announcement, and the removal.
|
||||
removal_milestone: "17.0"
|
||||
announcement_milestone: "16.10"
|
||||
# Change breaking_change to false if needed.
|
||||
breaking_change: true
|
||||
# The stage and GitLab username of the person reporting the change,
|
||||
# and a link to the deprecation issue
|
||||
reporter: tmaczukin
|
||||
stage: ci
|
||||
issue_url: https://gitlab.com/gitlab-org/ci-cd/shared-runners/infrastructure/-/issues/60
|
||||
impact: low # Can be one of: [critical, high, medium, low]
|
||||
scope: instance # Can be one or a combination of: [instance, group, project]
|
||||
resolution_role: Developer # Can be one of: [Admin, Owner, Maintainer, Developer]
|
||||
manual_task: true # Can be true or false. Use this to denote whether a resolution action must be performed manually (true), or if it can be automated by using the API or other automation (false).
|
||||
body: | # (required) Don't change this line.
|
||||
With GitLab 17.0 we're upgrading the container-optimized operating system ([COS](https://cloud.google.com/container-optimized-os/docs))
|
||||
of the ephemeral VMs used to execute jobs for [Hosted Runners on Linux](https://docs.gitlab.com/ee/ci/runners/saas/linux_saas_runner.html).
|
||||
The COS upgrade includes a Docker Engine upgrade from Version 19.03.15 to Version 23.0.5, which introduced
|
||||
a known compatibility issue.
|
||||
|
||||
GitLab CI/CD jobs [using Docker-in-Docker-based jobs](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker)
|
||||
with a Docker-in-Docker service version prior to 20.10 and GitLab CI/CD jobs [using Kaniko to build container images](https://docs.gitlab.com/ee/ci/docker/using_kaniko.html)
|
||||
with a Kaniko service version older than `v1.9.0` will start failing.
|
||||
|
||||
To fix these issues, an update of service version in `.gitlab-ci.yml` is required.
|
||||
|
||||
Both issues, including a detailed explanation of how they affect jobs and how to fix
|
||||
the issue, are described
|
||||
[in the announcement blog post](https://about.gitlab.com/blog/2023/10/04/updating-the-os-version-of-saas-runners-on-linux/).
|
||||
|
||||
# ==============================
|
||||
# OPTIONAL END-OF-SUPPORT FIELDS
|
||||
# ==============================
|
||||
#
|
||||
# If an End of Support period applies:
|
||||
# 1) Share this announcement in the `#spt_managers` Support channel in Slack
|
||||
# 2) Mention `@gitlab-com/support` in this merge request.
|
||||
#
|
||||
# When support for this feature ends, in XX.YY milestone format.
|
||||
end_of_support_milestone:
|
||||
# Array of tiers the feature is currently available to,
|
||||
# like [Free, Silver, Gold, Core, Premium, Ultimate]
|
||||
tiers:
|
||||
# Links to documentation and thumbnail image
|
||||
documentation_url:
|
||||
image_url:
|
||||
# Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
|
||||
video_url:
|
||||
|
|
@ -1,10 +1,25 @@
|
|||
---
|
||||
table_name: dependency_proxy_blob_states
|
||||
classes:
|
||||
- Geo::DependencyProxyBlobState
|
||||
- Geo::DependencyProxyBlobState
|
||||
feature_categories:
|
||||
- geo_replication
|
||||
- geo_replication
|
||||
description: Separate table for dependency proxy blob verification states
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101429
|
||||
milestone: '15.6'
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
allow_cross_transactions:
|
||||
- gitlab_main_clusterwide
|
||||
allow_cross_foreign_keys:
|
||||
- gitlab_main_clusterwide
|
||||
desired_sharding_key:
|
||||
group_id:
|
||||
references: namespaces
|
||||
backfill_via:
|
||||
parent:
|
||||
foreign_key: dependency_proxy_blob_id
|
||||
table: dependency_proxy_blobs
|
||||
sharding_key: group_id
|
||||
belongs_to: dependency_proxy_blob
|
||||
|
|
|
|||
|
|
@ -1,10 +1,25 @@
|
|||
---
|
||||
table_name: dependency_proxy_manifest_states
|
||||
classes:
|
||||
- Geo::DependencyProxyManifestState
|
||||
- Geo::DependencyProxyManifestState
|
||||
feature_categories:
|
||||
- geo_replication
|
||||
- geo_replication
|
||||
description: Separate table for dependency proxy manifest verification states
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/102908
|
||||
milestone: '15.6'
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
allow_cross_transactions:
|
||||
- gitlab_main_clusterwide
|
||||
allow_cross_foreign_keys:
|
||||
- gitlab_main_clusterwide
|
||||
desired_sharding_key:
|
||||
group_id:
|
||||
references: namespaces
|
||||
backfill_via:
|
||||
parent:
|
||||
foreign_key: dependency_proxy_manifest_id
|
||||
table: dependency_proxy_manifests
|
||||
sharding_key: group_id
|
||||
belongs_to: dependency_proxy_manifest
|
||||
|
|
|
|||
|
|
@ -7,4 +7,19 @@ feature_categories:
|
|||
description: User mentions in epic descriptions
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19009
|
||||
milestone: '12.6'
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
allow_cross_joins:
|
||||
- gitlab_main_clusterwide
|
||||
allow_cross_transactions:
|
||||
- gitlab_main_clusterwide
|
||||
allow_cross_foreign_keys:
|
||||
- gitlab_main_clusterwide
|
||||
desired_sharding_key:
|
||||
group_id:
|
||||
references: namespaces
|
||||
backfill_via:
|
||||
parent:
|
||||
foreign_key: epic_id
|
||||
table: epics
|
||||
sharding_key: group_id
|
||||
belongs_to: epic
|
||||
|
|
|
|||
|
|
@ -25479,6 +25479,7 @@ Check permissions for the current user on a vulnerability finding.
|
|||
| <a id="projectid"></a>`id` | [`ID!`](#id) | ID of the project. |
|
||||
| <a id="projectimportstatus"></a>`importStatus` | [`String`](#string) | Status of import background job of the project. |
|
||||
| <a id="projectincidentmanagementtimelineeventtags"></a>`incidentManagementTimelineEventTags` | [`[TimelineEventTagType!]`](#timelineeventtagtype) | Timeline event tags for the project. |
|
||||
| <a id="projectisadjourneddeletionenabled"></a>`isAdjournedDeletionEnabled` **{warning-solid}** | [`Boolean!`](#boolean) | **Introduced** in GitLab 16.11. **Status**: Experiment. Indicates if delayed project deletion is enabled. |
|
||||
| <a id="projectiscatalogresource"></a>`isCatalogResource` **{warning-solid}** | [`Boolean`](#boolean) | **Introduced** in GitLab 15.11. **Status**: Experiment. Indicates if a project is a catalog resource. |
|
||||
| <a id="projectisforked"></a>`isForked` | [`Boolean!`](#boolean) | Project is forked. |
|
||||
| <a id="projectissuesaccesslevel"></a>`issuesAccessLevel` | [`ProjectFeatureAccess`](#projectfeatureaccess) | Access level required for issues access. |
|
||||
|
|
@ -25509,6 +25510,7 @@ Check permissions for the current user on a vulnerability finding.
|
|||
| <a id="projectpackagesprotectionrules"></a>`packagesProtectionRules` | [`PackagesProtectionRuleConnection`](#packagesprotectionruleconnection) | Packages protection rules for the project. (see [Connections](#connections)) |
|
||||
| <a id="projectpath"></a>`path` | [`String!`](#string) | Path of the project. |
|
||||
| <a id="projectpathlocks"></a>`pathLocks` | [`PathLockConnection`](#pathlockconnection) | The project's path locks. (see [Connections](#connections)) |
|
||||
| <a id="projectpermanentdeletiondate"></a>`permanentDeletionDate` **{warning-solid}** | [`String`](#string) | **Introduced** in GitLab 16.11. **Status**: Experiment. Date when project will be deleted if delayed project deletion is enabled. |
|
||||
| <a id="projectpipelineanalytics"></a>`pipelineAnalytics` | [`PipelineAnalytics`](#pipelineanalytics) | Pipeline analytics. |
|
||||
| <a id="projectpipelinetriggers"></a>`pipelineTriggers` **{warning-solid}** | [`PipelineTriggerConnection`](#pipelinetriggerconnection) | **Introduced** in GitLab 16.3. **Status**: Experiment. List of pipeline trigger tokens. |
|
||||
| <a id="projectpreventmergewithoutjiraissueenabled"></a>`preventMergeWithoutJiraIssueEnabled` | [`Boolean!`](#boolean) | Indicates if an associated issue from Jira is required. |
|
||||
|
|
|
|||
|
|
@ -1241,33 +1241,6 @@ set `AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER` to `heroku/builder:20`.
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### Hosted Runners on Linux operating system upgrade
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">16.10</span>
|
||||
- Removal in GitLab <span class="milestone">17.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/ci-cd/shared-runners/infrastructure/-/issues/60).
|
||||
</div>
|
||||
|
||||
With GitLab 17.0 we're upgrading the container-optimized operating system ([COS](https://cloud.google.com/container-optimized-os/docs))
|
||||
of the ephemeral VMs used to execute jobs for [Hosted Runners on Linux](https://docs.gitlab.com/ee/ci/runners/saas/linux_saas_runner.html).
|
||||
The COS upgrade includes a Docker Engine upgrade from Version 19.03.15 to Version 23.0.5, which introduced
|
||||
a known compatibility issue.
|
||||
|
||||
GitLab CI/CD jobs [using Docker-in-Docker-based jobs](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker)
|
||||
with a Docker-in-Docker service version prior to 20.10 and GitLab CI/CD jobs [using Kaniko to build container images](https://docs.gitlab.com/ee/ci/docker/using_kaniko.html)
|
||||
with a Kaniko service version older than `v1.9.0` will start failing.
|
||||
|
||||
To fix these issues, an update of service version in `.gitlab-ci.yml` is required.
|
||||
|
||||
Both issues, including a detailed explanation of how they affect jobs and how to fix
|
||||
the issue, are described
|
||||
[in the announcement blog post](https://about.gitlab.com/blog/2023/10/04/updating-the-os-version-of-saas-runners-on-linux/).
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### Internal container registry API tag deletion endpoint
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ module Gitlab
|
|||
|
||||
def instance_count_request(amount = 1)
|
||||
@request_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_requests_total, 'Client side Redis request count, per Redis server')
|
||||
@request_counter.increment({ storage: storage_key }, amount)
|
||||
@request_counter.increment(storage_labels, amount)
|
||||
end
|
||||
|
||||
def instance_count_pipelined_request(size)
|
||||
|
|
@ -132,7 +132,7 @@ module Gitlab
|
|||
{},
|
||||
[10, 100, 1000, 10_000]
|
||||
)
|
||||
@pipeline_size_histogram.observe({ storage: storage_key, storage_shard: shard_key }, size)
|
||||
@pipeline_size_histogram.observe(storage_labels, size)
|
||||
end
|
||||
|
||||
def instance_count_exception(ex)
|
||||
|
|
@ -140,12 +140,12 @@ module Gitlab
|
|||
# server is doing. Redis itself does not expose error counts. This
|
||||
# metric can be used for Redis alerting and service health monitoring.
|
||||
@exception_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_exceptions_total, 'Client side Redis exception count, per Redis server, per exception class')
|
||||
@exception_counter.increment({ storage: storage_key, storage_shard: shard_key, exception: ex.class.to_s })
|
||||
@exception_counter.increment(storage_labels.merge(exception: ex.class.to_s))
|
||||
end
|
||||
|
||||
def instance_count_connection_exception(ex)
|
||||
@connection_exception_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_connection_exceptions_total, 'Client side Redis connection exception count, per Redis server, per exception class')
|
||||
@connection_exception_counter.increment({ storage: storage_key, storage_shard: shard_key, exception: ex.class.to_s })
|
||||
@connection_exception_counter.increment(storage_labels.merge(exception: ex.class.to_s))
|
||||
end
|
||||
|
||||
def instance_count_cluster_redirection(ex)
|
||||
|
|
@ -153,7 +153,7 @@ module Gitlab
|
|||
# redirected to the right node, especially during resharding..
|
||||
# This metric can be used for Redis alerting and service health monitoring.
|
||||
@redirection_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_redirections_total, 'Client side Redis Cluster redirection count, per Redis node, per slot')
|
||||
@redirection_counter.increment(decompose_redirection_message(ex.message).merge({ storage: storage_key, storage_shard: shard_key }))
|
||||
@redirection_counter.increment(decompose_redirection_message(ex.message).merge(storage_labels))
|
||||
end
|
||||
|
||||
def instance_observe_duration(duration)
|
||||
|
|
@ -164,15 +164,19 @@ module Gitlab
|
|||
[0.1, 0.5, 0.75, 1]
|
||||
)
|
||||
|
||||
@request_latency_histogram.observe({ storage: storage_key, storage_shard: shard_key }, duration)
|
||||
@request_latency_histogram.observe(storage_labels, duration)
|
||||
end
|
||||
|
||||
def log_exception(ex)
|
||||
::Gitlab::ErrorTracking.log_exception(ex, storage: storage_key, storage_shard: shard_key)
|
||||
::Gitlab::ErrorTracking.log_exception(ex, **storage_labels)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def storage_labels
|
||||
{ storage: storage_key, storage_shard: shard_key }
|
||||
end
|
||||
|
||||
def request_count_key
|
||||
strong_memoize(:request_count_key) { build_key(:redis_request_count) }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -52758,7 +52758,7 @@ msgstr ""
|
|||
msgid "TimeTracking|Time remaining: %{timeRemainingHumanReadable}"
|
||||
msgstr ""
|
||||
|
||||
msgid "TimeTracking|Use /spend or /estimate to manage time."
|
||||
msgid "TimeTracking|To manage time, use /spend or /estimate."
|
||||
msgstr ""
|
||||
|
||||
msgid "Timeago|%s days ago"
|
||||
|
|
@ -52999,6 +52999,9 @@ msgstr ""
|
|||
msgid "To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "To add active contacts, use /add_contacts."
|
||||
msgstr ""
|
||||
|
||||
msgid "To add the entry manually, provide the following details to the application on your phone."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -86,13 +86,27 @@ describe('~/api/projects_api.js', () => {
|
|||
jest.spyOn(axios, 'delete');
|
||||
});
|
||||
|
||||
it('deletes to the correct URL', () => {
|
||||
const expectedUrl = `/api/v7/projects/${projectId}`;
|
||||
describe('without params', () => {
|
||||
it('deletes to the correct URL', () => {
|
||||
const expectedUrl = `/api/v7/projects/${projectId}`;
|
||||
|
||||
mock.onDelete(expectedUrl).replyOnce(HTTP_STATUS_OK);
|
||||
mock.onDelete(expectedUrl).replyOnce(HTTP_STATUS_OK);
|
||||
|
||||
return projectsApi.deleteProject(projectId).then(() => {
|
||||
expect(axios.delete).toHaveBeenCalledWith(expectedUrl);
|
||||
return projectsApi.deleteProject(projectId).then(() => {
|
||||
expect(axios.delete).toHaveBeenCalledWith(expectedUrl, { params: undefined });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with params', () => {
|
||||
it('deletes to the correct URL with params', () => {
|
||||
const expectedUrl = `/api/v7/projects/${projectId}`;
|
||||
|
||||
mock.onDelete(expectedUrl).replyOnce(HTTP_STATUS_OK);
|
||||
|
||||
return projectsApi.deleteProject(projectId, { testParam: true }).then(() => {
|
||||
expect(axios.delete).toHaveBeenCalledWith(expectedUrl, { params: { testParam: true } });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import getIssueCrmContactsQuery from '~/sidebar/queries/get_issue_crm_contacts.q
|
|||
import issueCrmContactsSubscription from '~/sidebar/queries/issue_crm_contacts.subscription.graphql';
|
||||
import {
|
||||
getIssueCrmContactsQueryResponse,
|
||||
getIssueCrmContactsQueryResponseEmpty,
|
||||
issueCrmContactsUpdateResponse,
|
||||
issueCrmContactsUpdateNullResponse,
|
||||
} from '../mock_data';
|
||||
|
|
@ -21,6 +22,9 @@ describe('Issue crm contacts component', () => {
|
|||
let fakeApollo;
|
||||
|
||||
const successQueryHandler = jest.fn().mockResolvedValue(getIssueCrmContactsQueryResponse);
|
||||
const emptySuccessQueryHandler = jest
|
||||
.fn()
|
||||
.mockResolvedValue(getIssueCrmContactsQueryResponseEmpty);
|
||||
const successSubscriptionHandler = jest.fn().mockResolvedValue(issueCrmContactsUpdateResponse);
|
||||
const nullSubscriptionHandler = jest.fn().mockResolvedValue(issueCrmContactsUpdateNullResponse);
|
||||
|
||||
|
|
@ -80,6 +84,16 @@ describe('Issue crm contacts component', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('has an empty state', async () => {
|
||||
mountComponent({
|
||||
queryHandler: emptySuccessQueryHandler,
|
||||
subscriptionHandler: nullSubscriptionHandler,
|
||||
});
|
||||
await waitForPromises();
|
||||
|
||||
expect(wrapper.findByTestId('crm-empty-message').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders correct results after subscription update', async () => {
|
||||
mountComponent();
|
||||
await waitForPromises();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,18 @@ export const getIssueCrmContactsQueryResponse = {
|
|||
},
|
||||
};
|
||||
|
||||
export const getIssueCrmContactsQueryResponseEmpty = {
|
||||
data: {
|
||||
issue: {
|
||||
__typename: 'Issue',
|
||||
id: 'gid://gitlab/Issue/123',
|
||||
customerRelationsContacts: {
|
||||
nodes: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const issueCrmContactsUpdateNullResponse = {
|
||||
data: {
|
||||
issueCrmContactsUpdated: null,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { mountExtended } from 'helpers/vue_test_utils_helper';
|
|||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import { stubComponent, RENDER_ALL_SLOTS_TEMPLATE } from 'helpers/stub_component';
|
||||
import { Blob, BinaryBlob } from 'jest/blob/components/mock_data';
|
||||
import { differenceInMilliseconds } from '~/lib/utils/datetime_utility';
|
||||
import SnippetHeader, { i18n } from '~/snippets/components/snippet_header.vue';
|
||||
|
|
@ -83,6 +84,7 @@ describe('Snippet header component', () => {
|
|||
GlDisclosureDropdownGroup,
|
||||
GlDisclosureDropdownItem,
|
||||
GlIcon,
|
||||
GlModal: stubComponent(GlModal, { template: RENDER_ALL_SLOTS_TEMPLATE }),
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: createMockDirective('gl-tooltip'),
|
||||
|
|
@ -99,9 +101,10 @@ describe('Snippet header component', () => {
|
|||
const findSpamAction = () => wrapper.findByText('Submit as spam');
|
||||
const findDeleteAction = () => wrapper.findByText('Delete');
|
||||
const findDeleteModal = () => wrapper.findComponent(GlModal);
|
||||
const findDeleteModalDeleteAction = () => wrapper.findByTestId('delete-snippet-button');
|
||||
const findIcon = () => wrapper.findComponent(GlIcon);
|
||||
const findTooltip = () => getBinding(findIcon().element, 'gl-tooltip');
|
||||
const findSpamIcon = () => wrapper.findComponent('[data-testid="snippets-spam-icon"]');
|
||||
const findSpamIcon = () => wrapper.findByTestId('snippets-spam-icon');
|
||||
|
||||
const title = 'The property of Thor';
|
||||
|
||||
|
|
@ -294,17 +297,21 @@ describe('Snippet header component', () => {
|
|||
});
|
||||
|
||||
describe('Delete mutation', () => {
|
||||
const deleteSnippet = async () => {
|
||||
const openDeleteSnippetModal = async () => {
|
||||
// Click delete action
|
||||
findDropdown().trigger('click');
|
||||
findDeleteAction().trigger('click');
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const deleteSnippet = async () => {
|
||||
await openDeleteSnippetModal();
|
||||
|
||||
expect(findDeleteModal().props().visible).toBe(true);
|
||||
|
||||
// Click delete button in delete modal
|
||||
document.querySelector('[data-testid="delete-snippet-button"').click();
|
||||
findDeleteModalDeleteAction().trigger('click');
|
||||
|
||||
await waitForPromises();
|
||||
};
|
||||
|
|
@ -325,9 +332,19 @@ describe('Snippet header component', () => {
|
|||
|
||||
await deleteSnippet();
|
||||
|
||||
expect(document.querySelector('[data-testid="delete-alert"').textContent.trim()).toBe(
|
||||
ERROR_MSG,
|
||||
);
|
||||
expect(wrapper.findByTestId('delete-alert').text()).toBe(ERROR_MSG);
|
||||
});
|
||||
|
||||
it('puts the `Delete snippet` modal button in the loading state on click', async () => {
|
||||
createComponent();
|
||||
|
||||
expect(findDeleteModalDeleteAction().props('loading')).toBe(false);
|
||||
|
||||
await openDeleteSnippetModal();
|
||||
findDeleteModalDeleteAction().trigger('click');
|
||||
await nextTick();
|
||||
|
||||
expect(findDeleteModalDeleteAction().props('loading')).toBe(true);
|
||||
});
|
||||
|
||||
describe('in case of successful mutation, closes modal and redirects to correct listing', () => {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ describe('WorkItemTimeTracking component', () => {
|
|||
createComponent({ timeEstimate: 0, totalTimeSpent: 0 });
|
||||
|
||||
expect(findTimeTrackingBody().text()).toMatchInterpolatedText(
|
||||
'Use /spend or /estimate to manage time.',
|
||||
'To manage time, use /spend or /estimate.',
|
||||
);
|
||||
expect(findProgressBar().exists()).toBe(false);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue