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
f158dd2a
Commit
f158dd2a
authored
May 05, 2017
by
Regis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix ce to ee conflicts
parent
3fddf612
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
350 additions
and
136 deletions
+350
-136
app/assets/javascripts/issue_show/actions/tasks.js
app/assets/javascripts/issue_show/actions/tasks.js
+27
-0
app/assets/javascripts/issue_show/index.js
app/assets/javascripts/issue_show/index.js
+3
-3
app/assets/javascripts/issue_show/issue_title.vue
app/assets/javascripts/issue_show/issue_title.vue
+0
-80
app/assets/javascripts/issue_show/issue_title_description.vue
...assets/javascripts/issue_show/issue_title_description.vue
+180
-0
app/assets/stylesheets/pages/issues.scss
app/assets/stylesheets/pages/issues.scss
+9
-0
app/controllers/projects/issues_controller.rb
app/controllers/projects/issues_controller.rb
+10
-1
app/views/projects/issues/show.html.haml
app/views/projects/issues/show.html.haml
+4
-9
features/project/issues/issues.feature
features/project/issues/issues.feature
+1
-0
spec/features/issues/award_spec.rb
spec/features/issues/award_spec.rb
+6
-0
spec/features/task_lists_spec.rb
spec/features/task_lists_spec.rb
+22
-13
spec/javascripts/issue_show/issue_title_description_spec.js
spec/javascripts/issue_show/issue_title_description_spec.js
+60
-0
spec/javascripts/issue_show/issue_title_spec.js
spec/javascripts/issue_show/issue_title_spec.js
+0
-22
spec/javascripts/issue_show/mock_data.js
spec/javascripts/issue_show/mock_data.js
+26
-0
spec/javascripts/issue_spec.js
spec/javascripts/issue_spec.js
+0
-6
spec/support/features/issuable_slash_commands_shared_examples.rb
...pport/features/issuable_slash_commands_shared_examples.rb
+2
-2
No files found.
app/assets/javascripts/issue_show/actions/tasks.js
0 → 100644
View file @
f158dd2a
export
default
(
newStateData
,
tasks
)
=>
{
const
$tasks
=
$
(
'
#task_status
'
);
const
$tasksShort
=
$
(
'
#task_status_short
'
);
const
$issueableHeader
=
$
(
'
.issuable-header
'
);
const
tasksStates
=
{
newState
:
null
,
currentState
:
null
};
if
(
$tasks
.
length
===
0
)
{
if
(
!
(
newStateData
.
task_status
.
indexOf
(
'
0 of 0
'
)
===
0
))
{
$issueableHeader
.
append
(
`<span id="task_status">
${
newStateData
.
task_status
}
</span>`
);
}
else
{
$issueableHeader
.
append
(
'
<span id="task_status"></span>
'
);
}
}
else
{
tasksStates
.
newState
=
newStateData
.
task_status
.
indexOf
(
'
0 of 0
'
)
===
0
;
tasksStates
.
currentState
=
tasks
.
indexOf
(
'
0 of 0
'
)
===
0
;
}
if
(
$tasks
.
length
!==
0
&&
!
tasksStates
.
newState
)
{
$tasks
.
text
(
newStateData
.
task_status
);
$tasksShort
.
text
(
newStateData
.
task_status
);
}
else
if
(
tasksStates
.
currentState
)
{
$issueableHeader
.
append
(
`<span id="task_status">
${
newStateData
.
task_status
}
</span>`
);
}
else
if
(
tasksStates
.
newState
)
{
$tasks
.
remove
();
$tasksShort
.
remove
();
}
};
app/assets/javascripts/issue_show/index.js
View file @
f158dd2a
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
IssueTitle
from
'
./issue_title.vue
'
;
import
IssueTitle
from
'
./issue_title
_description
.vue
'
;
import
'
../vue_shared/vue_resource_interceptor
'
;
import
'
../vue_shared/vue_resource_interceptor
'
;
(()
=>
{
(()
=>
{
const
issueTitleData
=
document
.
querySelector
(
'
.issue-title-data
'
).
dataset
;
const
issueTitleData
=
document
.
querySelector
(
'
.issue-title-data
'
).
dataset
;
const
{
initialTitle
,
endpoint
}
=
issueTitleData
;
const
{
canUpdateTasksClass
,
endpoint
}
=
issueTitleData
;
const
vm
=
new
Vue
({
const
vm
=
new
Vue
({
el
:
'
.issue-title-entrypoint
'
,
el
:
'
.issue-title-entrypoint
'
,
render
:
createElement
=>
createElement
(
IssueTitle
,
{
render
:
createElement
=>
createElement
(
IssueTitle
,
{
props
:
{
props
:
{
initialTitle
,
canUpdateTasksClass
,
endpoint
,
endpoint
,
},
},
}),
}),
...
...
app/assets/javascripts/issue_show/issue_title.vue
deleted
100644 → 0
View file @
3fddf612
<
script
>
import
Visibility
from
'
visibilityjs
'
;
import
Poll
from
'
./../lib/utils/poll
'
;
import
Service
from
'
./services/index
'
;
export
default
{
props
:
{
initialTitle
:
{
required
:
true
,
type
:
String
},
endpoint
:
{
required
:
true
,
type
:
String
},
},
data
()
{
const
resource
=
new
Service
(
this
.
$http
,
this
.
endpoint
);
const
poll
=
new
Poll
({
resource
,
method
:
'
getTitle
'
,
successCallback
:
(
res
)
=>
{
this
.
renderResponse
(
res
);
},
errorCallback
:
(
err
)
=>
{
if
(
process
.
env
.
NODE_ENV
!==
'
production
'
)
{
// eslint-disable-next-line no-console
console
.
error
(
'
ISSUE SHOW TITLE REALTIME ERROR
'
,
err
);
}
else
{
throw
new
Error
(
err
);
}
},
});
return
{
poll
,
timeoutId
:
null
,
title
:
this
.
initialTitle
,
};
},
methods
:
{
renderResponse
(
res
)
{
const
body
=
JSON
.
parse
(
res
.
body
);
this
.
triggerAnimation
(
body
);
},
triggerAnimation
(
body
)
{
const
{
title
}
=
body
;
/**
* since opacity is changed, even if there is no diff for Vue to update
* we must check the title even on a 304 to ensure no visual change
*/
if
(
this
.
title
===
title
)
return
;
this
.
$el
.
style
.
opacity
=
0
;
this
.
timeoutId
=
setTimeout
(()
=>
{
this
.
title
=
title
;
this
.
$el
.
style
.
transition
=
'
opacity 0.2s ease
'
;
this
.
$el
.
style
.
opacity
=
1
;
clearTimeout
(
this
.
timeoutId
);
},
100
);
},
},
created
()
{
if
(
!
Visibility
.
hidden
())
{
this
.
poll
.
makeRequest
();
}
Visibility
.
change
(()
=>
{
if
(
!
Visibility
.
hidden
())
{
this
.
poll
.
restart
();
}
else
{
this
.
poll
.
stop
();
}
});
},
};
</
script
>
<
template
>
<h2
class=
"title"
v-html=
"title"
></h2>
</
template
>
app/assets/javascripts/issue_show/issue_title_description.vue
0 → 100644
View file @
f158dd2a
<
script
>
import
Visibility
from
'
visibilityjs
'
;
import
Poll
from
'
./../lib/utils/poll
'
;
import
Service
from
'
./services/index
'
;
import
tasks
from
'
./actions/tasks
'
;
export
default
{
props
:
{
endpoint
:
{
required
:
true
,
type
:
String
,
},
canUpdateTasksClass
:
{
required
:
true
,
type
:
String
,
},
},
data
()
{
const
resource
=
new
Service
(
this
.
$http
,
this
.
endpoint
);
const
poll
=
new
Poll
({
resource
,
method
:
'
getTitle
'
,
successCallback
:
(
res
)
=>
{
this
.
renderResponse
(
res
);
},
errorCallback
:
(
err
)
=>
{
throw
new
Error
(
err
);
},
});
return
{
poll
,
apiData
:
{},
tasks
:
'
0 of 0
'
,
title
:
null
,
titleText
:
''
,
titleFlag
:
{
pre
:
true
,
pulse
:
false
,
},
description
:
null
,
descriptionText
:
''
,
descriptionChange
:
false
,
descriptionFlag
:
{
pre
:
true
,
pulse
:
false
,
},
timeAgoEl
:
$
(
'
.issue_edited_ago
'
),
titleEl
:
document
.
querySelector
(
'
title
'
),
};
},
methods
:
{
updateFlag
(
key
,
toggle
)
{
this
[
key
].
pre
=
toggle
;
this
[
key
].
pulse
=
!
toggle
;
},
renderResponse
(
res
)
{
this
.
apiData
=
res
.
json
();
this
.
triggerAnimation
();
},
updateTaskHTML
()
{
tasks
(
this
.
apiData
,
this
.
tasks
);
},
elementsToVisualize
(
noTitleChange
,
noDescriptionChange
)
{
if
(
!
noTitleChange
)
{
this
.
titleText
=
this
.
apiData
.
title_text
;
this
.
updateFlag
(
'
titleFlag
'
,
true
);
}
if
(
!
noDescriptionChange
)
{
// only change to true when we need to bind TaskLists the html of description
this
.
descriptionChange
=
true
;
this
.
updateTaskHTML
();
this
.
tasks
=
this
.
apiData
.
task_status
;
this
.
updateFlag
(
'
descriptionFlag
'
,
true
);
}
},
setTabTitle
()
{
const
currentTabTitleScope
=
this
.
titleEl
.
innerText
.
split
(
'
·
'
);
currentTabTitleScope
[
0
]
=
`
${
this
.
titleText
}
(#
${
this
.
apiData
.
issue_number
}
) `
;
this
.
titleEl
.
innerText
=
currentTabTitleScope
.
join
(
'
·
'
);
},
animate
(
title
,
description
)
{
this
.
title
=
title
;
this
.
description
=
description
;
this
.
setTabTitle
();
this
.
$nextTick
(()
=>
{
this
.
updateFlag
(
'
titleFlag
'
,
false
);
this
.
updateFlag
(
'
descriptionFlag
'
,
false
);
});
},
triggerAnimation
()
{
// always reset to false before checking the change
this
.
descriptionChange
=
false
;
const
{
title
,
description
}
=
this
.
apiData
;
this
.
descriptionText
=
this
.
apiData
.
description_text
;
const
noTitleChange
=
this
.
title
===
title
;
const
noDescriptionChange
=
this
.
description
===
description
;
/**
* since opacity is changed, even if there is no diff for Vue to update
* we must check the title/description even on a 304 to ensure no visual change
*/
if
(
noTitleChange
&&
noDescriptionChange
)
return
;
this
.
elementsToVisualize
(
noTitleChange
,
noDescriptionChange
);
this
.
animate
(
title
,
description
);
},
updateEditedTimeAgo
()
{
const
toolTipTime
=
gl
.
utils
.
formatDate
(
this
.
apiData
.
updated_at
);
this
.
timeAgoEl
.
attr
(
'
datetime
'
,
this
.
apiData
.
updated_at
);
this
.
timeAgoEl
.
attr
(
'
title
'
,
toolTipTime
).
tooltip
(
'
fixTitle
'
);
},
},
created
()
{
if
(
!
Visibility
.
hidden
())
{
this
.
poll
.
makeRequest
();
}
Visibility
.
change
(()
=>
{
if
(
!
Visibility
.
hidden
())
{
this
.
poll
.
restart
();
}
else
{
this
.
poll
.
stop
();
}
});
},
updated
()
{
// if new html is injected (description changed) - bind TaskList and call renderGFM
if
(
this
.
descriptionChange
)
{
this
.
updateEditedTimeAgo
();
$
(
this
.
$refs
[
'
issue-content-container-gfm-entry
'
]).
renderGFM
();
const
tl
=
new
gl
.
TaskList
({
dataType
:
'
issue
'
,
fieldName
:
'
description
'
,
selector
:
'
.detail-page-description
'
,
});
return
tl
&&
null
;
}
return
null
;
},
};
</
script
>
<
template
>
<div>
<h2
class=
"title"
:class=
"
{ 'issue-realtime-pre-pulse': titleFlag.pre, 'issue-realtime-trigger-pulse': titleFlag.pulse }"
ref="issue-title"
v-html="title"
>
</h2>
<div
class=
"description is-task-list-enabled"
:class=
"canUpdateTasksClass"
v-if=
"description"
>
<div
class=
"wiki"
:class=
"
{ 'issue-realtime-pre-pulse': descriptionFlag.pre, 'issue-realtime-trigger-pulse': descriptionFlag.pulse }"
v-html="description"
ref="issue-content-container-gfm-entry"
>
</div>
<textarea
class=
"hidden js-task-list-field"
v-if=
"descriptionText"
>
{{
descriptionText
}}
</textarea>
</div>
</div>
</
template
>
app/assets/stylesheets/pages/issues.scss
View file @
f158dd2a
...
@@ -18,6 +18,15 @@
...
@@ -18,6 +18,15 @@
}
}
}
}
.issue-realtime-pre-pulse
{
opacity
:
0
;
}
.issue-realtime-trigger-pulse
{
transition
:
opacity
$fade-in-duration
linear
;
opacity
:
1
;
}
.check-all-holder
{
.check-all-holder
{
line-height
:
36px
;
line-height
:
36px
;
float
:
left
;
float
:
left
;
...
...
app/controllers/projects/issues_controller.rb
View file @
f158dd2a
...
@@ -209,7 +209,16 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -209,7 +209,16 @@ class Projects::IssuesController < Projects::ApplicationController
def
rendered_title
def
rendered_title
Gitlab
::
PollingInterval
.
set_header
(
response
,
interval:
3_000
)
Gitlab
::
PollingInterval
.
set_header
(
response
,
interval:
3_000
)
render
json:
{
title:
view_context
.
markdown_field
(
@issue
,
:title
)
}
render
json:
{
title:
view_context
.
markdown_field
(
@issue
,
:title
),
title_text:
@issue
.
title
,
description:
view_context
.
markdown_field
(
@issue
,
:description
),
description_text:
@issue
.
description
,
task_status:
@issue
.
task_status
,
issue_number:
@issue
.
iid
,
updated_at:
@issue
.
updated_at
,
}
end
end
def
create_merge_request
def
create_merge_request
...
...
app/views/projects/issues/show.html.haml
View file @
f158dd2a
...
@@ -50,17 +50,12 @@
...
@@ -50,17 +50,12 @@
=
link_to
'Edit'
,
edit_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
),
class:
'hidden-xs hidden-sm btn btn-grouped issuable-edit'
=
link_to
'Edit'
,
edit_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
),
class:
'hidden-xs hidden-sm btn btn-grouped issuable-edit'
.issue-details.issuable-details
.issue-details.issuable-details
.detail-page-description.content-block
.detail-page-description.content-block
{
class:
(
'hide-bottom-border'
unless
@issue
.
description
.
present?
)
}
.issue-title-data.hidden
{
"data"
=>
{
"
initial-title"
=>
markdown_field
(
@issue
,
:titl
e
),
.issue-title-data.hidden
{
"data"
=>
{
"
endpoint"
=>
rendered_title_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issu
e
),
"
endpoint"
=>
rendered_title_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
@issue
)
,
"
can-update-tasks-class"
=>
can?
(
current_user
,
:update_issue
,
@issue
)
?
'js-task-list-container'
:
''
,
}
}
}
}
.issue-title-entrypoint
.issue-title-entrypoint
-
if
@issue
.
description
.
present?
.description
{
class:
can?
(
current_user
,
:update_issue
,
@issue
)
?
'js-task-list-container'
:
''
}
.wiki
=
markdown_field
(
@issue
,
:description
)
%textarea
.hidden.js-task-list-field
=
@issue
.
description
=
edited_time_ago_with_tooltip
(
@issue
,
placement:
'bottom'
,
html_class:
'issue_edited_ago'
)
=
edited_time_ago_with_tooltip
(
@issue
,
placement:
'bottom'
,
html_class:
'issue_edited_ago'
)
#merge-requests
{
data:
{
url:
referenced_merge_requests_namespace_project_issue_url
(
@project
.
namespace
,
@project
,
@issue
)
}
}
#merge-requests
{
data:
{
url:
referenced_merge_requests_namespace_project_issue_url
(
@project
.
namespace
,
@project
,
@issue
)
}
}
...
...
features/project/issues/issues.feature
View file @
f158dd2a
...
@@ -82,6 +82,7 @@ Feature: Project Issues
...
@@ -82,6 +82,7 @@ Feature: Project Issues
# Markdown
# Markdown
@javascript
Scenario
:
Headers inside the description should have ids generated for them.
Scenario
:
Headers inside the description should have ids generated for them.
Given
I visit issue page
"Release 0.4"
Given
I visit issue page
"Release 0.4"
Then
Header
"Description header"
should have correct id and link
Then
Header
"Description header"
should have correct id and link
...
...
spec/features/issues/award_spec.rb
View file @
f158dd2a
...
@@ -6,9 +6,12 @@ feature 'Issue awards', js: true, feature: true do
...
@@ -6,9 +6,12 @@ feature 'Issue awards', js: true, feature: true do
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
describe
'logged in'
do
describe
'logged in'
do
include
WaitForVueResource
before
do
before
do
login_as
(
user
)
login_as
(
user
)
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
wait_for_vue_resource
end
end
it
'adds award to issue'
do
it
'adds award to issue'
do
...
@@ -38,8 +41,11 @@ feature 'Issue awards', js: true, feature: true do
...
@@ -38,8 +41,11 @@ feature 'Issue awards', js: true, feature: true do
end
end
describe
'logged out'
do
describe
'logged out'
do
include
WaitForVueResource
before
do
before
do
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
wait_for_vue_resource
end
end
it
'does not see award menu button'
do
it
'does not see award menu button'
do
...
...
spec/features/task_lists_spec.rb
View file @
f158dd2a
...
@@ -62,12 +62,15 @@ feature 'Task Lists', feature: true do
...
@@ -62,12 +62,15 @@ feature 'Task Lists', feature: true do
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
visit
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
end
end
describe
'for Issues'
do
describe
'for Issues'
,
feature:
true
do
describe
'multiple tasks'
do
describe
'multiple tasks'
,
js:
true
do
include
WaitForVueResource
let!
(
:issue
)
{
create
(
:issue
,
description:
markdown
,
author:
user
,
project:
project
)
}
let!
(
:issue
)
{
create
(
:issue
,
description:
markdown
,
author:
user
,
project:
project
)
}
it
'renders'
do
it
'renders'
do
visit_issue
(
project
,
issue
)
visit_issue
(
project
,
issue
)
wait_for_vue_resource
expect
(
page
).
to
have_selector
(
'ul.task-list'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'ul.task-list'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'li.task-list-item'
,
count:
6
)
expect
(
page
).
to
have_selector
(
'li.task-list-item'
,
count:
6
)
...
@@ -76,25 +79,24 @@ feature 'Task Lists', feature: true do
...
@@ -76,25 +79,24 @@ feature 'Task Lists', feature: true do
it
'contains the required selectors'
do
it
'contains the required selectors'
do
visit_issue
(
project
,
issue
)
visit_issue
(
project
,
issue
)
wait_for_vue_resource
container
=
'.detail-page-description .description.js-task-list-container'
expect
(
page
).
to
have_selector
(
".wiki .task-list .task-list-item .task-list-item-checkbox"
)
expect
(
page
).
to
have_selector
(
container
)
expect
(
page
).
to
have_selector
(
"
#{
container
}
.wiki .task-list .task-list-item .task-list-item-checkbox"
)
expect
(
page
).
to
have_selector
(
"
#{
container
}
.js-task-list-field"
)
expect
(
page
).
to
have_selector
(
'form.js-issuable-update'
)
expect
(
page
).
to
have_selector
(
'a.btn-close'
)
expect
(
page
).
to
have_selector
(
'a.btn-close'
)
end
end
it
'is only editable by author'
do
it
'is only editable by author'
do
visit_issue
(
project
,
issue
)
visit_issue
(
project
,
issue
)
expect
(
page
).
to
have_selector
(
'.js-task-list-container'
)
wait_for_vue_resource
logout
(
:user
)
expect
(
page
).
to
have_selector
(
".wiki .task-list .task-list-item .task-list-item-checkbox"
)
logout
(
:user
)
login_as
(
user2
)
login_as
(
user2
)
visit
current_path
visit
current_path
expect
(
page
).
not_to
have_selector
(
'.js-task-list-container'
)
wait_for_vue_resource
expect
(
page
).
to
have_selector
(
".wiki .task-list .task-list-item .task-list-item-checkbox"
)
end
end
it
'provides a summary on Issues#index'
do
it
'provides a summary on Issues#index'
do
...
@@ -103,11 +105,14 @@ feature 'Task Lists', feature: true do
...
@@ -103,11 +105,14 @@ feature 'Task Lists', feature: true do
end
end
end
end
describe
'single incomplete task'
do
describe
'single incomplete task'
,
js:
true
do
include
WaitForVueResource
let!
(
:issue
)
{
create
(
:issue
,
description:
singleIncompleteMarkdown
,
author:
user
,
project:
project
)
}
let!
(
:issue
)
{
create
(
:issue
,
description:
singleIncompleteMarkdown
,
author:
user
,
project:
project
)
}
it
'renders'
do
it
'renders'
do
visit_issue
(
project
,
issue
)
visit_issue
(
project
,
issue
)
wait_for_vue_resource
expect
(
page
).
to
have_selector
(
'ul.task-list'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'ul.task-list'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'li.task-list-item'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'li.task-list-item'
,
count:
1
)
...
@@ -116,15 +121,18 @@ feature 'Task Lists', feature: true do
...
@@ -116,15 +121,18 @@ feature 'Task Lists', feature: true do
it
'provides a summary on Issues#index'
do
it
'provides a summary on Issues#index'
do
visit
namespace_project_issues_path
(
project
.
namespace
,
project
)
visit
namespace_project_issues_path
(
project
.
namespace
,
project
)
expect
(
page
).
to
have_content
(
"0 of 1 task completed"
)
expect
(
page
).
to
have_content
(
"0 of 1 task completed"
)
end
end
end
end
describe
'single complete task'
do
describe
'single complete task'
,
js:
true
do
include
WaitForVueResource
let!
(
:issue
)
{
create
(
:issue
,
description:
singleCompleteMarkdown
,
author:
user
,
project:
project
)
}
let!
(
:issue
)
{
create
(
:issue
,
description:
singleCompleteMarkdown
,
author:
user
,
project:
project
)
}
it
'renders'
do
it
'renders'
do
visit_issue
(
project
,
issue
)
visit_issue
(
project
,
issue
)
wait_for_vue_resource
expect
(
page
).
to
have_selector
(
'ul.task-list'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'ul.task-list'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'li.task-list-item'
,
count:
1
)
expect
(
page
).
to
have_selector
(
'li.task-list-item'
,
count:
1
)
...
@@ -133,6 +141,7 @@ feature 'Task Lists', feature: true do
...
@@ -133,6 +141,7 @@ feature 'Task Lists', feature: true do
it
'provides a summary on Issues#index'
do
it
'provides a summary on Issues#index'
do
visit
namespace_project_issues_path
(
project
.
namespace
,
project
)
visit
namespace_project_issues_path
(
project
.
namespace
,
project
)
expect
(
page
).
to
have_content
(
"1 of 1 task completed"
)
expect
(
page
).
to
have_content
(
"1 of 1 task completed"
)
end
end
end
end
...
...
spec/javascripts/issue_show/issue_title_description_spec.js
0 → 100644
View file @
f158dd2a
import
Vue
from
'
vue
'
;
import
$
from
'
jquery
'
;
import
'
~/render_math
'
;
import
'
~/render_gfm
'
;
import
issueTitleDescription
from
'
~/issue_show/issue_title_description.vue
'
;
import
issueShowData
from
'
./mock_data
'
;
window
.
$
=
$
;
const
issueShowInterceptor
=
data
=>
(
request
,
next
)
=>
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
data
),
{
status
:
200
,
headers
:
{
'
POLL-INTERVAL
'
:
1
,
},
}));
};
describe
(
'
Issue Title
'
,
()
=>
{
document
.
body
.
innerHTML
=
'
<span id="task_status"></span>
'
;
let
IssueTitleDescriptionComponent
;
beforeEach
(()
=>
{
IssueTitleDescriptionComponent
=
Vue
.
extend
(
issueTitleDescription
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
issueShowInterceptor
);
});
it
(
'
should render a title/description and update title/description on update
'
,
(
done
)
=>
{
Vue
.
http
.
interceptors
.
push
(
issueShowInterceptor
(
issueShowData
.
initialRequest
));
const
issueShowComponent
=
new
IssueTitleDescriptionComponent
({
propsData
:
{
canUpdateIssue
:
'
.css-stuff
'
,
endpoint
:
'
/gitlab-org/gitlab-shell/issues/9/rendered_title
'
,
},
}).
$mount
();
setTimeout
(()
=>
{
expect
(
document
.
querySelector
(
'
title
'
).
innerText
).
toContain
(
'
this is a title (#1)
'
);
expect
(
issueShowComponent
.
$el
.
querySelector
(
'
.title
'
).
innerHTML
).
toContain
(
'
<p>this is a title</p>
'
);
expect
(
issueShowComponent
.
$el
.
querySelector
(
'
.wiki
'
).
innerHTML
).
toContain
(
'
<p>this is a description!</p>
'
);
expect
(
issueShowComponent
.
$el
.
querySelector
(
'
.js-task-list-field
'
).
innerText
).
toContain
(
'
this is a description
'
);
Vue
.
http
.
interceptors
.
push
(
issueShowInterceptor
(
issueShowData
.
secondRequest
));
setTimeout
(()
=>
{
expect
(
document
.
querySelector
(
'
title
'
).
innerText
).
toContain
(
'
2 (#1)
'
);
expect
(
issueShowComponent
.
$el
.
querySelector
(
'
.title
'
).
innerHTML
).
toContain
(
'
<p>2</p>
'
);
expect
(
issueShowComponent
.
$el
.
querySelector
(
'
.wiki
'
).
innerHTML
).
toContain
(
'
<p>42</p>
'
);
expect
(
issueShowComponent
.
$el
.
querySelector
(
'
.js-task-list-field
'
).
innerText
).
toContain
(
'
42
'
);
done
();
});
});
});
});
spec/javascripts/issue_show/issue_title_spec.js
deleted
100644 → 0
View file @
3fddf612
import
Vue
from
'
vue
'
;
import
issueTitle
from
'
~/issue_show/issue_title.vue
'
;
describe
(
'
Issue Title
'
,
()
=>
{
let
IssueTitleComponent
;
beforeEach
(()
=>
{
IssueTitleComponent
=
Vue
.
extend
(
issueTitle
);
});
it
(
'
should render a title
'
,
()
=>
{
const
component
=
new
IssueTitleComponent
({
propsData
:
{
initialTitle
:
'
wow
'
,
endpoint
:
'
/gitlab-org/gitlab-shell/issues/9/rendered_title
'
,
},
}).
$mount
();
expect
(
component
.
$el
.
classList
).
toContain
(
'
title
'
);
expect
(
component
.
$el
.
innerHTML
).
toContain
(
'
wow
'
);
});
});
spec/javascripts/issue_show/mock_data.js
0 → 100644
View file @
f158dd2a
export
default
{
initialRequest
:
{
title
:
'
<p>this is a title</p>
'
,
title_text
:
'
this is a title
'
,
description
:
'
<p>this is a description!</p>
'
,
description_text
:
'
this is a description
'
,
issue_number
:
1
,
task_status
:
'
2 of 4 completed
'
,
},
secondRequest
:
{
title
:
'
<p>2</p>
'
,
title_text
:
'
2
'
,
description
:
'
<p>42</p>
'
,
description_text
:
'
42
'
,
issue_number
:
1
,
task_status
:
'
0 of 0 completed
'
,
},
issueSpecRequest
:
{
title
:
'
<p>this is a title</p>
'
,
title_text
:
'
this is a title
'
,
description
:
'
<li class="task-list-item enabled"><input type="checkbox" class="task-list-item-checkbox">Task List Item</li>
'
,
description_text
:
'
- [ ] Task List Item
'
,
issue_number
:
1
,
task_status
:
'
0 of 1 completed
'
,
},
};
spec/javascripts/issue_spec.js
View file @
f158dd2a
...
@@ -81,12 +81,6 @@ describe('Issue', function() {
...
@@ -81,12 +81,6 @@ describe('Issue', function() {
this
.
issue
=
new
Issue
();
this
.
issue
=
new
Issue
();
});
});
it
(
'
modifies the Markdown field
'
,
function
()
{
spyOn
(
jQuery
,
'
ajax
'
).
and
.
stub
();
$
(
'
input[type=checkbox]
'
).
attr
(
'
checked
'
,
true
).
trigger
(
'
change
'
);
expect
(
$
(
'
.js-task-list-field
'
).
val
()).
toBe
(
'
- [x] Task List Item
'
);
});
it
(
'
submits an ajax request on tasklist:changed
'
,
function
()
{
it
(
'
submits an ajax request on tasklist:changed
'
,
function
()
{
spyOn
(
jQuery
,
'
ajax
'
).
and
.
callFake
(
function
(
req
)
{
spyOn
(
jQuery
,
'
ajax
'
).
and
.
callFake
(
function
(
req
)
{
expect
(
req
.
type
).
toBe
(
'
PATCH
'
);
expect
(
req
.
type
).
toBe
(
'
PATCH
'
);
...
...
spec/support/features/issuable_slash_commands_shared_examples.rb
View file @
f158dd2a
...
@@ -25,7 +25,7 @@ shared_examples 'issuable record that supports slash commands in its description
...
@@ -25,7 +25,7 @@ shared_examples 'issuable record that supports slash commands in its description
wait_for_ajax
wait_for_ajax
end
end
describe
"new
#{
issuable_type
}
"
do
describe
"new
#{
issuable_type
}
"
,
js:
true
do
context
'with commands in the description'
do
context
'with commands in the description'
do
it
"creates the
#{
issuable_type
}
and interpret commands accordingly"
do
it
"creates the
#{
issuable_type
}
and interpret commands accordingly"
do
visit
public_send
(
"new_namespace_project_
#{
issuable_type
}
_path"
,
project
.
namespace
,
project
,
new_url_opts
)
visit
public_send
(
"new_namespace_project_
#{
issuable_type
}
_path"
,
project
.
namespace
,
project
,
new_url_opts
)
...
@@ -44,7 +44,7 @@ shared_examples 'issuable record that supports slash commands in its description
...
@@ -44,7 +44,7 @@ shared_examples 'issuable record that supports slash commands in its description
end
end
end
end
describe
"note on
#{
issuable_type
}
"
do
describe
"note on
#{
issuable_type
}
"
,
js:
true
do
before
do
before
do
visit
public_send
(
"namespace_project_
#{
issuable_type
}
_path"
,
project
.
namespace
,
project
,
issuable
)
visit
public_send
(
"namespace_project_
#{
issuable_type
}
_path"
,
project
.
namespace
,
project
,
issuable
)
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