Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-08-14 00:10:05 +00:00
parent 79ecd9a748
commit d2608eb839
20 changed files with 343 additions and 165 deletions

View File

@ -14,6 +14,7 @@ import { mergeUrlParams, webIDEUrl } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
import MrWidgetHowToMergeModal from './mr_widget_how_to_merge_modal.vue';
import MrWidgetIcon from './mr_widget_icon.vue';
@ -30,6 +31,7 @@ export default {
GlDropdownItem,
GlLink,
GlSprintf,
WebIdeLink,
},
directives: {
GlTooltip: GlTooltipDirective,
@ -56,31 +58,24 @@ export default {
});
},
webIdePath() {
if (this.mr.canPushToSourceBranch) {
return mergeUrlParams(
{
target_project:
this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath
? this.mr.targetProjectFullPath
: '',
},
webIDEUrl(`/${this.mr.sourceProjectFullPath}/merge_requests/${this.mr.iid}`),
);
}
return null;
},
ideButtonTitle() {
return !this.mr.canPushToSourceBranch
? s__(
'mrWidget|You are not allowed to edit this project directly. Please fork to make changes.',
)
: '';
return mergeUrlParams(
{
target_project:
this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath
? this.mr.targetProjectFullPath
: '',
},
webIDEUrl(`/${this.mr.sourceProjectFullPath}/merge_requests/${this.mr.iid}`),
);
},
isFork() {
return this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath;
},
},
i18n: {
webIdeText: s__('mrWidget|Open in Web IDE'),
gitpodText: s__('mrWidget|Open in Gitpod'),
},
};
</script>
<template>
@ -123,22 +118,21 @@ export default {
<div class="branch-actions d-flex">
<template v-if="mr.isOpen">
<span
<web-ide-link
v-if="!mr.sourceBranchRemoved"
v-gl-tooltip
:title="ideButtonTitle"
class="gl-display-none d-md-inline-block gl-mr-3"
:tabindex="ideButtonTitle ? 0 : null"
>
<gl-button
:href="webIdePath"
:disabled="!mr.canPushToSourceBranch"
class="js-web-ide"
data-qa-selector="open_in_web_ide_button"
>
{{ s__('mrWidget|Open in Web IDE') }}
</gl-button>
</span>
:show-edit-button="false"
:show-web-ide-button="true"
:web-ide-url="webIdePath"
:web-ide-text="$options.i18n.webIdeText"
:show-gitpod-button="mr.showGitpodButton"
:gitpod-url="mr.gitpodUrl"
:gitpod-enabled="mr.gitpodEnabled"
:gitpod-text="$options.i18n.gitpodText"
class="gl-display-none gl-md-display-inline-block gl-mr-3"
data-placement="bottom"
tabindex="0"
data-qa-selector="open_in_web_ide_button"
/>
<gl-button
v-gl-modal-directive="'modal-merge-info'"
:disabled="mr.sourceBranchRemoved"

View File

@ -19,6 +19,7 @@ export default class MergeRequestStore {
this.setPaths(data);
this.setData(data);
this.setGitpodData(data);
}
setData(data, isRebased) {
@ -199,6 +200,12 @@ export default class MergeRequestStore {
}
}
setGitpodData(data) {
this.showGitpodButton = data.show_gitpod_button;
this.gitpodUrl = data.gitpod_url;
this.gitpodEnabled = data.gitpod_enabled;
}
setState() {
if (this.mergeOngoing) {
this.state = 'merging';

View File

@ -59,11 +59,21 @@ export default {
required: false,
default: '',
},
webIdeText: {
type: String,
required: false,
default: '',
},
gitpodUrl: {
type: String,
required: false,
default: '',
},
gitpodText: {
type: String,
required: false,
default: '',
},
},
data() {
return {
@ -99,6 +109,17 @@ export default {
...handleOptions,
};
},
webIdeActionText() {
if (this.webIdeText) {
return this.webIdeText;
} else if (this.isBlob) {
return __('Edit in Web IDE');
} else if (this.isFork) {
return __('Edit fork in Web IDE');
}
return __('Web IDE');
},
webIdeAction() {
if (!this.showWebIdeButton) {
return null;
@ -111,17 +132,9 @@ export default {
}
: { href: this.webIdeUrl };
let text = __('Web IDE');
if (this.isBlob) {
text = __('Edit in Web IDE');
} else if (this.isFork) {
text = __('Edit fork in Web IDE');
}
return {
key: KEY_WEB_IDE,
text,
text: this.webIdeActionText,
secondaryText: __('Quickly and easily edit multiple files in your project.'),
tooltip: '',
attrs: {
@ -132,6 +145,9 @@ export default {
...handleOptions,
};
},
gitpodActionText() {
return this.gitpodText || __('Gitpod');
},
gitpodAction() {
if (!this.showGitpodButton) {
return null;
@ -145,7 +161,7 @@ export default {
return {
key: KEY_GITPOD,
text: __('Gitpod'),
text: this.gitpodActionText,
secondaryText,
tooltip: secondaryText,
attrs: {

View File

@ -245,3 +245,12 @@ $gl-line-height-42: px-to-rem(42px);
.gl-min-w-8 {
min-width: $gl-spacing-scale-8;
}
// Will both be moved to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1526
.gl-opacity-6 {
opacity: 0.6;
}
.gl-opacity-7 {
opacity: 0.7;
}

View File

@ -137,6 +137,23 @@ class MergeRequestWidgetEntity < Grape::Entity
merge_request.enabled_reports
end
expose :show_gitpod_button do |merge_request|
Gitlab::CurrentSettings.gitpod_enabled
end
expose :gitpod_url do |merge_request|
next unless Gitlab::CurrentSettings.gitpod_enabled
gitpod_url = Gitlab::CurrentSettings.gitpod_url
context_url = project_merge_request_url(merge_request.project, merge_request)
"#{gitpod_url}##{context_url}"
end
expose :gitpod_enabled do |merge_request|
current_user&.gitpod_enabled || false
end
private
delegate :current_user, to: :request

View File

@ -97,4 +97,5 @@
#js-review-bar
= render 'projects/invite_members_modal', project: @project
- if Gitlab::CurrentSettings.gitpod_enabled && !current_user&.gitpod_enabled
= render 'shared/gitpod/enable_gitpod_modal'

View File

@ -23,8 +23,8 @@ GET /audit_events
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `created_after` | string | no | Return audit events created on or after the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `created_before` | string | no | Return audit events created on or before the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `created_after` | string | no | Return audit events created on or after the given time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `created_before` | string | no | Return audit events created on or before the given time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `entity_type` | string | no | Return audit events for the given entity type. Valid values are: `User`, `Group`, or `Project`. |
| `entity_id` | integer | no | Return audit events for the given entity ID. Requires `entity_type` attribute to be present. |
@ -148,8 +148,8 @@ GET /groups/:id/audit_events
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
| `created_after` | string | no | Return group audit events created on or after the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `created_before` | string | no | Return group audit events created on or before the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `created_after` | string | no | Return group audit events created on or after the given time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ)` |
| `created_before` | string | no | Return group audit events created on or before the given time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
By default, `GET` requests return 20 results at a time because the API results
are paginated.
@ -255,8 +255,8 @@ GET /projects/:id/audit_events
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
| `created_after` | string | no | Return project audit events created on or after the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `created_before` | string | no | Return project audit events created on or before the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `created_after` | string | no | Return project audit events created on or after the given time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `created_before` | string | no | Return project audit events created on or before the given time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
By default, `GET` requests return 20 results at a time because the API results
are paginated.

View File

@ -89,8 +89,8 @@ Parameters:
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
| `title` | string | yes | The title of a milestone |
| `description` | string | no | The description of the milestone |
| `due_date` | date | no | The due date of the milestone, in YYYY-MM-DD format (ISO 8601) |
| `start_date` | date | no | The start date of the milestone, in YYYY-MM-DD format (ISO 8601) |
| `due_date` | date | no | The due date of the milestone, in ISO 8601 format (`YYYY-MM-DD`) |
| `start_date` | date | no | The start date of the milestone, in ISO 8601 format (`YYYY-MM-DD`) |
## Edit milestone
@ -108,8 +108,8 @@ Parameters:
| `milestone_id` | integer | yes | The ID of a group milestone |
| `title` | string | no | The title of a milestone |
| `description` | string | no | The description of a milestone |
| `due_date` | date | no | The due date of the milestone, in YYYY-MM-DD format (ISO 8601) |
| `start_date` | date | no | The start date of the milestone, in YYYY-MM-DD format (ISO 8601) |
| `due_date` | date | no | The due date of the milestone, in ISO 8601 format (`YYYY-MM-DD`) |
| `start_date` | date | no | The start date of the milestone, in ISO 8601 format (`YYYY-MM-DD`) |
| `state_event` | string | no | The state event of the milestone _(`close` or `activate`)_ |
## Delete group milestone

View File

@ -49,8 +49,8 @@ GET /projects
| `archived` | boolean | **{dotted-circle}** No | Limit by archived status. |
| `id_after` | integer | **{dotted-circle}** No | Limit results to projects with IDs greater than the specified ID. |
| `id_before` | integer | **{dotted-circle}** No | Limit results to projects with IDs less than the specified ID. |
| `last_activity_after` | datetime | **{dotted-circle}** No | Limit results to projects with last_activity after specified time. Format: ISO 8601 `YYYY-MM-DDTHH:MM:SSZ` |
| `last_activity_before` | datetime | **{dotted-circle}** No | Limit results to projects with last_activity before specified time. Format: ISO 8601 `YYYY-MM-DDTHH:MM:SSZ` |
| `last_activity_after` | datetime | **{dotted-circle}** No | Limit results to projects with last_activity after specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `last_activity_before` | datetime | **{dotted-circle}** No | Limit results to projects with last_activity before specified time. Format: ISO 8601 (`YYYY-MM-DDTHH:MM:SSZ`) |
| `membership` | boolean | **{dotted-circle}** No | Limit by projects that the current user is a member of. |
| `min_access_level` | integer | **{dotted-circle}** No | Limit by current user minimal [access level](members.md#valid-access-levels). |
| `order_by` | string | **{dotted-circle}** No | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, `last_activity_at`, or `similarity` fields. `repository_size`, `storage_size`, `packages_size` or `wiki_size` fields are only allowed for admins. `similarity` ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332890) in GitLab 14.1) is only available when searching and is limited to projects that the current user is a member of. Default is `created_at`. |

View File

@ -91,10 +91,14 @@ your alerting rules, see [Embedding metrics based on alerts in incident issues](
[External Prometheus instances](../metrics/alerts.md#external-prometheus-instances) for information about setting up alerts for your self-managed Prometheus
instance.
Prerequisite:
- You must have at least the Developer [role](../../user/permissions.md).
To view the metrics for an alert:
1. Sign in as a user with Developer or higher [permissions](../../user/permissions.md).
1. Navigate to **Monitor > Alerts**.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Alerts**.
1. Select the alert you want to view.
1. Below the title of the alert, select the **Metrics** tab.
@ -111,10 +115,14 @@ application incident and need to [explore logs](../metrics/dashboards/index.md#c
from across your application. These logs help you understand what's affecting
your application's performance and how to resolve any problems.
Prerequisite:
- You must have at least the Developer [role](../../user/permissions.md).
To view the logs for an alert:
1. Sign in as a user with Developer or higher [permissions](../../user/permissions.md).
1. Navigate to **Monitor > Alerts**.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Alerts**.
1. Select the alert you want to view.
1. Below the title of the alert, select the **Metrics** tab.
1. Select the [menu](../metrics/dashboards/index.md#chart-context-menu) of
@ -167,17 +175,20 @@ difficult to track who is investigating and working on it. Assigning alerts ease
To assign an alert:
1. To display the list of current alerts, navigate to **Monitor > Alerts**.
1. Display the list of current alerts:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Alerts**.
1. Select your desired alert to display its details.
![Alert Details View Assignee(s)](img/alert_details_assignees_v13_1.png)
1. If the right sidebar is not expanded, select
**{angle-double-right}** **Expand sidebar** to expand it.
**Expand sidebar** (**{angle-double-right}**) to expand it.
1. In the right sidebar, locate the **Assignee**, and then select **Edit**.
From the dropdown menu, select each user you want to assign to the alert.
1. On the right sidebar, locate the **Assignee**, and then select **Edit**.
From the list, select each user you want to assign to the alert.
GitLab creates a [to-do item](../../user/todos.md) for each user.
After completing their portion of investigating or fixing the alert, users can
@ -192,13 +203,17 @@ You can manually create [To-Do list items](../../user/todos.md) for yourself
from the Alert details screen, and view them later on your **To-Do List**. To
add a to-do item:
1. To display the list of current alerts, navigate to **Monitor > Alerts**.
1. Display the list of current alerts:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Alerts**.
1. Select your desired alert to display its **Alert Management Details View**.
1. Select the **Add a to do** button in the right sidebar:
1. On the right sidebar, select **Add a to do**:
![Alert Details Add a to do](img/alert_detail_add_todo_v13_9.png)
Select the **To-Do List** **{todo-done}** in the navigation bar to view your current to-do list.
To view your To-Do List, on the top bar, select **To-Do List** (**{todo-done}**).
## View the environment that generated the alert

View File

@ -15,11 +15,17 @@ where you manage [On-call schedules](oncall_schedules.md).
## Add an escalation policy
If you have at least Maintainer [permissions](../../user/permissions.md),
you can create an escalation policy:
Prerequisite:
1. Go to **Operations > Escalation Policies** and select **Add an escalation policy**.
1. In the **Add escalation policy** form, enter the policy's name and description, and create
- You must have at least the Maintainer [role](../../user/permissions.md).
- You must have an [on-call schedule](oncall_schedules.md).
To create an escalation policy:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Escalation Policies**.
1. Select **Add an escalation policy**.
1. Enter the policy's name and description, and
escalation rules to follow when a primary responder misses an alert.
1. Select **Add escalation policy**.
@ -38,17 +44,19 @@ the paged users is created on the alert.
## Edit an escalation policy
Follow these steps to update an escalation policy:
To update an escalation policy:
1. Go to **Operations > Escalation Policies** and select the **Pencil** icon on the top right of the
policy card, across from the policy name.
1. In the **Edit policy** form, edit the information you wish to update.
1. Select the **Edit policy** button to save your changes.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Escalation Policies**.
1. Select **Edit escalation policy** (**{pencil}**).
1. Edit the information.
1. Select **Save changes**.
## Delete an escalation policy
Follow these steps to delete a policy:
To delete an escalation policy:
1. Go to **Operations > Escalation Policies** and select the **Trash Can** icon on the top right of
the policy card.
1. In the **Delete escalation policy** window, select the **Delete escalation policy** button.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Escalation Policies**.
1. Select **Delete escalation policy** (**{remove}**).
1. On the confirmation dialog, select **Delete escalation policy**.

View File

@ -13,24 +13,26 @@ responsibilities. Maintain the availability of your software services by putting
With an on-call schedule, your team is notified immediately when things go wrong so they can quickly
respond to service outages and disruptions.
To use on-call schedules, users with Maintainer [permissions](../../user/permissions.md)
must do the following:
To use on-call schedules:
1. [Create a schedule](#schedules).
1. [Add a rotation to the schedule](#rotations).
If you have at least Maintainer [permissions](../../user/permissions.md)
to create a schedule, you can do this manually.
## Schedules
Set up an on-call schedule for your team to add rotations to.
Follow these steps to create a schedule:
Prerequisite:
1. Go to **Monitor > On-call Schedules** and select **Add a schedule**.
1. In the **Add schedule** form, enter the schedule's name and description, and select a timezone.
1. Click **Add schedule**.
- You must have at least the Maintainer [role](../../user/permissions.md).
To create an on-call schedule:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. Select **Add a schedule**.
1. Enter the schedule's name and description and select a timezone.
1. Select **Add schedule**.
You now have an empty schedule with no rotations. This renders as an empty state, prompting you to
create [rotations](#rotations) for your schedule.
@ -39,59 +41,64 @@ create [rotations](#rotations) for your schedule.
### Edit a schedule
Follow these steps to update a schedule:
To update a schedule:
1. Go to **Monitor > On-call Schedules** and select the **Pencil** icon on the top right of the
schedule card, across from the schedule name.
1. In the **Edit schedule** form, edit the information you wish to update.
1. Click the **Edit schedule** button to save your changes.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. Select **Edit schedule** (**{pencil}**).
1. Edit the information.
1. Select **Save changes**.
If you change the schedule's time zone, GitLab automatically updates the rotation's restricted time
interval (if one is set) to the corresponding times in the new time zone.
### Delete a schedule
Follow these steps to delete a schedule:
To delete a schedule:
1. Go to **Monitor > On-call Schedules** and select the **Trash Can** icon on the top right of the
schedule card.
1. In the **Delete schedule** window, click the **Delete schedule** button.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. Select **Delete escalation policy** (**{remove}**).
1. On the confirmation dialog, select **Delete schedule**.
## Rotations
Add rotations to an existing schedule to put your team members on-call.
Follow these steps to create a rotation:
To create a rotation:
1. Go to **Monitor > On-call Schedules** and select **Add a rotation** on the top right of the
current schedule.
1. In the **Add rotation** form, enter the following:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. Select the **Add a rotation** link.
1. Enter the following information:
- **Name:** Your rotation's name.
- **Participants:** The people you want in the rotation.
- **Rotation length:** The rotation's duration.
- **Starts on:** The date and time the rotation begins.
- **Enable end date:** With the toggle set to on, you can select the date and time your rotation
- **Enable end date:** With the toggle on, you can select the date and time your rotation
ends.
- **Restrict to time intervals:** With the toggle set to on, you can restrict your rotation to the
- **Restrict to time intervals:** With the toggle on, you can restrict your rotation to the
time period you select.
### Edit a rotation
Follow these steps to edit a rotation:
To edit a rotation:
1. Go to **Monitor > On-call Schedules** and select the **Pencil** icon to the right of the title
of the rotation that you want to update.
1. In the **Edit rotation** form, make the changes that you want.
1. Select the **Edit rotation** button.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. In the **Rotations** section, select **Edit rotation** (**{pencil}**).
1. Edit the information.
1. Select **Save changes**.
### Delete a rotation
Follow these steps to delete a rotation:
To delete a rotation:
1. Go to **Monitor > On-call Schedules** and select the **Trash Can** icon to the right of the
title of the rotation that you want to delete.
1. In the **Delete rotation** window, select the **Delete rotation** button.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > On-call Schedules**.
1. In the **Rotations** section, select **Delete rotation** (**{remove}**).
1. On the confirmation dialog, select **Delete rotation**.
## View schedule rotations

View File

@ -36,8 +36,8 @@ The following table shows what attributes will be present in the CSV.
| Merged User | Full name of the merged user |
| Merged Username | Username of the merge user, with the @ symbol omitted |
| Milestone ID | ID of the merge request milestone |
| Created At (UTC) | Formatted as YYYY-MM-DD HH:MM:SS |
| Updated At (UTC) | Formatted as YYYY-MM-DD HH:MM:SS |
| Created At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
| Updated At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
## Limitations

View File

@ -17046,6 +17046,9 @@ msgstr ""
msgid "In this page you will find information about the settings that are used in your current instance."
msgstr ""
msgid "InProductMarketing|%{organization_name} logo"
msgstr ""
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@ -39748,6 +39751,9 @@ msgstr ""
msgid "mrWidget|More information"
msgstr ""
msgid "mrWidget|Open in Gitpod"
msgstr ""
msgid "mrWidget|Open in Web IDE"
msgstr ""
@ -39853,9 +39859,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
msgstr ""
msgid "mrWidget|You can merge after removing denied licenses"
msgstr ""

View File

@ -1,6 +1,7 @@
import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import Header from '~/vue_merge_request_widget/components/mr_widget_header.vue';
import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
describe('MRWidgetHeader', () => {
let wrapper;
@ -35,6 +36,8 @@ describe('MRWidgetHeader', () => {
statusPath: 'abc',
};
const findWebIdeButton = () => wrapper.findComponent(WebIdeLink);
describe('computed', () => {
describe('shouldShowCommitsBehindText', () => {
it('return true when there are divergedCommitsCount', () => {
@ -147,73 +150,81 @@ describe('MRWidgetHeader', () => {
statusPath: 'abc',
sourceProjectFullPath: 'root/gitlab-ce',
targetProjectFullPath: 'gitlab-org/gitlab-ce',
gitpodEnabled: true,
showGitpodButton: true,
gitpodUrl: 'http://gitpod.localhost',
};
beforeEach(() => {
it('renders checkout branch button with modal trigger', () => {
createComponent({
mr: { ...mrDefaultOptions },
});
});
it('renders checkout branch button with modal trigger', () => {
const button = wrapper.find('.js-check-out-branch');
expect(button.text().trim()).toBe('Check out branch');
});
it('renders web ide button', async () => {
const button = wrapper.find('.js-web-ide');
it.each([
[
'renders web ide button',
{
mrProps: {},
relativeUrl: '',
webIdeUrl:
'/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=gitlab-org%2Fgitlab-ce',
},
],
[
'renders web ide button with blank target_project, when mr has same target project',
{
mrProps: { targetProjectFullPath: 'root/gitlab-ce' },
relativeUrl: '',
webIdeUrl: '/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=',
},
],
[
'renders web ide button with relative url',
{
mrProps: { iid: 2 },
relativeUrl: '/gitlab',
webIdeUrl:
'/gitlab/-/ide/project/root/gitlab-ce/merge_requests/2?target_project=gitlab-org%2Fgitlab-ce',
},
],
])('%s', async (_, { mrProps, relativeUrl, webIdeUrl }) => {
gon.relative_url_root = relativeUrl;
createComponent({
mr: { ...mrDefaultOptions, ...mrProps },
});
await nextTick();
expect(button.text().trim()).toBe('Open in Web IDE');
expect(button.classes('disabled')).toBe(false);
expect(button.attributes('href')).toBe(
'/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=gitlab-org%2Fgitlab-ce',
);
expect(findWebIdeButton().props()).toMatchObject({
showEditButton: false,
showWebIdeButton: true,
webIdeText: 'Open in Web IDE',
gitpodText: 'Open in Gitpod',
gitpodEnabled: true,
showGitpodButton: true,
gitpodUrl: 'http://gitpod.localhost',
webIdeUrl,
});
});
it('renders web ide button in disabled state with no href', async () => {
const mr = { ...mrDefaultOptions, canPushToSourceBranch: false };
createComponent({ mr });
it('does not render web ide button if source branch is removed', async () => {
createComponent({ mr: { ...mrDefaultOptions, sourceBranchRemoved: true } });
await nextTick();
const link = wrapper.find('.js-web-ide');
expect(link.attributes('disabled')).toBe('true');
expect(link.attributes('href')).toBeUndefined();
});
it('renders web ide button with blank query string if target & source project branch', async () => {
createComponent({ mr: { ...mrDefaultOptions, targetProjectFullPath: 'root/gitlab-ce' } });
await nextTick();
const button = wrapper.find('.js-web-ide');
expect(button.text().trim()).toBe('Open in Web IDE');
expect(button.attributes('href')).toBe(
'/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=',
);
});
it('renders web ide button with relative URL', async () => {
gon.relative_url_root = '/gitlab';
createComponent({ mr: { ...mrDefaultOptions, iid: 2 } });
await nextTick();
const button = wrapper.find('.js-web-ide');
expect(button.text().trim()).toBe('Open in Web IDE');
expect(button.attributes('href')).toBe(
'/gitlab/-/ide/project/root/gitlab-ce/merge_requests/2?target_project=gitlab-org%2Fgitlab-ce',
);
expect(findWebIdeButton().exists()).toBe(false);
});
it('renders download dropdown with links', () => {
createComponent({
mr: { ...mrDefaultOptions },
});
expectDownloadDropdownItems();
});
});

View File

@ -281,6 +281,9 @@ export default {
security_reports_docs_path: 'security-reports-docs-path',
sast_comparison_path: '/sast_comparison_path',
secret_scanning_comparison_path: '/secret_scanning_comparison_path',
gitpod_enabled: true,
show_gitpod_button: true,
gitpod_url: 'http://gitpod.localhost',
};
export const mockStore = {

View File

@ -10,6 +10,14 @@ describe('MergeRequestStore', () => {
store = new MergeRequestStore(mockData);
});
it('should initialize gitpod attributes', () => {
expect(store).toMatchObject({
gitpodEnabled: mockData.gitpod_enabled,
showGitpodButton: mockData.show_gitpod_button,
gitpodUrl: mockData.gitpod_url,
});
});
describe('setData', () => {
it('should set isSHAMismatch when the diff SHA changes', () => {
store.setData({ ...mockData, diff_head_sha: 'a-different-string' });

View File

@ -84,6 +84,10 @@ describe('Web IDE link component', () => {
props: {},
expectedActions: [ACTION_WEB_IDE, ACTION_EDIT],
},
{
props: { webIdeText: 'Test Web IDE' },
expectedActions: [{ ...ACTION_WEB_IDE_EDIT_FORK, text: 'Test Web IDE' }, ACTION_EDIT],
},
{
props: { isFork: true },
expectedActions: [ACTION_WEB_IDE_EDIT_FORK, ACTION_EDIT],
@ -104,6 +108,10 @@ describe('Web IDE link component', () => {
props: { showGitpodButton: true, gitpodEnabled: false },
expectedActions: [ACTION_WEB_IDE, ACTION_EDIT, ACTION_GITPOD_ENABLE],
},
{
props: { showEditButton: false, showGitpodButton: true, gitpodText: 'Test Gitpod' },
expectedActions: [ACTION_WEB_IDE, { ...ACTION_GITPOD_ENABLE, text: 'Test Gitpod' }],
},
{
props: { showEditButton: false },
expectedActions: [ACTION_WEB_IDE],

View File

@ -354,4 +354,45 @@ RSpec.describe MergeRequestWidgetEntity do
end
end
end
describe 'when gitpod is disabled' do
before do
allow(Gitlab::CurrentSettings).to receive(:gitpod_enabled).and_return(false)
end
it 'exposes gitpod attributes' do
expect(subject).to include(
show_gitpod_button: false,
gitpod_url: nil,
gitpod_enabled: false
)
end
end
describe 'when gitpod is enabled' do
before do
allow(Gitlab::CurrentSettings).to receive(:gitpod_enabled).and_return(true)
allow(Gitlab::CurrentSettings).to receive(:gitpod_url).and_return("https://gitpod.example.com")
end
it 'exposes gitpod attributes' do
mr_url = Gitlab::Routing.url_helpers.project_merge_request_url(resource.project, resource)
expect(subject).to include(
show_gitpod_button: true,
gitpod_url: "https://gitpod.example.com##{mr_url}",
gitpod_enabled: false
)
end
describe 'when gitpod is enabled for user' do
before do
allow(user).to receive(:gitpod_enabled).and_return(true)
end
it 'exposes gitpod_enabled as true' do
expect(subject[:gitpod_enabled]).to be(true)
end
end
end
end

View File

@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'projects/merge_requests/show.html.haml', :aggregate_failures do
using RSpec::Parameterized::TableSyntax
include_context 'merge request show action'
before do
@ -43,4 +45,32 @@ RSpec.describe 'projects/merge_requests/show.html.haml', :aggregate_failures do
end
end
end
describe 'gitpod modal' do
let(:gitpod_modal_selector) { '#modal-enable-gitpod' }
let(:user) { create(:user) }
let(:user_gitpod_enabled) { create(:user).tap { |x| x.update!(gitpod_enabled: true) } }
where(:site_enabled, :current_user, :should_show) do
false | ref(:user) | false
true | ref(:user) | true
true | nil | true
true | ref(:user_gitpod_enabled) | false
end
with_them do
it 'handles rendering gitpod user enable modal' do
allow(Gitlab::CurrentSettings).to receive(:gitpod_enabled).and_return(site_enabled)
allow(view).to receive(:current_user).and_return(current_user)
render
if should_show
expect(rendered).to have_css(gitpod_modal_selector)
else
expect(rendered).to have_no_css(gitpod_modal_selector)
end
end
end
end
end