Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
c920712f
Commit
c920712f
authored
Oct 16, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add latest changes from gitlab-org/gitlab@master
parent
0ff031c7
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
536 additions
and
70 deletions
+536
-70
app/assets/javascripts/releases/list/components/release_block.vue
...ts/javascripts/releases/list/components/release_block.vue
+26
-8
app/controllers/projects/releases_controller.rb
app/controllers/projects/releases_controller.rb
+3
-0
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+2
-2
changelogs/unreleased/nfriend-add-edit-button-to-release-blocks.yml
.../unreleased/nfriend-add-edit-button-to-release-blocks.yml
+5
-0
doc/ci/multi_project_pipelines.md
doc/ci/multi_project_pipelines.md
+2
-1
doc/ci/yaml/README.md
doc/ci/yaml/README.md
+39
-1
doc/development/api_graphql_styleguide.md
doc/development/api_graphql_styleguide.md
+5
-0
doc/development/issuable-like-models.md
doc/development/issuable-like-models.md
+2
-2
doc/development/rake_tasks.md
doc/development/rake_tasks.md
+23
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/frontend/releases/list/components/__snapshots__/release_block_spec.js.snap
.../list/components/__snapshots__/release_block_spec.js.snap
+332
-0
spec/frontend/releases/list/components/release_block_spec.js
spec/frontend/releases/list/components/release_block_spec.js
+85
-50
spec/frontend/releases/mock_data.js
spec/frontend/releases/mock_data.js
+3
-0
spec/models/concerns/issuable_spec.rb
spec/models/concerns/issuable_spec.rb
+2
-2
spec/support/shared_examples/models/concern/issuable_shared_examples.rb
...hared_examples/models/concern/issuable_shared_examples.rb
+4
-4
No files found.
app/assets/javascripts/releases/list/components/release_block.vue
View file @
c920712f
<
script
>
/* eslint-disable @gitlab/vue-i18n/no-bare-strings */
import
_
from
'
underscore
'
;
import
{
GlTooltipDirective
,
GlLink
,
GlBadge
}
from
'
@gitlab/ui
'
;
import
{
GlTooltipDirective
,
GlLink
,
GlBadge
,
GlButton
}
from
'
@gitlab/ui
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
UserAvatarLink
from
'
~/vue_shared/components/user_avatar/user_avatar_link.vue
'
;
import
timeagoMixin
from
'
~/vue_shared/mixins/timeago
'
;
...
...
@@ -9,19 +9,21 @@ import { __, n__, sprintf } from '~/locale';
import
{
slugify
}
from
'
~/lib/utils/text_utility
'
;
import
{
getLocationHash
}
from
'
~/lib/utils/url_utility
'
;
import
{
scrollToElement
}
from
'
~/lib/utils/common_utils
'
;
import
glFeatureFlagsMixin
from
'
~/vue_shared/mixins/gl_feature_flags_mixin
'
;
export
default
{
name
:
'
ReleaseBlock
'
,
components
:
{
GlLink
,
GlBadge
,
GlButton
,
Icon
,
UserAvatarLink
,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
},
mixins
:
[
timeagoMixin
],
mixins
:
[
timeagoMixin
,
glFeatureFlagsMixin
()
],
props
:
{
release
:
{
type
:
Object
,
...
...
@@ -72,6 +74,11 @@ export default {
labelText
()
{
return
n__
(
'
Milestone
'
,
'
Milestones
'
,
this
.
release
.
milestones
.
length
);
},
shouldShowEditButton
()
{
return
Boolean
(
this
.
glFeatures
.
releaseEditPage
&&
this
.
release
.
_links
&&
this
.
release
.
_links
.
edit
,
);
},
},
mounted
()
{
const
hash
=
getLocationHash
();
...
...
@@ -89,12 +96,23 @@ export default {
<
template
>
<div
:id=
"id"
:class=
"
{ 'bg-line-target-blue': isHighlighted }" class="card release-block">
<div
class=
"card-body"
>
<h2
class=
"card-title mt-0"
>
<div
class=
"d-flex align-items-start"
>
<h2
class=
"card-title mt-0 mr-auto"
>
{{
release
.
name
}}
<gl-badge
v-if=
"release.upcoming_release"
variant=
"warning"
class=
"align-middle"
>
{{
__
(
'
Upcoming Release
'
)
}}
</gl-badge>
</h2>
<gl-link
v-if=
"shouldShowEditButton"
v-gl-tooltip
class=
"btn btn-default js-edit-button ml-2"
:title=
"__('Edit this release')"
:href=
"release._links.edit"
>
<icon
name=
"pencil"
/>
</gl-link>
</div>
<div
class=
"card-subtitle d-flex flex-wrap text-secondary"
>
<div
class=
"append-right-8"
>
...
...
app/controllers/projects/releases_controller.rb
View file @
c920712f
...
...
@@ -4,6 +4,9 @@ class Projects::ReleasesController < Projects::ApplicationController
# Authorize
before_action
:require_non_empty_project
before_action
:authorize_read_release!
before_action
do
push_frontend_feature_flag
(
:release_edit_page
,
project
)
end
def
index
end
...
...
app/models/concerns/issuable.rb
View file @
c920712f
...
...
@@ -28,8 +28,8 @@ module Issuable
TITLE_LENGTH_MAX
=
255
TITLE_HTML_LENGTH_MAX
=
800
DESCRIPTION_LENGTH_MAX
=
1
6000
DESCRIPTION_HTML_LENGTH_MAX
=
48000
DESCRIPTION_LENGTH_MAX
=
1
.
megabyte
DESCRIPTION_HTML_LENGTH_MAX
=
5
.
megabytes
# This object is used to gather issuable meta data for displaying
# upvotes, downvotes, notes and closing merge requests count for issues and merge requests
...
...
changelogs/unreleased/nfriend-add-edit-button-to-release-blocks.yml
0 → 100644
View file @
c920712f
---
title
:
Add edit button to release blocks on Releases page
merge_request
:
18411
author
:
type
:
added
doc/ci/multi_project_pipelines.md
View file @
c920712f
...
...
@@ -119,7 +119,8 @@ Use:
-
The
`project`
keyword to specify the full path to a downstream project.
-
The
`branch`
keyword to specify the name of a branch in the project specified by
`project`
.
Variable expansion is supported.
[
From GitLab 12.4
](
https://gitlab.com/gitlab-org/gitlab/issues/10126
)
, variable expansion is
supported.
GitLab will use a commit that is currently on the HEAD of the branch when
creating a downstream pipeline.
...
...
doc/ci/yaml/README.md
View file @
c920712f
...
...
@@ -1086,13 +1086,51 @@ Manual actions are considered to be write actions, so permissions for
[
protected branches
](
../../user/project/protected_branches.md
)
are used when
a user wants to trigger an action. In other words, in order to trigger a manual
action assigned to a branch that the pipeline is running for, the user needs to
have the ability to merge to this branch.
have the ability to merge to this branch. It is possible to use protected environments
to more strictly
[
protect manual deployments
](
#protecting-manual-jobs
)
from being
run by unauthorized users.
NOTE:
**Note:**
Using
`when:manual`
and
`trigger`
together results in the error
`jobs:#{job-name} when
should be on_success, on_failure or always`
, because
`when:manual`
prevents triggers
being used.
##### Protecting manual jobs
It's possible to use
[
protected environments
](
../environments/protected_environments.md
)
to define a precise list of users authorized to run a manual job. By allowing only
users associated with a protected environment to trigger manual jobs, it is possible
to implement some special use cases, such as:
-
more precisely limiting who can deploy to an environment.
-
enabling a pipeline to be blocked until an approved user "approves" it.
To do this, you must add an environment to the job. For example:
```
yaml
deploy_prod
:
stage
:
deploy
script
:
-
echo "Deploy to production server"
environment
:
name
:
production
url
:
https://example.com
when
:
manual
only
:
-
master
```
Then, in the
[
protected environments settings
](
../environments/protected_environments.md#protecting-environments
)
,
select the environment (
`production`
in the example above) and add the users, roles or groups
that are authorized to trigger the manual job to the
**Allowed to Deploy**
list. Only those in
this list will be able to trigger this manual job, as well as GitLab admins who are always able
to use protected environments.
Additionally, if a manual job is defined as blocking by adding
`allow_failure: false`
,
the next stages of the pipeline will not run until the manual job is triggered. This
can be used as a way to have a defined list of users allowed to "approve" later pipeline
stages by triggering the blocking manual job.
#### `when:delayed`
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/21767) in GitLab 11.4.
...
...
doc/development/api_graphql_styleguide.md
View file @
c920712f
...
...
@@ -539,3 +539,8 @@ it 'returns a successful response' do
expect
(
graphql_mutation_response
(
:merge_request_set_wip
)[
'errors'
]).
to
be_empty
end
```
## Documentation
For information on generating GraphQL documentation, see
[
Rake tasks related to GraphQL
](
rake_tasks.md#update-graphql-documentation
)
.
doc/development/issuable-like-models.md
View file @
c920712f
...
...
@@ -11,8 +11,8 @@ There are max length constraints for the most important text fields for `Issuabl
-
`title`
: 255 chars
-
`title_html`
: 800 chars
-
`description`
: 1
6000 chars
-
`description_html`
:
48000 char
s
-
`description`
: 1
megabyte
-
`description_html`
:
5 megabyte
s
[
Issue
]:
https://docs.gitlab.com/ee/user/project/issues
[
Merge Requests
]:
https://docs.gitlab.com/ee/user/project/merge_requests
...
...
doc/development/rake_tasks.md
View file @
c920712f
...
...
@@ -220,3 +220,26 @@ bundle exec rake db:obsolete_ignored_columns
```
Feel free to remove their definitions from their
`ignored_columns`
definitions.
## Update GraphQL Documentation
To generate GraphQL documentation based on the GitLab schema, run:
```
shell
bundle
exec
rake gitlab:graphql:compile_docs
```
In its current state, the rake task:
-
Generates output for GraphQL objects.
-
Places the output at
`docs/api/graphql/reference/index.md`
.
This uses some features from
`graphql-docs`
gem like its schema parser and helper methods.
The docs generator code comes from our side giving us more flexibility, like using Haml templates and generating Markdown files.
To edit the template used, please take a look at
`lib/gitlab/graphql/docs/templates/default.md.haml`
.
The actual renderer is at
`Gitlab::Graphql::Docs::Renderer`
.
`@parsed_schema`
is an instance variable that the
`graphql-docs`
gem expects to have available.
`Gitlab::Graphql::Docs::Helper`
defines the
`object`
method we currently use. This is also where you should implement any
new methods for new types you'd like to display.
locale/gitlab.pot
View file @
c920712f
...
...
@@ -5805,6 +5805,9 @@ msgstr ""
msgid "Edit stage"
msgstr ""
msgid "Edit this release"
msgstr ""
msgid "Edit wiki page"
msgstr ""
...
...
spec/frontend/releases/list/components/__snapshots__/release_block_spec.js.snap
0 → 100644
View file @
c920712f
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Release block with default props matches the snapshot 1`] = `
<div
class="card release-block"
id="v0.3"
>
<div
class="card-body"
>
<div
class="d-flex align-items-start"
>
<h2
class="card-title mt-0 mr-auto"
>
New release
<!---->
</h2>
<a
class="btn btn-default js-edit-button ml-2"
data-original-title="Edit this release"
href="http://0.0.0.0:3001/root/release-test/-/releases/v0.3/edit"
title=""
>
<svg
aria-hidden="true"
class="s16 ic-pencil"
>
<use
xlink:href="#pencil"
/>
</svg>
</a>
</div>
<div
class="card-subtitle d-flex flex-wrap text-secondary"
>
<div
class="append-right-8"
>
<svg
aria-hidden="true"
class="align-middle s16 ic-commit"
>
<use
xlink:href="#commit"
/>
</svg>
<span
data-original-title="Initial commit"
title=""
>
c22b0728
</span>
</div>
<div
class="append-right-8"
>
<svg
aria-hidden="true"
class="align-middle s16 ic-tag"
>
<use
xlink:href="#tag"
/>
</svg>
<span
data-original-title="Tag"
title=""
>
v0.3
</span>
</div>
<div
class="js-milestone-list-label"
>
<svg
aria-hidden="true"
class="align-middle s16 ic-flag"
>
<use
xlink:href="#flag"
/>
</svg>
<span
class="js-label-text"
>
Milestones
</span>
</div>
<a
class="append-right-4 prepend-left-4 js-milestone-link"
data-original-title="The 13.6 milestone!"
href="http://0.0.0.0:3001/root/release-test/-/milestones/2"
title=""
>
13.6
</a>
•
<a
class="append-right-4 prepend-left-4 js-milestone-link"
data-original-title="The 13.5 milestone!"
href="http://0.0.0.0:3001/root/release-test/-/milestones/1"
title=""
>
13.5
</a>
<!---->
<div
class="append-right-4"
>
•
<span
data-original-title="Aug 26, 2019 5:54pm GMT+0000"
title=""
>
released 1 month ago
</span>
</div>
<div
class="d-flex"
>
by
<a
class="user-avatar-link prepend-left-4"
href=""
>
<span>
<img
alt="root's avatar"
class="avatar s20 "
data-original-title=""
data-src="https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
height="20"
src="https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
title=""
width="20"
/>
<div
aria-hidden="true"
class="js-user-avatar-image-toolip d-none"
style="display: none;"
>
<div>
root
</div>
</div>
</span>
<!---->
</a>
</div>
</div>
<div
class="card-text prepend-top-default"
>
<b>
Assets
<span
class="js-assets-count badge badge-pill"
>
5
</span>
</b>
<ul
class="pl-0 mb-0 prepend-top-8 list-unstyled js-assets-list"
>
<li
class="append-bottom-8"
>
<a
class=""
data-original-title="Download asset"
href="https://google.com"
title=""
>
<svg
aria-hidden="true"
class="align-middle append-right-4 align-text-bottom s16 ic-package"
>
<use
xlink:href="#package"
/>
</svg>
my link
<span>
(external source)
</span>
</a>
</li>
<li
class="append-bottom-8"
>
<a
class=""
data-original-title="Download asset"
href="https://gitlab.com/gitlab-org/gitlab-foss/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50"
title=""
>
<svg
aria-hidden="true"
class="align-middle append-right-4 align-text-bottom s16 ic-package"
>
<use
xlink:href="#package"
/>
</svg>
my second link
<!---->
</a>
</li>
</ul>
<div
class="dropdown"
>
<button
aria-expanded="false"
aria-haspopup="true"
class="btn btn-link"
data-toggle="dropdown"
type="button"
>
<svg
aria-hidden="true"
class="align-top append-right-4 s16 ic-doc-code"
>
<use
xlink:href="#doc-code"
/>
</svg>
Source code
<svg
aria-hidden="true"
class="s16 ic-arrow-down"
>
<use
xlink:href="#arrow-down"
/>
</svg>
</button>
<div
class="js-sources-dropdown dropdown-menu"
>
<li>
<a
class=""
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.zip"
>
Download zip
</a>
</li>
<li>
<a
class=""
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar.gz"
>
Download tar.gz
</a>
</li>
<li>
<a
class=""
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar.bz2"
>
Download tar.bz2
</a>
</li>
<li>
<a
class=""
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar"
>
Download tar
</a>
</li>
</div>
</div>
</div>
<div
class="card-text prepend-top-default"
>
<div>
<p
data-sourcepos="1:1-1:21"
dir="auto"
>
A super nice release!
</p>
</div>
</div>
</div>
</div>
`;
spec/frontend/releases/list/components/release_block_spec.js
View file @
c920712f
...
...
@@ -19,46 +19,53 @@ jest.mock('~/lib/utils/common_utils', () => ({
describe
(
'
Release block
'
,
()
=>
{
let
wrapper
;
let
releaseClone
;
const
factory
=
releaseProp
=>
{
const
factory
=
(
releaseProp
,
releaseEditPageFeatureFlag
=
true
)
=>
{
wrapper
=
mount
(
ReleaseBlock
,
{
propsData
:
{
release
:
releaseProp
,
},
provide
:
{
glFeatures
:
{
releaseEditPage
:
releaseEditPageFeatureFlag
,
},
},
sync
:
false
,
});
return
wrapper
.
vm
.
$nextTick
();
};
const
milestoneListLabel
=
()
=>
wrapper
.
find
(
'
.js-milestone-list-label
'
);
const
editButton
=
()
=>
wrapper
.
find
(
'
.js-edit-button
'
);
beforeEach
(()
=>
{
releaseClone
=
JSON
.
parse
(
JSON
.
stringify
(
release
));
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
describe
(
'
with default props
'
,
()
=>
{
beforeEach
(()
=>
{
factory
(
release
);
beforeEach
(()
=>
factory
(
release
));
it
(
'
matches the snapshot
'
,
()
=>
{
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
it
(
"
renders the block with an id equal to the release's tag name
"
,
()
=>
{
expect
(
wrapper
.
attributes
().
id
).
toBe
(
'
v0.3
'
);
});
it
(
'
renders release name
'
,
()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
release
.
name
);
it
(
'
renders an edit button that links to the "Edit release" page
'
,
()
=>
{
expect
(
editButton
().
exists
()).
toBe
(
true
);
expect
(
editButton
().
attributes
(
'
href
'
)).
toBe
(
release
.
_links
.
edit
);
});
it
(
'
renders commit sha
'
,
()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
release
.
commit
.
short_id
);
wrapper
.
setProps
({
release
:
{
...
release
,
commit_path
:
'
/commit/example
'
}
});
expect
(
wrapper
.
find
(
'
a[href="/commit/example"]
'
).
exists
()).
toBe
(
true
);
});
it
(
'
renders tag name
'
,
()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
release
.
tag_name
);
wrapper
.
setProps
({
release
:
{
...
release
,
tag_path
:
'
/tag/example
'
}
});
expect
(
wrapper
.
find
(
'
a[href="/tag/example"]
'
).
exists
()).
toBe
(
true
);
it
(
'
renders release name
'
,
()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
release
.
name
);
});
it
(
'
renders release date
'
,
()
=>
{
...
...
@@ -141,45 +148,74 @@ describe('Release block', () => {
});
});
it
(
'
renders commit sha
'
,
()
=>
{
releaseClone
.
commit_path
=
'
/commit/example
'
;
return
factory
(
releaseClone
).
then
(()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
release
.
commit
.
short_id
);
expect
(
wrapper
.
find
(
'
a[href="/commit/example"]
'
).
exists
()).
toBe
(
true
);
});
});
it
(
'
renders tag name
'
,
()
=>
{
releaseClone
.
tag_path
=
'
/tag/example
'
;
return
factory
(
releaseClone
).
then
(()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
release
.
tag_name
);
expect
(
wrapper
.
find
(
'
a[href="/tag/example"]
'
).
exists
()).
toBe
(
true
);
});
});
it
(
"
does not render an edit button if release._links.edit isn't a string
"
,
()
=>
{
delete
releaseClone
.
_links
;
return
factory
(
releaseClone
).
then
(()
=>
{
expect
(
editButton
().
exists
()).
toBe
(
false
);
});
});
it
(
'
does not render an edit button if the releaseEditPage feature flag is disabled
'
,
()
=>
factory
(
releaseClone
,
false
).
then
(()
=>
{
expect
(
editButton
().
exists
()).
toBe
(
false
);
}));
it
(
'
does not render the milestone list if no milestones are associated to the release
'
,
()
=>
{
const
releaseClone
=
JSON
.
parse
(
JSON
.
stringify
(
release
));
delete
releaseClone
.
milestones
;
factory
(
releaseClone
);
return
factory
(
releaseClone
).
then
(()
=>
{
expect
(
milestoneListLabel
().
exists
()).
toBe
(
false
);
});
});
it
(
'
renders the label as "Milestone" if only a single milestone is passed in
'
,
()
=>
{
const
releaseClone
=
JSON
.
parse
(
JSON
.
stringify
(
release
));
releaseClone
.
milestones
=
releaseClone
.
milestones
.
slice
(
0
,
1
);
factory
(
releaseClone
);
return
factory
(
releaseClone
).
then
(()
=>
{
expect
(
milestoneListLabel
()
.
find
(
'
.js-label-text
'
)
.
text
(),
).
toEqual
(
'
Milestone
'
);
});
});
it
(
'
renders upcoming release badge
'
,
()
=>
{
const
releaseClone
=
JSON
.
parse
(
JSON
.
stringify
(
release
));
releaseClone
.
upcoming_release
=
true
;
factory
(
releaseClone
);
return
factory
(
releaseClone
).
then
(()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
'
Upcoming Release
'
);
});
});
it
(
'
slugifies the tag_name before setting it as the elements ID
'
,
()
=>
{
const
releaseClone
=
JSON
.
parse
(
JSON
.
stringify
(
release
));
releaseClone
.
tag_name
=
'
a dangerous tag name <script>alert("hello")</script>
'
;
factory
(
releaseClone
);
return
factory
(
releaseClone
).
then
(()
=>
{
expect
(
wrapper
.
attributes
().
id
).
toBe
(
'
a-dangerous-tag-name-script-alert-hello-script-
'
);
});
});
describe
(
'
anchor scrolling
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -190,40 +226,39 @@ describe('Release block', () => {
it
(
'
does not attempt to scroll the page if no anchor tag is included in the URL
'
,
()
=>
{
mockLocationHash
=
''
;
factory
(
release
);
return
factory
(
release
).
then
(()
=>
{
expect
(
scrollToElement
).
not
.
toHaveBeenCalled
();
});
});
it
(
"
does not attempt to scroll the page if the anchor tag doesn't match the release's tag name
"
,
()
=>
{
mockLocationHash
=
'
v0.4
'
;
factory
(
release
);
return
factory
(
release
).
then
(()
=>
{
expect
(
scrollToElement
).
not
.
toHaveBeenCalled
();
});
});
it
(
"
attempts to scroll itself into view if the anchor tag matches the release's tag name
"
,
()
=>
{
mockLocationHash
=
release
.
tag_name
;
factory
(
release
);
return
factory
(
release
).
then
(()
=>
{
expect
(
scrollToElement
).
toHaveBeenCalledTimes
(
1
);
expect
(
scrollToElement
).
toHaveBeenCalledWith
(
wrapper
.
element
);
});
});
it
(
'
renders with a light blue background if it is the target of the anchor
'
,
()
=>
{
mockLocationHash
=
release
.
tag_name
;
factory
(
release
);
return
wrapper
.
vm
.
$nextTick
(
).
then
(()
=>
{
return
factory
(
release
).
then
(()
=>
{
expect
(
hasTargetBlueBackground
()).
toBe
(
true
);
});
});
it
(
'
does not render with a light blue background if it is not the target of the anchor
'
,
()
=>
{
mockLocationHash
=
''
;
factory
(
release
);
return
wrapper
.
vm
.
$nextTick
(
).
then
(()
=>
{
return
factory
(
release
).
then
(()
=>
{
expect
(
hasTargetBlueBackground
()).
toBe
(
false
);
});
});
...
...
spec/frontend/releases/mock_data.js
View file @
c920712f
...
...
@@ -94,4 +94,7 @@ export const release = {
},
],
},
_links
:
{
edit
:
'
http://0.0.0.0:3001/root/release-test/-/releases/v0.3/edit
'
,
},
};
spec/models/concerns/issuable_spec.rb
View file @
c920712f
...
...
@@ -45,8 +45,8 @@ describe Issuable do
it
{
is_expected
.
to
validate_presence_of
(
:iid
)
}
it
{
is_expected
.
to
validate_presence_of
(
:author
)
}
it
{
is_expected
.
to
validate_presence_of
(
:title
)
}
it
{
is_expected
.
to
validate_length_of
(
:title
).
is_at_most
(
255
)
}
it
{
is_expected
.
to
validate_length_of
(
:description
).
is_at_most
(
16_000
).
on
(
:create
)
}
it
{
is_expected
.
to
validate_length_of
(
:title
).
is_at_most
(
described_class
::
TITLE_LENGTH_MAX
)
}
it
{
is_expected
.
to
validate_length_of
(
:description
).
is_at_most
(
described_class
::
DESCRIPTION_LENGTH_MAX
).
on
(
:create
)
}
it_behaves_like
'validates description length with custom validation'
it_behaves_like
'truncates the description to its allowed maximum length on import'
...
...
spec/support/shared_examples/models/concern/issuable_shared_examples.rb
View file @
c920712f
...
...
@@ -10,7 +10,7 @@ shared_examples_for 'matches_cross_reference_regex? fails fast' do
end
shared_examples_for
'validates description length with custom validation'
do
let
(
:issuable
)
{
build
(
:issue
,
description:
'x'
*
16_001
)
}
let
(
:issuable
)
{
build
(
:issue
,
description:
'x'
*
(
::
Issuable
::
DESCRIPTION_LENGTH_MAX
+
1
)
)
}
let
(
:context
)
{
:update
}
subject
{
issuable
.
validate
(
context
)
}
...
...
@@ -18,7 +18,7 @@ shared_examples_for 'validates description length with custom validation' do
context
'when Issuable is a new record'
do
it
'validates the maximum description length'
do
subject
expect
(
issuable
.
errors
[
:description
]).
to
eq
([
"is too long (maximum is
16000
characters)"
])
expect
(
issuable
.
errors
[
:description
]).
to
eq
([
"is too long (maximum is
#{
::
Issuable
::
DESCRIPTION_LENGTH_MAX
}
characters)"
])
end
context
'on create'
do
...
...
@@ -53,14 +53,14 @@ shared_examples_for 'truncates the description to its allowed maximum length on
allow
(
issuable
).
to
receive
(
:importing?
).
and_return
(
true
)
end
let
(
:issuable
)
{
build
(
:issue
,
description:
'x'
*
16_001
)
}
let
(
:issuable
)
{
build
(
:issue
,
description:
'x'
*
(
::
Issuable
::
DESCRIPTION_LENGTH_MAX
+
1
)
)
}
subject
{
issuable
.
validate
(
:create
)
}
it
'truncates the description to its allowed maximum length'
do
subject
expect
(
issuable
.
description
).
to
eq
(
'x'
*
16_000
)
expect
(
issuable
.
description
).
to
eq
(
'x'
*
::
Issuable
::
DESCRIPTION_LENGTH_MAX
)
expect
(
issuable
.
errors
[
:description
]).
to
be_empty
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment