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
c5e89ca0
Commit
c5e89ca0
authored
Feb 21, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
37993d95
499ca7f2
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
64 additions
and
57 deletions
+64
-57
app/assets/javascripts/notes/components/notes_app.vue
app/assets/javascripts/notes/components/notes_app.vue
+7
-0
app/views/projects/issues/_discussion.html.haml
app/views/projects/issues/_discussion.html.haml
+1
-1
app/views/projects/issues/show.html.haml
app/views/projects/issues/show.html.haml
+1
-2
spec/frontend/lib/utils/ajax_cache_spec.js
spec/frontend/lib/utils/ajax_cache_spec.js
+31
-54
spec/frontend/test_setup.js
spec/frontend/test_setup.js
+14
-0
spec/javascripts/notes/components/note_app_spec.js
spec/javascripts/notes/components/note_app_spec.js
+10
-0
No files found.
app/assets/javascripts/notes/components/notes_app.vue
View file @
c5e89ca0
...
@@ -90,8 +90,15 @@ export default {
...
@@ -90,8 +90,15 @@ export default {
this
.
fetchNotes
();
this
.
fetchNotes
();
}
}
},
},
allDiscussions
()
{
if
(
this
.
discussonsCount
)
{
this
.
discussonsCount
.
textContent
=
this
.
allDiscussions
.
length
;
}
},
},
},
created
()
{
created
()
{
this
.
discussonsCount
=
document
.
querySelector
(
'
.js-discussions-count
'
);
this
.
setNotesData
(
this
.
notesData
);
this
.
setNotesData
(
this
.
notesData
);
this
.
setNoteableData
(
this
.
noteableData
);
this
.
setNoteableData
(
this
.
noteableData
);
this
.
setUserData
(
this
.
userData
);
this
.
setUserData
(
this
.
userData
);
...
...
app/views/projects/issues/_discussion.html.haml
View file @
c5e89ca0
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
=
link_to
'Reopen issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :reopen
},
format:
'json'
),
data:
{
original_text:
"Reopen issue"
,
alternative_text:
"Comment & reopen issue"
},
class:
"btn btn-nr btn-reopen btn-comment js-note-target-reopen
#{
issue_button_visibility
(
@issue
,
false
)
}
"
,
title:
'Reopen issue'
=
link_to
'Reopen issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :reopen
},
format:
'json'
),
data:
{
original_text:
"Reopen issue"
,
alternative_text:
"Comment & reopen issue"
},
class:
"btn btn-nr btn-reopen btn-comment js-note-target-reopen
#{
issue_button_visibility
(
@issue
,
false
)
}
"
,
title:
'Reopen issue'
=
link_to
'Close issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :close
},
format:
'json'
),
data:
{
original_text:
"Close issue"
,
alternative_text:
"Comment & close issue"
},
class:
"btn btn-nr btn-close btn-comment js-note-target-close
#{
issue_button_visibility
(
@issue
,
true
)
}
"
,
title:
'Close issue'
=
link_to
'Close issue'
,
issue_path
(
@issue
,
issue:
{
state_event: :close
},
format:
'json'
),
data:
{
original_text:
"Close issue"
,
alternative_text:
"Comment & close issue"
},
class:
"btn btn-nr btn-close btn-comment js-note-target-close
#{
issue_button_visibility
(
@issue
,
true
)
}
"
,
title:
'Close issue'
%section
.js-vue-notes-event
%section
.
issuable-discussion.
js-vue-notes-event
#js-vue-notes
{
data:
{
notes_data:
notes_data
(
@issue
).
to_json
,
#js-vue-notes
{
data:
{
notes_data:
notes_data
(
@issue
).
to_json
,
noteable_data:
serialize_issuable
(
@issue
),
noteable_data:
serialize_issuable
(
@issue
),
noteable_type:
'Issue'
,
noteable_type:
'Issue'
,
...
...
app/views/projects/issues/show.html.haml
View file @
c5e89ca0
...
@@ -98,7 +98,6 @@
...
@@ -98,7 +98,6 @@
#js-vue-discussion-filter
{
data:
{
default_filter:
current_user
&
.
notes_filter_for
(
@issue
),
notes_filters:
UserPreference
.
notes_filters
.
to_json
}
}
#js-vue-discussion-filter
{
data:
{
default_filter:
current_user
&
.
notes_filter_for
(
@issue
),
notes_filters:
UserPreference
.
notes_filters
.
to_json
}
}
=
render
'new_branch'
unless
@issue
.
confidential?
=
render
'new_branch'
unless
@issue
.
confidential?
%section
.issuable-discussion
=
render_if_exists
'projects/issues/discussion'
=
render
'projects/issues/discussion'
=
render
'shared/issuable/sidebar'
,
issuable_sidebar:
@issuable_sidebar
,
assignees:
@issue
.
assignees
=
render
'shared/issuable/sidebar'
,
issuable_sidebar:
@issuable_sidebar
,
assignees:
@issue
.
assignees
spec/
javascripts
/lib/utils/ajax_cache_spec.js
→
spec/
frontend
/lib/utils/ajax_cache_spec.js
View file @
c5e89ca0
...
@@ -94,68 +94,54 @@ describe('AjaxCache', () => {
...
@@ -94,68 +94,54 @@ describe('AjaxCache', () => {
beforeEach
(()
=>
{
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
mock
=
new
MockAdapter
(
axios
);
spyOn
(
axios
,
'
get
'
).
and
.
callThrough
(
);
jest
.
spyOn
(
axios
,
'
get
'
);
});
});
afterEach
(()
=>
{
afterEach
(()
=>
{
mock
.
restore
();
mock
.
restore
();
});
});
it
(
'
stores and returns data from Ajax call if cache is empty
'
,
done
=>
{
it
(
'
stores and returns data from Ajax call if cache is empty
'
,
()
=>
{
mock
.
onGet
(
dummyEndpoint
).
reply
(
200
,
dummyResponse
);
mock
.
onGet
(
dummyEndpoint
).
reply
(
200
,
dummyResponse
);
AjaxCache
.
retrieve
(
dummyEndpoint
)
return
AjaxCache
.
retrieve
(
dummyEndpoint
).
then
(
data
=>
{
.
then
(
data
=>
{
expect
(
data
).
toEqual
(
dummyResponse
);
expect
(
data
).
toEqual
(
dummyResponse
);
expect
(
AjaxCache
.
internalStorage
[
dummyEndpoint
]).
toEqual
(
dummyResponse
);
expect
(
AjaxCache
.
internalStorage
[
dummyEndpoint
]).
toEqual
(
dummyResponse
);
})
});
.
then
(
done
)
.
catch
(
fail
);
});
});
it
(
'
makes no Ajax call if request is pending
'
,
done
=>
{
it
(
'
makes no Ajax call if request is pending
'
,
()
=>
{
mock
.
onGet
(
dummyEndpoint
).
reply
(
200
,
dummyResponse
);
mock
.
onGet
(
dummyEndpoint
).
reply
(
200
,
dummyResponse
);
AjaxCache
.
retrieve
(
dummyEndpoint
)
return
Promise
.
all
([
.
then
(
done
)
AjaxCache
.
retrieve
(
dummyEndpoint
),
.
catch
(
fail
);
AjaxCache
.
retrieve
(
dummyEndpoint
),
]).
then
(()
=>
{
AjaxCache
.
retrieve
(
dummyEndpoint
)
expect
(
axios
.
get
).
toHaveBeenCalledTimes
(
1
);
.
then
(
done
)
});
.
catch
(
fail
);
expect
(
axios
.
get
.
calls
.
count
()).
toBe
(
1
);
});
});
it
(
'
returns undefined if Ajax call fails and cache is empty
'
,
done
=>
{
it
(
'
returns undefined if Ajax call fails and cache is empty
'
,
()
=>
{
const
errorMessage
=
'
Network Error
'
;
const
errorMessage
=
'
Network Error
'
;
mock
.
onGet
(
dummyEndpoint
).
networkError
();
mock
.
onGet
(
dummyEndpoint
).
networkError
();
AjaxCache
.
retrieve
(
dummyEndpoint
)
expect
.
assertions
(
2
);
.
then
(
data
=>
fail
(
`Received unexpected data:
${
JSON
.
stringify
(
data
)}
`
))
return
AjaxCache
.
retrieve
(
dummyEndpoint
).
catch
(
error
=>
{
.
catch
(
error
=>
{
expect
(
error
.
message
).
toBe
(
`
${
dummyEndpoint
}
:
${
errorMessage
}
`
);
expect
(
error
.
message
).
toBe
(
`
${
dummyEndpoint
}
:
${
errorMessage
}
`
);
expect
(
error
.
textStatus
).
toBe
(
errorMessage
);
expect
(
error
.
textStatus
).
toBe
(
errorMessage
);
done
();
});
})
.
catch
(
fail
);
});
});
it
(
'
makes no Ajax call if matching data exists
'
,
done
=>
{
it
(
'
makes no Ajax call if matching data exists
'
,
()
=>
{
AjaxCache
.
internalStorage
[
dummyEndpoint
]
=
dummyResponse
;
AjaxCache
.
internalStorage
[
dummyEndpoint
]
=
dummyResponse
;
mock
.
onGet
(
dummyEndpoint
).
reply
(()
=>
{
fail
(
new
Error
(
'
expected no Ajax call!
'
));
});
AjaxCache
.
retrieve
(
dummyEndpoint
)
return
AjaxCache
.
retrieve
(
dummyEndpoint
).
then
(
data
=>
{
.
then
(
data
=>
{
expect
(
data
).
toBe
(
dummyResponse
);
expect
(
data
).
toBe
(
dummyResponse
);
})
expect
(
axios
.
get
).
not
.
toHaveBeenCalled
();
.
then
(
done
)
});
.
catch
(
fail
);
});
});
it
(
'
makes Ajax call even if matching data exists when forceRequest parameter is provided
'
,
done
=>
{
it
(
'
makes Ajax call even if matching data exists when forceRequest parameter is provided
'
,
()
=>
{
const
oldDummyResponse
=
{
const
oldDummyResponse
=
{
important
:
'
old dummy data
'
,
important
:
'
old dummy data
'
,
};
};
...
@@ -164,21 +150,12 @@ describe('AjaxCache', () => {
...
@@ -164,21 +150,12 @@ describe('AjaxCache', () => {
mock
.
onGet
(
dummyEndpoint
).
reply
(
200
,
dummyResponse
);
mock
.
onGet
(
dummyEndpoint
).
reply
(
200
,
dummyResponse
);
// Call without forceRetrieve param
return
Promise
.
all
([
AjaxCache
.
retrieve
(
dummyEndpoint
)
AjaxCache
.
retrieve
(
dummyEndpoint
),
.
then
(
data
=>
{
AjaxCache
.
retrieve
(
dummyEndpoint
,
true
),
expect
(
data
).
toBe
(
oldDummyResponse
);
]).
then
(
data
=>
{
})
expect
(
data
).
toEqual
([
oldDummyResponse
,
dummyResponse
]);
.
then
(
done
)
});
.
catch
(
fail
);
// Call with forceRetrieve param
AjaxCache
.
retrieve
(
dummyEndpoint
,
true
)
.
then
(
data
=>
{
expect
(
data
).
toEqual
(
dummyResponse
);
})
.
then
(
done
)
.
catch
(
fail
);
});
});
});
});
});
});
spec/frontend/test_setup.js
View file @
c5e89ca0
import
axios
from
'
~/lib/utils/axios_utils
'
;
const
testTimeoutInMs
=
300
;
const
testTimeoutInMs
=
300
;
jest
.
setTimeout
(
testTimeoutInMs
);
jest
.
setTimeout
(
testTimeoutInMs
);
...
@@ -14,3 +16,15 @@ afterEach(() => {
...
@@ -14,3 +16,15 @@ afterEach(() => {
throw
new
Error
(
`Test took too long (
${
elapsedTimeInMs
}
ms >
${
testTimeoutInMs
}
ms)!`
);
throw
new
Error
(
`Test took too long (
${
elapsedTimeInMs
}
ms >
${
testTimeoutInMs
}
ms)!`
);
}
}
});
});
// fail tests for unmocked requests
beforeEach
(
done
=>
{
axios
.
defaults
.
adapter
=
config
=>
{
const
error
=
new
Error
(
`Unexpected unmocked request:
${
JSON
.
stringify
(
config
,
null
,
2
)}
`
);
error
.
config
=
config
;
done
.
fail
(
error
);
return
Promise
.
reject
(
error
);
};
done
();
});
spec/javascripts/notes/components/note_app_spec.js
View file @
c5e89ca0
...
@@ -83,6 +83,8 @@ describe('note_app', () => {
...
@@ -83,6 +83,8 @@ describe('note_app', () => {
describe
(
'
render
'
,
()
=>
{
describe
(
'
render
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
setFixtures
(
'
<div class="js-discussions-count"></div>
'
);
Vue
.
http
.
interceptors
.
push
(
mockData
.
individualNoteInterceptor
);
Vue
.
http
.
interceptors
.
push
(
mockData
.
individualNoteInterceptor
);
wrapper
=
mountComponent
();
wrapper
=
mountComponent
();
});
});
...
@@ -127,6 +129,14 @@ describe('note_app', () => {
...
@@ -127,6 +129,14 @@ describe('note_app', () => {
it
(
'
should render form comment button as disabled
'
,
()
=>
{
it
(
'
should render form comment button as disabled
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
.js-note-new-discussion
'
).
attributes
(
'
disabled
'
)).
toEqual
(
'
disabled
'
);
expect
(
wrapper
.
find
(
'
.js-note-new-discussion
'
).
attributes
(
'
disabled
'
)).
toEqual
(
'
disabled
'
);
});
});
it
(
'
updates discussions badge
'
,
done
=>
{
setTimeout
(()
=>
{
expect
(
document
.
querySelector
(
'
.js-discussions-count
'
).
textContent
).
toEqual
(
'
2
'
);
done
();
});
});
});
});
describe
(
'
while fetching data
'
,
()
=>
{
describe
(
'
while fetching data
'
,
()
=>
{
...
...
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