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
51d03424
Commit
51d03424
authored
Apr 24, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
06d9bc6e
6015b521
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
74 additions
and
13 deletions
+74
-13
app/assets/javascripts/mr_popover/index.js
app/assets/javascripts/mr_popover/index.js
+8
-7
app/helpers/markup_helper.rb
app/helpers/markup_helper.rb
+2
-1
app/models/internal_id.rb
app/models/internal_id.rb
+6
-2
changelogs/unreleased/60540-merge-request-popover-is-not-working-on-the-to-do-page.yml
...erge-request-popover-is-not-working-on-the-to-do-page.yml
+5
-0
changelogs/unreleased/sh-disable-internal-ids-available-check.yml
...gs/unreleased/sh-disable-internal-ids-available-check.yml
+5
-0
spec/features/dashboard/todos/todos_spec.rb
spec/features/dashboard/todos/todos_spec.rb
+20
-0
spec/frontend/mr_popover/index_spec.js
spec/frontend/mr_popover/index_spec.js
+18
-2
spec/models/internal_id_spec.rb
spec/models/internal_id_spec.rb
+10
-1
No files found.
app/assets/javascripts/mr_popover/index.js
View file @
51d03424
...
@@ -22,13 +22,10 @@ const handleUserPopoverMouseOut = ({ target }) => {
...
@@ -22,13 +22,10 @@ const handleUserPopoverMouseOut = ({ target }) => {
* Adds a MergeRequestPopover component to the body, hands over as much data as the target element has in data attributes.
* Adds a MergeRequestPopover component to the body, hands over as much data as the target element has in data attributes.
* loads based on data-project-path and data-iid more data about an MR from the API and sets it on the popover
* loads based on data-project-path and data-iid more data about an MR from the API and sets it on the popover
*/
*/
const
handleMRPopoverMount
=
apolloProvider
=>
({
target
})
=>
{
const
handleMRPopoverMount
=
({
apolloProvider
,
projectPath
,
mrTitle
,
iid
})
=>
({
target
})
=>
{
// Add listener to actually remove it again
// Add listener to actually remove it again
target
.
addEventListener
(
'
mouseleave
'
,
handleUserPopoverMouseOut
);
target
.
addEventListener
(
'
mouseleave
'
,
handleUserPopoverMouseOut
);
const
{
projectPath
,
mrTitle
,
iid
}
=
target
.
dataset
;
const
mergeRequest
=
{};
renderFn
=
setTimeout
(()
=>
{
renderFn
=
setTimeout
(()
=>
{
const
MRPopoverComponent
=
Vue
.
extend
(
MRPopover
);
const
MRPopoverComponent
=
Vue
.
extend
(
MRPopover
);
renderedPopover
=
new
MRPopoverComponent
({
renderedPopover
=
new
MRPopoverComponent
({
...
@@ -36,7 +33,6 @@ const handleMRPopoverMount = apolloProvider => ({ target }) => {
...
@@ -36,7 +33,6 @@ const handleMRPopoverMount = apolloProvider => ({ target }) => {
target
,
target
,
projectPath
,
projectPath
,
mergeRequestIID
:
iid
,
mergeRequestIID
:
iid
,
mergeRequest
,
mergeRequestTitle
:
mrTitle
,
mergeRequestTitle
:
mrTitle
,
},
},
apolloProvider
,
apolloProvider
,
...
@@ -57,8 +53,13 @@ export default elements => {
...
@@ -57,8 +53,13 @@ export default elements => {
const
listenerAddedAttr
=
'
data-mr-listener-added
'
;
const
listenerAddedAttr
=
'
data-mr-listener-added
'
;
mrLinks
.
forEach
(
el
=>
{
mrLinks
.
forEach
(
el
=>
{
if
(
!
el
.
getAttribute
(
listenerAddedAttr
))
{
const
{
projectPath
,
mrTitle
,
iid
}
=
el
.
dataset
;
el
.
addEventListener
(
'
mouseenter
'
,
handleMRPopoverMount
(
apolloProvider
));
if
(
!
el
.
getAttribute
(
listenerAddedAttr
)
&&
projectPath
&&
mrTitle
&&
iid
)
{
el
.
addEventListener
(
'
mouseenter
'
,
handleMRPopoverMount
({
apolloProvider
,
projectPath
,
mrTitle
,
iid
}),
);
el
.
setAttribute
(
listenerAddedAttr
,
true
);
el
.
setAttribute
(
listenerAddedAttr
,
true
);
}
}
});
});
...
...
app/helpers/markup_helper.rb
View file @
51d03424
...
@@ -83,7 +83,8 @@ module MarkupHelper
...
@@ -83,7 +83,8 @@ module MarkupHelper
text
=
sanitize
(
text
=
sanitize
(
text
,
text
,
tags:
tags
,
tags:
tags
,
attributes:
Rails
::
Html
::
WhiteListSanitizer
.
allowed_attributes
+
[
'style'
,
'data-src'
,
'data-name'
,
'data-unicode-version'
]
attributes:
Rails
::
Html
::
WhiteListSanitizer
.
allowed_attributes
+
%w(style data-src data-name data-unicode-version data-iid data-project-path data-mr-title)
)
)
# since <img> tags are stripped, this can leave empty <a> tags hanging around
# since <img> tags are stripped, this can leave empty <a> tags hanging around
...
...
app/models/internal_id.rb
View file @
51d03424
...
@@ -87,12 +87,16 @@ class InternalId < ApplicationRecord
...
@@ -87,12 +87,16 @@ class InternalId < ApplicationRecord
end
end
def
available?
def
available?
@available_flag
||=
ActiveRecord
::
Migrator
.
current_version
>=
REQUIRED_SCHEMA_VERSION
# rubocop:disable Gitlab/PredicateMemoization
return
true
unless
Rails
.
env
.
test?
Gitlab
::
SafeRequestStore
.
fetch
(
:internal_ids_available_flag
)
do
ActiveRecord
::
Migrator
.
current_version
>=
REQUIRED_SCHEMA_VERSION
end
end
end
# Flushes cached information about schema
# Flushes cached information about schema
def
reset_column_information
def
reset_column_information
@available_flag
=
nil
Gitlab
::
SafeRequestStore
[
:internal_ids_available_flag
]
=
nil
super
super
end
end
end
end
...
...
changelogs/unreleased/60540-merge-request-popover-is-not-working-on-the-to-do-page.yml
0 → 100644
View file @
51d03424
---
title
:
Fix MR popover on ToDos page
merge_request
:
27382
author
:
type
:
fixed
changelogs/unreleased/sh-disable-internal-ids-available-check.yml
0 → 100644
View file @
51d03424
---
title
:
Always use internal ID tables in development and production
merge_request
:
27544
author
:
type
:
fixed
spec/features/dashboard/todos/todos_spec.rb
View file @
51d03424
...
@@ -17,6 +17,26 @@ describe 'Dashboard Todos' do
...
@@ -17,6 +17,26 @@ describe 'Dashboard Todos' do
end
end
end
end
context
'when the todo references a merge request'
do
let
(
:referenced_mr
)
{
create
(
:merge_request
,
source_project:
project
)
}
let
(
:note
)
{
create
(
:note
,
project:
project
,
note:
"Check out
#{
referenced_mr
.
to_reference
}
"
)
}
let!
(
:todo
)
{
create
(
:todo
,
:mentioned
,
user:
user
,
project:
project
,
author:
author
,
note:
note
)
}
before
do
sign_in
(
user
)
visit
dashboard_todos_path
end
it
'renders the mr link with the extra attributes'
do
link
=
page
.
find_link
(
referenced_mr
.
to_reference
)
expect
(
link
).
not_to
be_nil
expect
(
link
[
'data-iid'
]).
to
eq
(
referenced_mr
.
iid
.
to_s
)
expect
(
link
[
'data-project-path'
]).
to
eq
(
referenced_mr
.
project
.
full_path
)
expect
(
link
[
'data-mr-title'
]).
to
eq
(
referenced_mr
.
title
)
end
end
context
'User has a todo'
,
:js
do
context
'User has a todo'
,
:js
do
before
do
before
do
create
(
:todo
,
:mentioned
,
user:
user
,
project:
project
,
target:
issue
,
author:
author
)
create
(
:todo
,
:mentioned
,
user:
user
,
project:
project
,
target:
issue
,
author:
author
)
...
...
spec/frontend/mr_popover/index_spec.js
View file @
51d03424
...
@@ -7,18 +7,28 @@ createDefaultClient.default = jest.fn();
...
@@ -7,18 +7,28 @@ createDefaultClient.default = jest.fn();
describe
(
'
initMRPopovers
'
,
()
=>
{
describe
(
'
initMRPopovers
'
,
()
=>
{
let
mr1
;
let
mr1
;
let
mr2
;
let
mr2
;
let
mr3
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
setHTMLFixture
(
`
setHTMLFixture
(
`
<div id="one" class="gfm-merge_request">MR1</div>
<div id="one" class="gfm-merge_request" data-mr-title="title" data-iid="1" data-project-path="group/project">
<div id="two" class="gfm-merge_request">MR2</div>
MR1
</div>
<div id="two" class="gfm-merge_request" data-mr-title="title" data-iid="1" data-project-path="group/project">
MR2
</div>
<div id="three" class="gfm-merge_request">
MR3
</div>
`
);
`
);
mr1
=
document
.
querySelector
(
'
#one
'
);
mr1
=
document
.
querySelector
(
'
#one
'
);
mr2
=
document
.
querySelector
(
'
#two
'
);
mr2
=
document
.
querySelector
(
'
#two
'
);
mr3
=
document
.
querySelector
(
'
#three
'
);
mr1
.
addEventListener
=
jest
.
fn
();
mr1
.
addEventListener
=
jest
.
fn
();
mr2
.
addEventListener
=
jest
.
fn
();
mr2
.
addEventListener
=
jest
.
fn
();
mr3
.
addEventListener
=
jest
.
fn
();
});
});
it
(
'
does not add the same event listener twice
'
,
()
=>
{
it
(
'
does not add the same event listener twice
'
,
()
=>
{
...
@@ -27,4 +37,10 @@ describe('initMRPopovers', () => {
...
@@ -27,4 +37,10 @@ describe('initMRPopovers', () => {
expect
(
mr1
.
addEventListener
).
toHaveBeenCalledTimes
(
1
);
expect
(
mr1
.
addEventListener
).
toHaveBeenCalledTimes
(
1
);
expect
(
mr2
.
addEventListener
).
toHaveBeenCalledTimes
(
1
);
expect
(
mr2
.
addEventListener
).
toHaveBeenCalledTimes
(
1
);
});
});
it
(
'
does not add listener if it does not have the necessary data attributes
'
,
()
=>
{
initMRPopovers
([
mr1
,
mr2
,
mr3
]);
expect
(
mr3
.
addEventListener
).
not
.
toHaveBeenCalled
();
});
});
});
spec/models/internal_id_spec.rb
View file @
51d03424
...
@@ -93,7 +93,7 @@ describe InternalId do
...
@@ -93,7 +93,7 @@ describe InternalId do
before
do
before
do
described_class
.
reset_column_information
described_class
.
reset_column_information
# Project factory will also call the current_version
# Project factory will also call the current_version
expect
(
ActiveRecord
::
Migrator
).
to
receive
(
:current_version
).
twice
.
and_return
(
InternalId
::
REQUIRED_SCHEMA_VERSION
-
1
)
expect
(
ActiveRecord
::
Migrator
).
to
receive
(
:current_version
).
at_least
(
:once
)
.
and_return
(
InternalId
::
REQUIRED_SCHEMA_VERSION
-
1
)
end
end
let
(
:init
)
{
double
(
'block'
)
}
let
(
:init
)
{
double
(
'block'
)
}
...
@@ -104,6 +104,15 @@ describe InternalId do
...
@@ -104,6 +104,15 @@ describe InternalId do
expect
(
init
).
to
receive
(
:call
).
with
(
issue
).
and_return
(
val
)
expect
(
init
).
to
receive
(
:call
).
with
(
issue
).
and_return
(
val
)
expect
(
subject
).
to
eq
(
val
+
1
)
expect
(
subject
).
to
eq
(
val
+
1
)
end
end
it
'always attempts to generate internal IDs in production mode'
do
allow
(
Rails
.
env
).
to
receive
(
:test?
).
and_return
(
false
)
val
=
rand
(
1
..
100
)
generator
=
double
(
generate:
val
)
expect
(
InternalId
::
InternalIdGenerator
).
to
receive
(
:new
).
and_return
(
generator
)
expect
(
subject
).
to
eq
(
val
)
end
end
end
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