Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
6c7fe15312
commit
c70359a07f
28 changed files with 308 additions and 98 deletions
|
@ -1 +1 @@
|
|||
906840b1edd8f8c17b6d1d4a7016b2ef0acf5b22
|
||||
d758ff48fbf8392e08626b60685d037373347d72
|
||||
|
|
|
@ -530,6 +530,12 @@ const Api = {
|
|||
return axios.get(url);
|
||||
},
|
||||
|
||||
createRelease(projectPath, release) {
|
||||
const url = Api.buildUrl(this.releasesPath).replace(':id', encodeURIComponent(projectPath));
|
||||
|
||||
return axios.post(url, release);
|
||||
},
|
||||
|
||||
updateRelease(projectPath, tagName, release) {
|
||||
const url = Api.buildUrl(this.releasePath)
|
||||
.replace(':id', encodeURIComponent(projectPath))
|
||||
|
|
|
@ -87,11 +87,7 @@ export default {
|
|||
<template>
|
||||
<span>
|
||||
<span ref="issueDueDate" :class="cssClass" class="board-card-info card-number">
|
||||
<icon
|
||||
:class="{ 'text-danger': isPastDue }"
|
||||
class="board-card-info-icon align-top"
|
||||
name="calendar"
|
||||
/>
|
||||
<icon :class="{ 'text-danger': isPastDue }" class="board-card-info-icon" name="calendar" />
|
||||
<time :class="{ 'text-danger': isPastDue }" datetime="date" class="board-card-info-text">{{
|
||||
body
|
||||
}}</time>
|
||||
|
|
|
@ -34,10 +34,9 @@ export default {
|
|||
<template>
|
||||
<span>
|
||||
<span ref="issueTimeEstimate" class="board-card-info card-number">
|
||||
<icon name="hourglass" class="board-card-info-icon align-top" /><time
|
||||
class="board-card-info-text"
|
||||
>{{ timeEstimate }}</time
|
||||
>
|
||||
<icon name="hourglass" class="board-card-info-icon" /><time class="board-card-info-text">{{
|
||||
timeEstimate
|
||||
}}</time>
|
||||
</span>
|
||||
<gl-tooltip
|
||||
:target="() => $refs.issueTimeEstimate"
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
/* eslint-disable no-underscore-dangle, class-methods-use-this */
|
||||
|
||||
import ListIssue from 'ee_else_ce/boards/models/issue';
|
||||
import { __ } from '~/locale';
|
||||
import ListLabel from './label';
|
||||
import ListAssignee from './assignee';
|
||||
import flash from '~/flash';
|
||||
import boardsStore from '../stores/boards_store';
|
||||
import ListMilestone from './milestone';
|
||||
import 'ee_else_ce/boards/models/issue';
|
||||
|
||||
const TYPES = {
|
||||
backlog: {
|
||||
|
@ -100,12 +99,6 @@ class List {
|
|||
return boardsStore.newListIssue(this, issue);
|
||||
}
|
||||
|
||||
createIssues(data) {
|
||||
data.forEach(issueObj => {
|
||||
this.addIssue(new ListIssue(issueObj));
|
||||
});
|
||||
}
|
||||
|
||||
addMultipleIssues(issues, listFrom, newIndex) {
|
||||
boardsStore.addMultipleListIssues(this, issues, listFrom, newIndex);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable no-shadow, no-param-reassign,consistent-return */
|
||||
/* global List */
|
||||
|
||||
/* global ListIssue */
|
||||
import $ from 'jquery';
|
||||
import { sortBy } from 'lodash';
|
||||
import Vue from 'vue';
|
||||
|
@ -641,7 +641,9 @@ const boardsStore = {
|
|||
list.issues = [];
|
||||
}
|
||||
|
||||
list.createIssues(data.issues);
|
||||
data.issues.forEach(issueObj => {
|
||||
list.addIssue(new ListIssue(issueObj));
|
||||
});
|
||||
|
||||
return data;
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script>
|
||||
import { __, sprintf } from '~/locale';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import { GlIcon } from '@gitlab/ui';
|
||||
|
||||
export default {
|
||||
name: 'DesignNotePin',
|
||||
components: {
|
||||
Icon,
|
||||
GlIcon,
|
||||
},
|
||||
props: {
|
||||
position: {
|
||||
|
@ -47,13 +47,13 @@ export default {
|
|||
'btn-transparent comment-indicator': isNewNote,
|
||||
'js-image-badge badge badge-pill': !isNewNote,
|
||||
}"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center gl-p-0"
|
||||
type="button"
|
||||
@mousedown="$emit('mousedown', $event)"
|
||||
@mouseup="$emit('mouseup', $event)"
|
||||
@click="$emit('click', $event)"
|
||||
>
|
||||
<icon v-if="isNewNote" name="image-comment-dark" />
|
||||
<gl-icon v-if="isNewNote" name="image-comment-dark" :size="24" />
|
||||
<template v-else>
|
||||
{{ label }}
|
||||
</template>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script>
|
||||
import { __, sprintf } from '~/locale';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import { GlIcon } from '@gitlab/ui';
|
||||
|
||||
export default {
|
||||
name: 'DesignNotePin',
|
||||
components: {
|
||||
Icon,
|
||||
GlIcon,
|
||||
},
|
||||
props: {
|
||||
position: {
|
||||
|
@ -47,13 +47,13 @@ export default {
|
|||
'btn-transparent comment-indicator': isNewNote,
|
||||
'js-image-badge badge badge-pill': !isNewNote,
|
||||
}"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center gl-p-0"
|
||||
type="button"
|
||||
@mousedown="$emit('mousedown', $event)"
|
||||
@mouseup="$emit('mouseup', $event)"
|
||||
@click="$emit('click', $event)"
|
||||
>
|
||||
<icon v-if="isNewNote" name="image-comment-dark" />
|
||||
<gl-icon v-if="isNewNote" name="image-comment-dark" :size="24" />
|
||||
<template v-else>
|
||||
{{ label }}
|
||||
</template>
|
||||
|
|
|
@ -521,7 +521,7 @@
|
|||
}
|
||||
|
||||
&.board-card-weight {
|
||||
color: $gl-text-color;
|
||||
color: $gl-text-color-secondary;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
|
@ -531,8 +531,9 @@
|
|||
}
|
||||
|
||||
.board-card-info-icon {
|
||||
color: $gray-600;
|
||||
color: $gray-700;
|
||||
margin-right: $gl-padding-4;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
|
|
|
@ -992,7 +992,8 @@ table.code {
|
|||
}
|
||||
|
||||
.frame .badge.badge-pill,
|
||||
.frame .image-comment-badge {
|
||||
.frame .image-comment-badge,
|
||||
.frame .comment-indicator {
|
||||
// Center align badges on the frame
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ module GitlabRoutingHelper
|
|||
end
|
||||
end
|
||||
|
||||
def gitlab_raw_snippet_blob_url(snippet, path, ref = nil)
|
||||
def gitlab_raw_snippet_blob_url(snippet, path, ref = nil, **options)
|
||||
params = {
|
||||
snippet_id: snippet,
|
||||
ref: ref || snippet.repository.root_ref,
|
||||
|
@ -279,26 +279,14 @@ module GitlabRoutingHelper
|
|||
}
|
||||
|
||||
if snippet.is_a?(ProjectSnippet)
|
||||
project_snippet_blob_raw_url(snippet.project, params)
|
||||
project_snippet_blob_raw_url(snippet.project, **params, **options)
|
||||
else
|
||||
snippet_blob_raw_url(params)
|
||||
snippet_blob_raw_url(**params, **options)
|
||||
end
|
||||
end
|
||||
|
||||
def gitlab_raw_snippet_blob_path(blob, ref = nil)
|
||||
snippet = blob.container
|
||||
|
||||
params = {
|
||||
snippet_id: snippet,
|
||||
ref: ref || blob.repository.root_ref,
|
||||
path: blob.path
|
||||
}
|
||||
|
||||
if snippet.is_a?(ProjectSnippet)
|
||||
project_snippet_blob_raw_path(snippet.project, params)
|
||||
else
|
||||
snippet_blob_raw_path(params)
|
||||
end
|
||||
def gitlab_raw_snippet_blob_path(snippet, path, ref = nil, **options)
|
||||
gitlab_raw_snippet_blob_url(snippet, path, ref, only_path: true, **options)
|
||||
end
|
||||
|
||||
def gitlab_snippet_notes_path(snippet, *args)
|
||||
|
|
|
@ -17,7 +17,7 @@ class SnippetBlobPresenter < BlobPresenter
|
|||
end
|
||||
|
||||
def raw_path
|
||||
return gitlab_raw_snippet_blob_path(blob) if snippet_multiple_files?
|
||||
return gitlab_raw_snippet_blob_path(snippet, blob.path) if snippet_multiple_files?
|
||||
|
||||
gitlab_raw_snippet_path(snippet)
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
%li.key-list-item
|
||||
.float-left.gl-mr-3
|
||||
= icon 'key', class: "settings-list-icon d-none d-sm-block"
|
||||
= sprite_icon('key', size: 16, css_class: "settings-list-icon d-none d-sm-block gl-mt-4")
|
||||
.key-list-item-info
|
||||
- key.emails_with_verified_status.map do |email, verified|
|
||||
= render partial: 'shared/email_with_badge', locals: { email: email, verified: verified }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- requirements_link_url = help_page_path('user/project/issues/design_management', anchor: 'requirements')
|
||||
- requirements_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: requirements_link_url }
|
||||
- link_end = '</a>'.html_safe
|
||||
- enable_lfs_message = s_("DesignManagement|To upload designs, you'll need to %{requirements_link_start}enable LFS%{requirements_link_end}.").html_safe % { requirements_link_start: requirements_link_start, requirements_link_end: link_end }
|
||||
- enable_lfs_message = s_("DesignManagement|To upload designs, you'll need to enable LFS. %{requirements_link_start}More information%{requirements_link_end}").html_safe % { requirements_link_start: requirements_link_start, requirements_link_end: link_end }
|
||||
|
||||
- if @project.design_management_enabled?
|
||||
- if Feature.enabled?(:design_management_moved, @project, default_enabled: true)
|
||||
|
|
5
changelogs/unreleased/225208-fa-key-replacement.yml
Normal file
5
changelogs/unreleased/225208-fa-key-replacement.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Replace fa-key icon with svg
|
||||
merge_request: 37251
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove createIssues logic from list model
|
||||
merge_request: 32236
|
||||
author: nuwe1
|
||||
type: other
|
5
changelogs/unreleased/design-management-pin.yml
Normal file
5
changelogs/unreleased/design-management-pin.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix sizing of pins for new design comments
|
||||
merge_request: 37541
|
||||
author:
|
||||
type: fixed
|
5
changelogs/unreleased/issue-weight-alignment-color.yml
Normal file
5
changelogs/unreleased/issue-weight-alignment-color.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix icon alignment on board cards
|
||||
merge_request: 35710
|
||||
author: carolcarvalhosa
|
||||
type: fixed
|
|
@ -212,6 +212,7 @@ application server, or a Gitaly node.
|
|||
postgresql['enable'] = false
|
||||
redis['enable'] = false
|
||||
nginx['enable'] = false
|
||||
alertmanager['enable'] = false
|
||||
prometheus['enable'] = false
|
||||
grafana['enable'] = false
|
||||
puma['enable'] = false
|
||||
|
|
|
@ -11,6 +11,8 @@ last_update: 2019-07-03
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9186) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.0.
|
||||
> - [Squash and merge](../../../../user/project/merge_requests/squash_and_merge.md) support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13001) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.6.
|
||||
|
||||
For more information about why you might want to use Merge Trains, read [How merge trains keep your master green](https://about.gitlab.com/blog/2020/01/30/all-aboard-merge-trains/).
|
||||
|
||||
When [pipelines for merged results](../index.md#pipelines-for-merged-results-premium) are
|
||||
enabled, the pipeline jobs run as if the changes from your source branch have already
|
||||
been merged into the target branch.
|
||||
|
|
|
@ -145,6 +145,8 @@ build a matrix of targets and architectures.
|
|||
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
|
||||
For an overview, see [Create child pipelines using dynamically generated configurations](https://youtu.be/nMdfus2JWHM).
|
||||
|
||||
We also have an [example project using Dynamic Child Pipelines with Jsonnet](https://gitlab.com/gitlab-org/project-templates/jsonnet) which shows how to use a data templating language to generate your `.gitlab-ci.yml` at runtime. You could use a similar process for other templating languages like [Dhall](https://dhall-lang.org/) or [`ytt`](https://get-ytt.io/).
|
||||
|
||||
In GitLab 12.9, the child pipeline could fail to be created in certain cases, causing the parent pipeline to fail.
|
||||
This is [resolved in GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/issues/209070).
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ All template files reside in the `lib/gitlab/ci/templates` directory, and are ca
|
|||
|
||||
| Sub-directroy | Content | [Selectable in UI](#make-sure-the-new-template-can-be-selected-in-ui) |
|
||||
|---------------|--------------------------------------------------------------|-----------------------------------------------------------------------|
|
||||
| `/AWS/*` | Cloud Deployment (AWS) related jobs | No |
|
||||
| `/Jobs/*` | Auto DevOps related jobs | Yes |
|
||||
| `/Pages/*` | Static site generators for GitLab Pages (for example Jekyll) | Yes |
|
||||
| `/Security/*` | Security related jobs | Yes |
|
||||
|
@ -25,9 +26,37 @@ Also, all templates must be named with the `*.gitlab-ci.yml` suffix.
|
|||
### Backward compatibility
|
||||
|
||||
A template might be dynamically included with the `include:template:` keyword. If
|
||||
you make a change to an *existing* template, you must make sure that it won't break
|
||||
you make a change to an *existing* template, you **must** make sure that it won't break
|
||||
CI/CD in existing projects.
|
||||
|
||||
For example, changing a job name in a template could break pipelines in an existing project.
|
||||
Let's say there is a template named `Performance.gitlab-ci.yml` with the following content:
|
||||
|
||||
```yaml
|
||||
performance:
|
||||
image: registry.gitlab.com/gitlab-org/verify-tools/performance:v0.1.0
|
||||
script: ./performance-test $TARGET_URL
|
||||
```
|
||||
|
||||
and users include this template with passing an argument to the `performance` job.
|
||||
This can be done by specifying the environment variable `TARGET_URL` in _their_ `.gitlab-ci.yml`:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
template: Performance.gitlab-ci.yml
|
||||
|
||||
performance:
|
||||
variables:
|
||||
TARGET_URL: https://awesome-app.com
|
||||
```
|
||||
|
||||
If the job name `performance` in the template is renamed to `browser-performance`,
|
||||
user's `.gitlab-ci.yml` will immediately cause a lint error because there
|
||||
are no such jobs named `performance` in the included template anymore. Therefore,
|
||||
users have to fix their `.gitlab-ci.yml` that could annoy their workflow.
|
||||
|
||||
Please read [versioning](#versioning) section for introducing breaking change safely.
|
||||
|
||||
## Testing
|
||||
|
||||
Each CI/CD template must be tested in order to make sure that it's safe to be published.
|
||||
|
@ -64,3 +93,13 @@ You should write an RSpec test to make sure that pipeline jobs will be generated
|
|||
A template could contain malicious code. For example, a template that contains the `export` shell command in a job
|
||||
might accidentally expose project secret variables in a job log.
|
||||
If you're unsure if it's secure or not, you need to ask security experts for cross-validation.
|
||||
|
||||
## Versioning
|
||||
|
||||
Versioning allows you to introduce a new template without modifying the existing
|
||||
one. This is useful process especially when we need to introduce a breaking change,
|
||||
but don't want to affect the existing projects that depends on the current template.
|
||||
|
||||
There is an [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/17716) for
|
||||
introducing versioning concept in GitLab Ci Template. Please follow the issue for
|
||||
checking the progress.
|
||||
|
|
|
@ -8192,7 +8192,7 @@ msgstr ""
|
|||
msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "DesignManagement|To upload designs, you'll need to %{requirements_link_start}enable LFS%{requirements_link_end}."
|
||||
msgid "DesignManagement|To upload designs, you'll need to enable LFS. %{requirements_link_start}More information%{requirements_link_end}"
|
||||
msgstr ""
|
||||
|
||||
msgid "DesignManagement|Unresolve thread"
|
||||
|
@ -15537,6 +15537,9 @@ msgstr ""
|
|||
msgid "NetworkPolicies|Name"
|
||||
msgstr ""
|
||||
|
||||
msgid "NetworkPolicies|New policy"
|
||||
msgstr ""
|
||||
|
||||
msgid "NetworkPolicies|No policies detected"
|
||||
msgstr ""
|
||||
|
||||
|
@ -15549,6 +15552,12 @@ msgstr ""
|
|||
msgid "NetworkPolicies|Policy definition"
|
||||
msgstr ""
|
||||
|
||||
msgid "NetworkPolicies|Policy description"
|
||||
msgstr ""
|
||||
|
||||
msgid "NetworkPolicies|Policy editor"
|
||||
msgstr ""
|
||||
|
||||
msgid "NetworkPolicies|Something went wrong, failed to update policy"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -644,6 +644,45 @@ RSpec.describe 'GFM autocomplete', :js do
|
|||
expect(find('.tribute-container ul')).to have_content(unassigned_user.username)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when other notes are destroyed' do
|
||||
let!(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: issue.project) }
|
||||
|
||||
# This is meant to protect against this issue https://gitlab.com/gitlab-org/gitlab/-/issues/228729
|
||||
it 'keeps autocomplete key listeners' do
|
||||
visit project_issue_path(project, issue)
|
||||
note = find('#note-body')
|
||||
|
||||
start_comment_with_emoji(note)
|
||||
|
||||
start_and_cancel_discussion
|
||||
|
||||
note.fill_in(with: '')
|
||||
start_comment_with_emoji(note)
|
||||
note.native.send_keys(:enter)
|
||||
|
||||
expect(note.value).to eql('Hello :100: ')
|
||||
end
|
||||
|
||||
def start_comment_with_emoji(note)
|
||||
note.native.send_keys('Hello :10')
|
||||
|
||||
# Wait for emoji popup
|
||||
find('.atwho-view li', text: '100')
|
||||
end
|
||||
|
||||
def start_and_cancel_discussion
|
||||
click_button('Reply...')
|
||||
|
||||
fill_in('note_note', with: 'Whoops!')
|
||||
|
||||
page.accept_alert 'Are you sure you want to cancel creating this comment?' do
|
||||
click_button('Cancel')
|
||||
end
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -666,6 +666,97 @@ describe('Api', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('release', () => {
|
||||
const dummyProjectPath = 'gitlab-org/gitlab';
|
||||
const dummyTagName = 'v1.3';
|
||||
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${encodeURIComponent(
|
||||
dummyProjectPath,
|
||||
)}/releases/${encodeURIComponent(dummyTagName)}`;
|
||||
|
||||
describe('when the release is successfully returned', () => {
|
||||
it('resolves the Promise', () => {
|
||||
mock.onGet(expectedUrl).replyOnce(200);
|
||||
|
||||
return Api.release(dummyProjectPath, dummyTagName).then(() => {
|
||||
expect(mock.history.get).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an error occurs while fetching the release', () => {
|
||||
it('rejects the Promise', () => {
|
||||
mock.onGet(expectedUrl).replyOnce(500);
|
||||
|
||||
return Api.release(dummyProjectPath, dummyTagName).catch(() => {
|
||||
expect(mock.history.get).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('createRelease', () => {
|
||||
const dummyProjectPath = 'gitlab-org/gitlab';
|
||||
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${encodeURIComponent(
|
||||
dummyProjectPath,
|
||||
)}/releases`;
|
||||
|
||||
const release = {
|
||||
name: 'Version 1.0',
|
||||
};
|
||||
|
||||
describe('when the release is successfully created', () => {
|
||||
it('resolves the Promise', () => {
|
||||
mock.onPost(expectedUrl, release).replyOnce(201);
|
||||
|
||||
return Api.createRelease(dummyProjectPath, release).then(() => {
|
||||
expect(mock.history.post).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an error occurs while creating the release', () => {
|
||||
it('rejects the Promise', () => {
|
||||
mock.onPost(expectedUrl, release).replyOnce(500);
|
||||
|
||||
return Api.createRelease(dummyProjectPath, release).catch(() => {
|
||||
expect(mock.history.post).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateRelease', () => {
|
||||
const dummyProjectPath = 'gitlab-org/gitlab';
|
||||
const dummyTagName = 'v1.3';
|
||||
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${encodeURIComponent(
|
||||
dummyProjectPath,
|
||||
)}/releases/${encodeURIComponent(dummyTagName)}`;
|
||||
|
||||
const release = {
|
||||
name: 'Version 1.0',
|
||||
};
|
||||
|
||||
describe('when the release is successfully created', () => {
|
||||
it('resolves the Promise', () => {
|
||||
mock.onPut(expectedUrl, release).replyOnce(200);
|
||||
|
||||
return Api.updateRelease(dummyProjectPath, dummyTagName, release).then(() => {
|
||||
expect(mock.history.put).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an error occurs while creating the release', () => {
|
||||
it('rejects the Promise', () => {
|
||||
mock.onPut(expectedUrl, release).replyOnce(500);
|
||||
|
||||
return Api.updateRelease(dummyProjectPath, dummyTagName, release).catch(() => {
|
||||
expect(mock.history.put).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('createReleaseLink', () => {
|
||||
const dummyProjectPath = 'gitlab-org/gitlab';
|
||||
const dummyReleaseTag = 'v1.3';
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
exports[`Design note pin component should match the snapshot of note when repositioning 1`] = `
|
||||
<button
|
||||
aria-label="Comment form position"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center btn-transparent comment-indicator"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center gl-p-0 btn-transparent comment-indicator"
|
||||
style="left: 10px; top: 10px; cursor: move;"
|
||||
type="button"
|
||||
>
|
||||
<icon-stub
|
||||
<gl-icon-stub
|
||||
name="image-comment-dark"
|
||||
size="16"
|
||||
size="24"
|
||||
/>
|
||||
</button>
|
||||
`;
|
||||
|
@ -17,7 +17,7 @@ exports[`Design note pin component should match the snapshot of note when reposi
|
|||
exports[`Design note pin component should match the snapshot of note with index 1`] = `
|
||||
<button
|
||||
aria-label="Comment '1' position"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center js-image-badge badge badge-pill"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center gl-p-0 js-image-badge badge badge-pill"
|
||||
style="left: 10px; top: 10px;"
|
||||
type="button"
|
||||
>
|
||||
|
@ -30,13 +30,13 @@ exports[`Design note pin component should match the snapshot of note with index
|
|||
exports[`Design note pin component should match the snapshot of note without index 1`] = `
|
||||
<button
|
||||
aria-label="Comment form position"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center btn-transparent comment-indicator"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center gl-p-0 btn-transparent comment-indicator"
|
||||
style="left: 10px; top: 10px;"
|
||||
type="button"
|
||||
>
|
||||
<icon-stub
|
||||
<gl-icon-stub
|
||||
name="image-comment-dark"
|
||||
size="16"
|
||||
size="24"
|
||||
/>
|
||||
</button>
|
||||
`;
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
exports[`Design note pin component should match the snapshot of note when repositioning 1`] = `
|
||||
<button
|
||||
aria-label="Comment form position"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center btn-transparent comment-indicator"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center gl-p-0 btn-transparent comment-indicator"
|
||||
style="left: 10px; top: 10px; cursor: move;"
|
||||
type="button"
|
||||
>
|
||||
<icon-stub
|
||||
<gl-icon-stub
|
||||
name="image-comment-dark"
|
||||
size="16"
|
||||
size="24"
|
||||
/>
|
||||
</button>
|
||||
`;
|
||||
|
@ -17,7 +17,7 @@ exports[`Design note pin component should match the snapshot of note when reposi
|
|||
exports[`Design note pin component should match the snapshot of note with index 1`] = `
|
||||
<button
|
||||
aria-label="Comment '1' position"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center js-image-badge badge badge-pill"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center gl-p-0 js-image-badge badge badge-pill"
|
||||
style="left: 10px; top: 10px;"
|
||||
type="button"
|
||||
>
|
||||
|
@ -30,13 +30,13 @@ exports[`Design note pin component should match the snapshot of note with index
|
|||
exports[`Design note pin component should match the snapshot of note without index 1`] = `
|
||||
<button
|
||||
aria-label="Comment form position"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center btn-transparent comment-indicator"
|
||||
class="design-pin gl-absolute gl-display-flex gl-align-items-center gl-justify-content-center gl-p-0 btn-transparent comment-indicator"
|
||||
style="left: 10px; top: 10px;"
|
||||
type="button"
|
||||
>
|
||||
<icon-stub
|
||||
<gl-icon-stub
|
||||
name="image-comment-dark"
|
||||
size="16"
|
||||
size="24"
|
||||
/>
|
||||
</button>
|
||||
`;
|
||||
|
|
|
@ -182,18 +182,65 @@ RSpec.describe GitlabRoutingHelper do
|
|||
end
|
||||
|
||||
describe '#gitlab_raw_snippet_blob_path' do
|
||||
let(:snippet) { personal_snippet }
|
||||
let(:blob) { snippet.blobs.first }
|
||||
let(:ref) { 'test-ref' }
|
||||
let(:args) { {} }
|
||||
|
||||
it_behaves_like 'snippet blob raw path' do
|
||||
subject { gitlab_raw_snippet_blob_path(blob, ref) }
|
||||
subject { gitlab_raw_snippet_blob_path(snippet, blob.path, ref, args) }
|
||||
|
||||
it_behaves_like 'snippet blob raw path'
|
||||
|
||||
context 'when an argument is set' do
|
||||
let(:args) { { inline: true } }
|
||||
|
||||
it { expect(subject).to eq("/-/snippets/#{personal_snippet.id}/raw/#{ref}/#{blob.path}?inline=true") }
|
||||
end
|
||||
|
||||
context 'without a ref' do
|
||||
let(:blob) { personal_snippet.blobs.first }
|
||||
let(:ref) { blob.repository.root_ref }
|
||||
let(:ref) { nil }
|
||||
let(:expected_ref) { blob.repository.root_ref }
|
||||
|
||||
it 'uses the root ref' do
|
||||
expect(gitlab_raw_snippet_blob_path(blob)).to eq("/-/snippets/#{personal_snippet.id}/raw/#{ref}/#{blob.path}")
|
||||
expect(subject).to eq("/-/snippets/#{personal_snippet.id}/raw/#{expected_ref}/#{blob.path}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#gitlab_raw_snippet_blob_url' do
|
||||
let(:blob) { snippet.blobs.first }
|
||||
let(:ref) { 'snippet-test-ref' }
|
||||
let(:args) { {} }
|
||||
|
||||
subject { gitlab_raw_snippet_blob_url(snippet, blob.path, ref, args) }
|
||||
|
||||
context 'for a PersonalSnippet' do
|
||||
let(:snippet) { personal_snippet }
|
||||
|
||||
it { expect(subject).to eq("http://test.host/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}") }
|
||||
end
|
||||
|
||||
context 'for a ProjectSnippet' do
|
||||
let(:snippet) { project_snippet }
|
||||
|
||||
it { expect(subject).to eq("http://test.host/#{snippet.project.full_path}/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}") }
|
||||
end
|
||||
|
||||
context 'when an argument is set' do
|
||||
let(:args) { { inline: true } }
|
||||
|
||||
let(:snippet) { personal_snippet }
|
||||
|
||||
it { expect(subject).to eq("http://test.host/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}?inline=true") }
|
||||
end
|
||||
|
||||
context 'without a ref' do
|
||||
let(:snippet) { personal_snippet }
|
||||
let(:ref) { nil }
|
||||
let(:expected_ref) { snippet.repository.root_ref }
|
||||
|
||||
it 'uses the root ref' do
|
||||
expect(subject).to eq("http://test.host/-/snippets/#{snippet.id}/raw/#{expected_ref}/#{blob.path}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -208,32 +255,6 @@ RSpec.describe GitlabRoutingHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#gitlab_raw_snippet_blob_url' do
|
||||
let(:blob) { snippet.blobs.first }
|
||||
let(:ref) { 'snippet-test-ref' }
|
||||
|
||||
context 'for a PersonalSnippet' do
|
||||
let(:snippet) { personal_snippet }
|
||||
|
||||
it { expect(gitlab_raw_snippet_blob_url(snippet, blob.path, ref)).to eq("http://test.host/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}") }
|
||||
end
|
||||
|
||||
context 'for a ProjectSnippet' do
|
||||
let(:snippet) { project_snippet }
|
||||
|
||||
it { expect(gitlab_raw_snippet_blob_url(snippet, blob.path, ref)).to eq("http://test.host/#{snippet.project.full_path}/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}") }
|
||||
end
|
||||
|
||||
context 'without a ref' do
|
||||
let(:snippet) { personal_snippet }
|
||||
let(:ref) { snippet.repository.root_ref }
|
||||
|
||||
it 'uses the root ref' do
|
||||
expect(gitlab_raw_snippet_blob_url(snippet, blob.path)).to eq("http://test.host/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#gitlab_snippet_notes_path' do
|
||||
it 'returns the notes path for the personal snippet' do
|
||||
expect(gitlab_snippet_notes_path(personal_snippet)).to eq("/snippets/#{personal_snippet.id}/notes")
|
||||
|
|
Loading…
Reference in a new issue