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
0c1cf679
Commit
0c1cf679
authored
Aug 09, 2017
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ci skip] Adds tests for issue app
parent
23334ac0
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
275 additions
and
195 deletions
+275
-195
app/assets/javascripts/notes/components/issue_comment_form.vue
...ssets/javascripts/notes/components/issue_comment_form.vue
+2
-3
app/assets/javascripts/notes/components/issue_note_form.vue
app/assets/javascripts/notes/components/issue_note_form.vue
+4
-4
app/assets/javascripts/notes/components/issue_notes_app.vue
app/assets/javascripts/notes/components/issue_notes_app.vue
+3
-3
spec/javascripts/notes/components/issue_note_app_spec.js
spec/javascripts/notes/components/issue_note_app_spec.js
+131
-91
spec/javascripts/notes/mock_data.js
spec/javascripts/notes/mock_data.js
+135
-94
No files found.
app/assets/javascripts/notes/components/issue_comment_form.vue
View file @
0c1cf679
...
@@ -175,7 +175,6 @@
...
@@ -175,7 +175,6 @@
this
.
noteType
=
type
;
this
.
noteType
=
type
;
},
},
editCurrentUserLastNote
()
{
editCurrentUserLastNote
()
{
console
.
log
(
'
editCurrentUserLastNote
'
)
if
(
this
.
note
===
''
)
{
if
(
this
.
note
===
''
)
{
const
lastNote
=
this
.
getCurrentUserLastNote
(
window
.
gon
.
current_user_id
);
const
lastNote
=
this
.
getCurrentUserLastNote
(
window
.
gon
.
current_user_id
);
...
@@ -254,7 +253,7 @@
...
@@ -254,7 +253,7 @@
:disabled=
"isSubmitButtonDisabled"
:disabled=
"isSubmitButtonDisabled"
name=
"button"
name=
"button"
type=
"button"
type=
"button"
class=
"btn
btn-nr
comment-btn note-type-toggle js-note-new-discussion dropdown-toggle"
class=
"btn comment-btn note-type-toggle js-note-new-discussion dropdown-toggle"
data-toggle=
"dropdown"
data-toggle=
"dropdown"
aria-label=
"Open comment type dropdown"
>
aria-label=
"Open comment type dropdown"
>
<i
<i
...
@@ -305,7 +304,7 @@
...
@@ -305,7 +304,7 @@
type=
"submit"
type=
"submit"
v-if=
"canUpdateIssue"
v-if=
"canUpdateIssue"
:class=
"actionButtonClassNames"
:class=
"actionButtonClassNames"
class=
"btn btn-
nr btn-
comment btn-comment-and-close"
>
class=
"btn btn-comment btn-comment-and-close"
>
{{
issueActionButtonTitle
}}
{{
issueActionButtonTitle
}}
</button>
</button>
<button
<button
...
...
app/assets/javascripts/notes/components/issue_note_form.vue
View file @
0c1cf679
...
@@ -56,7 +56,7 @@
...
@@ -56,7 +56,7 @@
return
this
.
getNotesDataByProp
(
'
markdownDocs
'
);
return
this
.
getNotesDataByProp
(
'
markdownDocs
'
);
},
},
quickActionsDocsUrl
()
{
quickActionsDocsUrl
()
{
return
this
.
getNotesDataByProp
(
'
quickActionsDocs
'
)
;
return
!
this
.
isEditing
?
this
.
getNotesDataByProp
(
'
quickActionsDocs
'
)
:
undefined
;
},
},
currentUserId
()
{
currentUserId
()
{
return
this
.
getUserDataByProp
(
'
id
'
);
return
this
.
getUserDataByProp
(
'
id
'
);
...
@@ -134,15 +134,15 @@
...
@@ -134,15 +134,15 @@
ref=
"textarea"
ref=
"textarea"
slot=
"textarea"
slot=
"textarea"
placeholder=
"Write a comment or drag your files here..."
placeholder=
"Write a comment or drag your files here..."
@
keydown.meta.enter=
"handleUpdate"
@
keydown.meta.enter=
"handleUpdate
()
"
@
keydown.up=
"editMyLastNote"
@
keydown.up=
"editMyLastNote
()
"
@
keydown.esc=
"cancelHandler(true)"
>
@
keydown.esc=
"cancelHandler(true)"
>
</textarea>
</textarea>
</markdown-field>
</markdown-field>
<div
class=
"note-form-actions clearfix"
>
<div
class=
"note-form-actions clearfix"
>
<button
<button
type=
"submit"
type=
"submit"
@
click=
"handleUpdate"
@
click=
"handleUpdate
()
"
:disabled=
"isDisabled"
:disabled=
"isDisabled"
class=
"js-vue-issue-save btn btn-save"
>
class=
"js-vue-issue-save btn btn-save"
>
{{
saveButtonTitle
}}
{{
saveButtonTitle
}}
...
...
app/assets/javascripts/notes/components/issue_notes_app.vue
View file @
0c1cf679
...
@@ -97,11 +97,11 @@
...
@@ -97,11 +97,11 @@
},
},
checkLocationHash
()
{
checkLocationHash
()
{
const
hash
=
gl
.
utils
.
getLocationHash
();
const
hash
=
gl
.
utils
.
getLocationHash
();
const
$el
=
$
(
`#
${
hash
}
`
);
const
element
=
document
.
getElementById
(
hash
);
if
(
hash
&&
$el
)
{
if
(
hash
&&
element
)
{
this
.
setTargetNoteHash
(
hash
);
this
.
setTargetNoteHash
(
hash
);
this
.
scrollToNoteIfNeeded
(
$
el
);
this
.
scrollToNoteIfNeeded
(
$
(
element
)
);
}
}
},
},
},
},
...
...
spec/javascripts/notes/components/issue_note_app_spec.js
View file @
0c1cf679
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
issueNotesApp
from
'
~/notes/components/issue_notes_app.vue
'
;
import
issueNotesApp
from
'
~/notes/components/issue_notes_app.vue
'
;
import
service
from
'
~/notes/services/issue_notes_service
'
;
import
service
from
'
~/notes/services/issue_notes_service
'
;
import
{
keyboardDownEvent
}
from
'
../../issue_show/helpers
'
;
import
*
as
mockData
from
'
../mock_data
'
;
import
*
as
mockData
from
'
../mock_data
'
;
describe
(
'
issue_note_app
'
,
()
=>
{
describe
(
'
issue_note_app
'
,
()
=>
{
let
mountComponent
;
let
mountComponent
;
let
vm
;
const
individualNoteInterceptor
=
(
request
,
next
)
=>
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
mockData
.
individualNoteServerResponse
),
{
status
:
200
,
}));
};
const
discussionNoteInterceptor
=
(
request
,
next
)
=>
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
mockData
.
discussionNoteServerResponse
),
{
status
:
200
,
}));
};
beforeEach
(()
=>
{
beforeEach
(()
=>
{
const
IssueNotesApp
=
Vue
.
extend
(
issueNotesApp
);
const
IssueNotesApp
=
Vue
.
extend
(
issueNotesApp
);
mountComponent
=
props
=>
new
IssueNotesApp
({
mountComponent
=
(
data
)
=>
{
const
props
=
data
||
{
issueData
:
mockData
.
issueDataMock
,
notesData
:
mockData
.
notesDataMock
,
userData
:
mockData
.
userDataMock
,
};
return
new
IssueNotesApp
({
propsData
:
props
,
propsData
:
props
,
}).
$mount
();
}).
$mount
();
};
});
});
describe
(
'
set data
'
,
()
=>
{
afterEach
(()
=>
{
let
vm
;
vm
.
$destroy
();
});
describe
(
'
set data
'
,
()
=>
{
const
responseInterceptor
=
(
request
,
next
)
=>
{
const
responseInterceptor
=
(
request
,
next
)
=>
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
next
(
request
.
respondWith
(
JSON
.
stringify
([]),
{
status
:
200
,
status
:
200
,
...
@@ -26,11 +48,7 @@ describe('issue_note_app', () => {
...
@@ -26,11 +48,7 @@ describe('issue_note_app', () => {
beforeEach
(()
=>
{
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
responseInterceptor
);
Vue
.
http
.
interceptors
.
push
(
responseInterceptor
);
vm
=
mountComponent
({
vm
=
mountComponent
();
issueData
:
mockData
.
issueDataMock
,
notesData
:
mockData
.
notesDataMock
,
userData
:
mockData
.
userDataMock
,
});
});
});
afterEach
(()
=>
{
afterEach
(()
=>
{
...
@@ -55,29 +73,17 @@ describe('issue_note_app', () => {
...
@@ -55,29 +73,17 @@ describe('issue_note_app', () => {
});
});
describe
(
'
render
'
,
()
=>
{
describe
(
'
render
'
,
()
=>
{
let
vm
;
const
responseInterceptor
=
(
request
,
next
)
=>
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
mockData
.
discussionResponse
),
{
status
:
200
,
}));
};
beforeEach
(()
=>
{
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
responseInterceptor
);
Vue
.
http
.
interceptors
.
push
(
individualNoteInterceptor
);
vm
=
mountComponent
({
vm
=
mountComponent
();
issueData
:
mockData
.
issueDataMock
,
notesData
:
mockData
.
notesDataMock
,
userData
:
mockData
.
userDataMock
,
});
});
});
afterEach
(()
=>
{
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
respons
eInterceptor
);
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
individualNot
eInterceptor
);
});
});
it
(
'
should render list of notes
'
,
(
done
)
=>
{
it
(
'
should render list of notes
'
,
(
done
)
=>
{
const
note
=
mockData
.
discussion
Response
[
0
].
notes
[
0
];
const
note
=
mockData
.
individualNoteServer
Response
[
0
].
notes
[
0
];
setTimeout
(()
=>
{
setTimeout
(()
=>
{
expect
(
expect
(
...
@@ -95,16 +101,17 @@ describe('issue_note_app', () => {
...
@@ -95,16 +101,17 @@ describe('issue_note_app', () => {
vm
.
$el
.
querySelector
(
'
.js-main-target-form textarea
'
).
getAttribute
(
'
placeholder
'
),
vm
.
$el
.
querySelector
(
'
.js-main-target-form textarea
'
).
getAttribute
(
'
placeholder
'
),
).
toEqual
(
'
Write a comment or drag your files here...
'
);
).
toEqual
(
'
Write a comment or drag your files here...
'
);
});
});
it
(
'
should render form comment button as disabled
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-note-new-discussion
'
).
getAttribute
(
'
disabled
'
),
).
toEqual
(
'
disabled
'
);
});
});
});
describe
(
'
while fetching data
'
,
()
=>
{
describe
(
'
while fetching data
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
({
vm
=
mountComponent
();
issueData
:
mockData
.
issueDataMock
,
notesData
:
mockData
.
notesDataMock
,
userData
:
mockData
.
userDataMock
,
});
});
});
it
(
'
should render loading icon
'
,
()
=>
{
it
(
'
should render loading icon
'
,
()
=>
{
...
@@ -121,104 +128,137 @@ describe('issue_note_app', () => {
...
@@ -121,104 +128,137 @@ describe('issue_note_app', () => {
describe
(
'
update note
'
,
()
=>
{
describe
(
'
update note
'
,
()
=>
{
describe
(
'
individual note
'
,
()
=>
{
describe
(
'
individual note
'
,
()
=>
{
let
vm
;
const
responseInterceptor
=
(
request
,
next
)
=>
{
next
(
request
.
respondWith
(
JSON
.
stringify
(
mockData
.
discussionResponse
),
{
status
:
200
,
}));
};
beforeEach
(()
=>
{
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
responseInterceptor
);
Vue
.
http
.
interceptors
.
push
(
individualNoteInterceptor
);
spyOn
(
service
,
'
updateNote
'
).
and
.
callFake
(()
=>
Promise
.
resolve
());
vm
=
mountComponent
({
vm
=
mountComponent
();
issueData
:
mockData
.
issueDataMock
,
notesData
:
mockData
.
notesDataMock
,
userData
:
mockData
.
userDataMock
,
});
});
});
afterEach
(()
=>
{
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
respons
eInterceptor
);
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
individualNot
eInterceptor
);
});
});
it
(
'
renders edit form
'
,
()
=>
{
it
(
'
renders edit form
'
,
(
done
)
=>
{
setTimeout
(()
=>
{
setTimeout
(()
=>
{
vm
.
$el
.
querySelector
(
'
.js-note-edit
'
).
click
();
vm
.
$el
.
querySelector
(
'
.js-note-edit
'
).
click
();
Vue
.
nextTick
(()
=>
{
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-vue-issue-note-form
'
)).
toBeDefined
();
expect
(
vm
.
$el
.
querySelector
(
'
.js-vue-issue-note-form
'
)).
toBeDefined
();
done
();
});
});
},
0
);
},
0
);
});
});
it
(
'
updates the note and resets the edit form
'
,
()
=>
{});
it
(
'
calls the service to update the note
'
,
(
done
)
=>
{
});
setTimeout
(()
=>
{
vm
.
$el
.
querySelector
(
'
.js-note-edit
'
).
click
();
Vue
.
nextTick
(()
=>
{
vm
.
$el
.
querySelector
(
'
.js-vue-issue-note-form
'
).
value
=
'
this is a note
'
;
vm
.
$el
.
querySelector
(
'
.js-vue-issue-save
'
).
click
();
describe
(
'
dicussion note note
'
,
()
=>
{
expect
(
service
.
updateNote
).
toHaveBeenCalled
();
it
(
'
renders edit form
'
,
()
=>
{
done
();
});
});
},
0
);
it
(
'
updates the note and resets the edit form
'
,
()
=>
{});
});
});
});
});
describe
(
'
set target hash
'
,
()
=>
{
describe
(
'
dicussion note
'
,
()
=>
{
it
(
'
updates the URL when the note date is clicked
'
,
()
=>
{
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
discussionNoteInterceptor
);
spyOn
(
service
,
'
updateNote
'
).
and
.
callFake
(()
=>
Promise
.
resolve
());
vm
=
mountComponent
();
});
});
it
(
'
stores the correct hash
'
,
()
=>
{
afterEach
(
()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
discussionNoteInterceptor
);
});
});
it
(
'
updates visually the target note
'
,
()
=>
{
it
(
'
renders edit form
'
,
(
done
)
=>
{
setTimeout
(()
=>
{
vm
.
$el
.
querySelector
(
'
.js-note-edit
'
).
click
();
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-vue-issue-note-form
'
)).
toBeDefined
();
done
();
});
});
},
0
);
});
});
describe
(
'
create new note
'
,
()
=>
{
it
(
'
updates the note and resets the edit form
'
,
(
done
)
=>
{
it
(
'
should show placeholder note while new comment is being posted
'
,
()
=>
{});
setTimeout
(()
=>
{
it
(
'
should remove placeholder note when new comment is done posting
'
,
()
=>
{});
vm
.
$el
.
querySelector
(
'
.js-note-edit
'
).
click
();
it
(
'
should show actual note element when new comment is done posting
'
,
()
=>
{});
Vue
.
nextTick
(()
=>
{
it
(
'
should show flash error message when new comment failed to be posted
'
,
()
=>
{});
vm
.
$el
.
querySelector
(
'
.js-vue-issue-note-form
'
).
value
=
'
this is a note
'
;
it
(
'
should show flash error message when comment failed to be updated
'
,
()
=>
{});
vm
.
$el
.
querySelector
(
'
.js-vue-issue-save
'
).
click
();
});
describe
(
'
quick actions
'
,
()
=>
{
expect
(
service
.
updateNote
).
toHaveBeenCalled
();
it
(
'
should return executing quick action description when note has single quick action
'
,
()
=>
{
done
();
});
});
},
0
);
it
(
'
should return generic multiple quick action description when note has multiple quick actions
'
,
()
=>
{
});
});
it
(
'
should return generic quick action description when available quick actions list is not populated
'
,
()
=>
{
});
});
});
});
describe
(
'
new note form
'
,
()
=>
{
describe
(
'
new note form
'
,
()
=>
{
it
(
'
should render markdown docs url
'
,
()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
();
});
it
(
'
should render markdown docs url
'
,
()
=>
{
const
{
markdownDocs
}
=
mockData
.
notesDataMock
;
expect
(
vm
.
$el
.
querySelector
(
`a[href="
${
markdownDocs
}
"]`
).
textContent
.
trim
()).
toEqual
(
'
Markdown
'
);
});
});
it
(
'
should render quick action docs url
'
,
()
=>
{
it
(
'
should render quick action docs url
'
,
()
=>
{
const
{
quickActionsDocs
}
=
mockData
.
notesDataMock
;
expect
(
vm
.
$el
.
querySelector
(
`a[href="
${
quickActionsDocs
}
"]`
).
textContent
.
trim
()).
toEqual
(
'
quick actions
'
);
});
});
describe
(
'
edit form
'
,
()
=>
{
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
individualNoteInterceptor
);
vm
=
mountComponent
();
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptors
,
individualNoteInterceptor
);
});
});
it
(
'
should preview markdown
'
,
()
=>
{
it
(
'
should render markdown docs url
'
,
(
done
)
=>
{
setTimeout
(()
=>
{
vm
.
$el
.
querySelector
(
'
.js-note-edit
'
).
click
();
const
{
markdownDocs
}
=
mockData
.
notesDataMock
;
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
`.edit-note a[href="
${
markdownDocs
}
"]`
).
textContent
.
trim
(),
).
toEqual
(
'
Markdown is supported
'
);
done
();
});
},
0
);
});
});
describe
(
'
discard draft
'
,
()
=>
{
it
(
'
should not render quick actions docs url
'
,
(
done
)
=>
{
it
(
'
should reset form when reset button is clicked
'
,
()
=>
{
setTimeout
(()
=>
{
vm
.
$el
.
querySelector
(
'
.js-note-edit
'
).
click
();
const
{
quickActionsDocs
}
=
mockData
.
notesDataMock
;
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
`.edit-note a[href="
${
quickActionsDocs
}
"]`
),
).
toEqual
(
null
);
done
();
});
});
},
0
);
});
});
});
});
describe
(
'
edit form
'
,
()
=>
{
// TODO: FILIPA
it
(
'
should render markdown docs url
'
,
()
=>
{});
describe
(
'
create new note
'
,
()
=>
{
it
(
'
should not render quick actions docs url
'
,
()
=>
{});
it
(
'
should show placeholder note while new comment is being posted
'
,
()
=>
{});
it
(
'
should remove placeholder note when new comment is done posting
'
,
()
=>
{});
it
(
'
should show actual note element when new comment is done posting
'
,
()
=>
{});
it
(
'
should show flash error message when new comment failed to be posted
'
,
()
=>
{});
it
(
'
should show flash error message when comment failed to be updated
'
,
()
=>
{});
});
});
});
});
spec/javascripts/notes/mock_data.js
View file @
0c1cf679
/* eslint disable */
/* eslint-disable */
export
const
notesDataMock
=
{
export
const
notesDataMock
=
{
discussionsPath
:
'
/gitlab-org/gitlab-ce/issues/26/discussions.json
'
,
discussionsPath
:
'
/gitlab-org/gitlab-ce/issues/26/discussions.json
'
,
lastFetchedAt
:
'
1501862675
'
,
lastFetchedAt
:
'
1501862675
'
,
...
@@ -222,7 +221,7 @@ export const discussionMock = {
...
@@ -222,7 +221,7 @@ export const discussionMock = {
individual_note
:
false
,
individual_note
:
false
,
};
};
export
const
discussion
Response
=
[{
export
const
individualNoteServer
Response
=
[{
"
id
"
:
"
0fb4e0e3f9276e55ff32eb4195add694aece4edd
"
,
"
id
"
:
"
0fb4e0e3f9276e55ff32eb4195add694aece4edd
"
,
"
reply_id
"
:
"
0fb4e0e3f9276e55ff32eb4195add694aece4edd
"
,
"
reply_id
"
:
"
0fb4e0e3f9276e55ff32eb4195add694aece4edd
"
,
"
expanded
"
:
true
,
"
expanded
"
:
true
,
...
@@ -275,7 +274,7 @@ export const discussionResponse = [{
...
@@ -275,7 +274,7 @@ export const discussionResponse = [{
"
path
"
:
"
/gitlab-org/gitlab-ce/notes/1390
"
"
path
"
:
"
/gitlab-org/gitlab-ce/notes/1390
"
}],
}],
"
individual_note
"
:
true
"
individual_note
"
:
true
},
{
},
{
"
id
"
:
"
70d5c92a4039a36c70100c6691c18c27e4b0a790
"
,
"
id
"
:
"
70d5c92a4039a36c70100c6691c18c27e4b0a790
"
,
"
reply_id
"
:
"
70d5c92a4039a36c70100c6691c18c27e4b0a790
"
,
"
reply_id
"
:
"
70d5c92a4039a36c70100c6691c18c27e4b0a790
"
,
"
expanded
"
:
true
,
"
expanded
"
:
true
,
...
@@ -315,3 +314,45 @@ export const discussionResponse = [{
...
@@ -315,3 +314,45 @@ export const discussionResponse = [{
}],
}],
"
individual_note
"
:
true
"
individual_note
"
:
true
}];
}];
export
const
discussionNoteServerResponse
=
[{
"
id
"
:
"
a3ed36e29b1957efb3b68c53e2d7a2b24b1df052
"
,
"
reply_id
"
:
"
a3ed36e29b1957efb3b68c53e2d7a2b24b1df052
"
,
"
expanded
"
:
true
,
"
notes
"
:
[{
"
id
"
:
1471
,
"
attachment
"
:
{
"
url
"
:
null
,
"
filename
"
:
null
,
"
image
"
:
false
},
"
author
"
:
{
"
id
"
:
1
,
"
name
"
:
"
Root
"
,
"
username
"
:
"
root
"
,
"
state
"
:
"
active
"
,
"
avatar_url
"
:
null
,
"
path
"
:
"
/root
"
},
"
created_at
"
:
"
2017-08-08T16:53:00.666Z
"
,
"
updated_at
"
:
"
2017-08-08T16:53:00.666Z
"
,
"
system
"
:
false
,
"
noteable_id
"
:
124
,
"
noteable_type
"
:
"
Issue
"
,
"
noteable_iid
"
:
29
,
"
type
"
:
"
DiscussionNote
"
,
"
human_access
"
:
"
Owner
"
,
"
note
"
:
"
Adding a comment
"
,
"
note_html
"
:
"
\
u003cp dir=
\"
auto
\"\
u003eAdding a comment
\
u003c/p
\
u003e
"
,
"
current_user
"
:
{
"
can_edit
"
:
true
},
"
discussion_id
"
:
"
a3ed36e29b1957efb3b68c53e2d7a2b24b1df052
"
,
"
emoji_awardable
"
:
true
,
"
award_emoji
"
:
[],
"
toggle_award_path
"
:
"
/gitlab-org/gitlab-ce/notes/1471/toggle_award_emoji
"
,
"
report_abuse_path
"
:
"
/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F29%23note_1471
\
u0026user_id=1
"
,
"
path
"
:
"
/gitlab-org/gitlab-ce/notes/1471
"
}],
"
individual_note
"
:
false
}];
\ No newline at end of file
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